How to generate links to standard library types in scaladoc? - scala

I'm using sbt 0.13.7 and Scala 2.11.4.
In my build.sbt, I have:
autoAPIMappings := true
and in a File.scala:
/** scaladoc link to [[scala.concurrent.duration.FiniteDuration]] */
When running sbt doc, I’m getting:
[warn] ...:5: Could not find any member to link for "scala.concurrent.duration.FiniteDuration".
[warn] /** scaladoc link to [[scala.concurrent.duration.FiniteDuration]] */
[warn] ^
Now, when I replace autoAPIMappings := true with:
apiMappings += (scalaInstance.value.libraryJar ->
url(s"http://www.scala-lang.org/api/${scalaVersion.value}/"))
the compiler still gives the warning.
What could be a solution?

I wasn't able to reproduce this behavior using sbt 0.13.7 and Scala 2.11.4.
Do you have multi-project setup? If so make sure to explicitly add settings to each project, or define the common settings in ThisBuild scope.
project/build.properties
sbt.version=0.13.7
build.sbt
lazy val commonSettings = Seq(
scalaVersion := "2.11.4",
autoAPIMappings := true
)
lazy val root = (project in file(".")).
aggregate(app).
settings(commonSettings: _*)
lazy val app = (project in file("app")).
settings(commonSettings: _*)
src/main/scala/Hello.scala
/** scaladoc link to [[scala.concurrent.duration.FiniteDuration]] */
object Hello extends App {
}

Related

SBT Run Main Method from a Sub Project

I am writing a project which contains scala macros. This is why I have organized my project into two sub projects called "macroProj" and "coreProj". The "coreProj" depends on "macroProj" and also contains the main method to run my code.
My requirement is that when I do a sbt run from the root project, the main method is taken from the coreProj sub project. I search and found a thread which has a solution for this
sbt: run task on subproject
Based on this my build.sbt looks like
lazy val root = project.aggregate(coreProj,macroProj).dependsOn(coreProj,macroProj)
lazy val commonSettings = Seq(
scalaVersion := "2.11.7",
organization := "com.abhi"
)
lazy val coreProj = (project in file("core"))
.dependsOn(macroProj)
.settings(commonSettings : _*)
.settings(
mainClass in Compile := Some("demo.Usage")
)
lazy val macroProj = (project in file("macro"))
.settings(commonSettings : _*)
.settings(libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value)
mainClass in Compile <<= (run in Compile in coreProj)
But when I do sbt run from the root directory. I get an error
/Users/abhishek.srivastava/MyProjects/sbt-macro/built.sbt:19: error: type mismatch;
found : sbt.InputKey[Unit]
required: sbt.Def.Initialize[sbt.Task[Option[String]]]
mainClass in Compile <<= (run in Compile in coreProj)
^
[error] Type error in expression
In sbt, mainClass is a task that will return an entry point to your program, if any.
What you want to do is to have mainClass be the value of mainClass in coreProj.
You can achieve that this way:
mainClass in Compile := (mainClass in Compile in coreProj).value
This could also be achieved with
mainClass in Compile <<= mainClass in Compile in coreProj
However, the preferred syntax is (...).value since sbt 0.13.0.

sbt-assembly does not pick up configuration specific settings

