Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{
2 lib,
3 stdenvNoCC,
4 callPackage,
5 jq,
6 moreutils,
7 cacert,
8 makeSetupHook,
9 pnpm,
10 yq,
11}:
12
13let
14 pnpm' = pnpm;
15in
16{
17 fetchDeps = lib.makeOverridable (
18 {
19 hash ? "",
20 pname,
21 pnpm ? pnpm',
22 pnpmWorkspaces ? [ ],
23 prePnpmInstall ? "",
24 pnpmInstallFlags ? [ ],
25 fetcherVersion ? null,
26 ...
27 }@args:
28 let
29 args' = builtins.removeAttrs args [
30 "hash"
31 "pname"
32 ];
33 hash' =
34 if hash != "" then
35 { outputHash = hash; }
36 else
37 {
38 outputHash = "";
39 outputHashAlgo = "sha256";
40 };
41
42 filterFlags = lib.map (package: "--filter=${package}") pnpmWorkspaces;
43 in
44 # pnpmWorkspace was deprecated, so throw if it's used.
45 assert (lib.throwIf (args ? pnpmWorkspace)
46 "pnpm.fetchDeps: `pnpmWorkspace` is no longer supported, please migrate to `pnpmWorkspaces`."
47 ) true;
48
49 assert (lib.throwIf (fetcherVersion == null)
50 "pnpm.fetchDeps: `fetcherVersion` is not set, see https://nixos.org/manual/nixpkgs/stable/#javascript-pnpm-fetcherVersion."
51 ) true;
52
53 stdenvNoCC.mkDerivation (
54 finalAttrs:
55 (
56 args'
57 // {
58 name = "${pname}-pnpm-deps";
59
60 nativeBuildInputs = [
61 cacert
62 jq
63 moreutils
64 args.pnpm or pnpm'
65 yq
66 ];
67
68 impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ "NIX_NPM_REGISTRY" ];
69
70 installPhase = ''
71 runHook preInstall
72
73 lockfileVersion="$(yq -r .lockfileVersion pnpm-lock.yaml)"
74 if [[ ''${lockfileVersion:0:1} -gt ${lib.versions.major pnpm.version} ]]; then
75 echo "ERROR: lockfileVersion $lockfileVersion in pnpm-lock.yaml is too new for the provided pnpm version ${lib.versions.major pnpm.version}!"
76 exit 1
77 fi
78
79 export HOME=$(mktemp -d)
80
81 # If the packageManager field in package.json is set to a different pnpm version than what is in nixpkgs,
82 # any pnpm command would fail in that directory, the following disables this
83 pushd ..
84 pnpm config set manage-package-manager-versions false
85 popd
86
87 pnpm config set store-dir $out
88 # Some packages produce platform dependent outputs. We do not want to cache those in the global store
89 pnpm config set side-effects-cache false
90 # As we pin pnpm versions, we don't really care about updates
91 pnpm config set update-notifier false
92 # Run any additional pnpm configuration commands that users provide.
93 ${prePnpmInstall}
94 # pnpm is going to warn us about using --force
95 # --force allows us to fetch all dependencies including ones that aren't meant for our host platform
96 pnpm install \
97 --force \
98 --ignore-scripts \
99 ${lib.escapeShellArgs filterFlags} \
100 ${lib.escapeShellArgs pnpmInstallFlags} \
101 --registry="$NIX_NPM_REGISTRY" \
102 --frozen-lockfile
103
104 # Store newer fetcherVersion in case pnpm.configHook also needs it
105 if [[ ${toString fetcherVersion} -gt 1 ]]; then
106 echo ${toString fetcherVersion} > $out/.fetcher-version
107 fi
108
109 runHook postInstall
110 '';
111
112 fixupPhase = ''
113 runHook preFixup
114
115 # Remove timestamp and sort the json files
116 rm -rf $out/{v3,v10}/tmp
117 for f in $(find $out -name "*.json"); do
118 jq --sort-keys "del(.. | .checkedAt?)" $f | sponge $f
119 done
120
121 # Ensure consistent permissions
122 # NOTE: For reasons not yet fully understood, pnpm might create files with
123 # inconsistent permissions, for example inside the ubuntu-24.04
124 # github actions runner.
125 # To ensure stable derivations, we need to set permissions
126 # consistently, namely:
127 # * All files with `-exec` suffix have 555.
128 # * All other files have 444.
129 # * All folders have 555.
130 # See https://github.com/NixOS/nixpkgs/pull/350063
131 # See https://github.com/NixOS/nixpkgs/issues/422889
132 if [[ ${toString fetcherVersion} -ge 2 ]]; then
133 find $out -type f -name "*-exec" -print0 | xargs -0 chmod 555
134 find $out -type f -not -name "*-exec" -print0 | xargs -0 chmod 444
135 find $out -type d -print0 | xargs -0 chmod 555
136 fi
137
138 runHook postFixup
139 '';
140
141 passthru = {
142 inherit fetcherVersion;
143 serve = callPackage ./serve.nix {
144 pnpm = args.pnpm or pnpm';
145 pnpmDeps = finalAttrs.finalPackage;
146 };
147 };
148
149 dontConfigure = true;
150 dontBuild = true;
151 outputHashMode = "recursive";
152 }
153 // hash'
154 )
155 )
156 );
157
158 configHook = makeSetupHook {
159 name = "pnpm-config-hook";
160 propagatedBuildInputs = [ pnpm ];
161 } ./pnpm-config-hook.sh;
162}