summaryrefslogtreecommitdiff
path: root/project
diff options
context:
space:
mode:
Diffstat (limited to 'project')
-rw-r--r--project/JarJar.scala83
-rw-r--r--project/VersionUtil.scala103
-rw-r--r--project/plugins.sbt4
3 files changed, 189 insertions, 1 deletions
diff --git a/project/JarJar.scala b/project/JarJar.scala
new file mode 100644
index 0000000000..64281f23c1
--- /dev/null
+++ b/project/JarJar.scala
@@ -0,0 +1,83 @@
+import org.pantsbuild.jarjar
+import org.pantsbuild.jarjar._
+import org.pantsbuild.jarjar.util._
+import scala.collection.JavaConverters._
+import java.util.jar._
+import java.io._
+import sbt._
+
+object JarJar {
+ sealed abstract class JarJarConfig {
+ def toPatternElement: PatternElement
+ }
+ object JarJarConfig {
+ case class Rule(pattern: String, result: String) extends JarJarConfig {
+ def toPatternElement: PatternElement = {
+ val rule = new jarjar.Rule
+ rule.setPattern(pattern)
+ rule.setResult(result)
+ rule
+ }
+ }
+ case class Keep(pattern: String) extends JarJarConfig {
+ def toPatternElement: PatternElement = {
+ val keep = new jarjar.Keep
+ keep.setPattern(pattern)
+ keep
+ }
+ }
+ }
+
+ sealed abstract class Entry {
+ def name: String
+ def time: Long
+ def data: Array[Byte]
+ }
+
+ case class JarEntryInput(jarFile: JarFile, entry: JarEntry) extends Entry {
+ def name = entry.getName
+ def time = entry.getTime
+ def data = sbt.IO.readBytes(jarFile.getInputStream(entry))
+ }
+ case class FileInput(base: File, file: File) extends Entry {
+ def name = file.relativeTo(base).get.getPath
+ def time = file.lastModified
+ def data = sbt.IO.readBytes(file)
+ }
+
+ private def newMainProcessor(patterns: java.util.List[PatternElement], verbose: Boolean, skipManifest: Boolean): JarProcessor = {
+ val cls = Class.forName("org.pantsbuild.jarjar.MainProcessor")
+ val constructor = cls.getConstructor(classOf[java.util.List[_]], java.lang.Boolean.TYPE, java.lang.Boolean.TYPE)
+ constructor.setAccessible(true)
+ constructor.newInstance(patterns, Boolean.box(verbose), Boolean.box(skipManifest)).asInstanceOf[JarProcessor]
+ }
+
+ def apply(in: Iterator[Entry], outdir: File,
+ config: Seq[JarJarConfig], verbose: Boolean = false): Seq[File] = {
+ val patterns = config.map(_.toPatternElement).asJava
+ val processor: JarProcessor = newMainProcessor(patterns, verbose, false)
+ def process(e: Entry): Option[File] = {
+ val struct = new EntryStruct()
+ struct.name = e.name
+ struct.time = e.time
+ struct.data = e.data
+ if (processor.process(struct)) {
+ if (struct.name.endsWith("/")) None
+ else {
+ val f = outdir / struct.name
+ try {
+ f.getParentFile.mkdirs()
+ sbt.IO.write(f, struct.data)
+ } catch {
+ case ex: Exception =>
+ throw new IOException(s"Failed to write ${e.name} / ${f.getParentFile} / ${f.getParentFile.exists}", ex)
+ }
+ Some(f)
+ }
+ }
+ else None
+ }
+ in.flatMap(entry => process(entry)).toList
+
+ }
+}
diff --git a/project/VersionUtil.scala b/project/VersionUtil.scala
new file mode 100644
index 0000000000..71de772b08
--- /dev/null
+++ b/project/VersionUtil.scala
@@ -0,0 +1,103 @@
+import sbt._
+import Keys._
+import java.util.Properties
+import java.io.FileInputStream
+import scala.collection.JavaConverters._
+
+object VersionUtil {
+ lazy val copyrightString = settingKey[String]("Copyright string.")
+ lazy val versionProperties = settingKey[Versions]("Version properties.")
+ lazy val generateVersionPropertiesFile = taskKey[File]("Generating version properties file.")
+
+ lazy val versionPropertiesSettings = Seq[Setting[_]](
+ versionProperties := versionPropertiesImpl.value
+ )
+
+ lazy val generatePropertiesFileSettings = Seq[Setting[_]](
+ copyrightString := "Copyright 2002-2015, LAMP/EPFL",
+ resourceGenerators in Compile += generateVersionPropertiesFile.map(file => Seq(file)).taskValue,
+ versionProperties := versionPropertiesImpl.value,
+ generateVersionPropertiesFile := generateVersionPropertiesFileImpl.value
+ )
+
+ case class Versions(canonicalVersion: String, mavenVersion: String, osgiVersion: String, commitSha: String, commitDate: String, isRelease: Boolean) {
+ val githubTree =
+ if(isRelease) "v" + mavenVersion
+ else if(commitSha != "unknown") commitSha
+ else "master"
+
+ override def toString = s"Canonical: $canonicalVersion, Maven: $mavenVersion, OSGi: $osgiVersion, github: $githubTree"
+
+ def toProperties: Properties = {
+ val props = new Properties
+ props.put("version.number", canonicalVersion)
+ props.put("maven.version.number", mavenVersion)
+ props.put("osgi.version.number", osgiVersion)
+ props
+ }
+ }
+
+ lazy val versionPropertiesImpl: Def.Initialize[Versions] = Def.setting {
+ /** Regexp that splits version number split into two parts: version and suffix.
+ * Examples of how the split is performed:
+ *
+ * "2.11.5": ("2.11.5", null)
+ * "2.11.5-acda7a": ("2.11.5", "-acda7a")
+ * "2.11.5-SNAPSHOT": ("2.11.5", "-SNAPSHOT") */
+ val versionSplitted = """([\w+\.]+)(-[\w+\.]+)??""".r
+
+ val versionSplitted(ver, suffixOrNull) = version.value
+
+ val osgiSuffix = suffixOrNull match {
+ case null => "-VFINAL"
+ case "-SNAPSHOT" => ""
+ case suffixStr => suffixStr
+ }
+
+ def executeTool(tool: String) = {
+ val cmd =
+ if (System.getProperty("os.name").toLowerCase.contains("windows"))
+ s"cmd.exe /c tools\\$tool.bat -p"
+ else s"tools/$tool"
+ Process(cmd).lines.head
+ }
+
+ val commitDate = executeTool("get-scala-commit-date")
+ val commitSha = executeTool("get-scala-commit-sha")
+
+ Versions(
+ canonicalVersion = s"$ver-$commitDate-$commitSha",
+ mavenVersion = s"${version.value}",
+ osgiVersion = s"$ver.v$commitDate$osgiSuffix-$commitSha",
+ commitSha = commitSha,
+ commitDate = commitDate,
+ isRelease = !osgiSuffix.isEmpty
+ )
+ }
+
+ lazy val generateVersionPropertiesFileImpl: Def.Initialize[Task[File]] = Def.task {
+ val props = versionProperties.value.toProperties
+ val propFile = (resourceManaged in Compile).value / s"${thisProject.value.id}.properties"
+ props.put("copyright.string", copyrightString.value)
+
+ // unfortunately, this will write properties in arbitrary order
+ // this makes it harder to test for stability of generated artifacts
+ // consider using https://github.com/etiennestuder/java-ordered-properties
+ // instead of java.util.Properties
+ IO.write(props, null, propFile)
+ propFile
+ }
+
+ /** The global versions.properties data */
+ lazy val versionProps: Map[String, String] = {
+ val props = new Properties()
+ val in = new FileInputStream(file("versions.properties"))
+ try props.load(in)
+ finally in.close()
+ props.asScala.toMap
+ }
+
+ /** Get a subproject version number from `versionProps` */
+ def versionNumber(name: String): String =
+ versionProps(s"$name.version.number")
+}
diff --git a/project/plugins.sbt b/project/plugins.sbt
index dc266a8db1..862887d57f 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1 +1,3 @@
-libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.3.2" \ No newline at end of file
+libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.3.2"
+
+libraryDependencies += "org.pantsbuild" % "jarjar" % "1.6.0"