feat(nix/writeExecline): add writeExecline
This is a writer, similar to `pkgs.writeBashScript` or `pkgs.writers.writePython3`. The difference is that we can correctly write all execline scripts by using nix lists of lists, so the user doesn’t have to care about escaping arguments (like they have to in bash scripts with `lib.escapeShellArg` for example). Change-Id: I2f2874cf61170ddca07b89b692f762725f4a75dc Reviewed-on: https://cl.tvl.fyi/c/depot/+/625 Reviewed-by: Kane York <rikingcoding@gmail.com> Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
parent
22b8a49b87
commit
3fd583d27c
3 changed files with 72 additions and 0 deletions
3
nix/writeExecline/OWNERS
Normal file
3
nix/writeExecline/OWNERS
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
inherited: true
|
||||||
|
owners:
|
||||||
|
- Profpatsch
|
67
nix/writeExecline/default.nix
Normal file
67
nix/writeExecline/default.nix
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
|
# Write an execline script, represented as nested nix lists.
|
||||||
|
# Everything is escaped correctly.
|
||||||
|
# https://skarnet.org/software/execline/
|
||||||
|
|
||||||
|
# TODO(Profpatsch) upstream into nixpkgs
|
||||||
|
|
||||||
|
let
|
||||||
|
# replaces " and \ to \" and \\ respectively and quote with "
|
||||||
|
# e.g.
|
||||||
|
# a"b\c -> "a\"b\\c"
|
||||||
|
# a\"bc -> "a\\\"bc"
|
||||||
|
escapeExeclineArg = arg:
|
||||||
|
''"${builtins.replaceStrings [ ''"'' ''\'' ] [ ''\"'' ''\\'' ] (toString arg)}"'';
|
||||||
|
|
||||||
|
# Escapes an execline (list of execline strings) to be passed to execlineb
|
||||||
|
# Give it a nested list of strings. Nested lists are interpolated as execline
|
||||||
|
# blocks ({}).
|
||||||
|
# Everything is quoted correctly.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# escapeExecline [ "if" [ "somecommand" ] "true" ]
|
||||||
|
# == ''"if" { "somecommand" } "true"''
|
||||||
|
escapeExecline = execlineList: lib.concatStringsSep " "
|
||||||
|
(let
|
||||||
|
go = arg:
|
||||||
|
if builtins.isString arg then [(escapeExeclineArg arg)]
|
||||||
|
else if builtins.isPath arg then [(escapeExeclineArg "${arg}")]
|
||||||
|
else if lib.isDerivation arg then [(escapeExeclineArg arg)]
|
||||||
|
else if builtins.isList arg then [ "{" ] ++ builtins.concatMap go arg ++ [ "}" ]
|
||||||
|
else abort "escapeExecline can only hande nested lists of strings, was ${lib.generators.toPretty {} arg}";
|
||||||
|
in builtins.concatMap go execlineList);
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
name:
|
||||||
|
{
|
||||||
|
# "var": substitute readNArgs variables and start $@
|
||||||
|
# from the (readNArgs+1)th argument
|
||||||
|
# "var-full": substitute readNArgs variables and start $@ from $0
|
||||||
|
# "env": don’t substitute, set # and 0…n environment vaariables, where n=$#
|
||||||
|
# "none": don’t substitute or set any positional arguments
|
||||||
|
# "env-no-push": like "env", but bypass the push-phase. Not recommended.
|
||||||
|
argMode ? "var",
|
||||||
|
# Number of arguments to be substituted as variables (passed to "var"/"-s" or "var-full"/"-S"
|
||||||
|
readNArgs ? 0,
|
||||||
|
}:
|
||||||
|
# Nested list of lists of commands.
|
||||||
|
# Inner lists are translated to execline blocks.
|
||||||
|
argList:
|
||||||
|
|
||||||
|
let
|
||||||
|
env =
|
||||||
|
if argMode == "var" then "s${toString readNArgs}"
|
||||||
|
else if argMode == "var-full" then "S${toString readNArgs}"
|
||||||
|
else if argMode == "env" then ""
|
||||||
|
else if argMode == "none" then "P"
|
||||||
|
else if argMode == "env-no-push" then "p"
|
||||||
|
else abort ''"${toString argMode}" is not a valid argMode, use one of "var", "var-full", "env", "none", "env-no-push".'';
|
||||||
|
|
||||||
|
in
|
||||||
|
# TODO(Profpatsch): rewrite `writeScript` with `runExecline`
|
||||||
|
pkgs.writeScript name ''
|
||||||
|
#!${pkgs.execline}/bin/execlineb -W${env}
|
||||||
|
${escapeExecline argList}
|
||||||
|
''
|
2
third_party/default.nix
vendored
2
third_party/default.nix
vendored
|
@ -59,6 +59,7 @@ let
|
||||||
cudatoolkit
|
cudatoolkit
|
||||||
darwin
|
darwin
|
||||||
dockerTools
|
dockerTools
|
||||||
|
execline
|
||||||
fetchFromGitHub
|
fetchFromGitHub
|
||||||
fetchgit
|
fetchgit
|
||||||
fetchurl
|
fetchurl
|
||||||
|
@ -130,6 +131,7 @@ let
|
||||||
thttpd
|
thttpd
|
||||||
tree
|
tree
|
||||||
which
|
which
|
||||||
|
writeScript
|
||||||
writeShellScript
|
writeShellScript
|
||||||
writeShellScriptBin
|
writeShellScriptBin
|
||||||
writeText
|
writeText
|
||||||
|
|
Loading…
Reference in a new issue