Merge pull request #65 from adisbladis/minor-builder-refactor

Minor builder refactor
This commit is contained in:
adisbladis 2022-06-15 06:21:49 +08:00 committed by GitHub
commit 40d32f82fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -12,11 +12,16 @@
}: }:
let let
inherit (builtins) substring; inherit (builtins) substring toJSON hasAttr trace split readFile elemAt;
inherit (lib)
concatStringsSep replaceStrings removePrefix optionalString pathExists
optional concatMapStrings fetchers filterAttrs mapAttrs mapAttrsToList
warnIf optionalAttrs platforms
;
parseGoMod = import ./parser.nix; parseGoMod = import ./parser.nix;
removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}''; removeExpr = refs: ''remove-references-to ${concatMapStrings (ref: " -t ${ref}") refs}'';
# Internal only build-time attributes # Internal only build-time attributes
internal = internal =
@ -56,12 +61,34 @@ let
outputHashAlgo = null; outputHashAlgo = null;
outputHash = hash; outputHash = hash;
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ "GOPROXY" ]; impureEnvVars = fetchers.proxyImpureEnvVars ++ [ "GOPROXY" ];
}; };
mkVendorEnv = { go, modulesStruct, localReplaceCommands ? [ ], defaultPackage ? "" }: mkVendorEnv =
{ go
, modulesStruct
, localReplaceCommands ? [ ]
, defaultPackage ? ""
, goMod
, pwd
}:
let let
sources = lib.mapAttrs localReplaceCommands =
let
localReplaceAttrs = filterAttrs (n: v: hasAttr "path" v) goMod.replace;
commands = (
mapAttrsToList
(name: value: (
''
mkdir -p $(dirname vendor/${name})
ln -s ${pwd + "/${value.path}"} vendor/${name}
''
))
localReplaceAttrs);
in
if goMod != null then commands else [ ];
sources = mapAttrs
(goPackagePath: meta: fetchGoModule { (goPackagePath: meta: fetchGoModule {
goPackagePath = meta.replaced or goPackagePath; goPackagePath = meta.replaced or goPackagePath;
inherit (meta) version hash; inherit (meta) version hash;
@ -72,9 +99,9 @@ let
runCommand "vendor-env" runCommand "vendor-env"
{ {
nativeBuildInputs = [ go ]; nativeBuildInputs = [ go ];
json = builtins.toJSON (lib.filterAttrs (n: _: n != defaultPackage) modulesStruct.mod); json = toJSON (filterAttrs (n: _: n != defaultPackage) modulesStruct.mod);
sources = builtins.toJSON (lib.filterAttrs (n: _: n != defaultPackage) sources); sources = toJSON (filterAttrs (n: _: n != defaultPackage) sources);
passthru = { passthru = {
inherit sources; inherit sources;
@ -90,7 +117,7 @@ let
export GOPATH="$TMPDIR/go" export GOPATH="$TMPDIR/go"
${internal.symlink} ${internal.symlink}
${lib.concatStringsSep "\n" localReplaceCommands} ${concatStringsSep "\n" localReplaceCommands}
mv vendor $out mv vendor $out
'' ''
@ -101,22 +128,22 @@ let
( (
let let
goVersion = goMod.go; goVersion = goMod.go;
goAttr = "go_" + (lib.replaceStrings [ "." ] [ "_" ] goVersion); goAttr = "go_" + (replaceStrings [ "." ] [ "_" ] goVersion);
in in
( (
if builtins.hasAttr goAttr pkgs then pkgs.${goAttr} if hasAttr goAttr pkgs then pkgs.${goAttr}
else builtins.trace "go.mod specified Go version ${goVersion} but doesn't exist. Falling back to ${pkgs.go.version}." pkgs.go else trace "go.mod specified Go version ${goVersion} but doesn't exist. Falling back to ${pkgs.go.version}." pkgs.go
) )
)); ));
# Strip the rubbish that Go adds to versions, and fall back to a version based on the date if it's a placeholder value # Strip the rubbish that Go adds to versions, and fall back to a version based on the date if it's a placeholder value
stripVersion = version: stripVersion = version:
let let
parts = lib.elemAt (builtins.split "(\\+|-)" (lib.removePrefix "v" version)); parts = elemAt (split "(\\+|-)" (removePrefix "v" version));
v = parts 0; v = parts 0;
d = parts 2; d = parts 2;
in in
if v != "0.0.0" then v else "unstable-" + (lib.concatStringsSep "-" [ if v != "0.0.0" then v else "unstable-" + (concatStringsSep "-" [
(substring 0 4 d) (substring 0 4 d)
(substring 4 2 d) (substring 4 2 d)
(substring 6 2 d) (substring 6 2 d)
@ -126,18 +153,18 @@ let
{ pwd { pwd
}@attrs: }@attrs:
let let
goMod = parseGoMod (builtins.readFile "${builtins.toString pwd}/go.mod"); goMod = parseGoMod (readFile "${toString pwd}/go.mod");
modulesStruct = builtins.fromTOML (builtins.readFile "${builtins.toString pwd}/gomod2nix.toml"); modulesStruct = fromTOML (readFile "${toString pwd}/gomod2nix.toml");
go = selectGo attrs goMod; go = selectGo attrs goMod;
vendorEnv = mkVendorEnv { vendorEnv = mkVendorEnv {
inherit go modulesStruct; inherit go modulesStruct pwd goMod;
}; };
in in
stdenv.mkDerivation (builtins.removeAttrs attrs [ "pwd" ] // { stdenv.mkDerivation (removeAttrs attrs [ "pwd" ] // {
name = "${builtins.baseNameOf goMod.module}-env"; name = "${baseNameOf goMod.module}-env";
dontUnpack = true; dontUnpack = true;
dontConfigure = true; dontConfigure = true;
@ -160,7 +187,7 @@ let
export GOSUMDB=off export GOSUMDB=off
export GOPROXY=off export GOPROXY=off
'' + lib.optionalString (lib.pathExists (pwd + "/tools.go")) '' '' + optionalString (pathExists (pwd + "/tools.go")) ''
mkdir source mkdir source
cp ${pwd + "/go.mod"} source/go.mod cp ${pwd + "/go.mod"} source/go.mod
cp ${pwd + "/go.sum"} source/go.sum cp ${pwd + "/go.sum"} source/go.sum
@ -189,49 +216,35 @@ let
, ... , ...
}@attrs: }@attrs:
let let
modulesStruct = builtins.fromTOML (builtins.readFile modules); modulesStruct = fromTOML (readFile modules);
goModPath = "${builtins.toString pwd}/go.mod"; goModPath = "${toString pwd}/go.mod";
goMod = goMod =
if pwd != null && lib.pathExists goModPath if pwd != null && pathExists goModPath
then parseGoMod (builtins.readFile goModPath) then parseGoMod (readFile goModPath)
else null; else null;
localReplaceCommands =
let
localReplaceAttrs = lib.filterAttrs (n: v: lib.hasAttr "path" v) goMod.replace;
commands = (
lib.mapAttrsToList
(name: value: (
''
mkdir -p $(dirname vendor/${name})
ln -s ${pwd + "/${value.path}"} vendor/${name}
''
))
localReplaceAttrs);
in
if goMod != null then commands else [ ];
go = selectGo attrs goMod; go = selectGo attrs goMod;
removeReferences = [ ] ++ lib.optional (!allowGoReference) go; removeReferences = [ ] ++ optional (!allowGoReference) go;
defaultPackage = modulesStruct.goPackagePath or ""; defaultPackage = modulesStruct.goPackagePath or "";
vendorEnv = mkVendorEnv { vendorEnv = mkVendorEnv {
inherit go modulesStruct localReplaceCommands defaultPackage; inherit go modulesStruct defaultPackage goMod pwd;
}; };
in in
lib.warnIf (buildFlags != "" || buildFlagsArray != "") warnIf (buildFlags != "" || buildFlagsArray != "")
"Use the `ldflags` and/or `tags` attributes instead of `buildFlags`/`buildFlagsArray`" "Use the `ldflags` and/or `tags` attributes instead of `buildFlags`/`buildFlagsArray`"
stdenv.mkDerivation stdenv.mkDerivation
(lib.optionalAttrs (defaultPackage != "") (optionalAttrs (defaultPackage != "")
{ {
pname = attrs.pname or baseNameOf defaultPackage; pname = attrs.pname or baseNameOf defaultPackage;
version = stripVersion (modulesStruct.mod.${defaultPackage}).version; version = stripVersion (modulesStruct.mod.${defaultPackage}).version;
src = vendorEnv.passthru.sources.${defaultPackage}; src = vendorEnv.passthru.sources.${defaultPackage};
} // lib.optionalAttrs (lib.hasAttr "subPackages" modulesStruct) { } // optionalAttrs (hasAttr "subPackages" modulesStruct) {
subPackages = modulesStruct.subPackages; subPackages = modulesStruct.subPackages;
} // attrs // { } // attrs // {
nativeBuildInputs = [ removeReferencesTo go ] ++ nativeBuildInputs; nativeBuildInputs = [ removeReferencesTo go ] ++ nativeBuildInputs;
@ -277,7 +290,7 @@ let
d="$2" d="$2"
. $TMPDIR/buildFlagsArray . $TMPDIR/buildFlagsArray
local OUT local OUT
if ! OUT="$(go $cmd $buildFlags "''${buildFlagsArray[@]}" ''${tags:+-tags=${lib.concatStringsSep "," tags}} ''${ldflags:+-ldflags="$ldflags"} -v -p $NIX_BUILD_CORES $d 2>&1)"; then if ! OUT="$(go $cmd $buildFlags "''${buildFlagsArray[@]}" ''${tags:+-tags=${concatStringsSep "," tags}} ''${ldflags:+-ldflags="$ldflags"} -v -p $NIX_BUILD_CORES $d 2>&1)"; then
if echo "$OUT" | grep -qE 'imports .*?: no Go files in'; then if echo "$OUT" | grep -qE 'imports .*?: no Go files in'; then
echo "$OUT" >&2 echo "$OUT" >&2
return 1 return 1
@ -319,7 +332,7 @@ let
echo "Building subPackage $pkg" echo "Building subPackage $pkg"
buildGoDir install "$pkg" buildGoDir install "$pkg"
done done
'' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) '' '' + optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
# normalize cross-compiled builds w.r.t. native builds # normalize cross-compiled builds w.r.t. native builds
( (
dir=$GOPATH/bin/${go.GOOS}_${go.GOARCH} dir=$GOPATH/bin/${go.GOOS}_${go.GOARCH}
@ -361,11 +374,11 @@ let
strictDeps = true; strictDeps = true;
disallowedReferences = lib.optional (!allowGoReference) go; disallowedReferences = optional (!allowGoReference) go;
passthru = { inherit go vendorEnv; } // passthru; passthru = { inherit go vendorEnv; } // passthru;
meta = { platforms = go.meta.platforms or lib.platforms.all; } // meta; meta = { platforms = go.meta.platforms or platforms.all; } // meta;
}); });
in in