diff options
Diffstat (limited to 'project')
-rw-r--r-- | project/JarJar.scala | 83 | ||||
-rw-r--r-- | project/VersionUtil.scala | 103 | ||||
-rw-r--r-- | project/plugins.sbt | 4 |
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" |