Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reproducible setup #3

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,40 @@ It is (mainly) implemented in Scala and using sbt as build tool (like truediff),
DiffDetective and truediff are required in the local Maven repository.

To install DiffDetective using Maven:

```shell
git clone https://github.com/VariantSync/DiffDetective.git
cd DiffDetective
mvn install
mvn clean install
```
Be sure to actually (re-)compile DiffDetective with version 17 of Java.
In case of doubt or obscure errors later on, try removing the maven cache with `rm -rf ~/.m2` before installing DiffDetective.

To install truediff using sbt:

```shell
git clone https://gitlab.rlp.net/plmz/truediff.git
cd truediff
sbt publishM2
```

### Install TrueDiffDetective
To install truediff using sbt:

```shell
git clone https://github.com/VariantSync/TrueDiffDetective.git
cd TrueDiffDetective
sbt publishM2
```

### Using TrueDiffDetective
To use TrueDiffDetective in a sbt project add dependency:

```
"org.variantsync" % "truediffdetective_2.13" % "0.1.0-SNAPSHOT"
```

To use TrueDiffDetective in a Maven project add dependency:

```
<dependency>
<groupId>org.variantsync</groupId>
<artifactId>truediffdetective_2.13</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
</dependency>
```
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name := "TrueDiffDetective"

ThisBuild / organization := "org.variantsync"
// The version is duplicated in `default.nix`.
ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.1"
Expand Down
57 changes: 57 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
system ? builtins.currentSystem,
pkgs ?
import (builtins.fetchTarball {
name = "sources";
url = "https://github.com/nixos/nixpkgs/archive/6832d0d99649db3d65a0e15fa51471537b2c56a6.tar.gz";
sha256 = "1ww2vrgn8xrznssbd05hdlr3d4br6wbjlqprys1al8ahxkyl5syi";
}) {
inherit system;
config = {};
modules = [];
},
lib ? pkgs.lib,
callPackage ? pkgs.callPackage,
symlinkJoin ? pkgs.symlinkJoin,
sbt ?
pkgs.sbt.override {
jre = pkgs.jdk17;
},
buildSbtPackage ?
callPackage (import ./nix/buildSbtPackage.nix) {
inherit sbt;
},
truediff ?
callPackage (import ./nix/truediff.nix) {
inherit buildSbtPackage;
},
DiffDetective ?
import (builtins.fetchTarball {
name = "DiffDetective";
url = "https://github.com/VariantSync/DiffDetective/archive/0e7d810ae5826c9866750f87c7dce4140ac37ed6.tar.gz";
sha256 = "1kz55bivvbxg9g027q3a3r0q52cd54ayr96ifx87a7icmv7wp1yg";
}) {
inherit system pkgs;
},
dependenciesHash ? "sha256-Cev6nPHyUQvxv7ftA8fxVC4NYwCRzC/Dy4I1nyl+/wc=",
}:
buildSbtPackage {
pname = "TrueDiffDetective";
# The version is duplicated in `build.sbt`.
version = "0.1.0-SNAPSHOT";
src = with lib.fileset;
toSource {
root = ./.;
fileset = gitTracked ./.;
};

mavenRepo = symlinkJoin {
name = "TrueDiffDetective-maven-dependencies";
paths = [
DiffDetective.maven
truediff.maven
];
};

inherit dependenciesHash;
}
141 changes: 141 additions & 0 deletions nix/buildSbtPackage.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
lib,
stdenvNoCC,
sbt,
maven,
}: {
pname,
version,
src,
dependenciesHash ? lib.fakeHash,
mavenRepo ? null,
}:
stdenvNoCC.mkDerivation {
inherit pname;
inherit version;
inherit src;

outputs = ["out" "maven"];

nativeBuildInputs = [
sbt
];

fetchedDependencies = stdenvNoCC.mkDerivation {
pname = "${pname}-dependencies";
inherit version;
inherit src;

nativeBuildInputs = [
sbt
maven
];

# According to the wisdom of the internet
# (multiple issues, stack overflow etc., who mentioned this command along the way, but there is no actually useful documentation what that command should do),
# `sbt update` should be enough to download all necessary dependencies to build offline.
# However, it doesn't. Hence, we have to also do a fake compilation.
# In order to actually cache all depencies [1] without build artifacts
# (this could cause annoying reproducibility bugs caused by previous build outputs),
# we only add an empty file such that `sbt` "builds" without complains.
#
# [1]: https://stackoverflow.com/questions/52355642/sbt-compile-compiler-bridge#comment107617368_52430243
buildPhase = ''
runHook preBuild

# Find source directories
source_directories=($(find . -path "*/src/main/scala"))

# Delete all files except `build.sbt` and the `project/` directory to keep
# dependency fetching independet of other source changes.
find . -mindepth 1 -maxdepth 1 -not \( -name "build.sbt" -o -name "project" \) -exec rm -r {} +

# Add an empty file into each source directory such that sbt actually
# downloads all necessary dependencies.
for source_directory in "''${source_directories[@]}"
do
mkdir -p "$source_directory"
touch "$source_directory/empty.scala"
done

mkdir cache
${
lib.optionalString (mavenRepo != null) ''
cp -L -r ${mavenRepo} cache/maven-repo
chmod u+w -R cache/maven-repo
''
}

# Download necessary dependencies and tell sbt to cache them in a `cache/`
# directory.
sbt -Dsbt.home=cache/sbt -Dsbt.boot.directory=cache/sbt-boot -Dsbt.coursier.home=cache/coursier -Dsbt.ivy.home=cache/ivy -Dmaven.repo.local=cache/maven-repo update compile

runHook postBuild
'';

installPhase = ''
runHook preInstall

cp -r cache "$out"

if [ -d "$out/maven-repo" ]
then
# Keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside.
find "$out/maven-repo" -type f \
\( -not \( -name "*.pom" -o -name "*.jar" -o -name "*.sha1" -o -name "*.nbm" \) \
-o -name "maven-metadata*" \) \
-delete
fi

if [ -d "$out/ivy" ]
then
# Delete unnecessary files with impurities (timestamps).
find "$out/ivy" \
-type f \
-name "ivydata*.properties" \
-delete
# Override all other timestamps with a fixed value.
find "$out/ivy" \
-type f \
-name "*.xml" \
-exec sed -i 's/publication="[[:digit:]]*"/publication="19700101000001"/' -- {} +
fi

runHook postInstall
'';

dontFixup = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
outputHash = dependenciesHash;
};

buildPhase = ''
runHook preBuild

# sbt needs write access to the cache.
cp -r "$fetchedDependencies" cache
chmod u+w -R cache

sbt -Dsbt.home=cache/sbt -Dsbt.boot.directory=cache/sbt-boot -Dsbt.coursier.home=cache/coursier -Dsbt.ivy.home=cache/ivy -Dmaven.repo.local=cache/maven-repo compile test package publishM2

runHook postBuild
'';

installPhase = ''
runHook preInstall

mkdir -p "$out/share/jars"
find . -name cache -prune -o -name "*.jar" -exec cp -t "$out/share/jars" {} +

mv cache/maven-repo "$maven"

# Keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside.
find "$maven" -type f \
\( -not \( -name "*.pom" -o -name "*.jar" -o -name "*.sha1" -o -name "*.nbm" \) \
-o -name "maven-metadata*" \) \
-delete

runHook postInstall
'';
}
17 changes: 17 additions & 0 deletions nix/truediff.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
buildSbtPackage,
fetchFromGitLab,
}:
buildSbtPackage {
pname = "truediff";
version = "0.2.0-SNAPSHOT";
src = fetchFromGitLab {
domain = "gitlab.rlp.net";
owner = "plmz";
repo = "truediff";
rev = "e540bd251b9a0fa5ff019595577f7ac2abca74dc";
hash = "sha256-Tz7PlgMLakRhBxDZxHppjTWMQhP5f5bK8Ve9hILXUn0=";
};

dependenciesHash = "sha256-OUNhilRJN4isnNRUoHAXOs24FTm7JpdVcOiQL5fTCVw=";
}