nix-helpers: 184ce603363b2aa8c634978dc2e2aedb59480919
1: # Turns a list of Nix expressions into an attrset suitable for use in
2: # derivations, WITHOUT forcing anything to be built at eval time. Also provides
3: # a snippet of bash code to splice into scripts, which turns these env vars into
4: # a proper bash array.
5: #
6: # For example, if we did:
7: #
8: # nixListToBashArray { name = "x"; args = [ "bar", "baz", <derivation..> ]; }
9: #
10: # We will get back an 'env' attrset like this:
11: #
12: # { x1 = "bar"; x2 = "baz"; x3 = <derivation...>; }
13: #
14: # Note that the derivation hasn't been forced; if we append this set to a build
15: # environment, it will be treated like any other dependency. We also get a
16: # 'code' snippet, which will loop over these distinct variables to construct a
17: # single array (in this case, called "x")
18:
19: # Take lib from nixpkgs1609, since other versions (e.g. 1603) mess up escaping
20: {
21: nothing,
22: nixpkgs-lib,
23: runCommand,
24: }:
25:
26: with rec {
27: inherit (builtins)
28: attrNames
29: attrValues
30: foldl'
31: length
32: stringLength
33: toString
34: ;
35: inherit (nixpkgs-lib) escapeShellArg;
36:
37: # This is the actual implementation
38: go =
39: { args, name }:
40: rec {
41: # Store each arg in a separate variable, named numerically
42: env =
43: with foldl'
44: (result: arg: {
45: # Increment the count, for the next arg (if any)
46: count = result.count + 1;
47:
48: # Append a variable to the environment for this arg
49: vars = result.vars // {
50: "${name}${toString result.count}" = arg;
51: };
52: })
53: # Start with variable 1 in an empty environment
54: {
55: count = 1;
56: vars = { };
57: }
58: args;
59: vars;
60:
61: code = ''
62: ### Auto-generated by nixListToBashArray
63: ${name}=()
64:
65: for N in $(seq 1 "${toString (length args)}")
66: do
67: # Use a "variable variable" to look up "$name$N" as a variable name
68: NIXLISTTOBASHARRAYTEMP="${name}$N"
69: ${name}=("''${${name}[@]}" "''${!NIXLISTTOBASHARRAYTEMP}")
70: unset NIXLISTTOBASHARRAYTEMP
71: done
72: ### End of auto-generated code
73: '';
74: };
75:
76: ## Tests follow
77:
78: checkArgsAreNotForced =
79: with go {
80: name = "checkNotForced";
81: args = [ (abort "NLTBA shouldn't have forced") ];
82: };
83: # Force the code to be generated, and hence the content of any splices
84: (stringLength code > 0 || abort "No code generated")
85: &&
86:
87: # Force the environment "spine"/structure to be generated
88: (length (attrValues env) == 1 || abort "Wrong number of vars")
89: &&
90:
91: # Force the variable names (but not values!) to be generated
92: (attrNames env == [ "checkNotForced1" ] || abort "Wrong var name");
93:
94: checkWeGetTheRightValues =
95: with { mixture = ''mixture "of 'special" $characters''; };
96: with go {
97: name = "foo";
98: args = [
99: "simple"
100: "single 'quoted'"
101: ''double "quoted"''
102: mixture
103: nothing
104: ];
105: };
106: with rec {
107: context = env;
108:
109: check = runCommand "check-NLTBA.nix" context ''
110: function fail() {
111: echo -e "$*" 1>&2
112: exit 1
113: }
114:
115: function match() {
116: [[ "x$2" = "x$3" ]] || fail "Wrong $1 value '$2' (should be '$3')"
117: }
118:
119: match foo1 "$foo1" "simple"
120: match foo2 "$foo2" "single 'quoted'"
121: match foo3 "$foo3" 'double "quoted"'
122: match foo4 "$foo4" ${escapeShellArg mixture}
123:
124: [[ -d "$foo5" ]] || fail "foo5 should have been dir, got '$foo5'"
125:
126: ${code}
127:
128: [[ -n "$foo" ]] || fail "Didn't get foo: '$foo'"
129:
130: FOUND=0
131: for VAL in "''${foo[@]}"
132: do
133: FOUND=$(( FOUND + 1 ))
134: done
135: [[ "$FOUND" -eq 5 ]] || fail "foo has '$FOUND' elements"
136:
137: match 'foo[0]' "''${foo[0]}" "simple"
138: match 'foo[1]' "''${foo[1]}" "single 'quoted'"
139: match 'foo[2]' "''${foo[2]}" 'double "quoted"'
140: match 'foo[3]' "''${foo[3]}" ${escapeShellArg mixture}
141:
142: [[ -d "''${foo[4]}" ]] || fail "foo[4] should be dir, got: ''${foo[4]}"
143:
144: echo true > "$out"
145: '';
146: };
147: import check;
148: };
149:
150: assert checkArgsAreNotForced;
151: assert checkWeGetTheRightValues;
152: go
Generated by git2html.