Skip to content

Commit 9ec2558

Browse files
committed
Create a Nix Setup
1 parent a9d2aee commit 9ec2558

5 files changed

Lines changed: 341 additions & 0 deletions

File tree

default.nix

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
sources ? import ./nix/sources.nix,
3+
system ? builtins.currentSystem,
4+
pkgs ?
5+
import sources.nixpkgs {
6+
overlays = [];
7+
config = {};
8+
inherit system;
9+
},
10+
}: let
11+
DiffDetective =
12+
import (builtins.fetchGit {
13+
url = "https://github.com/VariantSync/DiffDetective.git";
14+
rev = "4adc0b84a390ea138f48dbb98918b9d2317bb896";
15+
ref = "develop";
16+
shallow = true;
17+
}) {
18+
inherit sources;
19+
inherit system;
20+
buildGitHubPages = false;
21+
};
22+
in
23+
pkgs.maven.buildMavenPackage rec {
24+
pname = "DiffDetective-Demo";
25+
# The single source of truth for the version number is stored in `pom.xml`.
26+
# Hence, this XML file needs to be parsed to extract the current version.
27+
version = pkgs.lib.removeSuffix "\n" (pkgs.lib.readFile
28+
(pkgs.runCommandLocal "DiffDetective-version" {}
29+
"${pkgs.xq-xml}/bin/xq -x '/project/version' ${./pom.xml} > $out"));
30+
31+
src = with pkgs.lib.fileset;
32+
toSource {
33+
root = ./.;
34+
fileset = gitTracked ./.;
35+
};
36+
37+
mvnHash = "sha256-dw/CXrUj6AW6yhLsloZX5F9O2edsaj3SaigKTPHidSs=";
38+
39+
mvnFetchExtraArgs = {
40+
preBuild = ''
41+
echo "Build dir: $out/.m2"
42+
mkdir -p $out/.m2
43+
# Copy the DiffDetective.jar into this build folder because Maven fails
44+
# when an absolute path is provided.
45+
cp ${DiffDetective}/share/java/DiffDetective/DiffDetective.jar .
46+
mvn deploy:deploy-file -e -Durl=file:$out/.m2 -Dmaven.repo.local=$out/.m2 -Dfile=./DiffDetective.jar -Dversion=${DiffDetective.version} -DgroupId=org.variantsync -DartifactId=diffdetective
47+
48+
# Fix the reproducibility issues of `mvn deploy:deploy-file`
49+
for f in $(find $out/.m2 -name '*.xml')
50+
do
51+
sed -i '/lastUpdated/ c\ <lastUpdated>2</lastUpdated>' "$f"
52+
if [ -f "$f.md5" ]
53+
then
54+
md5sum "$f" | cut -f 1 -d ' ' > "$f.md5"
55+
fi
56+
if [ -f "$f.sha1" ]
57+
then
58+
sha1sum "$f" | cut -f 1 -d ' ' > "$f.sha1"
59+
fi
60+
done
61+
'';
62+
};
63+
64+
nativeBuildInputs = [pkgs.makeWrapper];
65+
66+
postInstall = ''
67+
local jar="$out/share/java/DiffDetective-Demo.jar"
68+
install -Dm644 "target/diffdetectivedemo-${version}-jar-with-dependencies.jar" "$jar"
69+
makeWrapper "${pkgs.jdk}/bin/java" "$out/bin/DiffDetective-Demo" \
70+
--add-flags "-cp '$jar' org.variantsync.diffdetectivedemo.Main" \
71+
--prefix PATH : "${pkgs.graphviz}/bin"
72+
'';
73+
74+
meta.mainProgram = "DiffDetective-Demo";
75+
}

flake.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
outputs = inputs: {
3+
packages.x86_64-linux.default = import inputs.self {system = "x86_64-linux";};
4+
};
5+
}

