-
Notifications
You must be signed in to change notification settings - Fork 1
/
escape.nix
55 lines (47 loc) · 1.76 KB
/
escape.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# (Mostly) Taken from https://github.com/nrabulinski/cursed-nix. Huge thanks!
lib: let
startMarker = "__START__";
endMarker = "__END__";
dropFirst = lib.drop 1;
dropLast = list: lib.sublist 0 (lib.length list - 1) list;
yeet = string: builtins.unsafeDiscardStringContext (builtins.unsafeDiscardOutputDependency string);
getContent = drvPath: let
drv = lib.readFile drvPath;
isValid = builtins.match ".*${lib.escapeRegex startMarker}.*${lib.escapeRegex endMarker}.*" drv != null;
content = lib.pipe drv [
(lib.splitString startMarker)
dropFirst
(lib.concatStringsSep startMarker)
(lib.splitString endMarker)
dropLast
(lib.concatStringsSep endMarker)
];
in if isValid then content else toString (import drvPath);
escape = string: let
ctx = builtins.getContext string;
ctxNames = lib.attrNames ctx;
recurseSubDrv = restNames: strings: let
head = lib.head restNames;
headDrv = import head;
last = (lib.length restNames) == 1;
headContent = getContent head;
in map (string: let
m = lib.splitString (yeet headDrv.outPath) string;
__m = if last then map lib.strings.escapeXML else recurseSubDrv (lib.tail restNames);
out = __m m;
in lib.concatStringsSep headContent out) strings;
final = recurseSubDrv ctxNames [ string ];
final' = assert (lib.length final == 1); lib.head final;
in if builtins.hasContext string then
lib.replaceStrings [ ''\"'' ''\n'' ] [ ''"'' "\n" ] (yeet final')
else
lib.strings.escapeXML string;
raw = string: toString (derivation {
name = "_";
system = "_";
builder = "_";
rawContent = "${startMarker}${yeet string}${endMarker}";
});
in {
inherit escape raw;
}