pnpm.fetchDeps: output a tarball from fetcherVersion 3 (#469950)

This commit is contained in:
Sefa Eyeoglu
2025-12-15 13:30:04 +00:00
committed by GitHub
5 changed files with 57 additions and 16 deletions
@@ -354,7 +354,7 @@ stdenv.mkDerivation (finalAttrs: {
pnpmDeps = pnpm.fetchDeps {
inherit (finalAttrs) pname version src;
fetcherVersion = 2;
fetcherVersion = 3;
hash = "...";
};
})
@@ -501,6 +501,7 @@ Changes can include workarounds or bug fixes to existing PNPM issues.
- 1: Initial version, nothing special
- 2: [Ensure consistent permissions](https://github.com/NixOS/nixpkgs/pull/422975)
- 3: [Build a reproducible tarball](https://github.com/NixOS/nixpkgs/pull/469950)
### Yarn {#javascript-yarn}
@@ -28,8 +28,8 @@ stdenvNoCC.mkDerivation (finalAttrs: {
src
pnpmWorkspaces
;
fetcherVersion = 1;
hash = "sha256-NvyqPv5OKgZi3hW98Da8LhsYatmrzrPX8kLOfLr+BrI=";
fetcherVersion = 3;
hash = "sha256-6i+1V3ZkjiJ/IXDun3JfwmfDOiemxCmAXMzS/rGT6ZU=";
};
nativeBuildInputs = [
@@ -8,6 +8,7 @@
makeSetupHook,
pnpm,
yq,
zstd,
}:
let
@@ -16,6 +17,7 @@ let
supportedFetcherVersions = [
1 # First version. Here to preserve backwards compatibility
2 # Ensure consistent permissions. See https://github.com/NixOS/nixpkgs/pull/422975
3 # Build a reproducible tarball. See https://github.com/NixOS/nixpkgs/pull/469950
];
in
{
@@ -72,6 +74,7 @@ in
moreutils
args.pnpm or pnpm'
yq
zstd
];
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ "NIX_NPM_REGISTRY" ];
@@ -87,13 +90,23 @@ in
export HOME=$(mktemp -d)
# For fetcherVersion < 3, the pnpm store files are placed directly into $out.
# For fetcherVersion >= 3, it is bundled into a compressed tarball within $out,
# without distributing the uncompressed store files.
if [[ ${toString fetcherVersion} -ge 3 ]]; then
mkdir $out
storePath=$(mktemp -d)
else
storePath=$out
fi
# If the packageManager field in package.json is set to a different pnpm version than what is in nixpkgs,
# any pnpm command would fail in that directory, the following disables this
pushd ..
pnpm config set manage-package-manager-versions false
popd
pnpm config set store-dir $out
pnpm config set store-dir $storePath
# Some packages produce platform dependent outputs. We do not want to cache those in the global store
pnpm config set side-effects-cache false
# As we pin pnpm versions, we don't really care about updates
@@ -122,8 +135,8 @@ in
runHook preFixup
# Remove timestamp and sort the json files
rm -rf $out/{v3,v10}/tmp
for f in $(find $out -name "*.json"); do
rm -rf $storePath/{v3,v10}/tmp
for f in $(find $storePath -name "*.json"); do
jq --sort-keys "del(.. | .checkedAt?)" $f | sponge $f
done
@@ -139,9 +152,22 @@ in
# See https://github.com/NixOS/nixpkgs/pull/350063
# See https://github.com/NixOS/nixpkgs/issues/422889
if [[ ${toString fetcherVersion} -ge 2 ]]; then
find $out -type f -name "*-exec" -print0 | xargs -0 chmod 555
find $out -type f -not -name "*-exec" -print0 | xargs -0 chmod 444
find $out -type d -print0 | xargs -0 chmod 555
find $storePath -type f -name "*-exec" -print0 | xargs -0 chmod 555
find $storePath -type f -not -name "*-exec" -print0 | xargs -0 chmod 444
find $storePath -type d -print0 | xargs -0 chmod 555
fi
if [[ ${toString fetcherVersion} -ge 3 ]]; then
(
cd $storePath
# Build a reproducible tarball, per instructions at https://reproducible-builds.org/docs/archives/
tar --sort=name \
--mtime="@$SOURCE_DATE_EPOCH" \
--owner=0 --group=0 --numeric-owner \
--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
--zstd -cf $out/pnpm-store.tar.zst .
)
fi
runHook postFixup
@@ -166,7 +192,10 @@ in
configHook = makeSetupHook {
name = "pnpm-config-hook";
propagatedBuildInputs = [ pnpm ];
propagatedBuildInputs = [
pnpm
zstd
];
substitutions = {
npmArch = stdenvNoCC.targetPlatform.node.arch;
npmPlatform = stdenvNoCC.targetPlatform.node.platform;
@@ -12,10 +12,7 @@ pnpmConfigHook() {
exit 1
fi
fetcherVersion=1
if [[ -e "${pnpmDeps}/.fetcher-version" ]]; then
fetcherVersion=$(cat "${pnpmDeps}/.fetcher-version")
fi
fetcherVersion=$(cat "${pnpmDeps}/.fetcher-version" || echo 1)
echo "Using fetcherVersion: $fetcherVersion"
@@ -26,7 +23,12 @@ pnpmConfigHook() {
export npm_config_arch="@npmArch@"
export npm_config_platform="@npmPlatform@"
cp -Tr "$pnpmDeps" "$STORE_PATH"
if [[ $fetcherVersion -ge 3 ]]; then
tar --zstd -xf "$pnpmDeps/pnpm-store.tar.zst" -C "$STORE_PATH"
else
cp -Tr "$pnpmDeps" "$STORE_PATH"
fi
chmod -R +w "$STORE_PATH"
@@ -2,6 +2,7 @@
writeShellApplication,
pnpm,
pnpmDeps,
zstd,
}:
writeShellApplication {
@@ -9,11 +10,14 @@ writeShellApplication {
runtimeInputs = [
pnpm
zstd
];
text = ''
storePath=$(mktemp -d)
fetcherVersion=$(cat "${pnpmDeps}/.fetcher-version" || echo 1)
clean() {
echo "Cleaning up temporary store at '$storePath'..."
@@ -22,7 +26,12 @@ writeShellApplication {
echo "Copying pnpm store '${pnpmDeps}' to temporary store..."
cp -Tr "${pnpmDeps}" "$storePath"
if [[ $fetcherVersion -ge 3 ]]; then
tar --zstd -xf "${pnpmDeps}/pnpm-store.tar.zst" -C "$storePath"
else
cp -Tr "${pnpmDeps}" "$storePath"
fi
chmod -R +w "$storePath"
echo "Run 'pnpm install --store-dir \"$storePath\"' to install packages from this store."