5 You define you custom builder script by adding all build steps to a list.
7 builder = writeScript "fsg-4.4-builder"
8 (textClosure [doUnpack addInputs preBuild doMake installPhase doForceShare]);
10 a step is defined by noDepEntry, fullDepEntry or packEntry.
11 To ensure that prerequisite are met those are added before the task itself by
12 textClosureDupList. Duplicated items are removed again.
14 See trace/nixpkgs/trunk/pkgs/top-level/builder-defs.nix for some predefined build steps
19 pkgs = (import <nixpkgs>) {};
21 inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
22 inherit (pkgs.lib) id;
24 nameA = noDepEntry "Text a";
25 nameB = fullDepEntry "Text b" ["nameA"];
26 nameC = fullDepEntry "Text c" ["nameA"];
29 nameHeader = noDepEntry "#! /bin/sh \n";
30 inherit nameA nameB nameC;
33 textClosureMap id stages
34 [ "nameHeader" "nameA" "nameB" "nameC"
35 nameC # <- added twice. add a dep entry if you know that it will be added once only [1]
36 "nameB" # <- this will not be added again because the attr name (reference) is used
39 # result: Str("#! /bin/sh \n\nText a\nText b\nText c\nText c",[])
41 [1] maybe this behaviour should be removed to keep things simple (?)
56 Topologically sort a collection of dependent strings.
57 Only the values to keys listed in `arg` and their dependencies will be included in the result.
60 This function doesn't formally fulfill the definition of topological sorting, but it's good enough for our purposes in Nixpkgs.
65 `predefined` (attribute set)
67 : strings with annotated dependencies (strings or attribute set)
68 A value can be a simple string if it has no dependencies.
69 Otherwise, is can be an attribute set with the following attributes:
70 - `deps` (list of strings)
73 `arg` (list of strings)
75 : Keys for which the values in the dependency closure will be included in the result
80 textClosureList :: { ${phase} :: { deps :: [String]; text :: String; } | String; } -> [String] -> [String]
85 ## `lib.stringsWithDeps.textClosureList` usage example
90 deps = [ "b" "c" "e" ];
91 text = "a: depends on b, c and e";
95 text = "b: no dependencies";
99 text = "c: depends on b";
103 text = "d: not being depended on by anything in `arg`";
107 text = "e: depends on c, depended on by a, not in `arg`";
117 "e: depends on c, depended on by a, not in `arg`"
118 "a: depends on b, c and e"
123 Common real world usages are:
124 - Ordering the dependent phases of `system.activationScripts`
125 - Ordering the dependent phases of `system.userActivationScripts`
127 For further examples see: [NixOS activation script](https://nixos.org/manual/nixos/stable/#sec-activation-script)
130 textClosureList = predefined: arg:
133 if todo == [] then {result = []; inherit done;}
135 let entry = head todo; in
136 if isAttrs entry then
137 let x = f done entry.deps;
138 y = f x.done (tail todo);
139 in { result = x.result ++ [entry.text] ++ y.result;
142 else if done ? ${entry} then f done (tail todo)
143 else f (done // listToAttrs [{name = entry; value = 1;}]) ([predefined.${entry}] ++ tail todo);
144 in (f {} arg).result;
146 textClosureMap = f: predefined: names:
147 concatStringsSep "\n" (map f (textClosureList predefined names));
149 noDepEntry = text: {inherit text; deps = [];};
150 fullDepEntry = text: deps: {inherit text deps;};
151 packEntry = deps: {inherit deps; text="";};
153 stringAfter = deps: text: { inherit text deps; };