Skip to content

Instantly share code, notes, and snippets.

@QuantumGhost
Forked from NickCao/gomod.nix
Created July 20, 2021 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save QuantumGhost/4e6c3d08084887da596cf2bc73119c99 to your computer and use it in GitHub Desktop.
Save QuantumGhost/4e6c3d08084887da596cf2bc73119c99 to your computer and use it in GitHub Desktop.
{ pkgs, sumFile }:
with pkgs;
let
mod2prefix = path: version: hash:
let
fullpath = "${path}@${lib.strings.removeSuffix "/go.mod" version}";
manifest = runCommand "${fullpath}.manifest"
{
outputHashMode = "flat";
outputHashAlgo = "sha256";
outputHash = hash;
nativeBuildInputs = [ go cacert ];
} ''
export HOME=$TMPDIR
export GOMODCACHE=$TMPDIR/mod
go mod download ${fullpath}
cd $GOMODCACHE
find ${fullpath} -type f | LC_COLLATE=C sort | xargs sha256sum > $out
'';
modonlymanifest = runCommand "${fullpath}.manifest"
{
outputHashMode = "flat";
outputHashAlgo = "sha256";
outputHash = hash;
nativeBuildInputs = [ go cacert ];
} ''
export HOME=$TMPDIR
export GOMODCACHE=$TMPDIR/mod
go mod download ${fullpath}
cd $GOMODCACHE/${fullpath}
if [ ! -f "go.mod" ]; then
cd $TMPDIR
echo module ${path} > go.mod
fi
sha256sum go.mod > $out
'';
modonlyfile = runCommand "${fullpath}.mod"
{
outputHashMode = "flat";
outputHashAlgo = "sha256";
outputHash = builtins.elemAt (builtins.split " " (builtins.readFile modonlymanifest)) 0;
nativeBuildInputs = [ go cacert ];
} ''
export HOME=$TMPDIR
export GOMODCACHE=$TMPDIR/mod
go mod download ${fullpath}
cd $GOMODCACHE/${fullpath}
if [ ! -f "go.mod" ]; then
cd $TMPDIR
echo module ${path} > go.mod
fi
cp go.mod $out
'';
modonly = runCommand "${fullpath}" { } "mkdir -p $out/${path}/@v; cp ${modonlyfile} $out/${path}/@v/${lib.strings.removeSuffix "/go.mod" version}.mod";
filelist = runCommand "${fullpath}.json"
{
nativeBuildInputs = [ jq ];
} ''
jq --raw-input --slurp '[split("\n")[] | select(length > 0) | split(" ") | {path: .[1], hash: .[0]}]' ${manifest} > $out
'';
files = builtins.map
(file: runCommand file.path
{
outputHashMode = "flat";
outputHashAlgo = "sha256";
outputHash = file.hash;
nativeBuildInputs = [ go cacert ];
passthru = {
path = file.path;
};
} ''
export HOME=$TMPDIR
export GOMODCACHE=$TMPDIR/mod
go mod download ${fullpath}
cd $GOMODCACHE
cp ${file.path} $out
'')
(builtins.fromJSON (builtins.readFile filelist));
prefix = runCommand path { } (builtins.concatStringsSep "\n" (builtins.map (file: "install -D ${file} $out/${file.path}") files));
zipped = runCommand "${fullpath}" { nativeBuildInputs = [ zip ]; } ''
mkdir -p $out/${path}/@v
if [ -f "${prefix}/${fullpath}/go.mod" ]; then
cp ${prefix}/${fullpath}/go.mod $out/${path}/@v/${version}.mod
else
echo module ${path} > $out/${path}/@v/${version}.mod
fi
cd ${prefix}
zip -D -r $out/${path}/@v/${version}.zip .
'';
in
if lib.strings.hasSuffix "/go.mod" version then modonly else zipped;
sum2vendor = sum:
let
mods = runCommand "mods.json"
{
nativeBuildInputs = [ jq ];
} ''
jq --raw-input --slurp '[split("\n")[] | select(length > 0) | split (" ") | { path: .[0], version: .[1], hash: .[2] | sub("^h1:"; "") }]' ${sum} > $out
'';
prefixes = builtins.map (mod: mod2prefix mod.path mod.version mod.hash) (builtins.fromJSON (builtins.readFile mods));
in
symlinkJoin {
name = "download";
paths = prefixes;
};
in
sum2vendor sumFile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment