You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.7 KiB
74 lines
2.7 KiB
buildArgs@{ nixpkgs ? <nixpkgs>, pkgs ? import nixpkgs {}, lib ? import ./lib.nix { inherit pkgs; }, root, filter ? [] }: |
|
let |
|
inherit (lib) searchPath whichdo d1 d2 getSrc; |
|
|
|
resolve = path: let |
|
builder = (whichdo path); |
|
in if builder == "" then throw "No rule to build ${path}" |
|
else runBuilder (d1 path builder) (d2 path builder) builder; |
|
|
|
runBuilder = d1: d2: builder: |
|
with pkgs.lib; |
|
with builtins; |
|
let |
|
|
|
# CWD relative to source root |
|
rcwd = dirOf (removePrefix (root + "/") builder); |
|
|
|
# Funktionalise pkgs; our main entry point to resolve default*nix build |
|
# scripts. |
|
funcPkgs = { |
|
__functor = self: arg: resolve arg; |
|
src = getSrc root rcwd filter resolve id; |
|
inherit pkgs rcwd d1 d2; |
|
# Convenience function that calculates the source tree, links it to src |
|
# and cd's to the location of the current builder. |
|
S = getSrc root rcwd filter resolve (src: '' |
|
ln -s ${src} src |
|
cd src/${rcwd} |
|
''); |
|
}; |
|
|
|
_builder = let |
|
imported = (tryEval (let |
|
# Needs to be done as nix chokes on empty files rn. |
|
# Potential source of memory exhaustion for untrusted very large *.do files! |
|
content = readFile builder; |
|
in assert content != "" && (! (hasPrefix "#!" content)); import builder)); |
|
in if imported.success |
|
then imported.value |
|
else { |
|
src = getSrc (/. + root); |
|
builder = '' |
|
#!/bin/sh |
|
set -e |
|
pout=$(mktemp -u -p $PWD) |
|
cp -r --reflink=auto --no-preserve=mode "$src/" src |
|
cd src/${rcwd} |
|
${/. + builder} "$d1" "$d2" "$out" >$pout |
|
if [ -e "$out" -a -s "$pout" ]; then |
|
printf "Error: %s wrote to stdout and created \$3\n" "${baseNameOf builder}" >&2 |
|
exit 207 |
|
elif [ -s $pout ]; then |
|
mv $pout $out |
|
fi |
|
''; |
|
}; |
|
__builder = if isFunction _builder then _builder funcPkgs |
|
else _builder; |
|
|
|
args = { stdenv = pkgs.stdenvNoCC; } // (if isString __builder |
|
then { builder = __builder; } |
|
else __builder); |
|
|
|
drv = (args.deriver or args.stdenv.mkDerivation) ({ |
|
name = pkgs.lib.strings.sanitizeDerivationName d1; |
|
buildCommand = args.builder; |
|
passAsFile = [ "buildCommand" ]; |
|
preferLocalBuild = true; |
|
allowSubstitutes = false; |
|
outputs = [ "out" ]; |
|
inherit d1 d2; |
|
} // (removeAttrs args [ "builder" "system" "deriver" "stdenv" "outputs" ])); |
|
in drv; # myself |
|
in resolve
|
|
|