nix/docker.nix

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
sources ? import ./sources.nix,
3+
system ? builtins.currentSystem,
4+
pkgs ?
5+
import sources.nixpkgs {
6+
overlays = [];
7+
config = {};
8+
inherit system;
9+
},
10+
}: let
11+
DiffDetectiveDemo = import ../default.nix {};
12+
in {
13+
esecfse24 = pkgs.dockerTools.buildImage rec {
14+
name = "DiffDetective-Demo";
15+
tag = DiffDetectiveDemo.version;
16+
17+
copyToRoot = pkgs.buildEnv {
18+
name = "DiffDetective-Demo-image-root";
19+
paths = [ (DiffDetectiveDemo.src + "/data") ];
20+
extraPrefix = config.WorkingDir + "/data";
21+
};
22+
23+
runAsRoot = ''
24+
mkdir -p /etc/fonts
25+
26+
cat >/etc/fonts/fonts.conf <<"EOF"
27+
<?xml version="1.0" encoding="UTF-8"?>
28+
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
29+
<fontconfig>
30+
<description>Configuration file</description>
31+
<dir>${pkgs.dejavu_fonts}/share/fonts</dir>
32+
<cachedir>/var/cache/fontconfig</cachedir>
33+
</fontconfig>
34+
EOF
35+
36+
mkdir -p /var/cache/fontconfig
37+
${pkgs.fontconfig}/bin/fc-cache
38+
'';
39+
40+
config = {
41+
Cmd = ["${DiffDetectiveDemo}/bin/DiffDetective-Demo"];
42+
WorkingDir = "/home/user";
43+
Env = [
44+
"DISPLAY=:0"
45+
"HOME=/home/user"
46+
];
47+
};
48+
};
49+
}

nix/sources.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"nixpkgs": {
3+
"branch": "nixos-23.11",
4+
"description": "Nix Packages collection",
5+
"homepage": null,
6+
"owner": "NixOS",
7+
"repo": "nixpkgs",
8+
"rev": "6832d0d99649db3d65a0e15fa51471537b2c56a6",
9+
"sha256": "1ww2vrgn8xrznssbd05hdlr3d4br6wbjlqprys1al8ahxkyl5syi",
10+
"type": "tarball",
11+
"url": "https://github.com/NixOS/nixpkgs/archive/6832d0d99649db3d65a0e15fa51471537b2c56a6.tar.gz",
12+
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
13+
}
14+
}

nix/sources.nix

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# This file has been generated by Niv.
2+
3+
let
4+
5+
#
6+
# The fetchers. fetch_<type> fetches specs of type <type>.
7+
#
8+
9+
fetch_file = pkgs: name: spec:
10+
let
11+
name' = sanitizeName name + "-src";
12+
in
13+
if spec.builtin or true then
14+
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
15+
else
16+
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
17+
18+
fetch_tarball = pkgs: name: spec:
19+
let
20+
name' = sanitizeName name + "-src";
21+
in
22+
if spec.builtin or true then
23+
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
24+
else
25+
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
26+
27+
fetch_git = name: spec:
28+
let
29+
ref =
30+
spec.ref or (
31+
if spec ? branch then "refs/heads/${spec.branch}" else
32+
if spec ? tag then "refs/tags/${spec.tag}" else
33+
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"
34+
);
35+
submodules = spec.submodules or false;
36+
submoduleArg =
37+
let
38+
nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0;
39+
emptyArgWithWarning =
40+
if submodules
41+
then
42+
builtins.trace
43+
(
44+
"The niv input \"${name}\" uses submodules "
45+
+ "but your nix's (${builtins.nixVersion}) builtins.fetchGit "
46+
+ "does not support them"
47+
)
48+
{ }
49+
else { };
50+
in
51+
if nixSupportsSubmodules
52+
then { inherit submodules; }
53+
else emptyArgWithWarning;
54+
in
55+
builtins.fetchGit
56+
({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
57+
58+
fetch_local = spec: spec.path;
59+
60+
fetch_builtin-tarball = name: throw
61+
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
62+
$ niv modify ${name} -a type=tarball -a builtin=true'';
63+
64+
fetch_builtin-url = name: throw
65+
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
66+
$ niv modify ${name} -a type=file -a builtin=true'';
67+
68+
#
69+
# Various helpers
70+
#
71+
72+
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
73+
sanitizeName = name:
74+
(
75+
concatMapStrings (s: if builtins.isList s then "-" else s)
76+
(
77+
builtins.split "[^[:alnum:]+._?=-]+"
78+
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
79+
)
80+
);
81+
82+
# The set of packages used when specs are fetched using non-builtins.
83+
mkPkgs = sources: system:
84+
let
85+
sourcesNixpkgs =
86+
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
87+
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
88+
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
89+
in
90+
if builtins.hasAttr "nixpkgs" sources
91+
then sourcesNixpkgs
92+
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
93+
import <nixpkgs> { }
94+
else
95+
abort
96+
''
97+
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
98+
add a package called "nixpkgs" to your sources.json.
99+
'';
100+
101+
# The actual fetching function.
102+
fetch = pkgs: name: spec:
103+
104+
if ! builtins.hasAttr "type" spec then
105+
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
106+
else if spec.type == "file" then fetch_file pkgs name spec
107+
else if spec.type == "tarball" then fetch_tarball pkgs name spec
108+
else if spec.type == "git" then fetch_git name spec
109+
else if spec.type == "local" then fetch_local spec
110+
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
111+
else if spec.type == "builtin-url" then fetch_builtin-url name
112+
else
113+
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
114+
115+
# If the environment variable NIV_OVERRIDE_${name} is set, then use
116+
# the path directly as opposed to the fetched source.
117+
replace = name: drv:
118+
let
119+
saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name;
120+
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
121+
in
122+
if ersatz == "" then drv else
123+
# this turns the string into an actual Nix path (for both absolute and
124+
# relative paths)
125+
if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
126+
127+
# Ports of functions for older nix versions
128+
129+
# a Nix version of mapAttrs if the built-in doesn't exist
130+
mapAttrs = builtins.mapAttrs or (
131+
f: set: with builtins;
132+
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
133+
);
134+
135+
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
136+
range = first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1);
137+
138+
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
139+
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
140+
141+
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
142+
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
143+
concatMapStrings = f: list: concatStrings (map f list);
144+
concatStrings = builtins.concatStringsSep "";
145+
146+
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
147+
optionalAttrs = cond: as: if cond then as else { };
148+
149+
# fetchTarball version that is compatible between all the versions of Nix
150+
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
151+
let
152+
inherit (builtins) lessThan nixVersion fetchTarball;
153+
in
154+
if lessThan nixVersion "1.12" then
155+
fetchTarball ({ inherit url; } // (optionalAttrs (name != null) { inherit name; }))
156+
else
157+
fetchTarball attrs;
158+
159+
# fetchurl version that is compatible between all the versions of Nix
160+
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
161+
let
162+
inherit (builtins) lessThan nixVersion fetchurl;
163+
in
164+
if lessThan nixVersion "1.12" then
165+
fetchurl ({ inherit url; } // (optionalAttrs (name != null) { inherit name; }))
166+
else
167+
fetchurl attrs;
168+
169+
# Create the final "sources" from the config
170+
mkSources = config:
171+
mapAttrs
172+
(
173+
name: spec:
174+
if builtins.hasAttr "outPath" spec
175+
then
176+
abort
177+
"The values in sources.json should not have an 'outPath' attribute"
178+
else
179+
spec // { outPath = replace name (fetch config.pkgs name spec); }
180+
)
181+
config.sources;
182+
183+
# The "config" used by the fetchers
184+
mkConfig =
185+
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
186+
, sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile)
187+
, system ? builtins.currentSystem
188+
, pkgs ? mkPkgs sources system
189+
}: rec {
190+
# The sources, i.e. the attribute set of spec name to spec
191+
inherit sources;
192+
193+
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
194+
inherit pkgs;
195+
};
196+
197+
in
198+
mkSources (mkConfig { }) // { __functor = _: settings: mkSources (mkConfig settings); }

0 commit comments

Comments
 (0)