summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.sbt187
-rw-r--r--project/BuildSettings.scala11
-rw-r--r--project/MiMa.scala95
-rw-r--r--project/Osgi.scala4
-rw-r--r--project/Quiet.scala2
-rw-r--r--project/ScalaTool.scala12
-rw-r--r--project/ScriptCommands.scala21
-rw-r--r--project/VersionUtil.scala34
-rw-r--r--project/plugins.sbt5
-rwxr-xr-xscripts/jobs/validate/publish-core4
-rwxr-xr-xscripts/jobs/validate/test35
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala18
-rw-r--r--test/disabled/run/t7843-jsr223-service.check (renamed from test/files/run/t7843-jsr223-service.check)0
-rw-r--r--test/disabled/run/t7843-jsr223-service.scala (renamed from test/files/run/t7843-jsr223-service.scala)0
-rw-r--r--test/disabled/run/t7933.check (renamed from test/files/run/t7933.check)0
-rw-r--r--test/disabled/run/t7933.scala (renamed from test/files/run/t7933.scala)0
-rw-r--r--test/osgi/src/logback.xml10
-rw-r--r--test/scaladoc/.gitignore2
-rw-r--r--test/scaladoc/run/SI-191.scala12
-rw-r--r--test/scaladoc/run/t8557.scala20
-rw-r--r--versions.properties2
21 files changed, 382 insertions, 92 deletions
diff --git a/build.sbt b/build.sbt
index 13bbd8be03..3df0d43c00 100644
--- a/build.sbt
+++ b/build.sbt
@@ -55,25 +55,23 @@
import VersionUtil._
-val bootstrapScalaVersion = versionProps("starr.version")
-
-def withoutScalaLang(moduleId: ModuleID): ModuleID = moduleId exclude("org.scala-lang", "*")
-
-// exclusion of the scala-library transitive dependency avoids eviction warnings during `update`.
-val actorsMigrationDep = withoutScalaLang("org.scala-lang" %% "scala-actors-migration" % versionNumber("actors-migration"))
-val akkaActorDep = withoutScalaLang("com.typesafe.akka" %% "akka-actor" % versionNumber("akka-actor"))
-val scalaContinuationsLibraryDep = withoutScalaLang("org.scala-lang.plugins" %% "scala-continuations-library" % versionNumber("scala-continuations-library"))
-val scalaContinuationsPluginDep = withoutScalaLang("org.scala-lang.plugins" % ("scala-continuations-plugin_" + versionProps("scala.full.version")) % versionNumber("scala-continuations-plugin"))
-val scalaParserCombinatorsDep = withoutScalaLang("org.scala-lang.modules" %% "scala-parser-combinators" % versionNumber("scala-parser-combinators"))
-val scalaSwingDep = withoutScalaLang("org.scala-lang.modules" %% "scala-swing" % versionNumber("scala-swing"))
-val scalaXmlDep = withoutScalaLang("org.scala-lang.modules" %% "scala-xml" % versionNumber("scala-xml"))
-val partestDep = withoutScalaLang("org.scala-lang.modules" %% "scala-partest" % versionNumber("partest"))
-val junitDep = "junit" % "junit" % "4.11"
-val junitInterfaceDep = "com.novocode" % "junit-interface" % "0.11" % "test"
-val asmDep = "org.scala-lang.modules" % "scala-asm" % versionProps("scala-asm.version")
-val jlineDep = "jline" % "jline" % versionProps("jline.version")
-val antDep = "org.apache.ant" % "ant" % "1.9.4"
-val scalacheckDep = withoutScalaLang("org.scalacheck" %% "scalacheck" % versionNumber("scalacheck") % "it")
+// Scala dependencies:
+val scalaContinuationsPluginDep = scalaDep("org.scala-lang.plugins", "scala-continuations-plugin", compatibility = "full")
+val scalaContinuationsLibraryDep = scalaDep("org.scala-lang.plugins", "scala-continuations-library")
+val scalaParserCombinatorsDep = scalaDep("org.scala-lang.modules", "scala-parser-combinators")
+val scalaSwingDep = scalaDep("org.scala-lang.modules", "scala-swing")
+val scalaXmlDep = scalaDep("org.scala-lang.modules", "scala-xml")
+val partestDep = scalaDep("org.scala-lang.modules", "scala-partest", versionProp = "partest")
+val akkaActorDep = scalaDep("com.typesafe.akka", "akka-actor")
+val actorsMigrationDep = scalaDep("org.scala-lang", "scala-actors-migration", versionProp = "actors-migration")
+val scalacheckDep = scalaDep("org.scalacheck", "scalacheck", scope = "it")
+
+// Non-Scala dependencies:
+val junitDep = "junit" % "junit" % "4.11"
+val junitInterfaceDep = "com.novocode" % "junit-interface" % "0.11" % "test"
+val asmDep = "org.scala-lang.modules" % "scala-asm" % versionProps("scala-asm.version")
+val jlineDep = "jline" % "jline" % versionProps("jline.version")
+val antDep = "org.apache.ant" % "ant" % "1.9.4"
/** Publish to ./dists/maven-sbt, similar to the ANT build which publishes to ./dists/maven. This
* can be used to compare the output of the sbt and ANT builds during the transition period. Any
@@ -117,20 +115,27 @@ lazy val publishSettings : Seq[Setting[_]] = Seq(
globalVersionSettings
baseVersion in Global := "2.11.9"
baseVersionSuffix in Global := "SNAPSHOT"
+mimaReferenceVersion in Global := Some("2.11.0")
lazy val commonSettings = clearSourceAndResourceDirectories ++ publishSettings ++ Seq[Setting[_]](
organization := "org.scala-lang",
- scalaVersion := bootstrapScalaVersion,
// we don't cross build Scala itself
crossPaths := false,
// do not add Scala library jar as a dependency automatically
autoScalaLibrary := false,
- // we also do not add scala instance automatically because it introduces
- // a circular instance, see: https://github.com/sbt/sbt/issues/1872
+ // Avoid circular dependencies for scalaInstance (see https://github.com/sbt/sbt/issues/1872)
managedScalaInstance := false,
- // this is a way to workaround issue described in https://github.com/sbt/sbt/issues/1872
- // check it out for more details
- scalaInstance := ScalaInstance(scalaVersion.value, appConfiguration.value.provider.scalaProvider.launcher getScala scalaVersion.value),
+ scalaInstance := {
+ val s = (scalaInstance in bootstrap).value
+ // sbt claims that s.isManagedVersion is false even though s was resolved by Ivy
+ // We create a managed copy to prevent sbt from putting it on the classpath where we don't want it
+ if(s.isManagedVersion) s else {
+ val s2 = new ScalaInstance(s.version, s.loader, s.libraryJar, s.compilerJar, s.extraJars, Some(s.actualVersion))
+ assert(s2.isManagedVersion)
+ s2
+ }
+ },
+ scalaVersion := (scalaVersion in bootstrap).value,
// we always assume that Java classes are standalone and do not have any dependency
// on Scala classes
compileOrder := CompileOrder.JavaThenScala,
@@ -151,7 +156,7 @@ lazy val commonSettings = clearSourceAndResourceDirectories ++ publishSettings +
target := (baseDirectory in ThisBuild).value / "target" / thisProject.value.id,
classDirectory in Compile := buildDirectory.value / "quick/classes" / thisProject.value.id,
target in Compile in doc := buildDirectory.value / "scaladoc" / thisProject.value.id,
- // given that classDirectory and doc target are overriden to be _outside_ of target directory, we have
+ // given that classDirectory and doc target are overridden to be _outside_ of target directory, we have
// to make sure they are being cleaned properly
cleanFiles += (classDirectory in Compile).value,
cleanFiles += (target in Compile in doc).value,
@@ -166,9 +171,10 @@ lazy val commonSettings = clearSourceAndResourceDirectories ++ publishSettings +
"-sourcepath", (baseDirectory in ThisBuild).value.toString,
"-doc-source-url", s"https://github.com/scala/scala/tree/${versionProperties.value.githubTree}€{FILE_PATH}.scala#L1"
),
+ incOptions <<= (incOptions in LocalProject("root")),
homepage := Some(url("http://www.scala-lang.org")),
startYear := Some(2002),
- licenses += ("BSD 3-Clause", url("http://www.scala-lang.org/license.html")),
+ licenses += (("BSD 3-Clause", url("http://www.scala-lang.org/license.html"))),
apiURL := Some(url("http://www.scala-lang.org/api/" + versionProperties.value.mavenVersion + "/")),
pomIncludeRepository := { _ => false },
pomExtra := {
@@ -213,8 +219,7 @@ lazy val commonSettings = clearSourceAndResourceDirectories ++ publishSettings +
// Don't log process output (e.g. of forked `compiler/runMain ...Main`), just pass it
// directly to stdout
outputStrategy in run := Some(StdoutOutput),
- Quiet.silenceScalaBinaryVersionWarning,
- Quiet.silenceIvyUpdateInfoLogging
+ Quiet.silenceScalaBinaryVersionWarning
)
/** Extra post-processing for the published POM files. These are needed to create POMs that
@@ -250,7 +255,7 @@ def removePomDependencies(deps: (String, String)*): Seq[Setting[_]] = Seq(
val n2 = pomPostProcess.value.apply(n)
import scala.xml._
import scala.xml.transform._
- (new RuleTransformer(new RewriteRule {
+ new RuleTransformer(new RewriteRule {
override def transform(node: Node) = node match {
case e: Elem if e.label == "dependency" &&
deps.exists { case (g, a) =>
@@ -259,13 +264,13 @@ def removePomDependencies(deps: (String, String)*): Seq[Setting[_]] = Seq(
} => Seq.empty
case n => Seq(n)
}
- })).transform(Seq(n2)).head
+ }).transform(Seq(n2)).head
},
deliverLocal := {
import scala.xml._
import scala.xml.transform._
val f = deliverLocal.value
- val e = (new RuleTransformer(new RewriteRule {
+ val e = new RuleTransformer(new RewriteRule {
override def transform(node: Node) = node match {
case e: Elem if e.label == "dependency" && {
val org = e.attribute("org").getOrElse("").toString
@@ -276,7 +281,7 @@ def removePomDependencies(deps: (String, String)*): Seq[Setting[_]] = Seq(
} => Seq.empty
case n => Seq(n)
}
- })).transform(Seq(XML.loadFile(f))).head
+ }).transform(Seq(XML.loadFile(f))).head
XML.save(f.getAbsolutePath, e, xmlDecl = true)
f
}
@@ -309,7 +314,7 @@ lazy val setJarLocation: Setting[_] =
lazy val scalaSubprojectSettings: Seq[Setting[_]] = commonSettings :+ setJarLocation
def filterDocSources(ff: FileFilter): Seq[Setting[_]] = Seq(
- sources in (Compile, doc) ~= (_.filter(ff.accept _)),
+ sources in (Compile, doc) ~= (_.filter(ff.accept)),
// Excluded sources may still be referenced by the included sources, so we add the compiler
// output to the scaladoc classpath to resolve them. For the `library` project this is
// always required because otherwise the compiler cannot even initialize Definitions without
@@ -326,6 +331,11 @@ def regexFileFilter(s: String): FileFilter = new FileFilter {
def accept(f: File) = pat.matcher(f.getAbsolutePath.replace('\\', '/')).matches()
}
+// This project provides the STARR scalaInstance for bootstrapping
+lazy val bootstrap = (project in file("target/bootstrap")).settings(
+ scalaVersion := versionProps("starr.version")
+)
+
lazy val library = configureAsSubproject(project)
.settings(generatePropertiesFileSettings: _*)
.settings(Osgi.settings: _*)
@@ -363,6 +373,7 @@ lazy val library = configureAsSubproject(project)
.settings(filterDocSources("*.scala" -- (regexFileFilter(".*/runtime/.*\\$\\.scala") ||
regexFileFilter(".*/runtime/ScalaRunTime\\.scala") ||
regexFileFilter(".*/runtime/StringAdd\\.scala"))): _*)
+ .settings(MiMa.settings: _*)
.dependsOn(forkjoin)
lazy val reflect = configureAsSubproject(project)
@@ -385,6 +396,7 @@ lazy val reflect = configureAsSubproject(project)
"/project/packaging" -> <packaging>jar</packaging>
)
)
+ .settings(MiMa.settings: _*)
.dependsOn(library)
lazy val compiler = configureAsSubproject(project)
@@ -581,6 +593,56 @@ lazy val junit = project.in(file("test") / "junit")
unmanagedSourceDirectories in Test := List(baseDirectory.value)
)
+lazy val osgiTestFelix = osgiTestProject(
+ project.in(file(".") / "target" / "osgiTestFelix"),
+ "org.apache.felix" % "org.apache.felix.framework" % "4.4.0")
+
+lazy val osgiTestEclipse = osgiTestProject(
+ project.in(file(".") / "target" / "osgiTestEclipse"),
+ "org.eclipse.osgi" % "org.eclipse.osgi" % "3.7.1")
+
+def osgiTestProject(p: Project, framework: ModuleID) = p
+ .dependsOn(library, reflect, compiler, actors, forkjoin)
+ .settings(clearSourceAndResourceDirectories: _*)
+ .settings(commonSettings: _*)
+ .settings(disableDocs: _*)
+ .settings(disablePublishing: _*)
+ .settings(
+ fork in Test := true,
+ parallelExecution in Test := false,
+ libraryDependencies ++= {
+ val paxExamVersion = "3.5.0" // Last version which supports Java 6
+ Seq(
+ junitDep,
+ junitInterfaceDep,
+ "org.ops4j.pax.exam" % "pax-exam-container-native" % paxExamVersion
+ exclude("org.osgi", "org.osgi.core"), // Avoid dragging in a dependency which requires Java >6
+ "org.osgi" % "org.osgi.core" % "4.2.0" % "provided", // The framework (Felix / Eclipse) provides the classes
+ "org.ops4j.pax.exam" % "pax-exam-junit4" % paxExamVersion,
+ "org.ops4j.pax.exam" % "pax-exam-link-assembly" % paxExamVersion,
+ "org.ops4j.pax.url" % "pax-url-aether" % "2.2.0",
+ "org.ops4j.pax.swissbox" % "pax-swissbox-tracker" % "1.8.0",
+ "ch.qos.logback" % "logback-core" % "1.1.2",
+ "ch.qos.logback" % "logback-classic" % "1.1.2",
+ framework % "test"
+ )
+ },
+ Keys.test in Test <<= Keys.test in Test dependsOn (packageBin in Compile),
+ testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-v", "-q"),
+ unmanagedSourceDirectories in Test := List((baseDirectory in ThisBuild).value / "test" / "osgi" / "src"),
+ unmanagedResourceDirectories in Compile := (unmanagedSourceDirectories in Test).value,
+ includeFilter in unmanagedResources in Compile := "*.xml",
+ packageBin in Compile := { // Put the bundle JARs required for the tests into build/osgi
+ val targetDir = (buildDirectory in ThisBuild).value / "osgi"
+ val mappings = ((mkPack in dist).value / "lib").listFiles.collect {
+ case f if f.getName.startsWith("scala-") && f.getName.endsWith(".jar") => (f, targetDir / f.getName)
+ }
+ IO.copy(mappings, overwrite = true)
+ targetDir
+ },
+ cleanFiles += (buildDirectory in ThisBuild).value / "osgi"
+ )
+
lazy val partestJavaAgent = Project("partest-javaagent", file(".") / "src" / "partest-javaagent")
.settings(commonSettings: _*)
.settings(generatePropertiesFileSettings: _*)
@@ -610,8 +672,15 @@ lazy val test = project
.settings(Defaults.itSettings: _*)
.settings(
libraryDependencies ++= Seq(asmDep, partestDep, scalaXmlDep, scalacheckDep),
- unmanagedBase in IntegrationTest := baseDirectory.value / "files" / "lib",
- unmanagedJars in IntegrationTest <+= (unmanagedBase) (j => Attributed.blank(j)) map(identity),
+ libraryDependencies ++= {
+ // Resolve the JARs for all test/files/lib/*.jar.desired.sha1 files through Ivy
+ val baseDir = (baseDirectory in ThisBuild).value
+ (baseDir / "test/files/lib").list.toSeq.filter(_.endsWith(".jar.desired.sha1"))
+ .map(f => bootstrapDep(baseDir, "test/files/lib", f.dropRight(17)))
+ },
+ // Two hardcoded depenencies in partest, resolved in the otherwise unused scope "test":
+ libraryDependencies += bootstrapDep((baseDirectory in ThisBuild).value, "test/files/codelib", "code") % "test",
+ libraryDependencies += bootstrapDep((baseDirectory in ThisBuild).value, "test/files/speclib", "instrumented") % "test",
// no main sources
sources in Compile := Seq.empty,
// test sources are compiled in partest run, not here
@@ -619,18 +688,24 @@ lazy val test = project
fork in IntegrationTest := true,
javaOptions in IntegrationTest += "-Xmx1G",
testFrameworks += new TestFramework("scala.tools.partest.sbt.Framework"),
- testOptions in IntegrationTest += Tests.Setup( () => root.base.getAbsolutePath + "/pull-binary-libs.sh" ! ),
testOptions in IntegrationTest += Tests.Argument("-Dpartest.java_opts=-Xmx1024M -Xms64M -XX:MaxPermSize=128M"),
- definedTests in IntegrationTest += (
- new sbt.TestDefinition(
- "partest",
- // marker fingerprint since there are no test classes
- // to be discovered by sbt:
- new sbt.testing.AnnotatedFingerprint {
- def isModule = true
- def annotationName = "partest"
- }, true, Array())
- )
+ testOptions in IntegrationTest += Tests.Argument("-Dpartest.scalac_opts=" + (scalacOptions in Compile).value.mkString(" ")),
+ testOptions in IntegrationTest += Tests.Setup { () =>
+ val cp = (dependencyClasspath in Test).value
+ val baseDir = (baseDirectory in ThisBuild).value
+ // Copy code.jar and instrumented.jar to the location where partest expects them
+ copyBootstrapJar(cp, baseDir, "test/files/codelib", "code")
+ copyBootstrapJar(cp, baseDir, "test/files/speclib", "instrumented")
+ },
+ definedTests in IntegrationTest += new sbt.TestDefinition(
+ "partest",
+ // marker fingerprint since there are no test classes
+ // to be discovered by sbt:
+ new sbt.testing.AnnotatedFingerprint {
+ def isModule = true
+ def annotationName = "partest"
+ }, true, Array()
+ )
)
lazy val manual = configureAsSubproject(project)
@@ -704,7 +779,7 @@ lazy val scalaDist = Project("scala-dist", file(".") / "target" / "scala-dist-di
)
.dependsOn(libraryAll, compiler, scalap)
-lazy val root = (project in file("."))
+lazy val root: Project = (project in file("."))
.settings(disableDocs: _*)
.settings(disablePublishing: _*)
.settings(generateBuildCharacterFileSettings: _*)
@@ -712,8 +787,9 @@ lazy val root = (project in file("."))
publish := {},
publishLocal := {},
commands ++= ScriptCommands.all,
- Quiet.silenceIvyUpdateInfoLogging
-)
+ antStyle := false,
+ incOptions := incOptions.value.withNameHashing(!antStyle.value).withAntStyle(antStyle.value)
+ )
.aggregate(library, forkjoin, reflect, compiler, interactive, repl, replJline, replJlineEmbedded,
scaladoc, scalap, actors, partestExtras, junit, libraryAll, scalaDist).settings(
sources in Compile := Seq.empty,
@@ -737,8 +813,9 @@ lazy val dist = (project in file("dist"))
val props = new java.util.Properties()
props.setProperty("partest.classpath", cp.map(_.data.getAbsolutePath).mkString(sys.props("path.separator")))
IO.write(props, null, propsFile)
+ (buildDirectory in ThisBuild).value / "quick"
} dependsOn ((distDependencies.map(products in Runtime in _) :+ mkBin): _*),
- mkPack <<= Def.task {} dependsOn (packagedArtifact in (Compile, packageBin), mkBin),
+ mkPack <<= Def.task { (buildDirectory in ThisBuild).value / "pack" } dependsOn (packagedArtifact in (Compile, packageBin), mkBin),
target := (baseDirectory in ThisBuild).value / "target" / thisProject.value.id,
packageBin in Compile := {
val extraDeps = Set(scalaContinuationsLibraryDep, scalaContinuationsPluginDep, scalaSwingDep, scalaParserCombinatorsDep, scalaXmlDep)
@@ -749,7 +826,7 @@ lazy val dist = (project in file("dist"))
case (Some(m), f) if extraModules contains uniqueModule(m) => f
}
val jlineJAR = (dependencyClasspath in Compile).value.find(_.get(moduleID.key) == Some(jlineDep)).get.data
- val mappings = extraJars.map(f => (f, targetDir / f.getName)) :+ (jlineJAR, targetDir / "jline.jar")
+ val mappings = extraJars.map(f => (f, targetDir / f.getName)) :+ ((jlineJAR, targetDir / "jline.jar"))
IO.copy(mappings, overwrite = true)
targetDir
},
@@ -802,8 +879,8 @@ def configureAsForkOfJavaProject(project: Project): Project = {
lazy val buildDirectory = settingKey[File]("The directory where all build products go. By default ./build")
lazy val mkBin = taskKey[Seq[File]]("Generate shell script (bash or Windows batch).")
-lazy val mkQuick = taskKey[Unit]("Generate a full build, including scripts, in build/quick")
-lazy val mkPack = taskKey[Unit]("Generate a full build, including scripts, in build/pack")
+lazy val mkQuick = taskKey[File]("Generate a full build, including scripts, in build/quick")
+lazy val mkPack = taskKey[File]("Generate a full build, including scripts, in build/pack")
// Defining these settings is somewhat redundant as we also redefine settings that depend on them.
// However, IntelliJ's project import works better when these are set correctly.
@@ -929,7 +1006,7 @@ intellij := {
def moduleDep(name: String, jars: Seq[File]) = {
val entries = jars.map(f => s""" <root url="jar://${f.toURI.getRawPath}!/" />""").mkString("\n")
- s"""| <library name="${name}-deps">
+ s"""| <library name="$name-deps">
| <CLASSES>
|$entries
| </CLASSES>
diff --git a/project/BuildSettings.scala b/project/BuildSettings.scala
new file mode 100644
index 0000000000..76cd888a2d
--- /dev/null
+++ b/project/BuildSettings.scala
@@ -0,0 +1,11 @@
+import sbt._
+
+/** This object defines keys that should be visible with an unqualified name in all .sbt files and the command line */
+object BuildSettings extends AutoPlugin {
+ object autoImport {
+ lazy val antStyle = settingKey[Boolean]("Use ant-style incremental builds instead of name-hashing")
+ lazy val baseVersion = settingKey[String]("The base version number from which all others are derived")
+ lazy val baseVersionSuffix = settingKey[String]("Identifies the kind of version to build")
+ lazy val mimaReferenceVersion = settingKey[Option[String]]("Scala version number to run MiMa against")
+ }
+}
diff --git a/project/MiMa.scala b/project/MiMa.scala
new file mode 100644
index 0000000000..66442fc725
--- /dev/null
+++ b/project/MiMa.scala
@@ -0,0 +1,95 @@
+// It would be nice to use sbt-mima-plugin here, but the plugin is missing
+// at least two features we need:
+// * ability to run MiMa twice, swapping `curr` and `prev`, to detect
+// both forwards and backwards incompatibilities (possibly fixed as of
+// https://github.com/typesafehub/migration-manager/commit/2844ffa48b6d2255aa64bd687703aec21dadd55e)
+// * ability to pass a filter file (https://github.com/typesafehub/migration-manager/issues/102)
+// So we invoke the MiMa CLI directly; it's also what the Ant build did.
+
+import sbt._
+import sbt.Keys._
+import BuildSettings.autoImport._
+
+object MiMa {
+ lazy val mima =
+ taskKey[Unit]("run Migration Manager to detect binary incompatibilities")
+
+ lazy val settings =
+ Seq(
+ mima := {
+ val log = streams.value.log
+ mimaReferenceVersion.value.fold {
+ log.info(s"No reference version defined - skipping binary compatibility checks")
+ } { refVersion =>
+ def runOnce(prev: java.io.File, curr: java.io.File, isForward: Boolean): Unit = {
+ val direction = if (isForward) "forward" else "backward"
+ log.info(s"Checking $direction binary compatibility")
+ log.debug(s"prev = $prev, curr = $curr")
+ runMima(
+ prev = if (isForward) curr else prev,
+ curr = if (isForward) prev else curr,
+ // TODO: it would be nicer if each subproject had its own whitelist, but for now
+ // for compatibility with how Ant did things, there's just one at the root.
+ // once Ant is gone we'd be free to split it up.
+ filter = (baseDirectory in ThisBuild).value / s"bincompat-$direction.whitelist.conf",
+ log)
+ }
+ val artifact =
+ getPreviousArtifact(
+ "org.scala-lang" % s"${name.value}" % refVersion,
+ ivySbt.value, streams.value)
+ for (isForward <- Seq(false, true))
+ runOnce(artifact, (packageBin in Compile).value, isForward)
+ }
+ }
+ )
+
+ def runMima(prev: java.io.File, curr: java.io.File, filter: java.io.File, log: Logger): Unit = {
+ val args = Array(
+ "--prev", prev.getAbsolutePath,
+ "--curr", curr.getAbsolutePath,
+ "--filters", filter.getAbsolutePath,
+ "--generate-filters"
+ )
+ val exitCode = TrapExit(com.typesafe.tools.mima.cli.Main.main(args), log)
+ if (exitCode != 0)
+ throw new RuntimeException(s"MiMa failed with exit code $exitCode")
+ }
+
+ // cribbed from https://github.com/typesafehub/migration-manager/blob/master/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala
+ def getPreviousArtifact(m: ModuleID, ivy: IvySbt, s: TaskStreams): File = {
+ val moduleSettings = InlineConfiguration(
+ "dummy" % "test" % "version",
+ ModuleInfo("dummy-test-project-for-resolving"),
+ dependencies = Seq(m))
+ val module = new ivy.Module(moduleSettings)
+ val report = Deprecated.Inner.ivyUpdate(ivy)(module, s)
+ val optFile = (for {
+ config <- report.configurations
+ module <- config.modules
+ (artifact, file) <- module.artifacts
+ // TODO - Hardcode this?
+ if artifact.name == m.name
+ } yield file).headOption
+ optFile getOrElse sys.error("Could not resolve previous artifact: " + m)
+ }
+
+}
+
+// use the SI-7934 workaround to silence a deprecation warning on an sbt API
+// we have no choice but to call. on the lack of any suitable alternative,
+// see https://gitter.im/sbt/sbt-dev?at=5616e2681b0e279854bd74a4 :
+// "it's my intention to eventually come up with a public API" says Eugene Y
+object Deprecated {
+ @deprecated("", "") class Inner {
+ def ivyUpdate(ivy: IvySbt)(module: ivy.Module, s: TaskStreams) =
+ IvyActions.update(
+ module,
+ new UpdateConfiguration(
+ retrieve = None,
+ missingOk = false,
+ logging = UpdateLogging.DownloadOnly),
+ s.log)
+ }
+ object Inner extends Inner
+}
diff --git a/project/Osgi.scala b/project/Osgi.scala
index d780be2f78..b557df1688 100644
--- a/project/Osgi.scala
+++ b/project/Osgi.scala
@@ -28,8 +28,8 @@ object Osgi {
"Bundle-Name" -> bundleName.value,
"Bundle-SymbolicName" -> bundleSymbolicName.value,
"ver" -> v,
- "Export-Package" -> ("*;version=${ver}"),
- "Import-Package" -> ("scala.*;version=\"${range;[==,=+);${ver}}\",*"),
+ "Export-Package" -> "*;version=${ver}",
+ "Import-Package" -> "scala.*;version=\"${range;[==,=+);${ver}}\",*",
"Bundle-Version" -> v,
"Bundle-RequiredExecutionEnvironment" -> "JavaSE-1.6, JavaSE-1.7",
"-eclipse" -> "false"
diff --git a/project/Quiet.scala b/project/Quiet.scala
index de30ebe6ab..84d01d5544 100644
--- a/project/Quiet.scala
+++ b/project/Quiet.scala
@@ -28,6 +28,4 @@ object Quiet {
case x => x
}
}
-
- def silenceIvyUpdateInfoLogging = logLevel in update := Level.Warn
}
diff --git a/project/ScalaTool.scala b/project/ScalaTool.scala
index e9531f229e..5e3f20b1ba 100644
--- a/project/ScalaTool.scala
+++ b/project/ScalaTool.scala
@@ -27,12 +27,12 @@ case class ScalaTool(mainClass: String,
} else classpath.mkString(":").replace('\\', '/').replaceAll(varRegex, """\${$1}""")
val variables = Map(
- ("@@" -> "@"), // for backwards compatibility
- ("@class@" -> mainClass),
- ("@properties@" -> (properties map { case (k, v) => s"""-D$k="$v""""} mkString " ")),
- ("@javaflags@" -> javaOpts),
- ("@toolflags@" -> toolFlags),
- ("@classpath@" -> platformClasspath)
+ "@@" -> "@", // for backwards compatibility
+ "@class@" -> mainClass,
+ "@properties@" -> (properties map { case (k, v) => s"""-D$k="$v""""} mkString " "),
+ "@javaflags@" -> javaOpts,
+ "@toolflags@" -> toolFlags,
+ "@classpath@" -> platformClasspath
)
val (from, to) = variables.unzip
diff --git a/project/ScriptCommands.scala b/project/ScriptCommands.scala
index 537990d985..efeac95e6d 100644
--- a/project/ScriptCommands.scala
+++ b/project/ScriptCommands.scala
@@ -1,19 +1,32 @@
import sbt._
import Keys._
-import complete.DefaultParsers._
+import BuildSettings.autoImport._
/** Custom commands for use by the Jenkins scripts. This keeps the surface area and call syntax small. */
object ScriptCommands {
- def all = Seq(setupPublishCore)
+ def all = Seq(setupPublishCore, setupValidateTest)
/** Set up the environment for `validate/publish-core`. The argument is the Artifactory snapshot repository URL. */
def setupPublishCore = Command.single("setupPublishCore") { case (state, url) =>
Project.extract(state).append(Seq(
- VersionUtil.baseVersionSuffix in Global := "SHA-SNAPSHOT",
+ baseVersionSuffix in Global := "SHA-SNAPSHOT",
// Append build.timestamp to Artifactory URL to get consistent build numbers (see https://github.com/sbt/sbt/issues/2088):
publishTo in Global := Some("scala-pr" at url.replaceAll("/$", "") + ";build.timestamp=" + System.currentTimeMillis),
publishArtifact in (Compile, packageDoc) in ThisBuild := false,
- scalacOptions in Compile in ThisBuild += "-optimise"
+ scalacOptions in Compile in ThisBuild += "-optimise",
+ logLevel in ThisBuild := Level.Info,
+ logLevel in update in ThisBuild := Level.Warn
), state)
}
+
+ /** Set up the environment for `validate/test`. The argument is the Artifactory snapshot repository URL. */
+ def setupValidateTest = Command.single("setupValidateTest") { case (state, url) =>
+ //TODO When ant is gone, pass starr version as an argument to this command instead of using version.properties
+ Project.extract(state).append(Seq(
+ resolvers in Global += "scala-pr" at url,
+ scalacOptions in Compile in ThisBuild += "-optimise",
+ logLevel in ThisBuild := Level.Info,
+ logLevel in update in ThisBuild := Level.Warn
+ ), state)
+ }
}
diff --git a/project/VersionUtil.scala b/project/VersionUtil.scala
index 6c8aebf74f..4705bbb6ce 100644
--- a/project/VersionUtil.scala
+++ b/project/VersionUtil.scala
@@ -1,12 +1,11 @@
import sbt._
import Keys._
import java.util.Properties
-import java.io.FileInputStream
+import java.io.{File, FileInputStream}
import scala.collection.JavaConverters._
+import BuildSettings.autoImport._
object VersionUtil {
- lazy val baseVersion = settingKey[String]("The base version number from which all others are derived")
- lazy val baseVersionSuffix = settingKey[String]("Identifies the kind of version to build")
lazy val copyrightString = settingKey[String]("Copyright string.")
lazy val versionProperties = settingKey[Versions]("Version properties.")
lazy val generateVersionPropertiesFile = taskKey[File]("Generating version properties file.")
@@ -123,4 +122,33 @@ object VersionUtil {
/** Get a subproject version number from `versionProps` */
def versionNumber(name: String): String =
versionProps(s"$name.version.number")
+
+ /** Build a dependency to a Scala module with the given group and artifact ID */
+ def scalaDep(group: String, artifact: String, versionProp: String = null, scope: String = null, compatibility: String = "binary") = {
+ val vp = if(versionProp eq null) artifact else versionProp
+ val m = group % (artifact + "_" + versionProps(s"scala.$compatibility.version")) % versionNumber(vp)
+ val m2 = if(scope eq null) m else m % scope
+ // exclusion of the scala-library transitive dependency avoids eviction warnings during `update`:
+ m2.exclude("org.scala-lang", "*")
+ }
+
+ private def bootstrapOrganization(path: String) =
+ "org.scala-lang.scala-sha-bootstrap." + path.replace('/', '.')
+
+ /** Build a dependency to a JAR file in the bootstrap repository */
+ def bootstrapDep(baseDir: File, path: String, libName: String): ModuleID = {
+ val sha = IO.read(baseDir / path / s"$libName.jar.desired.sha1").split(' ')(0)
+ bootstrapOrganization(path) % libName % sha from
+ s"https://dl.bintray.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap/$sha/$path/$libName.jar"
+ }
+
+ /** Copy a boostrap dependency JAR that is on the classpath to a file */
+ def copyBootstrapJar(cp: Seq[Attributed[File]], baseDir: File, path: String, libName: String): Unit = {
+ val org = bootstrapOrganization(path)
+ val resolved = cp.find { a =>
+ val mod = a.get(moduleID.key)
+ mod.map(_.organization) == Some(org) && mod.map(_.name) == Some(libName)
+ }.map(_.data).get
+ IO.copyFile(resolved, baseDir / path / s"$libName.jar")
+ }
}
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 46203565b4..4c0a6e7b8a 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,3 +1,6 @@
+scalacOptions ++= Seq("-unchecked", "-feature", /*"-deprecation",*/
+ "-Xlint" /*, "-Xfatal-warnings"*/)
+
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.3.2"
libraryDependencies += "org.pantsbuild" % "jarjar" % "1.6.3"
@@ -15,3 +18,5 @@ buildClasspath := (externalDependencyClasspath in Compile).value.map(_.data).mkS
buildInfoKeys := Seq[BuildInfoKey](buildClasspath)
buildInfoPackage := "scalabuild"
+
+libraryDependencies += "com.typesafe" %% "mima-reporter" % "0.1.8"
diff --git a/scripts/jobs/validate/publish-core b/scripts/jobs/validate/publish-core
index bb0056722d..b0bfd48083 100755
--- a/scripts/jobs/validate/publish-core
+++ b/scripts/jobs/validate/publish-core
@@ -16,7 +16,7 @@ case $prDryRun in
;;
*)
echo ">>> Getting Scala version number."
- $SBT_CMD "setupPublishCore $prRepoUrl" generateBuildCharacterPropertiesFile
+ $SBT_CMD --warn "setupPublishCore $prRepoUrl" generateBuildCharacterPropertiesFile
parseScalaProperties buildcharacter.properties # produce maven_version_number
echo ">>> Checking availability of Scala ${maven_version_number} in $prRepoUrl."
@@ -27,7 +27,7 @@ case $prDryRun in
if $libraryAvailable && $reflectAvailable && $compilerAvailable; then
echo "Scala core already built!"
else
- $SBT_CMD "setupPublishCore $prRepoUrl" $antBuildArgs publish
+ $SBT_CMD --warn "setupPublishCore $prRepoUrl" publish
fi
mv buildcharacter.properties jenkins.properties # parsed by the jenkins job
diff --git a/scripts/jobs/validate/test b/scripts/jobs/validate/test
index bedef2e458..3cd8af5608 100755
--- a/scripts/jobs/validate/test
+++ b/scripts/jobs/validate/test
@@ -1,17 +1,36 @@
-#!/bin/bash -e
+#!/bin/bash -e -v -x
+
+baseDir=${WORKSPACE-`pwd`}
+scriptsDir="$baseDir/scripts"
+. $scriptsDir/common
case $prDryRun in
+
yep)
echo "DRY RUN"
;;
+
*)
- ./pull-binary-libs.sh
# build quick using STARR built upstream, as specified by scalaVersion
- # (in that sense it's locker, since it was built with starr by that upstream job)
- ant -Dstarr.version=$scalaVersion \
- -Dscalac.args.optimise=-optimise \
- -Dlocker.skip=1 -Dextra.repo.url=$prRepoUrl \
- $testExtraArgs ${testTarget-test.core docs.done}
+ # (in that sense it's locker, since it was built with starr by that upstream job);
+ # and run JUnit tests, partest, OSGi tests, MiMa and scaladoc
+ $SBT_CMD \
+ -Dstarr.version=$scalaVersion \
+ --warn \
+ "setupValidateTest $prRepoUrl" \
+ $testExtraArgs \
+ "test" \
+ "partest run pos neg jvm" \
+ "partest res scalap specialized scalacheck" \
+ "partest instrumented presentation" \
+ "partest --srcpath scaladoc" \
+ osgiTestFelix/test \
+ osgiTestEclipse/test \
+ library/mima \
+ reflect/mima \
+ doc
+
;;
-esac \ No newline at end of file
+
+esac
diff --git a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala
index 64eb1adbea..a649c175d0 100644
--- a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala
@@ -44,8 +44,22 @@ trait MemberLookup extends base.MemberLookupBase {
/* Get package object which has associatedFile ne null */
sym.info.member(newTermName("package"))
else sym
- Option(sym1.associatedFile) flatMap (_.underlyingSource) flatMap { src =>
- val path = src.canonicalPath
+ def classpathEntryFor(s: Symbol): Option[String] = {
+ Option(s.associatedFile).flatMap(_.underlyingSource).map { src =>
+ val path = src.canonicalPath
+ if(path.endsWith(".class")) { // Individual class file -> Classpath entry is root dir
+ var nesting = s.ownerChain.count(_.hasPackageFlag)
+ if(nesting > 0) {
+ val p = 0.until(nesting).foldLeft(src) {
+ case (null, _) => null
+ case (f, _) => f.container
+ }
+ if(p eq null) path else p.canonicalPath
+ } else path
+ } else path // JAR file (and fallback option)
+ }
+ }
+ classpathEntryFor(sym1) flatMap { path =>
settings.extUrlMapping get path map { url =>
LinkToExternal(name, url + "#" + name)
}
diff --git a/test/files/run/t7843-jsr223-service.check b/test/disabled/run/t7843-jsr223-service.check
index a668df3567..a668df3567 100644
--- a/test/files/run/t7843-jsr223-service.check
+++ b/test/disabled/run/t7843-jsr223-service.check
diff --git a/test/files/run/t7843-jsr223-service.scala b/test/disabled/run/t7843-jsr223-service.scala
index 3c853878ba..3c853878ba 100644
--- a/test/files/run/t7843-jsr223-service.scala
+++ b/test/disabled/run/t7843-jsr223-service.scala
diff --git a/test/files/run/t7933.check b/test/disabled/run/t7933.check
index 317e9677c3..317e9677c3 100644
--- a/test/files/run/t7933.check
+++ b/test/disabled/run/t7933.check
diff --git a/test/files/run/t7933.scala b/test/disabled/run/t7933.scala
index 58e39dd384..58e39dd384 100644
--- a/test/files/run/t7933.scala
+++ b/test/disabled/run/t7933.scala
diff --git a/test/osgi/src/logback.xml b/test/osgi/src/logback.xml
new file mode 100644
index 0000000000..692ccbfdd9
--- /dev/null
+++ b/test/osgi/src/logback.xml
@@ -0,0 +1,10 @@
+<configuration>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>*** \(%logger{30}\)%green(%X{debugId}) %msg%n</pattern>
+ </encoder>
+ </appender>
+ <root level="${log.root:-warn}">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
diff --git a/test/scaladoc/.gitignore b/test/scaladoc/.gitignore
new file mode 100644
index 0000000000..161be5b55f
--- /dev/null
+++ b/test/scaladoc/.gitignore
@@ -0,0 +1,2 @@
+*.log
+*.obj/
diff --git a/test/scaladoc/run/SI-191.scala b/test/scaladoc/run/SI-191.scala
index 29b1e7dd29..f3d269ceb0 100644
--- a/test/scaladoc/run/SI-191.scala
+++ b/test/scaladoc/run/SI-191.scala
@@ -33,10 +33,14 @@ object Test extends ScaladocModelTest {
def scalaURL = "http://bog.us"
override def scaladocSettings = {
- val scalaLibUri = getClass.getClassLoader.getResource("scala/Function1.class").getPath.split("!")(0)
- val scalaLibPath = new URI(scalaLibUri).getPath
- val externalArg = s"$scalaLibPath#$scalaURL"
- "-no-link-warnings -doc-external-doc " + externalArg
+ val samplePath = getClass.getClassLoader.getResource("scala/Function1.class").getPath
+ val scalaLibPath = if(samplePath.contains("!")) { // in scala-library.jar
+ val scalaLibUri = samplePath.split("!")(0)
+ new URI(scalaLibUri).getPath
+ } else { // individual class files on disk
+ samplePath.replace('\\', '/').dropRight("scala/Function1.class".length)
+ }
+ s"-no-link-warnings -doc-external-doc $scalaLibPath#$scalaURL"
}
def testModel(rootPackage: Package) {
diff --git a/test/scaladoc/run/t8557.scala b/test/scaladoc/run/t8557.scala
index 451f004d7d..7876896bb7 100644
--- a/test/scaladoc/run/t8557.scala
+++ b/test/scaladoc/run/t8557.scala
@@ -1,3 +1,5 @@
+import java.net.URI
+
import scala.tools.nsc.doc.base._
import scala.tools.nsc.doc.model._
import scala.tools.partest.ScaladocModelTest
@@ -15,10 +17,22 @@ object Test extends ScaladocModelTest {
class A
"""
+ def scalaURL = "http://www.scala-lang.org/api/current/"
+
// a non-canonical path to scala-library.jar should still work
- // this is a bit fragile (depends on the current directory being the root of the repo ;
- // ant & partest seem to do that properly)
- def scaladocSettings = "-doc-external-doc build/pack/bin/../lib/scala-library.jar#http://www.scala-lang.org/api/current/"
+ override def scaladocSettings = {
+ val samplePath = getClass.getClassLoader.getResource("scala/Function1.class").getPath.replace('\\', '/')
+ val scalaLibPath = if(samplePath.contains("!")) { // in scala-library.jar
+ val scalaLibUri = samplePath.split("!")(0)
+ val p = new URI(scalaLibUri).getPath
+ // this is a bit fragile (depends on the scala library being in build/pack as produced by ant)
+ p.replace("/pack/lib/scala-library.jar", "/pack/bin/../lib/scala-library.jar")
+ } else { // individual class files on disk
+ val p = samplePath.dropRight("scala/Function1.class".length + 1)
+ p + "/.." + p.takeRight(p.length - p.lastIndexOf('/'))
+ }
+ s"-doc-external-doc $scalaLibPath#$scalaURL"
+ }
def testModel(rootPackage: Package) = {
// get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
diff --git a/versions.properties b/versions.properties
index afea93f666..9cfd359800 100644
--- a/versions.properties
+++ b/versions.properties
@@ -36,7 +36,7 @@ jline.version=2.12.1
scala-asm.version=5.0.4-scala-3
# external modules, used internally (not shipped)
-partest.version.number=1.0.13
+partest.version.number=1.0.16
scalacheck.version.number=1.11.6
# TODO: modularize the compiler