Enable cross-version support for Scala sources.

This allows attaching unmanaged sources on `per-ScalaVersion` basis.

Sources from `src/{main,test}/scala-<scalaBinaryVersion>` is collected
in addition to `src/{main,test}/scala` by default.

Note that the treatment of `scalaBinaryVersion` would vary depending on
`scalaVersion` pre-2.10 and 2.10 onwards.

For example:
- with `scalaVersion` `2.9.3`, the `scalaBinaryVersion` is set to `2.9.3`
  thus the files in `src/{main,test}/scala-2.9.3` as well
 `src/{main,test}/scala` would be available in the `sources` list.

- with `scalaVersion` `2.10.1`, the `scalaBinaryVersion` is set to `2.10`
  thus the files in `src/{main,test}/scala-2.10` as well
 `src/{main,test}/scala` would be available in the `sources` list.
This commit is contained in:
Indrajit Raychaudhuri 2014-04-21 18:39:16 -05:00
parent c6bf00c2c2
commit 1b15653bcb
6 changed files with 38 additions and 5 deletions

View File

@ -181,7 +181,7 @@ object Defaults extends BuildCommon {
sourceManaged <<= configSrcSub(sourceManaged),
scalaSource := sourceDirectory.value / "scala",
javaSource := sourceDirectory.value / "java",
unmanagedSourceDirectories := Seq(scalaSource.value, javaSource.value),
unmanagedSourceDirectories := makeCrossSources(scalaSource.value, javaSource.value, scalaBinaryVersion.value, crossPaths.value),
unmanagedSources <<= collectFiles(unmanagedSourceDirectories, includeFilter in unmanagedSources, excludeFilter in unmanagedSources),
watchSources in ConfigGlobal <++= unmanagedSources,
managedSourceDirectories := Seq(sourceManaged.value),
@ -241,6 +241,14 @@ object Defaults extends BuildCommon {
derive(compilersSetting),
derive(scalaBinaryVersion := binaryScalaVersion(scalaVersion.value))
))
def makeCrossSources(scalaSrcDir: File, javaSrcDir: File, sv: String, cross: Boolean): Seq[File] = {
if (cross)
Seq(scalaSrcDir.getParentFile / s"${scalaSrcDir.name}-$sv", scalaSrcDir, javaSrcDir)
else
Seq(scalaSrcDir, javaSrcDir)
}
def makeCrossTarget(t: File, sv: String, sbtv: String, plugin: Boolean, cross: Boolean): File =
{
val scalaBase = if (cross) t / ("scala-" + sv) else t
@ -948,7 +956,7 @@ object Defaults extends BuildCommon {
@deprecated("Settings now split into AutoPlugins.", "0.13.2")
lazy val projectBaseSettings: Seq[Setting[_]] = projectCore ++ runnerSettings ++ paths ++ baseClasspaths ++ baseTasks ++ compileBase ++ disableAggregation
// These are project level settings that MUST be on every project.
// These are project level settings that MUST be on every project.
lazy val coreDefaultSettings: Seq[Setting[_]] =
projectCore ++ disableAggregation ++ Seq(
// Missing but core settings
@ -1111,8 +1119,8 @@ object Classpaths {
projectResolver <<= projectResolverTask,
projectDependencies <<= projectDependenciesTask,
// TODO - Is this the appropriate split? Ivy defines this simply as
// just project + library, while the JVM plugin will define it as
// having the additional sbtPlugin + autoScala magikz.
// just project + library, while the JVM plugin will define it as
// having the additional sbtPlugin + autoScala magikz.
allDependencies := {
projectDependencies.value ++ libraryDependencies.value
},

View File

@ -106,7 +106,7 @@ object Keys {
val cacheDirectory = SettingKey[File]("cache-directory", "Directory used for caching task data.", BMinusSetting)
val cleanFiles = SettingKey[Seq[File]]("clean-files", "The files to recursively delete during a clean.", BSetting)
val cleanKeepFiles = SettingKey[Seq[File]]("clean-keep-files", "Files to keep during a clean.", CSetting)
val crossPaths = SettingKey[Boolean]("cross-paths", "If true, enables cross paths, which distinguish output directories for cross-building.", ASetting)
val crossPaths = SettingKey[Boolean]("cross-paths", "If true, enables cross paths, which distinguish input and output directories for cross-building.", ASetting)
val taskTemporaryDirectory = SettingKey[File]("task-temporary-directory", "Directory used for temporary files for tasks that is deleted after each task execution.", DSetting)
// Generators

View File

@ -0,0 +1,3 @@
object B {
def show(what: String): String = s"String interpolation is ${what.toUpperCase}!"
}

View File

@ -0,0 +1,3 @@
object B {
def show(what: String): String = "String interpolation is " + what.toUpperCase
}

View File

@ -0,0 +1,3 @@
class A {
def show(what: String): String = B.show(what)
}

View File

@ -0,0 +1,16 @@
# A.scala needs B.scala, it won't be in source list
> ++2.11.4
-> compile
# A.scala needs B.scala, it would be in source list
> ++2.10.4
> compile
# A.scala needs B.scala, it would be in source list
> ++2.9.3
> compile
# Injecting the wrong B.scala in source list
$ copy-file src/main/scala-2.10/B.scala src/main/scala-2.9.3/B.scala
> ++2.9.3
-> compile