fully automated reproducible space deterministic builds

This commit is contained in:
Leijurv
2018-10-11 18:51:33 -07:00
parent 130b21f738
commit f33a2ef11b
3 changed files with 65 additions and 36 deletions

49
scripts/Determinizer.java Normal file
View File

@ -0,0 +1,49 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;
/**
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 0.
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
* @author leijurv
*/
public class Determinizer {
public static void main(String[] args) throws IOException {
System.out.println("Input path: " + args[0] + " Output path: " + args[1]);
JarFile jarFile = new JarFile(new File(args[0]));
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File(args[1])));
ArrayList<JarEntry> entries = jarFile.stream().collect(Collectors.toCollection(ArrayList::new));
entries.sort(Comparator.comparing(JarEntry::getName));
for (JarEntry entry : entries) {
if (entry.getName().equals("META-INF/fml_cache_annotation.json")) {
continue;
}
if (entry.getName().equals("META-INF/fml_cache_class_versions.json")) {
continue;
}
JarEntry clone = new JarEntry(entry.getName());
clone.setTime(0);
jos.putNextEntry(clone);
copy(jarFile.getInputStream(entry), jos);
}
jos.finish();
jarFile.close();
}
public static void copy(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
}
}

View File

@ -3,9 +3,17 @@ set -e # this makes the whole script fail immediately if any one of these comman
./gradlew build
export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2)
cd scripts
javac Determinizer.java
java Determinizer ../build/libs/baritone-$VERSION.jar temp.jar
mv temp.jar ../build/libs/baritone-$VERSION.jar
cd ..
wget -nv https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip
unzip proguard6.0.3.zip 2>&1 > /dev/null
cd build/libs
rm -rf api.pro
echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version
cat ../../scripts/proguard.pro | grep -v "this is the rt jar" | grep -v "\-injars" >> api.pro # remove default rt jar and injar lines
echo "-libraryjars '$(java -verbose 2>/dev/null | sed -ne '1 s/\[Opened \(.*\)\]/\1/p')'" >> api.pro # insert correct rt.jar location
@ -16,11 +24,17 @@ cat api.pro | grep -v "this is the keep api" > standalone.pro # standalone doesn
mkdir -p tempLibraries
cat ../../scripts/proguard.pro | grep tempLibraries | grep .jar | cut -d "/" -f 2- | cut -d "'" -f -1 | xargs -n1 -I{} bash -c "find ~/.gradle -name {}" | tee /dev/stderr | xargs -n1 -I{} cp {} tempLibraries
rm -rf ../../dist
mkdir ../../dist
java -jar ../../proguard6.0.3/lib/proguard.jar @api.pro
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-api-$VERSION.jar
cd ../../scripts
java Determinizer ../build/libs/Obfuscated/baritone-$VERSION.jar ../dist/baritone-api-$VERSION.jar
cd ../build/libs
rm -rf Obfuscated/*
java -jar ../../proguard6.0.3/lib/proguard.jar @standalone.pro
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-standalone-$VERSION.jar
cd ../../scripts
java Determinizer ../build/libs/Obfuscated/baritone-$VERSION.jar ../dist/baritone-standalone-$VERSION.jar
cd ../build/libs
mv baritone-$VERSION.jar ../../dist/baritone-unoptimized-$VERSION.jar
cd ../../dist
shasum * | tee checksums.txt