I am updating an old 0.7.x build file from the tool sbt that thankfully removed the reference to "simple" from its name in the meantime.
Something that once worked, does not do so any longer. I had different config entries for platform specific assembly tasks. These include specific filters that for some reason are now called assemblyExcludedJars instead of excludedJars, and specific jar names that for some reason are now called assemblyJarName instead of jarName.
Basically:
val Foo = config("foo") extend Compile
lazy val assemblyFoo = TaskKey[File]("assembly-foo")
lazy val root = Project(id = "root", base = file("."))
// .configs(Foo) // needed? doesn't change anything
.settings(
inConfig(Foo)(inTask(assembly) {
assemblyJarName := "wtf.jar"
}),
scalaVersion := "2.11.7",
assemblyFoo <<= assembly in Foo
)
Now I would expect that if I run sbt assembly-foo or sbt foo:assembly, it would produce a file wtf.jar. But I am getting the default root-assembly-0.1-snapshot.jar. The same problem happens when I try to specify assemblyExcludedJars, they are simply ignored and still included.
If I remove the inConfig it works:
lazy val root = Project(id = "root", base = file("."))
.settings(
inTask(assembly) {
assemblyJarName := "wtf.jar"
},
scalaVersion := "2.11.7",
assemblyFoo <<= assembly in Foo
)
But now I cannot use different jar names for different configurations (which is the whole point).
As described in a blog post by one of sbt's authors and the author of sbt-assembly, this should work. It was also written in this Stackoverflow question. But the example requires an antique version of sbt-assembly (0.9.0 from 2013, before auto plugins etc.) and doesn't seem to apply to the current versions.
If one defines a new configuration, one has to redefine (?) all the tasks one is about to use. Apparently for sbt-assembly, this means running baseAssemblySettings:
val Foo = config("foo") extend Compile
lazy val assemblyFoo = TaskKey[File]("assembly-foo")
lazy val root = Project(id = "root", base = file("."))
.settings(
inConfig(Foo)(baseAssemblySettings /* !!! */ ++ inTask(assembly) {
jarName := "wtf.jar"
}),
scalaVersion := "2.11.7",
assemblyFoo := (assembly in Foo).value
)
Tested with sbt 0.13.9 and sbt-assembly 0.14.1.

SBT/Scala: macro implementation not found

