diff options
Diffstat (limited to 'pkgs/profpatsch/execline')
-rw-r--r-- | pkgs/profpatsch/execline/run-execline-tests.nix | 83 | ||||
-rw-r--r-- | pkgs/profpatsch/execline/run-execline.nix | 42 |
2 files changed, 117 insertions, 8 deletions
diff --git a/pkgs/profpatsch/execline/run-execline-tests.nix b/pkgs/profpatsch/execline/run-execline-tests.nix new file mode 100644 index 00000000..ebfdeb20 --- /dev/null +++ b/pkgs/profpatsch/execline/run-execline-tests.nix @@ -0,0 +1,83 @@ +{ stdenv, drvSeqL, runExecline, bin +# https://www.mail-archive.com/skaware@list.skarnet.org/msg01256.html +, coreutils }: + +# TODO: run all of these locally! runExeclineLocal + +let + + # lol + writeScript = name: script: runExecline { + inherit name; + derivationArgs = { + inherit script; + passAsFile = [ "script" ]; + }; + execline = '' + importas -ui s scriptPath + importas -ui out out + foreground { + ${coreutils}/bin/mv $s $out + } + ${bin.s6-chmod} 0755 $out + ''; + }; + + # execline block of depth 1 + block = args: builtins.map (arg: " ${arg}") args ++ [ "" ]; + + # derivation that tests whether a given line exists + # in the given file. Does not use runExecline, because + # that should be tested after all. + fileHasLine = line: file: derivation { + name = "file-${file.name}-has-line"; + inherit (stdenv) system; + builder = bin.execlineIf; + args = + (block [ + bin.redirfd "-r" "0" file # read file to stdin + bin.s6-grep "-F" "-q" line # and grep for the line + ]) + ++ [ + # if the block succeeded, touch $out + bin.importas "-ui" "out" "out" + bin.s6-touch "$out" + ]; + }; + + # basic test that touches out + basic = runExecline { + name = "basic"; + execline = '' + importas -ui out out + ${bin.s6-touch} $out + ''; + }; + + # whether the stdin argument works as intended + stdin = fileHasLine "foo" (runExecline { + name = "stdin"; + stdin = "foo\nbar\nfoo"; + execline = '' + importas -ui out out + # this pipes stdout of s6-cat to $out + # and s6-cat redirects from stdin to stdout + redirfd -w 1 $out ${bin.s6-cat} + ''; + }); + + wrapWithVar = runExecline { + name = "wrap-with-var"; + builderWrapper = writeScript "var-wrapper" '' + #!${bin.execlineb} -S0 + export myvar myvalue $@ + ''; + execline = '' + importas -ui v myvar + if { ${bin.s6-test} myvalue = $v } + importas out out + ${bin.s6-touch} $out + ''; + }; + +in args: drvSeqL [ basic stdin wrapWithVar ] (runExecline args) diff --git a/pkgs/profpatsch/execline/run-execline.nix b/pkgs/profpatsch/execline/run-execline.nix index 40915f25..dbc6f4fd 100644 --- a/pkgs/profpatsch/execline/run-execline.nix +++ b/pkgs/profpatsch/execline/run-execline.nix @@ -1,7 +1,12 @@ -{ stdenv, importasCommand, execlinebCommand }: +{ stdenv, bin }: { name -# the execline script +# the execline script as string , execline +# a string to pass as stdin to the execline script +, stdin ? "" +# a program wrapping the acutal execline invocation; +# should be in Bernstein-chaining style +, builderWrapper ? bin.exec # additional arguments to pass to the derivation , derivationArgs ? {} }: @@ -18,20 +23,41 @@ derivation (derivationArgs // { # okay, `builtins.toFile` does not accept strings # that reference drv outputs. This means we need - # to pass the script as envvar; + # to pass the script and stdin as envvar; # this might clash with another passed envar, # so we give it a long & unique name _runExeclineScript = execline; - passAsFile = [ "_runExeclineScript" ] - ++ derivationArgs.passAsFile or []; + _runExeclineStdin = stdin; + passAsFile = [ + "_runExeclineScript" + "_runExeclineStdin" + ] ++ derivationArgs.passAsFile or []; + + # the default, exec acts as identity executable + builder = builderWrapper; - builder = importasCommand; args = [ + bin.importas # import script file as $script "-ui" # drop the envvar afterwards "script" # substitution name "_runExeclineScriptPath" # passed script file - execlinebCommand # the actual invocation - "-P" # ignore command line arguments + + # TODO: can we scrap stdin via builderWrapper? + bin.importas # do the same for $stdin + "-ui" + "stdin" + "_runExeclineStdinPath" + + bin.redirfd # now we + "-r" # read the file + "0" # into the stdin of execlineb + "$stdin" # that was given via stdin + + bin.execlineb # the actual invocation + # TODO: depending on the use-case, -S0 might not be enough + # in all use-cases, then a wrapper for execlineb arguments + # should be added (-P, -S, -s). + "-S0" # set $@ inside the execline script "-W" # die on syntax error "$script" # substituted by importas ]; |