Files
yarn-plugin-nixify-patched/src/tmpl/yarn-project.nix.in
T
2023-01-23 14:48:37 +01:00

208 lines
6.5 KiB
Plaintext

# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!
{ lib, stdenv, nodejs, git, cacert, fetchurl, writeShellScript, writeShellScriptBin }:
{ src, overrideAttrs ? null, ... } @ args:
let
cacheFolder = @@CACHE_FOLDER@@;
#@@ IF NEED_ISOLATED_BUILD_SUPPRORT
lockfile = ./@@LOCKFILE@@;
#@@ ENDIF NEED_ISOLATED_BUILD_SUPPRORT
# Call overrideAttrs on a derivation if a function is provided.
optionalOverride = fn: drv:
if fn == null then drv else drv.overrideAttrs fn;
# Simple stub that provides the global yarn command.
yarn = writeShellScriptBin "yarn" ''
exec '${nodejs}/bin/node' '${./@@YARN_PATH@@}' "$@"
'';
# Common attributes between Yarn derivations.
drvCommon = {
# Make sure the build uses the right Node.js version everywhere.
buildInputs = [ nodejs yarn ];
# Tell node-gyp to use the provided Node.js headers for native code builds.
npm_config_nodedir = nodejs;
};
# Comman variables that we set in a Nix build, but not in a Nix shell.
buildVars = ''
# Make Yarn produce friendlier logging for automated builds.
export CI=1
# Tell node-pre-gyp to never fetch binaries / always build from source.
export npm_config_build_from_source=true
# Disable Nixify plugin to save on some unnecessary processing.
export yarn_enable_nixify=false
'';
# Create derivations for fetching dependencies.
cacheDrvs = let
builder = writeShellScript "yarn-cache-builder" ''
source $stdenv/setup
cd "$src"
${buildVars}
HOME="$TMP" yarn_cache_folder="$TMP" \
yarn nixify fetch-one $locator
# Because we change the cache dir, Yarn may generate a different name.
mv "$TMP/$(sed 's/-[^-]*\.[^-]*$//' <<< "$outputFilename")"-* $out
'';
in lib.mapAttrs (locator: { filename, sha512 }: stdenv.mkDerivation {
inherit src builder locator;
name = lib.strings.sanitizeDerivationName locator;
buildInputs = [ yarn git cacert ];
outputFilename = filename;
outputHashMode = "flat";
outputHashAlgo = "sha512";
outputHash = sha512;
}) cacheEntries;
# Create a shell snippet to copy dependencies from a list of derivations.
mkCacheBuilderForDrvs = drvs:
writeShellScript "collect-yarn-cache" (lib.concatMapStrings (drv: ''
cp ${drv} '${drv.outputFilename}'
'') drvs);
#@@ IF NEED_ISOLATED_BUILD_SUPPRORT
# Create a shell snippet to copy dependencies from a list of locators.
mkCacheBuilderForLocators = let
pickCacheDrvs = map (locator: cacheDrvs.${locator});
in locators:
mkCacheBuilderForDrvs (pickCacheDrvs locators);
# Create a derivation that builds a node-pre-gyp module in isolation.
mkIsolatedBuild = { pname, version, reference, locators }: stdenv.mkDerivation (drvCommon // {
inherit pname version;
dontUnpack = true;
configurePhase = ''
${buildVars}
unset yarn_enable_nixify # plugin is not present
'';
buildPhase = ''
mkdir -p .yarn/cache
pushd .yarn/cache > /dev/null
source ${mkCacheBuilderForLocators locators}
popd > /dev/null
echo '{ "dependencies": { "${pname}": "${reference}" } }' > package.json
install -m 0600 ${lockfile} ./yarn.lock
export yarn_global_folder="$TMP"
export YARN_ENABLE_IMMUTABLE_INSTALLS=false
yarn --immutable-cache
'';
installPhase = ''
unplugged=( .yarn/unplugged/${pname}-*/node_modules/* )
if [[ ! -e "''${unplugged[@]}" ]]; then
echo >&2 "Could not find the unplugged path for ${pname}"
exit 1
fi
mv "$unplugged" $out
'';
});
#@@ ENDIF NEED_ISOLATED_BUILD_SUPPRORT
# Main project derivation.
project = stdenv.mkDerivation (drvCommon // {
inherit src;
name = @@PROJECT_NAME@@;
configurePhase = ''
${buildVars}
# Copy over the Yarn cache.
rm -fr '${cacheFolder}'
mkdir -p '${cacheFolder}'
pushd '${cacheFolder}' > /dev/null
source ${mkCacheBuilderForDrvs (lib.attrValues cacheDrvs)}
popd > /dev/null
# Yarn may need a writable home directory.
export yarn_global_folder="$TMP"
# Some node-gyp calls may call out to npm, which could fail due to an
# read-only home dir.
export HOME="$TMP"
# running preConfigure after the cache is populated allows for
# preConfigure to contain substituteInPlace for dependencies as well as the
# main project. This is necessary for native bindings that maybe have
# hardcoded values.
runHook preConfigure
@@ISOLATED_INTEGRATION@@
# Run normal Yarn install to complete dependency installation.
yarn install --immutable --immutable-cache
runHook postConfigure
'';
buildPhase = ''
runHook preBuild
runHook postBuild
'';
installPhase = ''
runHook preInstall
# Move the package contents to the output directory.
if grep -q '"workspaces"' package.json; then
# We can't use `yarn pack` in a workspace setup, because it only
# packages the outer workspace.
mkdir -p "$out/libexec"
mv $PWD "$out/libexec/$name"
else
# - If the package.json has a `files` field, only files matching those patterns are copied
# - Otherwise all files are copied.
yarn pack --out package.tgz
mkdir -p "$out/libexec/$name"
tar xzvf package.tgz --directory "$out/libexec/$name" --strip-components=1
cp .yarnrc* '@@LOCKFILE@@' "$out/libexec/$name"
cp --recursive .yarn "$out/libexec/$name"
# If the project uses the node-modules linker, then
# include the node_modules folder in the package.
if [ -d node_modules ]; then
cp --recursive node_modules "$out/libexec/$name"
else
# Otherwise, assume PnP. Copy the loader into the package.
cp .pnp.* "$out/libexec/$name"
fi
fi
cd "$out/libexec/$name"
# Invoke a plugin internal command to setup binaries.
mkdir -p "$out/bin"
yarn nixify install-bin $out/bin
# A package with node_modules doesn't need the cache
if [ -d node_modules ]; then
yarn cache clean
fi
runHook postInstall
'';
passthru = {
inherit nodejs;
yarn-freestanding = yarn;
yarn = writeShellScriptBin "yarn" ''
exec '${yarn}/bin/yarn' --cwd '${overriddenProject}/libexec/${overriddenProject.name}' "$@"
'';
};
});
overriddenProject = optionalOverride overrideAttrs project;
@@CACHE_ENTRIES@@
@@ISOLATED@@
in overriddenProject