-
Notifications
You must be signed in to change notification settings - Fork 23
/
lockfile.nix
123 lines (117 loc) · 3.61 KB
/
lockfile.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
{ lib
, runCommand
, remarshal
, fetchurl
, ...
}:
with lib;
rec {
parseLockfile = lockfile: builtins.fromJSON (readFile (runCommand "toJSON" { } "${remarshal}/bin/yaml2json ${lockfile} $out"));
processLockfile = { registry, lockfile, noDevDependencies }:
let
splitVersion = name: splitString "@" (head (splitString "(" name));
getVersion = name: last (splitVersion name);
withoutVersion = name: concatStringsSep "@" (init (splitVersion name));
switch = options:
if ((length options) == 0)
then throw "No matching case found!"
else
if ((head options).case or true)
then (head options).result
else switch (tail options);
mkTarball = pkg: contents:
runCommand "${last (init (splitString "/" (head (splitString "(" pkg))))}.tgz" { } ''
tar -czf $out -C ${contents} .
'';
findTarball = n: v:
switch [
{
case = (v.resolution.type or "") == "git";
result =
mkTarball n (
fetchGit {
url = v.resolution.repo;
rev = v.resolution.commit;
shallow = true;
}
);
}
{
case = hasAttrByPath [ "resolution" "tarball" ] v && hasAttrByPath [ "resolution" "integrity" ] v;
result = fetchurl {
url = v.resolution.tarball;
${head (splitString "-" v.resolution.integrity)} = v.resolution.integrity;
};
}
{
case = hasPrefix "https://codeload.github.com" (v.resolution.tarball or "");
result =
let
m = strings.match "https://codeload.github.com/([^/]+)/([^/]+)/tar\\.gz/([a-f0-9]+)" v.resolution.tarball;
in
mkTarball n (
fetchGit {
url = "https://github.com/${elemAt m 0}/${elemAt m 1}";
rev = (elemAt m 2);
shallow = true;
}
);
}
{
case = (v ? id);
result =
let
split = splitString "/" v.id;
in
mkTarball n (
fetchGit {
url = "https://${concatStringsSep "/" (init split)}.git";
rev = (last split);
shallow = true;
}
);
}
{
case = hasPrefix "/" n;
result =
let
name = withoutVersion n;
baseName = last (splitString "/" (withoutVersion n));
version = getVersion n;
in
fetchurl {
url = "${registry}/${name}/-/${baseName}-${version}.tgz";
${head (splitString "-" v.resolution.integrity)} = v.resolution.integrity;
};
}
];
in
{
dependencyTarballs =
unique (
mapAttrsToList
findTarball
(filterAttrs
(n: v: !noDevDependencies || !(v.dev or false))
(parseLockfile lockfile).packages
)
);
patchedLockfile =
let
orig = parseLockfile lockfile;
in
orig // {
packages = mapAttrs
(n: v:
v // (
if noDevDependencies && (v.dev or false)
then { resolution = { }; }
else {
resolution.tarball = "file:${findTarball n v}";
}
)
)
orig.packages;
};
};
}