notes: 2.3.0 -> 2.3.1 (#352950)
[NixPkgs.git] / lib / strings-with-deps.nix
blob7b88b018da578695e3ae97e81c7639432cc0c030
1 { lib }:
2 /*
3 Usage:
5   You define you custom builder script by adding all build steps to a list.
6   for example:
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
16   Attention:
18   let
19     pkgs = (import <nixpkgs>) {};
20   in let
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"];
28     stages = {
29       nameHeader = noDepEntry "#! /bin/sh \n";
30       inherit nameA nameB nameC;
31     };
32   in
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
37     ]
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 (?)
44 let
45   inherit (lib)
46     concatStringsSep
47     head
48     isAttrs
49     listToAttrs
50     tail
51     ;
53 rec {
55   /* !!! The interface of this function is kind of messed up, since
56      it's way too overloaded and almost but not quite computes a
57      topological sort of the depstrings. */
59   textClosureList = predefined: arg:
60     let
61       f = done: todo:
62         if todo == [] then {result = []; inherit done;}
63         else
64           let entry = head todo; in
65           if isAttrs entry then
66             let x = f done entry.deps;
67                 y = f x.done (tail todo);
68             in { result = x.result ++ [entry.text] ++ y.result;
69                  done = y.done;
70                }
71           else if done ? ${entry} then f done (tail todo)
72           else f (done // listToAttrs [{name = entry; value = 1;}]) ([predefined.${entry}] ++ tail todo);
73     in (f {} arg).result;
75   textClosureMap = f: predefined: names:
76     concatStringsSep "\n" (map f (textClosureList predefined names));
78   noDepEntry = text: {inherit text; deps = [];};
79   fullDepEntry = text: deps: {inherit text deps;};
80   packEntry = deps: {inherit deps; text="";};
82   stringAfter = deps: text: { inherit text deps; };