aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2017-07-03 15:48:13 -0700
committerJakob Odersky <jakob@odersky.com>2017-07-03 16:20:22 -0700
commit234b2617ff515414b80ee72933315ed5bf2b5c8b (patch)
treea2080599dc2808cbd2af32570027fc9d28c56fd8
parente5d25b1f0fc6200eb9f89ef37c2037399c350269 (diff)
downloadcbt-234b2617ff515414b80ee72933315ed5bf2b5c8b.tar.gz
cbt-234b2617ff515414b80ee72933315ed5bf2b5c8b.tar.bz2
cbt-234b2617ff515414b80ee72933315ed5bf2b5c8b.zip
Make packages reproducible
Don't include time information in jars in order to make them reproducible. This allows builds to be verified with hash sums. Also see https://reproducible-builds.org/
-rw-r--r--stage2/Lib.scala17
1 files changed, 15 insertions, 2 deletions
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index 8801b33..a237409 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -257,6 +257,13 @@ final class Lib(val logger: Logger) extends
m
}
+ /** Create a jar from the given files and optionally make it
+ * executable by providing a main class.
+ *
+ * Note that all build-time related information is stripped from
+ * the jar, in order to make it reproducible on an independent
+ * system. See https://reproducible-builds.org/ for more
+ * information on reproducible builds. */
def createJar( jarFile: File, files: Seq[File], mainClass: Option[String] = None ): Option[File] = {
deleteIfExists(jarFile.toPath)
if( files.isEmpty ){
@@ -264,13 +271,19 @@ final class Lib(val logger: Logger) extends
} else {
jarFile.getParentFile.mkdirs
logger.lib("Start packaging "++jarFile.string)
- val jar = new JarOutputStream(new FileOutputStream(jarFile), createManifest(mainClass))
+ val jar = new JarOutputStream(new FileOutputStream(jarFile))
try{
+ val manifestEntry = new JarEntry( "META-INF/MANIFEST.MF" )
+ manifestEntry.setTime(0l)
+ jar.putNextEntry(manifestEntry)
+ createManifest(mainClass).write(jar)
+ jar.closeEntry
+
assert( files.forall(_.exists) )
autoRelative(files).collect{
case (file, relative) if file.isFile =>
val entry = new JarEntry( relative )
- entry.setTime(file.lastModified)
+ entry.setTime(0l)
jar.putNextEntry(entry)
jar.write( readAllBytes( file.toPath ) )
jar.closeEntry