diff options
author | Jakob Odersky <jakob@odersky.com> | 2017-07-03 15:48:13 -0700 |
---|---|---|
committer | Jakob Odersky <jakob@odersky.com> | 2017-07-03 16:20:22 -0700 |
commit | 234b2617ff515414b80ee72933315ed5bf2b5c8b (patch) | |
tree | a2080599dc2808cbd2af32570027fc9d28c56fd8 | |
parent | e5d25b1f0fc6200eb9f89ef37c2037399c350269 (diff) | |
download | cbt-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.scala | 17 |
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 |