I tried my hand on macros, and I keep running into the error
macro implementation not found: W
[error] (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
I believe I've set up a two pass compilation with the macro implementation being compiled first, and the usage second.
Here is part of the /build.sbt:
lazy val root = (project in file(".")).
settings(rootSettings: _*).
settings(name := "Example").
aggregate(macros, core).
dependsOn(macros, core)
lazy val macros = (project in file("src/main/com/example/macros")).
settings(macrosSettings: _*).
settings(name := "Macros")
lazy val core = (project in file("src/main/com/example/core")).
settings(coreSettings: _*).
settings (name := "Core").
dependsOn(macros)
lazy val commonSettings = Seq(
organization := Organization,
version := Version,
scalaVersion := ScalaVersion
)
lazy val rootSettings = commonSettings ++ Seq(
libraryDependencies ++= commonDeps ++ rootDeps ++ macrosDeps ++ coreDeps
)
lazy val macrosSettings = commonSettings ++ Seq(
libraryDependencies ++= commonDeps ++ macrosDeps
)
lazy val coreSettings = commonSettings ++ Seq(
libraryDependencies ++= commonDeps ++ coreDeps
)
The macro implementation looks like this:
/src/main/com/example/macros/Macros.scala
object Macros {
object Color {
def ColorWhite(c: Context): c.Expr[ObjectColor] = c.Expr[ObjectColor](c.universe.reify(ObjectColor(White())).tree)
}
}
The usage looks like this:
/src/main/com/example/core/Main.scala
object Macros {
import com.example.macros.Macros._
def W: ObjectColor = macro Color.ColorWhite
}
object Main extends App {
import Macros._
println(W)
}
Scala 2.11.6. SBT 0.13.8.
What am I doing wrong?
Thanks for your advice!
Fawlty Project:
The Project on Github
Working Project:
Rearranged the projects to a more correct form:
The cleanedup working project
Your macros and core projects don't contain any files, so they don't cause the problem. The error happens when sbt compiles root, which contains both Main.scala and Macros.scala by the virtue of you saying project in file(".") in the sbt build.

How to have sbt multi-project builds configure setting for subprojects?

I have an sbt (0.13.1) project with a bunch of subprojects. I am generating eclipse project configurations using sbteclipse. My projects only have scala source files, so I want to remove the generated src/java folders.
I can achieve that by (redundantly) adding the following to the build.sbt of each subproject:
unmanagedSourceDirectories in Compile := (scalaSource in Compile).value :: Nil
unmanagedSourceDirectories in Test := (scalaSource in Test).value :: Nil
I tried just adding the above configuration to the root build.sbt but the eclipse command still generated the java source folders.
Is there any way to specify a configuration like this once (in the root build.sbt) and have it flow down to each subproject?
You could define the settings unscoped and then reuse them
val onlyScalaSources = Seq(
unmanagedSourceDirectories in Compile := Seq((scalaSource in Compile).value),
unmanagedSourceDirectories in Test := Seq((scalaSource in Test).value)
)
val project1 = project.in( file( "project1" )
.settings(onlyScalaSources: _*)
val project2 = project.in( file( "project2" )
.settings(onlyScalaSources: _*)
You could also create a simple plugin (untested code)
object OnlyScalaSources extends AutoPlugin {
override def trigger = allRequirements
override lazy val projectSettings = Seq(
unmanagedSourceDirectories in Compile := Seq((scalaSource in Compile).value),
unmanagedSourceDirectories in Test := Seq((scalaSource in Test).value)
)
}
More details about creating plugins in the plugins documentation

sbt using different Scala versions in a multi project build

I have a multi project which uses two versions of Scala. The Build.scala looks like this:
import sbt._
import Keys._
object Build extends sbt.Build {
lazy val root: Project = Project(
id = "scalacolliderugens",
base = file("."),
aggregate = Seq(gen, core)
)
lazy val gen = Project(...)
lazy val core = Project(...)
val ugenGenerator = TaskKey[Seq[File]]("ugen-generate", "Generate UGen class files")
def runUGenGenerator(source: File, cp: Seq[File]): Seq[File] = Nil // TODO
}
Where I have a pure source generating project using Scala 2.9.2:
lazy val gen = Project(
id = "scalacolliderugens-gen",
base = file("gen"),
settings = Project.defaultSettings ++ Seq(
scalaVersion := "2.9.2", // !!!
libraryDependencies ++= Seq(
"org.scala-refactoring" % "org.scala-refactoring_2.9.1" % "0.4.1"
),
libraryDependencies <+= scalaVersion { sv =>
"org.scala-lang" % "scala-compiler" % sv
}
)
)
And the actual project which incorporates the generated sources, compiling against Scala 2.10:
lazy val core = Project(
id = "scalacolliderugens-core",
base = file("core"),
settings = Project.defaultSettings ++ Seq(
scalaVersion := "2.10.0", // !!!
sourceGenerators in Compile <+= (ugenGenerator in Compile),
ugenGenerator in Compile <<=
(scalaSource in Compile, dependencyClasspath in Runtime in gen) map {
(src, cp) => runUGenGenerator(src, cp.files)
}
)
).dependsOn(gen)
When I compile this, I get sbt warnings:
[warn] Binary version (2.9.2) for dependency org.scala-lang#scala-library;2.9.2
[warn] in de.sciss#scalacolliderugens_2.10;1.0.1 differs from Scala binary \
version in project (2.10).
[info] Resolving org.scala-lang#scala-library;2.9.2 ...
[info] Done updating.
[warn] Binary version (2.9.2) for dependency org.scala-lang#scala-library;2.9.2
[warn] in de.sciss#scalacolliderugens-gen_2.10;1.0.1 differs from Scala binary \
version in project (2.10).
[warn] Binary version (2.9.2) for dependency org.scala-lang#scala-compiler;2.9.2
[warn] in de.sciss#scalacolliderugens-gen_2.10;1.0.1 differs from Scala binary \
version in project (2.10).
Should I be worried? Am I doing something bad here?
Add the following setting to the gen project.
scalaBinaryVersion:= CrossVersion.binaryScalaVersion("2.9.2")
OK...
I have multi-project SBT projects and they generally have SBT settings that are partly shared by all and partly specific to each sub-project. In my case the common settings include the Scala version to use.
You could structure you build specification the same way and put the Scala version setting in the sub-project-specific settings. If necessary, you could stratify the settings further if there are some settings common to all and some common to subsets of the sub-projects and other specific to each individual sub-project.
You cannot mix bytecode from different minor versions of Scala. I.e., code compiled by any 2.9.x series compiler is not compatible with that emitted by a 2.10.x (or 2.8.x) compiler.