nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenvNoCC,
4 rustPlatform,
5 makeWrapper,
6 pkg-config,
7 curl,
8 gnutar,
9 gzip,
10 testers,
11 fetchurl,
12 cacert,
13 prefetch-npm-deps,
14 fetchNpmDeps,
15}:
16
17{
18 prefetch-npm-deps = rustPlatform.buildRustPackage {
19 pname = "prefetch-npm-deps";
20 version = (lib.importTOML ./Cargo.toml).package.version;
21
22 src = lib.cleanSourceWith {
23 src = ./.;
24 filter =
25 name: type:
26 let
27 name' = builtins.baseNameOf name;
28 in
29 name' != "default.nix" && name' != "target";
30 };
31
32 cargoLock.lockFile = ./Cargo.lock;
33
34 nativeBuildInputs = [
35 makeWrapper
36 pkg-config
37 ];
38 buildInputs = [ curl ];
39
40 postInstall = ''
41 wrapProgram "$out/bin/prefetch-npm-deps" --prefix PATH : ${
42 lib.makeBinPath [
43 gnutar
44 gzip
45 ]
46 }
47 '';
48
49 passthru.tests =
50 let
51 makeTestSrc =
52 { name, src }:
53 stdenvNoCC.mkDerivation {
54 name = "${name}-src";
55
56 inherit src;
57
58 buildCommand = ''
59 mkdir -p $out
60 cp $src $out/package-lock.json
61 '';
62 };
63
64 makeTest =
65 {
66 name,
67 src,
68 hash,
69 forceGitDeps ? false,
70 forceEmptyCache ? false,
71 }:
72 testers.invalidateFetcherByDrvHash fetchNpmDeps {
73 inherit
74 name
75 hash
76 forceGitDeps
77 forceEmptyCache
78 ;
79
80 src = makeTestSrc { inherit name src; };
81 };
82 in
83 {
84 lockfileV1 = makeTest {
85 name = "lockfile-v1";
86
87 src = fetchurl {
88 url = "https://raw.githubusercontent.com/jellyfin/jellyfin-web/v10.8.4/package-lock.json";
89 hash = "sha256-uQmc+S+V1co1Rfc4d82PpeXjmd1UqdsG492ADQFcZGA=";
90 };
91
92 hash = "sha256-wca1QvxUw3OrLStfYN9Co6oVBR1LbfcNUKlDqvObps4=";
93 };
94
95 lockfileV2 = makeTest {
96 name = "lockfile-v2";
97
98 src = fetchurl {
99 url = "https://raw.githubusercontent.com/jesec/flood/v4.7.0/package-lock.json";
100 hash = "sha256-qS29tq5QPnGxV+PU40VgMAtdwVLtLyyhG2z9GMeYtC4=";
101 };
102
103 hash = "sha256-tuEfyePwlOy2/mOPdXbqJskO6IowvAP4DWg8xSZwbJw=";
104 };
105
106 hashPrecedence = makeTest {
107 name = "hash-precedence";
108
109 src = fetchurl {
110 url = "https://raw.githubusercontent.com/matrix-org/matrix-appservice-irc/0.34.0/package-lock.json";
111 hash = "sha256-1+0AQw9EmbHiMPA/H8OP8XenhrkhLRYBRhmd1cNPFjk=";
112 };
113
114 hash = "sha256-oItUls7AXcCECuyA+crQO6B0kv4toIr8pBubNwB7kAM=";
115 };
116
117 hostedGitDeps = makeTest {
118 name = "hosted-git-deps";
119
120 src = fetchurl {
121 url = "https://cyberchaos.dev/yuka/trainsearch/-/raw/e3cba6427e8ecfd843d0f697251ddaf5e53c2327/package-lock.json";
122 hash = "sha256-X9mCwPqV5yP0S2GonNvpYnLSLJMd/SUIked+hMRxDpA=";
123 };
124
125 hash = "sha256-tEdElWJ+KBTxBobzXBpPopQSwK2usGW/it1+yfbVzBw=";
126 };
127
128 linkDependencies = makeTest {
129 name = "link-dependencies";
130
131 src = fetchurl {
132 url = "https://raw.githubusercontent.com/evcc-io/evcc/0.106.3/package-lock.json";
133 hash = "sha256-6ZTBMyuyPP/63gpQugggHhKVup6OB4hZ2rmSvPJ0yEs=";
134 };
135
136 hash = "sha256-VzQhArHoznYSXUT7l9HkJV4yoSOmoP8eYTLel1QwmB4=";
137 };
138
139 # This package has no resolved deps whatsoever, which will not actually work but does test the forceEmptyCache option.
140 emptyCache = makeTest {
141 name = "empty-cache";
142
143 src = fetchurl {
144 url = "https://raw.githubusercontent.com/bufbuild/protobuf-es/v1.2.1/package-lock.json";
145 hash = "sha256-UdBUEb4YRHsbvyjymIyjemJEiaI9KQRirqt+SFSK0wA=";
146 };
147
148 hash = "sha256-Cdv40lQjRszzJtJydZt25uYfcJVeJGwH54A+agdH9wI=";
149
150 forceEmptyCache = true;
151 };
152
153 # This package contains both hosted Git shorthand, and a bundled dependency that happens to override an existing one.
154 etherpadLite1818 = makeTest {
155 name = "etherpad-lite-1.8.18";
156
157 src = fetchurl {
158 url = "https://raw.githubusercontent.com/ether/etherpad-lite/1.8.18/src/package-lock.json";
159 hash = "sha256-1fGNxYJi1I4cXK/jinNG+Y6tPEOhP3QAqWOBEQttS9E=";
160 };
161
162 hash = "sha256-+KA8/orSBJ4EhuSyQO8IKSxsN/FAsYU3lOzq+awuxNQ=";
163
164 forceGitDeps = true;
165 };
166
167 # This package has a lockfile v1 git dependency with no `dependencies` attribute, since it semantically has no dependencies.
168 jitsiMeet9111 = makeTest {
169 name = "jitsi-meet-9111";
170
171 src = fetchurl {
172 url = "https://raw.githubusercontent.com/jitsi/jitsi-meet/stable/jitsi-meet_9111/package-lock.json";
173 hash = "sha256-NU+eQD4WZ4BMur8uX79uk8wUPsZvIT02KhPWHTmaihk=";
174 };
175
176 hash = "sha256-FhxlJ0HdJMPiWe7+n1HaGLWOr/2HJEPwiS65uqXZM8Y=";
177 };
178 };
179
180 meta = with lib; {
181 description = "Prefetch dependencies from npm (for use with `fetchNpmDeps`)";
182 mainProgram = "prefetch-npm-deps";
183 maintainers = with maintainers; [ winter ];
184 license = licenses.mit;
185 };
186 };
187
188 fetchNpmDeps =
189 {
190 name ? "npm-deps",
191 hash ? "",
192 forceGitDeps ? false,
193 forceEmptyCache ? false,
194 nativeBuildInputs ? [ ],
195 ...
196 }@args:
197 let
198 hash_ =
199 if hash != "" then
200 {
201 outputHash = hash;
202 }
203 else
204 {
205 outputHash = "";
206 outputHashAlgo = "sha256";
207 };
208
209 forceGitDeps_ = lib.optionalAttrs forceGitDeps { FORCE_GIT_DEPS = true; };
210 forceEmptyCache_ = lib.optionalAttrs forceEmptyCache { FORCE_EMPTY_CACHE = true; };
211 in
212 stdenvNoCC.mkDerivation (
213 args
214 // {
215 inherit name;
216
217 nativeBuildInputs = nativeBuildInputs ++ [ prefetch-npm-deps ];
218
219 buildPhase = ''
220 runHook preBuild
221
222 if [[ ! -e package-lock.json ]]; then
223 echo
224 echo "ERROR: The package-lock.json file does not exist!"
225 echo
226 echo "package-lock.json is required to make sure that npmDepsHash doesn't change"
227 echo "when packages are updated on npm."
228 echo
229 echo "Hint: You can copy a vendored package-lock.json file via postPatch."
230 echo
231
232 exit 1
233 fi
234
235 prefetch-npm-deps package-lock.json $out
236
237 runHook postBuild
238 '';
239
240 dontInstall = true;
241
242 # NIX_NPM_TOKENS environment variable should be a JSON mapping in the shape of:
243 # `{ "registry.example.com": "example-registry-bearer-token", ... }`
244 impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ "NIX_NPM_TOKENS" ];
245
246 SSL_CERT_FILE =
247 if
248 (
249 hash_.outputHash == ""
250 || hash_.outputHash == lib.fakeSha256
251 || hash_.outputHash == lib.fakeSha512
252 || hash_.outputHash == lib.fakeHash
253 )
254 then
255 "${cacert}/etc/ssl/certs/ca-bundle.crt"
256 else
257 "/no-cert-file.crt";
258
259 outputHashMode = "recursive";
260 }
261 // hash_
262 // forceGitDeps_
263 // forceEmptyCache_
264 );
265}