diff --git a/.drone.yml b/.drone.yml index 7c57dbafb9..e2e256726d 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,35 +1,44 @@ +matrix: + CI_SCALA_VERSION: + - 2.12.6 + +clone: + git: + image: plugins/git + tags: true + recursive: true + depth: 50 + pipeline: - # Fetch folders from distributed cache - sftp_cache_restore: - image: plugins/sftp-cache + restore_cache: + image: appleboy/drone-sftp-cache + when: + ref: [ refs/heads/1.x, refs/tags/*, refs/pull/*/head ] + secrets: [ sftp_cache_username, sftp_cache_private_key, sftp_cache_server, sftp_cache_path ] restore: true mount: - - /drone/.ivy2 + - /drone/.ivy2/cache - /drone/.coursier-cache - /drone/.sbt - /drone/.git - when: - event: [push, pull_request, tag, deployment] tests: - image: scalacenter/scala:1.0 + image: scalacenter/scala-docs:1.3 + when: + ref: [ refs/heads/1.x, refs/tags/*, refs/pull/*/head ] commands: + - export DRONE_DIR="/drone" - git fetch --tags && git log | head -n 20 - - ./bin/run-ci.sh ${CI_SCALA_VERSION} + - ./bin/run-ci.sh - # Save folders in distributed cache - sftp_cache_rebuild: - image: plugins/sftp-cache + rebuild_cache: + image: appleboy/drone-sftp-cache + when: + ref: [ refs/heads/1.x, refs/tags/*, refs/pull/*/head ] + secrets: [ sftp_cache_username, sftp_cache_private_key, sftp_cache_server, sftp_cache_path ] rebuild: true mount: - - /drone/.ivy2 + - /drone/.ivy2/cache - /drone/.coursier-cache - /drone/.sbt - /drone/.git - when: - event: [push, pull_request, tag, deployment] - -matrix: - CI_SCALA_VERSION: - - 2.11.11 - - 2.12.3 diff --git a/.drone.yml.sig b/.drone.yml.sig deleted file mode 100644 index 73a9c94e73..0000000000 --- a/.drone.yml.sig +++ /dev/null @@ -1 +0,0 @@ -eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgIyBGZXRjaCBmb2xkZXJzIGZyb20gZGlzdHJpYnV0ZWQgY2FjaGUKICBzZnRwX2NhY2hlX3Jlc3RvcmU6CiAgICBpbWFnZTogcGx1Z2lucy9zZnRwLWNhY2hlCiAgICByZXN0b3JlOiB0cnVlCiAgICBtb3VudDoKICAgICAgLSAvZHJvbmUvLml2eTIKICAgICAgLSAvZHJvbmUvLmNvdXJzaWVyLWNhY2hlCiAgICAgIC0gL2Ryb25lLy5zYnQKICAgICAgLSAvZHJvbmUvLmdpdAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFtwdXNoLCBwdWxsX3JlcXVlc3QsIHRhZywgZGVwbG95bWVudF0KCiAgdGVzdHM6CiAgICBpbWFnZTogc2NhbGFjZW50ZXIvc2NhbGE6MS4wCiAgICBjb21tYW5kczoKICAgICAgLSBnaXQgZmV0Y2ggLS10YWdzICYmIGdpdCBsb2cgfCBoZWFkIC1uIDIwCiAgICAgIC0gLi9iaW4vcnVuLWNpLnNoICR7Q0lfU0NBTEFfVkVSU0lPTn0KCiAgIyBTYXZlIGZvbGRlcnMgaW4gZGlzdHJpYnV0ZWQgY2FjaGUKICBzZnRwX2NhY2hlX3JlYnVpbGQ6CiAgICBpbWFnZTogcGx1Z2lucy9zZnRwLWNhY2hlCiAgICByZWJ1aWxkOiB0cnVlCiAgICBtb3VudDoKICAgICAgLSAvZHJvbmUvLml2eTIKICAgICAgLSAvZHJvbmUvLmNvdXJzaWVyLWNhY2hlCiAgICAgIC0gL2Ryb25lLy5zYnQKICAgICAgLSAvZHJvbmUvLmdpdAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFtwdXNoLCBwdWxsX3JlcXVlc3QsIHRhZywgZGVwbG95bWVudF0KCm1hdHJpeDoKICBDSV9TQ0FMQV9WRVJTSU9OOgogICAgLSAyLjExLjExCiAgICAtIDIuMTIuMwo.usuc6GVWQgjD1XYQW9Fd8U8N7Qj1b6WfmGdtIn44Q-8 \ No newline at end of file diff --git a/.gitignore b/.gitignore index e8a589fd3f..fff4478fc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ target/ +target-2.10/ +target-2.11/ +target-2.12/ +target-2.13/ zinc/src/test/resources/bin diff --git a/bin/run-ci.sh b/bin/run-ci.sh index fcf367c47c..741540a0c0 100755 --- a/bin/run-ci.sh +++ b/bin/run-ci.sh @@ -1,19 +1,18 @@ #!/usr/bin/env bash set -eu set -o nounset -SCALA_VERSION="$1" +PROJECT_ROOT="zincRoot" sbt -Dfile.encoding=UTF-8 \ - -J-XX:ReservedCodeCacheSize=256M \ - -J-Xmx3046M -J-Xms3046M -J-server \ - +mimaReportBinaryIssues \ + -J-XX:ReservedCodeCacheSize=512M \ + -J-Xms1024M -J-Xmx4096M -J-server \ + "$PROJECT_ROOT/mimaReportBinaryIssues" \ scalafmt::test \ test:scalafmt::test \ whitesourceCheckPolicies \ - compilerInterfaceJava6Compat/compile \ - zincRoot/test:compile \ + "$PROJECT_ROOT/test:compile" \ bloopScripted/compile \ crossTestBridges \ - "publishBridgesAndSet $SCALA_VERSION" \ - zincRoot/test \ - zincRoot/scripted + "publishBridges" \ + "$PROJECT_ROOT/test" \ + "$PROJECT_ROOT/scripted" diff --git a/build.sbt b/build.sbt index eca40fba19..a293c9764a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,17 +1,15 @@ import Util._ import Dependencies._ -import Scripted._ +import localzinc.Scripted, Scripted._ import com.typesafe.tools.mima.core._, ProblemFilters._ def internalPath = file("internal") -lazy val compilerBridgeScalaVersions = List(scala212, scala213, scala211, scala210) -lazy val compilerBridgeTestScalaVersions = List(scala212, scala211, scala210) - def mimaSettings: Seq[Setting[_]] = Seq( mimaPreviousArtifacts := Set( "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", "1.0.5", "1.1.0", "1.1.1", "1.1.2", "1.1.3", + "1.2.0", ) map (version => organization.value %% moduleName.value % version cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) @@ -19,7 +17,7 @@ def mimaSettings: Seq[Setting[_]] = Seq( ) def buildLevelSettings: Seq[Setting[_]] = Seq( - git.baseVersion := "1.2.0", + git.baseVersion := "1.2.1", // https://github.com/sbt/sbt-git/issues/109 // Workaround from https://github.com/sbt/sbt-git/issues/92#issuecomment-161853239 git.gitUncommittedChanges := { @@ -74,9 +72,9 @@ def commonSettings: Seq[Setting[_]] = Seq( // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), - crossScalaVersions := Seq(scala211, scala212), + crossScalaVersions := Seq(scala212), publishArtifact in Test := false, - commands ++= Seq(publishBridgesAndTest, publishBridgesAndSet, crossTestBridges), + commands ++= Seq(publishBridges, crossTestBridges), scalacOptions ++= Seq( "-YdisableFlatCpCaching", "-target:jvm-1.8", @@ -113,30 +111,6 @@ def baseSettings: Seq[Setting[_]] = def addBaseSettingsAndTestDeps(p: Project): Project = p.settings(baseSettings).configure(addTestDependencies) -val altLocalRepoName = "alternative-local" -val altLocalRepoPath = sys.props("user.home") + "/.ivy2/sbt-alternative" -lazy val altLocalResolver = Resolver.file( - altLocalRepoName, - file(sys.props("user.home") + "/.ivy2/sbt-alternative"))(Resolver.ivyStylePatterns) -lazy val altLocalPublish = - TaskKey[Unit]("alt-local-publish", "Publishes an artifact locally to an alternative location.") -def altPublishSettings: Seq[Setting[_]] = - Seq( - resolvers += altLocalResolver, - altLocalPublish := { - import sbt.librarymanagement._ - import sbt.internal.librarymanagement._ - val config = (Keys.publishLocalConfiguration).value - val moduleSettings = (Keys.moduleSettings).value - val ivy = new IvySbt((ivyConfiguration.value)) - - val module = new ivy.Module(moduleSettings) - val newConfig = config.withResolverName(altLocalRepoName).withOverwrite(false) - streams.value.log.info(s"Publishing $module to local repo: $altLocalRepoName") - IvyActions.publish(module, newConfig, streams.value.log) - } - ) - val noPublish: Seq[Setting[_]] = List( publish := {}, publishLocal := {}, @@ -146,8 +120,10 @@ val noPublish: Seq[Setting[_]] = List( skip in publish := true, ) +// TODO: Test Scala 2.13.0 when we upgrade to M5 (this means we need to publish sbt dependencies for this milestone too) + +// zincRoot is now only 2.12 (2.11.x is not supported anymore) lazy val zincRoot: Project = (project in file(".")) -// configs(Sxr.sxrConf). .aggregate( zinc, zincTesting, @@ -156,12 +132,15 @@ lazy val zincRoot: Project = (project in file(".")) zincIvyIntegration, zincCompile, zincCompileCore, - compilerInterface, - compilerBridge, + compilerInterface212, + compilerBridge210, + compilerBridge211, + compilerBridge212, + compilerBridge213, zincBenchmarks, - zincApiInfo, - zincClasspath, - zincClassfile, + zincApiInfo212, + zincClasspath212, + zincClassfile212, zincScripted ) .settings( @@ -178,7 +157,7 @@ lazy val zinc = (project in file("zinc")) zincCore, zincPersist, zincCompileCore, - zincClassfile, + zincClassfile212, zincIvyIntegration % "compile->compile;test->test", zincTesting % Test ) @@ -222,10 +201,10 @@ lazy val zincPersist = (project in internalPath / "zinc-persist") // Defines the data structures for representing file fingerprints and relationships and the overall source analysis lazy val zincCore = (project in internalPath / "zinc-core") .dependsOn( - zincApiInfo, - zincClasspath, - compilerInterface, - compilerBridge % Test, + zincApiInfo212, + zincClasspath212, + compilerInterface212, + compilerBridge212 % Test, zincTesting % Test ) .configure(addBaseSettingsAndTestDeps) @@ -244,8 +223,8 @@ lazy val zincCore = (project in internalPath / "zinc-core") .configure(addSbtIO, addSbtUtilLogging, addSbtUtilRelation) lazy val zincBenchmarks = (project in internalPath / "zinc-benchmarks") - .dependsOn(compilerInterface % "compile->compile;compile->test") - .dependsOn(compilerBridge, zincCore, zincTesting % Test) + .dependsOn(compilerInterface212 % "compile->compile;compile->test") + .dependsOn(compilerBridge212, zincCore, zincTesting % Test) .enablePlugins(JmhPlugin) .settings( noPublish, @@ -255,7 +234,7 @@ lazy val zincBenchmarks = (project in internalPath / "zinc-benchmarks") "net.openhft" % "affinity" % "3.0.6" ), scalaVersion := scala212, - crossScalaVersions := Seq(scala211, scala212), + crossScalaVersions := Seq(scala212), javaOptions in Test ++= List("-Xmx600M", "-Xms600M"), ) @@ -266,6 +245,10 @@ lazy val zincIvyIntegration = (project in internalPath / "zinc-ivy-integration") name := "zinc Ivy Integration", compileOrder := sbt.CompileOrder.ScalaThenJava, mimaSettings, + test in Test := { + // Test in ivy integration needs the published compiler bridges to work + (test in Test).value + } ) .configure(addSbtLmCore, addSbtLmIvyTest) @@ -273,17 +256,17 @@ lazy val zincIvyIntegration = (project in internalPath / "zinc-ivy-integration") lazy val zincCompileCore = (project in internalPath / "zinc-compile-core") .enablePlugins(ContrabandPlugin) .dependsOn( - compilerInterface % "compile;test->test", - zincClasspath, - zincApiInfo, - zincClassfile, + compilerInterface212 % "compile;test->test", + zincClasspath212, + zincApiInfo212, + zincClassfile212, zincTesting % Test ) .configure(addBaseSettingsAndTestDeps) .settings( name := "zinc Compile Core", libraryDependencies ++= Seq(scalaCompiler.value % Test, launcherInterface, parserCombinator), - unmanagedJars in Test := Seq(packageSrc in compilerBridge in Compile value).classpath, + unmanagedJars in Test := Seq(packageSrc in compilerBridge212 in Compile value).classpath, managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-java", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-java", @@ -303,7 +286,7 @@ lazy val zincCompileCore = (project in internalPath / "zinc-compile-core") // defines Java structures used across Scala versions, such as the API structures and relationships extracted by // the analysis compiler phases and passed back to sbt. The API structures are defined in a simple // format from which Java sources are generated by the sbt-contraband plugin. -lazy val compilerInterface = (project in internalPath / "compiler-interface") +lazy val compilerInterface212 = (project in internalPath / "compiler-interface") .enablePlugins(ContrabandPlugin) .settings( minimalSettings, @@ -329,7 +312,6 @@ lazy val compilerInterface = (project in internalPath / "compiler-interface") sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-java", crossPaths := false, autoScalaLibrary := false, - altPublishSettings, mimaSettings, mimaBinaryIssueFilters ++= { import com.typesafe.tools.mima.core._ @@ -345,12 +327,30 @@ lazy val compilerInterface = (project in internalPath / "compiler-interface") /* Create a duplicated compiler-interface project that uses Scala 2.10 to parse Java files. * Scala 2.10's parser uses Java 6 semantics, so this way we ensure that the interface can * be compiled with Java 6 too. `compiler-interface` checks compilation for Java 8. */ -val compilerInterfaceJava6Compat = compilerInterface - .withId("compilerInterfaceJava6Compat") +val compilerInterface210 = compilerInterface212 + .withId("compilerInterface210") .settings( scalaVersion := scala210, crossScalaVersions := Seq(scala210), - target := (target in compilerInterface).value / "java6-parser-compat", + target := (target in compilerInterface212).value.getParentFile / "target-2.10", + skip in publish := true + ) + +val compilerInterface211 = compilerInterface212 + .withId("compilerInterface211") + .settings( + scalaVersion := scala211, + crossScalaVersions := Seq(scala211), + target := (target in compilerInterface212).value.getParentFile / "target-2.11", + skip in publish := true + ) + +val compilerInterface213 = compilerInterface212 + .withId("compilerInterface213") + .settings( + scalaVersion := scala213, + crossScalaVersions := Seq(scala213), + target := (target in compilerInterface212).value.getParentFile / "target-2.13", skip in publish := true ) @@ -362,6 +362,13 @@ def wrapIn(color: String, content: String): String = { else color + content + scala.Console.RESET } +def noSourcesForTemplate: Seq[Setting[_]] = inBoth( + sources := { + val oldSources = sources.value + if (Keys.thisProject.value.id.contains("Template")) Seq.empty[File] else oldSources + }, +) + /** * Compiler-side interface to compiler that is compiled against the compiler being used either in advance or on the fly. * Includes API and Analyzer phases that extract source API and relationships. @@ -371,11 +378,10 @@ def wrapIn(color: String, content: String): String = { * and therefore there's no `mimaSettings` added. * For the case of Scala 2.13 bridge, we didn't even have the bridge to compare against when Zinc 1.0.0 came out. */ -lazy val compilerBridge: Project = (project in internalPath / "compiler-bridge") - .dependsOn(compilerInterface) +lazy val compilerBridgeTemplate: Project = (project in internalPath / "compiler-bridge") .settings( baseSettings, - crossScalaVersions := compilerBridgeScalaVersions, + noSourcesForTemplate, compilerVersionDependentScalacOptions, libraryDependencies += scalaCompiler.value % "provided", autoScalaLibrary := false, @@ -425,7 +431,42 @@ lazy val compilerBridge: Project = (project in internalPath / "compiler-bridge") } }, publishLocal := publishLocal.dependsOn(cleanSbtBridge).value, - altPublishSettings, + ) + +lazy val compilerBridge210 = compilerBridgeTemplate + .withId("compilerBridge210") + .dependsOn(compilerInterface210) + .settings( + scalaVersion := scala210, + crossScalaVersions := Seq(scala210), + target := (target in compilerBridgeTemplate).value.getParentFile / "target-2.10" + ) + +lazy val compilerBridge211 = compilerBridgeTemplate + .withId("compilerBridge211") + .dependsOn(compilerInterface211) + .settings( + scalaVersion := scala211, + crossScalaVersions := Seq(scala211), + target := (target in compilerBridgeTemplate).value.getParentFile / "target-2.11" + ) + +lazy val compilerBridge212 = compilerBridgeTemplate + .withId("compilerBridge212") + .dependsOn(compilerInterface212) + .settings( + scalaVersion := scala212, + crossScalaVersions := Seq(scala212), + target := (target in compilerBridgeTemplate).value.getParentFile / "target-2.12" + ) + +lazy val compilerBridge213 = compilerBridgeTemplate + .withId("compilerBridge213") + .dependsOn(compilerInterface213) + .settings( + scalaVersion := scala213, + crossScalaVersions := Seq(scala213), + target := (target in compilerBridgeTemplate).value.getParentFile / "target-2.13" ) /** @@ -433,8 +474,7 @@ lazy val compilerBridge: Project = (project in internalPath / "compiler-bridge") * This is split into a separate subproject because testing introduces more dependencies * (Zinc API Info, which transitively depends on IO). */ -lazy val compilerBridgeTest = (project in internalPath / "compiler-bridge-test") - .dependsOn(compilerBridge, compilerInterface % "test->test", zincApiInfo % "test->test") +lazy val compilerBridgeTestTemplate = (project in internalPath / "compiler-bridge-test") .settings( name := "Compiler Bridge Test", baseSettings, @@ -446,10 +486,42 @@ lazy val compilerBridgeTest = (project in internalPath / "compiler-bridge-test") // needed because we fork tests and tests are ran in parallel so we have multiple Scala // compiler instances that are memory hungry javaOptions in Test += "-Xmx1G", - crossScalaVersions := compilerBridgeTestScalaVersions, libraryDependencies += scalaCompiler.value, - altPublishSettings, skip in publish := true, + autoScalaLibrary := false, + ) + +lazy val compilerBridgeTest210 = compilerBridgeTestTemplate + .withId("compilerBridgeTest210") + .dependsOn(compilerInterface210 % "test->test") + .dependsOn(compilerBridge210, zincApiInfo210 % "test->test") + .settings( + scalaVersion := scala210, + crossScalaVersions := Seq(scala210), + target := (target in compilerBridgeTestTemplate).value.getParentFile / "target-2.10", + skip in publish := true + ) + +lazy val compilerBridgeTest211 = compilerBridgeTestTemplate + .withId("compilerBridgeTest211") + .dependsOn(compilerInterface211 % "test->test") + .dependsOn(compilerBridge211, zincApiInfo211 % "test->test") + .settings( + scalaVersion := scala211, + crossScalaVersions := Seq(scala211), + target := (target in compilerBridgeTestTemplate).value.getParentFile / "target-2.11", + skip in publish := true + ) + +lazy val compilerBridgeTest212 = compilerBridgeTestTemplate + .withId("compilerBridgeTest212") + .dependsOn(compilerInterface212 % "test->test") + .dependsOn(compilerBridge212, zincApiInfo212 % "test->test") + .settings( + scalaVersion := scala212, + crossScalaVersions := Seq(scala212), + target := (target in compilerBridgeTestTemplate).value.getParentFile / "target-2.12", + skip in publish := true ) val scalaPartialVersion = Def setting (CrossVersion partialVersion scalaVersion.value) @@ -458,13 +530,12 @@ def inBoth(ss: Setting[_]*): Seq[Setting[_]] = Seq(Compile, Test) flatMap (inCon // defines operations on the API of a source, including determining whether it has changed and converting it to a string // and discovery of Projclasses and annotations -lazy val zincApiInfo = (project in internalPath / "zinc-apiinfo") - .dependsOn(compilerInterface, zincClassfile % "compile;test->test") +lazy val zincApiInfoTemplate = (project in internalPath / "zinc-apiinfo") .configure(addBaseSettingsAndTestDeps) .settings( name := "zinc ApiInfo", - crossScalaVersions := compilerBridgeTestScalaVersions, compilerVersionDependentScalacOptions, + noSourcesForTemplate, mimaSettings, mimaBinaryIssueFilters ++= { import com.typesafe.tools.mima.core._ @@ -489,15 +560,43 @@ lazy val zincApiInfo = (project in internalPath / "zinc-apiinfo") } ) +lazy val zincApiInfo210 = zincApiInfoTemplate + .withId("zincApiInfo210") + .dependsOn(compilerInterface210, zincClassfile210 % "compile;test->test") + .settings( + scalaVersion := scala210, + crossScalaVersions := Seq(scala210), + target := (target in zincApiInfoTemplate).value.getParentFile / "target-2.10" + ) + +lazy val zincApiInfo211 = zincApiInfoTemplate + .withId("zincApiInfo211") + .dependsOn(compilerInterface211, compilerBridge211) + .dependsOn(zincClassfile211 % "compile;test->test") + .settings( + scalaVersion := scala211, + crossScalaVersions := Seq(scala211), + target := (target in zincApiInfoTemplate).value.getParentFile / "target-2.11" + ) + +lazy val zincApiInfo212 = zincApiInfoTemplate + .withId("zincApiInfo212") + .dependsOn(compilerInterface212, compilerBridge212) + .dependsOn(zincClassfile212 % "compile;test->test") + .settings( + scalaVersion := scala212, + crossScalaVersions := Seq(scala212), + target := (target in zincApiInfoTemplate).value.getParentFile / "target-2.12" + ) + // Utilities related to reflection, managing Scala versions, and custom class loaders -lazy val zincClasspath = (project in internalPath / "zinc-classpath") - .dependsOn(compilerInterface) +lazy val zincClasspathTemplate = (project in internalPath / "zinc-classpath") .configure(addBaseSettingsAndTestDeps) .settings( name := "zinc Classpath", - crossScalaVersions := compilerBridgeTestScalaVersions, compilerVersionDependentScalacOptions, libraryDependencies ++= Seq(scalaCompiler.value, launcherInterface), + noSourcesForTemplate, mimaSettings, mimaBinaryIssueFilters ++= Seq( // Changed the signature of a private[sbt] method @@ -506,18 +605,71 @@ lazy val zincClasspath = (project in internalPath / "zinc-classpath") ) .configure(addSbtIO) +lazy val zincClasspath210 = zincClasspathTemplate + .withId("zincClasspath210") + .dependsOn(compilerInterface210) + .settings( + scalaVersion := scala210, + crossScalaVersions := Seq(scala210), + target := (target in zincClasspathTemplate).value.getParentFile / "target-2.10" + ) + +lazy val zincClasspath211 = zincClasspathTemplate + .withId("zincClasspath211") + .dependsOn(compilerInterface211) + .settings( + scalaVersion := scala211, + crossScalaVersions := Seq(scala211), + target := (target in zincClasspathTemplate).value.getParentFile / "target-2.11" + ) + +lazy val zincClasspath212 = zincClasspathTemplate + .withId("zincClasspath212") + .dependsOn(compilerInterface212) + .settings( + scalaVersion := scala212, + crossScalaVersions := Seq(scala212), + target := (target in zincClasspathTemplate).value.getParentFile / "target-2.12" + ) + // class file reader and analyzer -lazy val zincClassfile = (project in internalPath / "zinc-classfile") - .dependsOn(compilerInterface % "compile;test->test") +lazy val zincClassfileTemplate = (project in internalPath / "zinc-classfile") .configure(addBaseSettingsAndTestDeps) .settings( name := "zinc Classfile", - crossScalaVersions := compilerBridgeTestScalaVersions, compilerVersionDependentScalacOptions, mimaSettings, + noSourcesForTemplate, ) .configure(addSbtIO, addSbtUtilLogging) +lazy val zincClassfile210 = zincClassfileTemplate + .withId("zincClassfile210") + .dependsOn(compilerInterface210 % "compile;test->test") + .settings( + scalaVersion := scala210, + crossScalaVersions := Seq(scala210), + target := (target in zincClassfileTemplate).value.getParentFile / "target-2.10" + ) + +lazy val zincClassfile211 = zincClassfileTemplate + .withId("zincClassfile211") + .dependsOn(compilerInterface211 % "compile;test->test") + .settings( + scalaVersion := scala211, + crossScalaVersions := Seq(scala211), + target := (target in zincClassfileTemplate).value.getParentFile / "target-2.11" + ) + +lazy val zincClassfile212 = zincClassfileTemplate + .withId("zincClassfile212") + .dependsOn(compilerInterface212 % "compile;test->test") + .settings( + scalaVersion := scala212, + crossScalaVersions := Seq(scala212), + target := (target in zincClassfileTemplate).value.getParentFile / "target-2.12" + ) + // re-implementation of scripted engine lazy val zincScripted = (project in internalPath / "zinc-scripted") .dependsOn(zinc, zincIvyIntegration % "test->test") @@ -545,46 +697,28 @@ lazy val bloopScripted = (project in internalPath / "zinc-scripted-bloop") lazy val crossTestBridges = { Command.command("crossTestBridges") { state => - (compilerBridgeTestScalaVersions.flatMap { (bridgeVersion: String) => - // Note the ! here. You need this so compilerInterface gets forced to the scalaVersion - s"++ $bridgeVersion!" :: - s"${compilerBridgeTest.id}/test" :: - Nil - }) ::: - (s"++ $scala212!" :: - state) - } -} + val publishCommands = List( + s"${compilerBridgeTest210.id}/test", + s"${compilerBridgeTest211.id}/test", + s"${compilerBridgeTest212.id}/test", + ) -lazy val publishBridgesAndSet = { - Command.args("publishBridgesAndSet", "") { (state, args) => - require(args.nonEmpty, "Missing Scala version argument.") - val userScalaVersion = args.mkString("") - s"${compilerInterface.id}/publishLocal" :: - compilerBridgeScalaVersions.flatMap { (bridgeVersion: String) => - s"++ $bridgeVersion!" :: - s"${compilerBridge.id}/publishLocal" :: Nil - } ::: - s"++ $userScalaVersion!" :: - state + publishCommands ::: state } } -lazy val publishBridgesAndTest = Command.args("publishBridgesAndTest", "") { - (state, args) => - require(args.nonEmpty, - "Missing arguments to publishBridgesAndTest. Maybe quotes are missing around command?") - val version = args mkString "" - s"${compilerInterface.id}/publishLocal" :: - (compilerBridgeScalaVersions.flatMap { (bridgeVersion: String) => - s"++ $bridgeVersion" :: - s"${compilerBridge.id}/publishLocal" :: Nil - }) ::: - s"++ $version" :: - s"zincRoot/scalaVersion" :: - s"zincRoot/test" :: - s"zincRoot/scripted" :: - state +lazy val publishBridges = { + Command.command("publishBridges") { state => + val publishCommands = List( + s"${compilerInterface212.id}/publishLocal", + s"${compilerBridge210.id}/publishLocal", + s"${compilerBridge211.id}/publishLocal", + s"${compilerBridge212.id}/publishLocal", + s"${compilerBridge213.id}/publishLocal" + ) + + publishCommands ::: state + } } val dir = IO.createTemporaryDirectory @@ -601,9 +735,9 @@ addCommandAlias( ) lazy val otherRootSettings = Seq( - Scripted.scriptedBufferLog := true, - Scripted.scriptedPrescripted := { addSbtAlternateResolver _ }, - Scripted.scripted := scriptedTask.evaluated, + scriptedBufferLog := true, + scripted := scriptedTask.evaluated, + Scripted.scriptedPrescripted := { (_: File) => () }, Scripted.scriptedUnpublished := scriptedUnpublishedTask.evaluated, Scripted.scriptedSource := (sourceDirectory in zinc).value / "sbt-test", publishAll := { @@ -614,11 +748,6 @@ lazy val otherRootSettings = Seq( def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask { val result = scriptedSource(dir => (s: State) => scriptedParser(dir)).parsed publishAll.value - // These two projects need to be visible in a repo even if the default - // local repository is hidden, so we publish them to an alternate location and add - // that alternate repo to the running scripted test (in Scripted.scriptedpreScripted). - (altLocalPublish in compilerInterface).value - (altLocalPublish in compilerBridge).value doScripted( (fullClasspath in zincScripted in Test).value, (scalaInstance in zincScripted).value, @@ -629,26 +758,6 @@ def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask { ) } -def addSbtAlternateResolver(scriptedRoot: File) = { - val resolver = scriptedRoot / "project" / "AddResolverPlugin.scala" - if (!resolver.exists) { - IO.write( - resolver, - s"""import sbt._ - |import Keys._ - | - |object AddResolverPlugin extends AutoPlugin { - | override def requires = sbt.plugins.JvmPlugin - | override def trigger = allRequirements - | - | override lazy val projectSettings = Seq(resolvers += alternativeLocalResolver) - | lazy val alternativeLocalResolver = Resolver.file("$altLocalRepoName", file("$altLocalRepoPath"))(Resolver.ivyStylePatterns) - |} - |""".stripMargin - ) - } -} - def scriptedUnpublishedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask { val result = scriptedSource(dir => (s: State) => scriptedParser(dir)).parsed doScripted( diff --git a/internal/compiler-interface/src/main/java/xsbti/compile/DefaultExternalHooks.java b/internal/compiler-interface/src/main/java/xsbti/compile/DefaultExternalHooks.java index 84b0931929..f517dc51be 100644 --- a/internal/compiler-interface/src/main/java/xsbti/compile/DefaultExternalHooks.java +++ b/internal/compiler-interface/src/main/java/xsbti/compile/DefaultExternalHooks.java @@ -30,17 +30,15 @@ public Optional getExternalClassFileManager() { @Override public ExternalHooks withExternalClassFileManager(ClassFileManager externalClassFileManager) { - Optional currentManager = this.getExternalClassFileManager(); - Optional mixedManager = currentManager; - if (currentManager.isPresent()) { - Optional external = Optional.of(externalClassFileManager); - mixedManager = Optional.of(WrappedClassFileManager.of(currentManager.get(), external)); - } - return new DefaultExternalHooks(this.getExternalLookup(), mixedManager); + Optional external = Optional.of(externalClassFileManager); + Optional mixedManager = classFileManager.isPresent() + ? Optional.of(WrappedClassFileManager.of(classFileManager.get(), external)) + : external; + return new DefaultExternalHooks(lookup, mixedManager); } @Override public ExternalHooks withExternalLookup(ExternalHooks.Lookup externalLookup) { - return new DefaultExternalHooks(Optional.of(externalLookup), this.getExternalClassFileManager()); + return new DefaultExternalHooks(Optional.of(externalLookup), classFileManager); } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 191ee17259..122681781e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,9 +7,9 @@ object Dependencies { val scala212 = "2.12.6" val scala213 = "2.13.0-M2" - private val ioVersion = "1.2.0-M1" - private val utilVersion = "1.2.0-M1" - private val lmVersion = "1.2.0-M1" + private val ioVersion = "1.2.0" + private val utilVersion = "1.2.0" + private val lmVersion = "1.2.0" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/Scripted.scala b/project/Scripted.scala index d018b64b69..fb16162c05 100644 --- a/project/Scripted.scala +++ b/project/Scripted.scala @@ -1,3 +1,5 @@ +package localzinc + import sbt._ import Keys._ import Def.Initialize @@ -8,13 +10,11 @@ import scala.language.reflectiveCalls object Scripted { def scriptedPath = file("scripted") - lazy val scripted = InputKey[Unit]("scripted") - lazy val scriptedUnpublished = InputKey[Unit]( - "scripted-unpublished", - "Execute scripted without publishing SBT first. Saves you some time when only your test has changed.") - lazy val scriptedSource = SettingKey[File]("scripted-source") - lazy val scriptedPrescripted = TaskKey[File => Unit]("scripted-prescripted") - lazy val scriptedBufferLog = SettingKey[Boolean]("scripted-buffer-log") + val publishLocalBinAll = taskKey[Unit]("") + val scriptedUnpublished = inputKey[Unit]("Execute scripted without publishing sbt first. " + + "Saves you some time when only your test has changed") + val scriptedSource = settingKey[File]("") + val scriptedPrescripted = taskKey[File => Unit]("") import sbt.complete._ import DefaultParsers._ diff --git a/project/build.properties b/project/build.properties index d6e35076cc..5620cc502b 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.6 +sbt.version=1.2.1 diff --git a/zinc/src/test/scala/sbt/inc/ClassFileManagerHookSpec.scala b/zinc/src/test/scala/sbt/inc/ClassFileManagerHookSpec.scala new file mode 100644 index 0000000000..809d7378de --- /dev/null +++ b/zinc/src/test/scala/sbt/inc/ClassFileManagerHookSpec.scala @@ -0,0 +1,39 @@ +package sbt.inc + +import java.io.File + +import sbt.io.IO + +import xsbti.compile.ClassFileManager +import xsbti.compile.IncOptions + +class ClassFileManagerHookSpec extends BaseCompilerSpec { + it should "allow client to add their own class file manager" in { + IO.withTemporaryDirectory { tempDir => + val setup = ProjectSetup.simple(tempDir.toPath, SourceFiles.Foo :: Nil) + + var callbackCalled = 0 + val myClassFileManager = new ClassFileManager { + override def delete(classes: Array[File]): Unit = { + callbackCalled += 1 + } + override def generated(classes: Array[File]): Unit = { + callbackCalled += 1 + } + override def complete(success: Boolean): Unit = { + callbackCalled += 1 + } + } + + val incOptions = IncOptions.of() + val newExternalHooks = + incOptions.externalHooks.withExternalClassFileManager(myClassFileManager) + + val compiler = + setup.createCompiler().copy(incOptions = incOptions.withExternalHooks(newExternalHooks)) + compiler.doCompile() + + callbackCalled.shouldEqual(3) + } + } +}