diff options
author | Profpatsch <mail@profpatsch.de> | 2018-07-25 03:11:41 +0200 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2018-07-25 03:17:14 +0200 |
commit | 097307c46fc5a7bda63a5916cfd1ee3ad661a0a6 (patch) | |
tree | 21aad88f5d534f3546e3d3a6b43ed64c2d275c6e /pkgs/profpatsch/execline | |
parent | fd8db354af44cfd2142186c762d2c280c0639233 (diff) |
pkgs/profpatsch: WIP execline experiments
* runExecline: like runCommand, but a lot more lightweight * symlink: symlink a given list of links together * importer: a small DSL to “import” “modules” into a build context Some highlights: * runExecline does not use any stdenv (apart from the `execline` build) * symlink uses netstrings to pass correct fields into the derivation * no use of bash, everything uses execline.
Diffstat (limited to 'pkgs/profpatsch/execline')
-rw-r--r-- | pkgs/profpatsch/execline/importer.nix | 45 | ||||
-rw-r--r-- | pkgs/profpatsch/execline/run-execline.nix | 38 | ||||
-rw-r--r-- | pkgs/profpatsch/execline/symlink.nix | 50 |
3 files changed, 133 insertions, 0 deletions
diff --git a/pkgs/profpatsch/execline/importer.nix b/pkgs/profpatsch/execline/importer.nix new file mode 100644 index 00000000..67464d17 --- /dev/null +++ b/pkgs/profpatsch/execline/importer.nix @@ -0,0 +1,45 @@ +{ lib, coreutils, s6-portable-utils, symlink }: +let + example = {from, as, just, ...}: + [ + (from coreutils [ + (just "echo") + (as "core-ls" "ls") + ]) + (from s6-portable-utils [ + (as "ls" "s6-ls") + (just "s6-echo") + ]) + ]; + + runImport = impsFn: + let + combinators = rec { + from = source: imports: { + inherit source imports; + }; + as = newname: oldname: { + inherit oldname newname; + }; + just = x: as x x; + }; + + # Drv -> As -> Symlink + toBin = module: {oldname, newname}: { + dest = "bin/${newname}"; + orig = "${module}/bin/${oldname}"; + }; + # List (Import { source: Drv + # , imports: List (As { oldname: String + # , newname: String })) + # -> Drv + run = imps: + symlink "foo" (lib.concatLists + (map ({source, imports}: + map (toBin source) imports) + imps)); + + # TODO: typecheck w/ newtypes + in run (impsFn combinators); + +in runImport example diff --git a/pkgs/profpatsch/execline/run-execline.nix b/pkgs/profpatsch/execline/run-execline.nix new file mode 100644 index 00000000..40915f25 --- /dev/null +++ b/pkgs/profpatsch/execline/run-execline.nix @@ -0,0 +1,38 @@ +{ stdenv, importasCommand, execlinebCommand }: +{ name +# the execline script +, execline +# additional arguments to pass to the derivation +, derivationArgs ? {} +}: + +# those arguments can’t be overwritten +assert !derivationArgs ? system; +assert !derivationArgs ? name; +assert !derivationArgs ? builder; +assert !derivationArgs ? args; + +derivation (derivationArgs // { + inherit (stdenv) system; + inherit name; + + # okay, `builtins.toFile` does not accept strings + # that reference drv outputs. This means we need + # to pass the script as envvar; + # this might clash with another passed envar, + # so we give it a long & unique name + _runExeclineScript = execline; + passAsFile = [ "_runExeclineScript" ] + ++ derivationArgs.passAsFile or []; + + builder = importasCommand; + args = [ + "-ui" # drop the envvar afterwards + "script" # substitution name + "_runExeclineScriptPath" # passed script file + execlinebCommand # the actual invocation + "-P" # ignore command line arguments + "-W" # die on syntax error + "$script" # substituted by importas + ]; +}) diff --git a/pkgs/profpatsch/execline/symlink.nix b/pkgs/profpatsch/execline/symlink.nix new file mode 100644 index 00000000..ca8684d2 --- /dev/null +++ b/pkgs/profpatsch/execline/symlink.nix @@ -0,0 +1,50 @@ +{ lib, s6-portable-utils, coreutils, runExecline }: +# DrvPath :: path relative to the derivation +# AbsPath :: absolute path in the store +# Name +# -> List (Symlink { dest: DrvPath, orig: AbsPath }) +# -> Drv +name: links: + +let + toNetstring = s: + "${toString (builtins.stringLength s)}:${s},"; + +in +runExecline { + inherit name; + + derivationArgs = { + pathTuples = lib.concatMapStrings + ({dest, orig}: toNetstring + (toNetstring dest + (toNetstring orig))) + links; + passAsFile = [ "pathTuples" ]; + # bah! coreutils just for cat :( + PATH = lib.makeBinPath [ s6-portable-utils ]; + }; + + execline = '' + importas -ui p pathTuplesPath + importas -ui out out + forbacktickx -d "" destorig { ${coreutils}/bin/cat $p } + importas -ui do destorig + multidefine -d "" $do { destsuffix orig } + define dest ''${out}/''${destsuffix} + + # this call happens for every file, not very efficient + foreground { + backtick -n d { s6-dirname $dest } + importas -ui d d + s6-mkdir -p $d + } + + ifthenelse { s6-test -L $orig } { + backtick -n res { s6-linkname -f $orig } + importas -ui res res + s6-ln -fs $res $dest + } { + s6-ln -fs $orig $dest + } + ''; +} |