From 379aa01a4962fc09e8648f26690fb8d569fca0d0 Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Sun, 10 Nov 2024 18:53:59 +0100 Subject: [PATCH] fetch-yarn-deps: add yarn-berry support A new argument has been added to fetch-yarn-deps: `yarnVersion` which will default to `1` which uses the original `yarn`. For newer `yarn-berry` `yarn.lock`, one can set the `yarnVersion` to either `3` or `4` which will use yarn-berry3 or yarn-berry4 respectively. The difference is the `yarn.lock` file, which follows a different format, depending on the version. This also adds the corresponding tests. The added support for yarn.lock files > version 1 has been inspired by @szlend from https://github.com/NixOS/nixpkgs/issues/254369#issuecomment-2080460150 fixes #254369 Signed-off-by: Florian Brandes Co-authored-by: Doron Behar --- .../node/fetch-yarn-deps/default.nix | 83 +++++++++++++++++-- .../tests/berry_3/package.json | 7 ++ .../fetch-yarn-deps/tests/berry_3/yarn.lock | 30 +++++++ .../tests/berry_4/package.json | 7 ++ .../fetch-yarn-deps/tests/berry_4/yarn.lock | 30 +++++++ .../node/fetch-yarn-deps/tests/default.nix | 10 +++ .../fetch-yarn-deps/yarn-berry-config-hook.sh | 30 +++++++ pkgs/top-level/all-packages.nix | 1 + 8 files changed, 191 insertions(+), 7 deletions(-) create mode 100644 pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/package.json create mode 100644 pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/yarn.lock create mode 100644 pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/package.json create mode 100644 pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/yarn.lock create mode 100644 pkgs/build-support/node/fetch-yarn-deps/yarn-berry-config-hook.sh diff --git a/pkgs/build-support/node/fetch-yarn-deps/default.nix b/pkgs/build-support/node/fetch-yarn-deps/default.nix index 29a76d3d9f3e8..468d3c7f7d5c8 100644 --- a/pkgs/build-support/node/fetch-yarn-deps/default.nix +++ b/pkgs/build-support/node/fetch-yarn-deps/default.nix @@ -14,6 +14,8 @@ prefetch-yarn-deps, fixup-yarn-lock, yarn, + yarn-berry3, + yarn-berry4, makeSetupHook, cacert, callPackage, @@ -104,6 +106,7 @@ in src ? null, hash ? "", sha256 ? "", + yarnVersion ? 1, ... }@args: let @@ -132,22 +135,66 @@ in dontInstall = true; nativeBuildInputs = [ - prefetch-yarn-deps + ( + { + "1" = prefetch-yarn-deps; + "3" = yarn-berry3; + "4" = yarn-berry4; + } + .${builtins.toString yarnVersion} + ) cacert ]; GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt"; NODE_EXTRA_CA_CERTS = "${cacert}/etc/ssl/certs/ca-bundle.crt"; - buildPhase = '' - runHook preBuild + supportedArchitectures = builtins.toJSON { + os = [ + "darwin" + "linux" + ]; + cpu = [ + "arm" + "arm64" + "ia32" + "x64" + ]; + libc = [ + "glibc" + "musl" + ]; + }; - yarnLock=''${yarnLock:=$PWD/yarn.lock} - mkdir -p $out - (cd $out; prefetch-yarn-deps --verbose --builder $yarnLock) + configurePhase = lib.optionalString (yarnVersion > 1) '' + runHook preConfigure - runHook postBuild + export HOME="$NIX_BUILD_TOP" + export YARN_ENABLE_TELEMETRY=0 + + yarn config set enableGlobalCache false + yarn config set cacheFolder $out + yarn config set supportedArchitectures --json "$supportedArchitectures" + + runHook postConfigure ''; + buildPhase = + '' + runHook preBuild + + mkdir -p $out + '' + + lib.optionalString (yarnVersion > 1) '' + yarn install --immutable --mode skip-build + '' + + lib.optionalString (yarnVersion == 1) '' + yarnLock=''${yarnLock:=$PWD/yarn.lock} + (cd $out; prefetch-yarn-deps --verbose --builder $yarnLock) + '' + + '' + runHook postBuild + ''; + outputHashMode = "recursive"; } // hash_ @@ -174,6 +221,28 @@ in }; } ./yarn-config-hook.sh; + yarnBerry3ConfigHook = makeSetupHook { + name = "yarn-config-hook"; + propagatedBuildInputs = [ yarn-berry3 ]; + substitutions = { + yarn = lib.getExe yarn-berry3; + }; + meta = { + description = "Install nodejs dependencies from an offline yarn berry cache (version 3)"; + }; + } ./yarn-berry-config-hook.sh; + + yarnBerry4ConfigHook = makeSetupHook { + name = "yarn-config-hook"; + propagatedBuildInputs = [ yarn-berry4 ]; + substitutions = { + yarn = lib.getExe yarn-berry4; + }; + meta = { + description = "Install nodejs dependencies from an offline yarn berry cache (version 4)"; + }; + } ./yarn-berry-config-hook.sh; + yarnBuildHook = makeSetupHook { name = "yarn-build-hook"; meta = { diff --git a/pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/package.json b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/package.json new file mode 100644 index 0000000000000..418b021a0049b --- /dev/null +++ b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/package.json @@ -0,0 +1,7 @@ +{ + "name": "yarn-testing", + "packageManager": "yarn@4.5.0", + "dependencies": { + "lit-html": "^3.2.1" + } +} diff --git a/pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/yarn.lock b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/yarn.lock new file mode 100644 index 0000000000000..136794fafb6af --- /dev/null +++ b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_3/yarn.lock @@ -0,0 +1,30 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 6 + cacheKey: 10c0 + +"@types/trusted-types@npm:^2.0.2": + version: 2.0.7 + resolution: "@types/trusted-types@npm:2.0.7" + checksum: 4c4855f10de7c6c135e0d32ce462419d8abbbc33713b31d294596c0cc34ae1fa6112a2f9da729c8f7a20707782b0d69da3b1f8df6645b0366d08825ca1522e0c + languageName: node + linkType: hard + +"lit-html@npm:^3.2.1": + version: 3.2.1 + resolution: "lit-html@npm:3.2.1" + dependencies: + "@types/trusted-types": "npm:^2.0.2" + checksum: 31c02df2148bf9a73545570cbe57aae01c4de1d9b44060b6ff13641837d38e39e6b1abcf92e13882cc84f5fee37605ed79602b91ad479728549014462808118e + languageName: node + linkType: hard + +"yarn-testing@workspace:.": + version: 0.0.0-use.local + resolution: "yarn-testing@workspace:." + dependencies: + lit-html: ^3.2.1 + languageName: unknown + linkType: soft diff --git a/pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/package.json b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/package.json new file mode 100644 index 0000000000000..418b021a0049b --- /dev/null +++ b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/package.json @@ -0,0 +1,7 @@ +{ + "name": "yarn-testing", + "packageManager": "yarn@4.5.0", + "dependencies": { + "lit-html": "^3.2.1" + } +} diff --git a/pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/yarn.lock b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/yarn.lock new file mode 100644 index 0000000000000..345fbe233cb82 --- /dev/null +++ b/pkgs/build-support/node/fetch-yarn-deps/tests/berry_4/yarn.lock @@ -0,0 +1,30 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@types/trusted-types@npm:^2.0.2": + version: 2.0.7 + resolution: "@types/trusted-types@npm:2.0.7" + checksum: 10c0/4c4855f10de7c6c135e0d32ce462419d8abbbc33713b31d294596c0cc34ae1fa6112a2f9da729c8f7a20707782b0d69da3b1f8df6645b0366d08825ca1522e0c + languageName: node + linkType: hard + +"lit-html@npm:^3.2.1": + version: 3.2.1 + resolution: "lit-html@npm:3.2.1" + dependencies: + "@types/trusted-types": "npm:^2.0.2" + checksum: 10c0/31c02df2148bf9a73545570cbe57aae01c4de1d9b44060b6ff13641837d38e39e6b1abcf92e13882cc84f5fee37605ed79602b91ad479728549014462808118e + languageName: node + linkType: hard + +"yarn-testing@workspace:.": + version: 0.0.0-use.local + resolution: "yarn-testing@workspace:." + dependencies: + lit-html: "npm:^3.2.1" + languageName: unknown + linkType: soft diff --git a/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix b/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix index 2d563dac87dc9..dda298b51a025 100644 --- a/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix +++ b/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix @@ -25,4 +25,14 @@ yarnLock = ./giturl.lock; sha256 = "sha256-VPnyqN6lePQZGXwR7VhbFnP7/0/LB621RZwT1F+KzVQ="; }; + berry_3 = testers.invalidateFetcherByDrvHash fetchYarnDeps { + src = ./berry_3; + yarnVersion = 3; + sha256 = "sha256-eiVOpRHuAS7zb6JpCzS3TIHbqQU+wCrMItzZGrE6Fbo="; + }; + berry_4 = testers.invalidateFetcherByDrvHash fetchYarnDeps { + src = ./berry_4; + yarnVersion = 4; + sha256 = "sha256-Eq37qKn5P7rkufJBhME0OG/3BsWlCsFYVnWHP5uVhAQ="; + }; } diff --git a/pkgs/build-support/node/fetch-yarn-deps/yarn-berry-config-hook.sh b/pkgs/build-support/node/fetch-yarn-deps/yarn-berry-config-hook.sh new file mode 100644 index 0000000000000..940362178d3b4 --- /dev/null +++ b/pkgs/build-support/node/fetch-yarn-deps/yarn-berry-config-hook.sh @@ -0,0 +1,30 @@ +yarnBerryConfigHook(){ + echo "Executing yarnBerryConfigHook" + + # Use a constant HOME directory + mkdir -p /tmp/home + export HOME=/tmp/home + if [[ -n "$yarnOfflineCache" ]]; then + offlineCache="$yarnOfflineCache" + fi + if [[ -z "$offlineCache" ]]; then + echo yarnConfigHook: No yarnOfflineCache or offlineCache were defined\! >&2 + exit 2 + fi + + export YARN_ENABLE_TELEMETRY=0 + yarn config set enableGlobalCache false + yarn config set enableScripts false + yarn config set cacheFolder "$offlineCache" + + yarn install --immutable --immutable-cache + + # TODO: Check if this is really needed + patchShebangs node_modules + + echo "finished yarnConfigHook" +} + +if [[ -z "${dontYarnInstallDeps-}" ]]; then + postConfigureHooks+=(yarnBerryConfigHook) +fi diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index b6aaf89004f43..14e7d8d14a540 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -521,6 +521,7 @@ with pkgs; prefetch-yarn-deps yarnConfigHook yarnBerry3ConfigHook + yarnBerry4ConfigHook yarnBuildHook yarnInstallHook fetchYarnDeps;