How to exclude java source files in doc task? - scala

I'm using sbt 0.11.2 for a mixed Java/Scala project. I've realized that when I run the doc command from within sbt, it does not only create the scaladocs for the Scala source files in src/main/scala, but also for the Java source files in src/main/java (the sbt wiki claims to create them for src/main/scala only that seems not true).
However, this does not look very well. For instance, for a Java class named Foo with static methods there are two entries in the generated scaladoc: a Foo class and a Foo object. The class only lists the constructor and the object lists the static methods.
Is there any way I can tell sbt to exclude the src/main/java folder from the scaladoc generation? I want to create javadocs for those instead.

The usual way to handle that is to use inspect to see where the information is coming from, and then change it. Inspecting at doc shows compile:sources(for doc), which is a Seq[java.io.File], and can be changed like this:
sources in (Compile, doc) ~= (_ filter (_.getName endsWith ".scala"))
You can use show compile:sources(for doc) to see what it contains, and then set to change it and check again its value.

Related

Is there any options to disable source maps generation in ScalaJS sbt plugin?

I would like to disable source maps generation for fullOptJS (production mode).
It is not always appropriate to have all the information about original Scala source files.
I didn't find any suitable options to disable output entirely or something similar?
Is there any link to the documentation with all the options available for scalajs sbt plugin?
Thanks for any help
The sbt setting scalaJSLinkerConfig, of type StandardLinker.Config, contains all the options you can possibly give to the Scala.js linker, i.e., the thing that optimizes everything and emits a .js file. For some reason, Scaladoc refuses to display the comments on of the vals, although they exist in the source code.
You can see there a val sourceMap: Boolean, which clearly configures whether the linker is going to emit source maps. You can set it to false in fullOptJS with the following sbt incantation, to be placed in the .settings(...) of the relevant project:
scalaJSLinkerConfig in (Compile, fullOptJS) ~= { _.withSourceMap(false) }
(see also this answer about what ~= means in sbt)

Adding resource to project-specific SBT autoplugins

SBT lets you define autoplugins specific to your project by putting them in ./project.
I'm trying to add resources to one such autoplugin - by which I mean something that it could access through a call to getClass.getResourceAsStream.
I have, however, not been able to work out how to do that, or even if it was possible. There's no documentation that I could find on the subject, and the obvious (simply putting resources in ./project with the plugin) fails.
Is what I'm trying to achieve possible?
Yes, you need to place your resource in ./project/src/main/resources/
For a quick demonstration that this works, assume the file name is test.txt, put the following in your build.sbt:
lazy val hello = taskKey[Unit]("prints the content of test.txt")
hello := println(IO.readStream(getClass.getResourceAsStream("test.txt")))

How to share code between project and build definition project in SBT

If I have written some source code in my build definition project (in /project/src/main/scala) in SBT. Now I want to use these classes also in the project I am building. Is there a best practice? Currently I have created a custom Task that copies the .scala files over.
Those seem like unnecessarily indirect mechanisms.
unmanagedSourceDirectories in Compile += baseDirectory.value / "project/src/main"
Sharing sourceDirectories as in extempore's answer is the simplest way to go about it, but unfortunately it won't work well with IntelliJ because the project model doesn't allow sharing source roots between multiple modules.
Seth Tisue's approach will work, but requires rebuilding to update sources.
To actually share the sources and have IntelliJ pick up on it directly, you can define a module within the build.
The following approach seems to only work in sbt 1.0+
Create a file project/metabuild.sbt:
val buildShared = project
val buildRoot = (project in file("."))
.dependsOn(buildShared)
and in your build.sbt:
val buildShared = ProjectRef(file("project"), "buildShared")
val root = (project in file("."))
.dependsOn(buildShared)
Then put your shared code in project/buildShared/src/main/scala/ and refresh. Your project will look something like this in IntelliJ:
Full example project: https://github.com/jastice/shared-build-sources
Can you make the following work? Put the source code for the classes in question should be part of your project, not part of your build definition; the “task which serializes a graph of Scala objects using Kryo and writes them as files into the classpath of the project” part sounds like a perfect job for resourceGenerators (see http://www.scala-sbt.org/0.13.2/docs/Howto/generatefiles.html). Then the only remaining problem is how to reference the compiled classes from your resource generator. I'm not familiar with Kryo. In order to use it, do you need to have the compiled classes on the classpath at the time your generator is compiled, or do they just need to be on the classpath on runtime? If the latter is sufficient, that's easier. You can get a classloader from the testLoader in Test key, load the class and instantiate some objects via reflection, and then call Kryo.
If you really need the compiled classes to be on the classpath when your resource generator is compiled, then you have a chicken and egg problem where the build can't be compiled until the project has been compiled, but of course the project can't be compiled before the build definition has been compiled, either. In that case it seems to me you have no choices other than:
1) the workaround you're already doing ("best practice" in this case would consist of using sourceGenerators to copy the sources out of your build definition and into target/src_managed)
2) put the classes in question in a separate project and depend on it from both your build and your project. this is the cleanest solution overall, but you might consider it too heavyweight.
Hope this helps. Interested in seeing others' opinions on this, too.

Is there a way to make IntelliJ IDEA *not* put Scala source files in their Java-style package directory?

In Java, you have to put source files in the directory structure corresponding to their package. foo.bar.Baz has to live in foo/bar/Baz.java.
In Scala, that requirement is relaxed. If all your classes in a particular project are in package foo.bar, you might just want them to live in the root source directory.
But IDEA flags this as an error, and forces me to put Scala classes in their Java-style directory when, for example, I copy or move classes. Is there a way to turn off this behavior?
Go Settings -> Scala -> Other settings -> Resolve to all classes, even in wrong directories.

Linking to sources from scaladoc?

I need to link to sources on github from my scaladoc. I build those docs with the sbt's doc task.
There are two problems - first, I do not like creating several nested empty directories for my .scala files, so I usually pack them all in one - like src/main/scala/org.rogach.scallop instead of src/main/scala/org/rogach/scallop. Is there a way to make links to docs work without splitting that directory?
Second, when I put this line in my build.sbt:
scalacOptions in (Compile, doc) ++=
Opts.doc.sourceUrl("https://raw.github.com/Rogach/scallop/master/src/main/scala/")
docs contain links to sources, but all those links just point to the source root url, not files themselves. What am I doing wrong?
From the output of scaladoc help:
-doc-source-url <url> A URL pattern used to build links to template
sources; use variables, for example:
€{TPL_NAME} ('Seq'),
€{TPL_OWNER} ('scala.collection'),
€{FILE_PATH} ('scala/collection/Seq')
(Yes that is the euro symbol.)
Something like the following should work as an argument to sourceUrl if all of your sources are defined in a package:
https://raw.github.com/Rogach/scallop/master/src/main/scala/€{TPL_OWNER}.€{TPL_NAME}.scala