summaryrefslogtreecommitdiff
path: root/project
diff options
context:
space:
mode:
authorStefan Zeiger <szeiger@novocode.com>2015-11-13 14:00:50 +0100
committerStefan Zeiger <szeiger@novocode.com>2015-11-27 16:11:33 +0100
commit9fb85af78034c117c46dcd3d2d6e73f6abd081ec (patch)
treed7e969ecb38b8a2bf3452766f91f2d94fcb4ca7f /project
parenta1fed79c13132d750198f2e68f2fadd351398c6d (diff)
downloadscala-9fb85af78034c117c46dcd3d2d6e73f6abd081ec.tar.gz
scala-9fb85af78034c117c46dcd3d2d6e73f6abd081ec.tar.bz2
scala-9fb85af78034c117c46dcd3d2d6e73f6abd081ec.zip
Create a full Scala distribution from sbt
This replicates the results of `ant -Dlocker.skip=1 distpack` with the following differences: - The POM files produced by the ant build under dists/maven still contain unresolved variables like `@VERSION@`. The ant build resolves them in the actual publishing process. The sbt build generates the correct version numbers directly. - Scaladoc sets in the ant build are created with the scaladoc tool from “quick”. The sbt build uses the STARR scaladoc. - The scaladoc sets for scala-actors, scala-compiler, scala-reflect and scalap from the ant build contain documentation for the classes `Null`, `Nothing`, `Any` and `AnyRef`. The sbt build omits those classes from all doc sets (except for scala-library, of course) under the assumption that this is a bug in the ant build. Other idiosyncracies of the ant build like declaring a packaging type of `jar` (instead of `bundle`) for OSGi bundles, or using slightly different module names and descriptions in scaladocs, OSGi bundles and POMs, are reproduced faithfully for now. Publishing from the sbt build is done in the usual sbt way. No actual publishing targets are currently defined in the build. In order to test stability of the publishing process, the `publishDists` task can be used to publish to dists/maven-sbt with the same directory layout and naming conventions employed by the ant build for publishing to dists/maven. Source and binary JARs are OSGi-enabled. For the source JARs this is done by hand-crafting the appropriate MANIFEST.MF entries (like the ant build does). Binary JARs are packaged with BND, using the same outdated BND version as the ant build for now to get identical results. We do not use sbt-osgi because it depends on a newer version of BND (probably OK to upgrade in the future) and does not allow a crucial bit of configuration that we need: Setting the classpath for BND. In sbt-osgi this is always `fullClasspath in Compile` whereas we really want `products in Compile in packageBin` to keep things simple. Conflicts: build.sbt
Diffstat (limited to 'project')
-rw-r--r--project/Osgi.scala69
-rw-r--r--project/plugins.sbt2
2 files changed, 71 insertions, 0 deletions
diff --git a/project/Osgi.scala b/project/Osgi.scala
new file mode 100644
index 0000000000..78370b695b
--- /dev/null
+++ b/project/Osgi.scala
@@ -0,0 +1,69 @@
+import aQute.bnd.osgi.Builder
+import aQute.bnd.osgi.Constants._
+import java.util.Properties
+import sbt._
+import sbt.Keys._
+import scala.collection.JavaConversions._
+import VersionUtil.versionProperties
+
+/** OSGi packaging for the Scala build, distilled from sbt-osgi. We do not use sbt-osgi because it
+ * depends on a newer version of BND which gives slightly different output (probably OK to upgrade
+ * in the future but for now it would make comparing the sbt and ant build output harder) and does
+ * not allow a crucial bit of configuration that we need: Setting the classpath for BND. In sbt-osgi
+ * this is always `fullClasspath in Compile` whereas we want `products in Compile in packageBin`. */
+object Osgi {
+ val bundle = TaskKey[File]("osgiBundle", "Create an OSGi bundle.")
+ val bundleName = SettingKey[String]("osgiBundleName", "The Bundle-Name for the manifest.")
+ val bundleSymbolicName = SettingKey[String]("osgiBundleSymbolicName", "The Bundle-SymbolicName for the manifest.")
+ val headers = SettingKey[Seq[(String, String)]]("osgiHeaders", "Headers and processing instructions for BND.")
+
+ def settings: Seq[Setting[_]] = Seq(
+ bundleName := description.value,
+ bundleSymbolicName := organization.value + "." + name.value,
+ headers := {
+ val v = VersionUtil.versionProperties.value.osgiVersion
+ Seq(
+ "Bundle-Name" -> bundleName.value,
+ "Bundle-SymbolicName" -> bundleSymbolicName.value,
+ "ver" -> v,
+ "Export-Package" -> ("*;version=${ver}"),
+ "Import-Package" -> ("scala.*;version=\"${range;[==,=+);${ver}}\",*"),
+ "Bundle-Version" -> v,
+ "Bundle-RequiredExecutionEnvironment" -> "JavaSE-1.8",
+ "-eclipse" -> "false"
+ )
+ },
+ bundle <<= Def.task {
+ val res = (products in Compile in packageBin).value
+ bundleTask(headers.value.toMap, (products in Compile in packageBin).value,
+ (artifactPath in (Compile, packageBin)).value, res, streams.value)
+ },
+ packagedArtifact in (Compile, packageBin) <<= (artifact in (Compile, packageBin), bundle).identityMap,
+ // Also create OSGi source bundles:
+ artifact in (Compile, packageBin) ~= (_.copy(`type` = "bundle")),
+ packageOptions in (Compile, packageSrc) += Package.ManifestAttributes(
+ "Bundle-Name" -> (description.value + " Sources"),
+ "Bundle-SymbolicName" -> (bundleSymbolicName.value + ".source"),
+ "Bundle-Version" -> versionProperties.value.osgiVersion,
+ "Eclipse-SourceBundle" -> (bundleSymbolicName.value + ";version=\"" + versionProperties.value.osgiVersion + "\";roots:=\".\"")
+ )
+ )
+
+ def bundleTask(headers: Map[String, String], fullClasspath: Seq[File], artifactPath: File,
+ resourceDirectories: Seq[File], streams: TaskStreams): File = {
+ val log = streams.log
+ val builder = new Builder
+ builder.setClasspath(fullClasspath.toArray)
+ headers foreach { case (k, v) => builder.setProperty(k, v) }
+ val includeRes = resourceDirectories.filter(_.exists).map(_.getAbsolutePath).mkString(",")
+ if(!includeRes.isEmpty) builder.setProperty(INCLUDERESOURCE, includeRes)
+ builder.getProperties.foreach { case (k, v) => log.debug(s"bnd: $k: $v") }
+ // builder.build is not thread-safe because it uses a static SimpleDateFormat. This ensures
+ // that all calls to builder.build are serialized.
+ val jar = synchronized { builder.build }
+ builder.getWarnings.foreach(s => log.warn(s"bnd: $s"))
+ builder.getErrors.foreach(s => log.error(s"bnd: $s"))
+ jar.write(artifactPath)
+ artifactPath
+ }
+}
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 862887d57f..02d66a16dd 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,3 +1,5 @@
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.3.2"
libraryDependencies += "org.pantsbuild" % "jarjar" % "1.6.0"
+
+libraryDependencies += "biz.aQute.bnd" % "biz.aQute.bnd" % "2.4.1"