diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 9259e5485..b0fb30cbf 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -195,7 +195,6 @@ object Defaults extends BuildCommon ) def compileBase = inTask(console)(compilersSetting :: Nil) ++ compileBaseGlobal ++ Seq( - compilersSetting, incOptions in GlobalScope := sbt.inc.IncOptions.defaultTransactional(crossTarget.value.getParentFile / "classes.bak"), scalaInstance <<= scalaInstanceTask, crossVersion := (if(crossPaths.value) CrossVersion.binary else CrossVersion.Disabled), @@ -209,9 +208,11 @@ object Defaults extends BuildCommon javacOptions :== Nil, scalacOptions :== Nil, scalaVersion := appConfiguration.value.provider.scalaProvider.version, - scalaBinaryVersion := binaryScalaVersion(scalaVersion.value), crossScalaVersions := Seq(scalaVersion.value) - )) + )) ++ Seq( + derive(compilersSetting), + derive(scalaBinaryVersion := binaryScalaVersion(scalaVersion.value)) + ) def makeCrossTarget(t: File, sv: String, sbtv: String, plugin: Boolean, cross: Boolean): File = { val scalaBase = if(cross) t / ("scala-" + sv) else t @@ -219,7 +220,7 @@ object Defaults extends BuildCommon } def compilersSetting = compilers := Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value)(appConfiguration.value, streams.value.log) - lazy val configTasks = docTaskSettings(doc) ++ compileTaskSettings ++ compileInputsSettings ++ configGlobal ++ Seq( + lazy val configTasks = docTaskSettings(doc) ++ inTask(compile)(compileInputsSettings) ++ configGlobal ++ Seq( compile <<= compileTask tag(Tags.Compile, Tags.CPU), printWarnings <<= printWarningsTask, compileIncSetup <<= compileIncSetupTask, @@ -373,9 +374,10 @@ object Defaults extends BuildCommon testListeners.in(TaskGlobal).value }, testOptions := Tests.Listeners(testListeners.value) +: (testOptions in TaskGlobal).value, - testExecution <<= testExecutionTask(key), - testGrouping <<= testGrouping or singleTestGroup(key) - ) ) + testExecution <<= testExecutionTask(key) + ) ) ++ Seq( + derive(testGrouping <<= singleTestGroupDefault) + ) def testLogger(manager: Streams, baseKey: Scoped)(tdef: TestDefinition): Logger = { val scope = baseKey.scope @@ -389,10 +391,11 @@ object Defaults extends BuildCommon val mod = tdef.fingerprint match { case f: SubclassFingerprint => f.isModule; case f: AnnotatedFingerprint => f.isModule; case _ => false } extra.put(name.key, tdef.name).put(isModule, mod) } - def singleTestGroup(key: Scoped): Initialize[Task[Seq[Tests.Group]]] = Def.task { - val tests = (definedTests in key).value - val fk = (fork in key).value - val opts = inTask(key, forkOptions).value + def singleTestGroup(key: Scoped): Initialize[Task[Seq[Tests.Group]]] = inTask(key, singleTestGroupDefault) + def singleTestGroupDefault: Initialize[Task[Seq[Tests.Group]]] = Def.task { + val tests = definedTests.value + val fk = fork.value + val opts = forkOptions.value Seq(new Tests.Group("", tests, if(fk) Tests.SubProcess(opts) else Tests.InProcess)) } private[this] def forkOptions: Initialize[Task[ForkOptions]] = @@ -648,24 +651,30 @@ object Defaults extends BuildCommon @deprecated("Use `docTaskSettings` instead", "0.12.0") def docSetting(key: TaskKey[File]) = docTaskSettings(key) - def docTaskSettings(key: TaskKey[File] = doc): Seq[Setting[_]] = inTask(key)(compileInputsSettings ++ Seq( + def docTaskSettings(key: TaskKey[File] = doc): Seq[Setting[_]] = inTask(key)(Seq( apiMappings ++= { if(autoAPIMappings.value) APIMappings.extract(dependencyClasspath.value, streams.value.log).toMap else Map.empty[File,URL] }, - key in TaskGlobal <<= (compileInputs, target, configuration, apiMappings, streams) map { (in, out, config, xapis, s) => - val srcs = in.config.sources + key in TaskGlobal := { + val s = streams.value + val cs = compilers.value + val srcs = sources.value + val out = target.value + val sOpts = scalacOptions.value + val jOpts = javacOptions.value + val xapis = apiMappings.value val hasScala = srcs.exists(_.name.endsWith(".scala")) val hasJava = srcs.exists(_.name.endsWith(".java")) - val cp = in.config.classpath.toList.filterNot(_ == in.config.classesDirectory) - val label = nameForSrc(config.name) + val cp = data(dependencyClasspath.value).toList + val label = nameForSrc(configuration.value.name) val (options, runDoc) = if(hasScala) - (in.config.options ++ Opts.doc.externalAPI(xapis), - Doc.scaladoc(label, s.cacheDirectory / "scala", in.compilers.scalac.onArgs(exported(s, "scaladoc")))) + (sOpts ++ Opts.doc.externalAPI(xapis), // can't put the .value calls directly here until 2.10.2 + Doc.scaladoc(label, s.cacheDirectory / "scala", cs.scalac.onArgs(exported(s, "scaladoc")))) else if(hasJava) - (in.config.javacOptions, - Doc.javadoc(label, s.cacheDirectory / "java", in.compilers.javac.onArgs(exported(s, "javadoc")))) + (jOpts, + Doc.javadoc(label, s.cacheDirectory / "java", cs.javac.onArgs(exported(s, "javadoc")))) else (Nil, RawCompileLike.nop) - runDoc(srcs, cp, out, options, in.config.maxErrors, s.log) + runDoc(srcs, cp, out, options, maxErrors.value, s.log) out } )) @@ -695,6 +704,7 @@ object Defaults extends BuildCommon private[this] def exported(s: TaskStreams, command: String): Seq[String] => Unit = args => exported(s.text("export"), command) + @deprecated("Use inTask(compile)(compileInputsSettings)", "0.13.0") def compileTaskSettings: Seq[Setting[_]] = inTask(compile)(compileInputsSettings) def compileTask: Initialize[Task[inc.Analysis]] = Def.task { compileTaskImpl(streams.value, (compileInputs in compile).value) } @@ -848,7 +858,7 @@ object Classpaths lazy val configSettings: Seq[Setting[_]] = classpaths ++ Seq( products <<= makeProducts, - productDirectories := compileInputs.value.config.classesDirectory :: Nil, + productDirectories := classDirectory.value :: Nil, classpathConfiguration := findClasspathConfig(internalConfigurationMap.value, configuration.value, classpathConfiguration.?.value, update.value) ) private[this] def classpaths: Seq[Setting[_]] = Seq( @@ -1190,8 +1200,11 @@ object Classpaths } def analyzed[T](data: T, analysis: inc.Analysis) = Attributed.blank(data).put(Keys.analysis, analysis) - def makeProducts: Initialize[Task[Seq[File]]] = - (compile, compileInputs, copyResources) map { (_, i, _) => i.config.classesDirectory :: Nil } + def makeProducts: Initialize[Task[Seq[File]]] = Def.task { + val x1 = compile.value + val x2 = copyResources.value + classDirectory.value :: Nil + } def exportProductsTask: Initialize[Task[Classpath]] = (products.task, packageBin.task, exportJars, compile, apiURL) flatMap { (psTask, pkgTask, useJars, analysis, u) => (if(useJars) Seq(pkgTask).join else psTask) map { _ map { f => APIMappings.store(analyzed(f, analysis), u) } } @@ -1596,4 +1609,6 @@ trait BuildCommon def getPrevious[T](task: TaskKey[T]): Initialize[Task[Option[T]]] = (state, resolvedScoped) map { (s, ctx) => getFromContext(task, ctx, s) } + + private[sbt] def derive[T](s: Setting[T]): Setting[T] = Def.derive(s, allowDynamic=true, trigger = _ != streams.key) } diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index fa0e04ec9..fc36f7c87 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -220,6 +220,7 @@ object Keys val defaultConfigurationMapping = SettingKey[String]("default-configuration-mapping", "Defines the mapping used for a simple, unmapped configuration definition.", CSetting) val products = TaskKey[Seq[File]]("products", "Build products that get packaged.", BMinusTask) + @deprecated("This task is unused by the default project and will be removed.", "0.13.0") val productDirectories = TaskKey[Seq[File]]("product-directories", "Base directories of build products.", CTask) val exportJars = SettingKey[Boolean]("export-jars", "Determines whether the exported classpath for this project contains classes (false) or a packaged jar (true).", BSetting) val exportedProducts = TaskKey[Classpath]("exported-products", "Build products that go on the exported classpath.", CTask) diff --git a/sbt/src/sbt-test/actions/doc-scala-instance/a/A.scala b/sbt/src/sbt-test/actions/doc-scala-instance/a/A.scala new file mode 100644 index 000000000..e89cff328 --- /dev/null +++ b/sbt/src/sbt-test/actions/doc-scala-instance/a/A.scala @@ -0,0 +1,7 @@ +class A { + def x = 3 +} +class B +object B { + implicit def bToA(b: B): A = new A +} diff --git a/sbt/src/sbt-test/actions/doc-scala-instance/build.sbt b/sbt/src/sbt-test/actions/doc-scala-instance/build.sbt new file mode 100644 index 000000000..549ec33c7 --- /dev/null +++ b/sbt/src/sbt-test/actions/doc-scala-instance/build.sbt @@ -0,0 +1,10 @@ +lazy val a = project.settings( + scalaVersion := "2.9.2", + scalaInstance in (Compile,doc) := (scalaInstance in b).value, + // 2.10.1-only, so this will only succeed if `doc` recognizes the more specific scalaInstance scoped to `doc` + scalacOptions in (Compile,doc) += "-implicits" +) + +lazy val b = project.settings( + scalaVersion := "2.10.1" +) diff --git a/sbt/src/sbt-test/actions/doc-scala-instance/test b/sbt/src/sbt-test/actions/doc-scala-instance/test new file mode 100644 index 000000000..285de2cc4 --- /dev/null +++ b/sbt/src/sbt-test/actions/doc-scala-instance/test @@ -0,0 +1 @@ +> a/doc diff --git a/sbt/src/sbt-test/project/src-scala-binary-version/b/build.sbt b/sbt/src/sbt-test/project/src-scala-binary-version/b/build.sbt new file mode 100644 index 000000000..71f584c70 --- /dev/null +++ b/sbt/src/sbt-test/project/src-scala-binary-version/b/build.sbt @@ -0,0 +1 @@ +scalaVersion := "2.10.1" diff --git a/sbt/src/sbt-test/project/src-scala-binary-version/build.sbt b/sbt/src/sbt-test/project/src-scala-binary-version/build.sbt new file mode 100644 index 000000000..911a1df80 --- /dev/null +++ b/sbt/src/sbt-test/project/src-scala-binary-version/build.sbt @@ -0,0 +1,14 @@ +lazy val a = project.dependsOn(b).settings(scalaVersion := "2.8.2") +lazy val b = RootProject(uri("b")) +lazy val check = taskKey[Unit]("Checks the configured scalaBinaryVersion") + +check := { + val av = (scalaBinaryVersion in a).value + val bv = (scalaBinaryVersion in b).value + same(av, "2.8.2") + same(bv, "2.10") +} + +def same(actual: String, expected: String) { + assert(actual == expected, s"Expected binary version to be $expected, was $actual") +} diff --git a/sbt/src/sbt-test/project/src-scala-binary-version/test b/sbt/src/sbt-test/project/src-scala-binary-version/test new file mode 100644 index 000000000..15675b169 --- /dev/null +++ b/sbt/src/sbt-test/project/src-scala-binary-version/test @@ -0,0 +1 @@ +> check diff --git a/sbt/src/sbt-test/tests/fork/project/ForkTestsTest.scala b/sbt/src/sbt-test/tests/fork/project/ForkTestsTest.scala index e3595c778..961962f8e 100755 --- a/sbt/src/sbt-test/tests/fork/project/ForkTestsTest.scala +++ b/sbt/src/sbt-test/tests/fork/project/ForkTestsTest.scala @@ -14,7 +14,7 @@ object ForkTestsTest extends Build { lazy val root = Project("root", file("."), settings = defaultSettings ++ Seq( scalaVersion := "2.9.2", - testGrouping <<= definedTests in Test map { tests => + testGrouping in Test <<= definedTests in Test map { tests => assert(tests.size == 1) val groups = Stream continually tests(0) take totalFiles grouped groupSize for ((ts, idx) <- groups.toSeq.zipWithIndex) yield { diff --git a/sbt/src/sbt-test/tests/it/changes/AlwaysFail.scala b/sbt/src/sbt-test/tests/it/changes/AlwaysFail.scala new file mode 100644 index 000000000..48ebd9767 --- /dev/null +++ b/sbt/src/sbt-test/tests/it/changes/AlwaysFail.scala @@ -0,0 +1,20 @@ +package org.example + +// this tests that normal tests do not +// interfere with integration tests (#539) + +import org.specs2.mutable._ + +class B extends Specification +{ + "this" should { + "not work" in { 1 must_== 2 } + } +} + +object A extends Specification +{ + "this" should { + "not work" in { 1 must_== 2 } + } +} diff --git a/sbt/src/sbt-test/tests/it/project/B.scala b/sbt/src/sbt-test/tests/it/project/B.scala index 12b1223eb..5d98a1e89 100644 --- a/sbt/src/sbt-test/tests/it/project/B.scala +++ b/sbt/src/sbt-test/tests/it/project/B.scala @@ -3,14 +3,12 @@ object B extends Build { + lazy val IntegrationTest = config("it") extend(Test) lazy val root = Project("root", file(".")) .configs( IntegrationTest ) .settings( Defaults.itSettings : _*) - .settings( - libraryDependencies += specs, - resolvers += ScalaToolsReleases - ) + .settings( libraryDependencies += specs ) - lazy val specs = "org.specs2" % "specs2_2.10" % "1.12.3" % "it,test" -} \ No newline at end of file + lazy val specs = "org.specs2" % "specs2_2.10" % "1.12.3" % "test" +} diff --git a/sbt/src/sbt-test/tests/it/test b/sbt/src/sbt-test/tests/it/test index c870bb832..c313c9831 100644 --- a/sbt/src/sbt-test/tests/it/test +++ b/sbt/src/sbt-test/tests/it/test @@ -17,4 +17,12 @@ $ copy-file changes/ClassSuccessModuleFail.scala src/it/scala/Test.scala > clean $ delete src/ $ copy-file changes/ClassSuccessModuleSuccess.scala src/it/scala/Test.scala -> it:test \ No newline at end of file +> it:test + +# verify that a failing normal test fails when run directly +$ copy-file changes/AlwaysFail.scala src/test/scala/AlwaysFail.scala +-> test:test + +# but that it does not affect the result of it:test (#539) +> it:test +