nix-helpers: d72bd0197ba449cab21bfe63c7dc4e3adb48a8d2
1: # Adding files to the Nix store in a general way turns out to be quite tricky.
2: # In particular:
3: # - Filenames with certain characters (e.g. " " or "'") will cause an error
4: # if we try adding them as-is. We can work around this using builtins.path.
5: # - Paths which reference things in the Nix store can cause errors when used
6: # with functions like builtins.path.
7: # - We can use builtins.unsafeDiscardStringContext to avoid errors, but we
8: # must ensure that the context is added back in so that dependencies are
9: # are built when needed and not garbage collected from under us.
10: { asPath, hello, lib, runCommand, sanitiseName, writeScript }:
11:
12: with builtins;
13: with lib;
14: p:
15: with rec {
16: strP = unsafeDiscardStringContext (toString p);
17:
18: # Checks whether a path is from the Nix store, since Nix will abort if
19: # store paths are referenced in certain ways.
20: isStore = x: hasPrefix storeDir (toString x);
21:
22: # Chops suffices off a store path until it's a top-level entry, e.g.
23: # getRoot "/nix/store/...-foo/bar/baz" -> "/nix/store/...-foo"
24: # This way we're guaranteed to avoid filename characters which aren't
25: # valid store paths.
26: getRoot = x:
27: if toString (dirOf x) == toString storeDir then x else getRoot (dirOf x);
28:
29: # Complements getRoot:
30: # p = "/nix/store/...-foo/bar/baz" -> trunk = "bar/baz"
31: trunk = removePrefix "/" (removePrefix (getRoot strP) strP);
32:
33: # Avoids characters which are incompatible with store paths
34: safeName = sanitiseName (baseNameOf strP);
35:
36: # For store paths, we make a symlink which depends on p's context. By
37: # using the root we avoid incompatible characters, without using
38: # builtins.path (which Nix complains about if we give it a store path).
39: symlink = runCommand safeName {
40: inherit trunk;
41: root = toString (asPath (getRoot p));
42: } ''
43: ${if isString p then addContextFrom p "" else ""}
44: if [[ -z "$trunk" ]]
45: then
46: ln -s "$root" "$out"
47: else
48: ln -s "$root/$trunk" "$out"
49: fi
50: '';
51: };
52: if isStore p then
53: symlink
54: else
55: builtins.path {
56: name = safeName;
57: path = p;
58: }
Generated by git2html.