diff --git a/flake.nix b/flake.nix index 5d93396f..832bfb9b 100644 --- a/flake.nix +++ b/flake.nix @@ -77,6 +77,7 @@ inherit (pkgs) lib; inherit (pkgs) mkPnpmPackage; inherit callPackage dream2nix pkgs; + inherit (callPackage ./pkgs/build-support/node/fetch-pnpm-deps { }) fetchPnpmDeps pnpmConfigHook; }; explicitPkgs = import ./pkgs { diff --git a/pkgs/build-support/node/fetch-pnpm-deps/default.nix b/pkgs/build-support/node/fetch-pnpm-deps/default.nix new file mode 100644 index 00000000..dc2de38f --- /dev/null +++ b/pkgs/build-support/node/fetch-pnpm-deps/default.nix @@ -0,0 +1,73 @@ +{ lib +, stdenvNoCC +, nodePackages +, jq +, moreutils +, cacert +, makeSetupHook +}: { + fetchPnpmDeps = + { src + , hash ? "" + , pname + , pnpm ? nodePackages.pnpm + , ... + } @ args: + let + args' = builtins.removeAttrs args [ "hash" "pname" "pnpm" "supportedArchitectures" ]; + hash' = + if hash != "" then { + outputHash = hash; + } else { + outputHash = ""; + outputHashAlgo = "sha256"; + }; + in + # NOTE: This requires pnpm 8.10.0 or newer + # https://github.com/pnpm/pnpm/pull/7214 + assert lib.versionAtLeast pnpm.version "8.10.0"; + stdenvNoCC.mkDerivation (args' // { + name = "${pname}-pnpm-deps"; + + nativeBuildInputs = [ + jq + moreutils + pnpm + cacert + ]; + + # https://github.com/NixOS/nixpkgs/blob/763e59ffedb5c25774387bf99bc725df5df82d10/pkgs/applications/misc/pot/default.nix#L56 + installPhase = '' + runHook preInstall + + export HOME=$(mktemp -d) + pnpm config set store-dir $out + # pnpm is going to warn us about using --force + # --force allows us to fetch all dependencies including ones that aren't meant for our host platform + pnpm install --frozen-lockfile --ignore-script --force + + runHook postInstall + ''; + + fixupPhase = '' + runHook preFixup + + rm -rf $out/v3/tmp + for f in $(find $out -name "*.json"); do + sed -i -E -e 's/"checkedAt":[0-9]+,//g' $f + jq --sort-keys . $f | sponge $f + done + + runHook postFixup + ''; + + dontConfigure = true; + dontBuild = true; + outputHashMode = "recursive"; + } // hash'); + + pnpmConfigHook = makeSetupHook + { + name = "pnpm-config-hook"; + } ./pnpm-config-hook.sh; +} diff --git a/pkgs/build-support/node/fetch-pnpm-deps/pnpm-config-hook.sh b/pkgs/build-support/node/fetch-pnpm-deps/pnpm-config-hook.sh new file mode 100644 index 00000000..db87532f --- /dev/null +++ b/pkgs/build-support/node/fetch-pnpm-deps/pnpm-config-hook.sh @@ -0,0 +1,36 @@ +# shellcheck shell=bash + +pnpmConfigHook() { + echo "Executing pnpmConfigHook" + + if [ -z "${pnpmDeps-}" ]; then + echo "Error: 'npmDeps' should be set when using npmConfigHook." + exit 1 + fi + + echo "Configuring pnpm store" + + export HOME=$(mktemp -d) + export STORE_PATH=$(mktemp -d) + + cp -Tr "$pnpmDeps" "$STORE_PATH" + chmod -R +w "$STORE_PATH" + + pnpm config set store-dir "$STORE_PATH" + + echo "Installing dependencies" + + if ! pnpm install --offline --frozen-lockfile --ignore-script; then + echo + echo "ERROR: pnpm failed to install dependencies" + echo + + exit 1 + fi + + patchShebangs node_modules/{*,.*} + + echo "Finished pnpmConfigHook" +} + +postConfigureHooks+=(pnpmConfigHook) diff --git a/pkgs/by-name/atomic-browser/package.nix b/pkgs/by-name/atomic-browser/package.nix index 21f787be..390da48b 100644 --- a/pkgs/by-name/atomic-browser/package.nix +++ b/pkgs/by-name/atomic-browser/package.nix @@ -1,7 +1,10 @@ { + mkDerivation, fetchFromGitHub, lib, mkPnpmPackage, + fetchPnpmDeps, + pnpmConfigHook, }: let inherit (lib) @@ -9,7 +12,7 @@ maintainers ; in -mkPnpmPackage rec { +mkDerivation rec { pname = "atomic-browser"; version = "v0.37.0"; @@ -21,11 +24,17 @@ mkPnpmPackage rec { }; src = "${monorepoSrc}/browser"; + pnpmDeps = fetchPnpmDeps { + inherit src pname; + hash = ""; + }; + + nativeBuildInputs = [ pnpmConfigHook ]; # These 2 options are needed to work with pnpm workspaces, which atomic-browser is using # https://github.com/nzbr/pnpm2nix-nzbr/issues/29#issuecomment-1918811838 - installInPlace = true; - distDir = "."; + #installInPlace = true; + #distDir = "."; meta = { description = "Create, share, fetch and model linked Atomic Data! There are three components: a javascript / typescript library, a react library, and a complete GUI: Atomic-Data Browser."; diff --git a/pkgs/by-name/default.nix b/pkgs/by-name/default.nix index 6caf1122..a1db4ecb 100644 --- a/pkgs/by-name/default.nix +++ b/pkgs/by-name/default.nix @@ -3,6 +3,8 @@ callPackage, dream2nix, mkPnpmPackage, + fetchPnpmDeps, + pnpmConfigHook, pkgs, }: let baseDirectory = ./.; @@ -49,7 +51,7 @@ mapAttrs ( _: directory: if pathExists (directory + "/package.nix") - then callPackage (directory + "/package.nix") {} + then callPackage (directory + "/package.nix") { } else if pathExists (directory + "/dream2.nix") then callModule (directory + "/dream2.nix") else throw "No package.nix or dream2.nix found in ${directory}"