Isolated builds of dependencies
This commit is contained in:
+108
-66
@@ -1,103 +1,145 @@
|
||||
# This file is generated by running "yarn install" inside your project.
|
||||
# Manual changes might be lost - proceed with caution!
|
||||
|
||||
{ lib, coreutils, nodejs, stdenv, writeText }: src:
|
||||
{ lib, nodejs, stdenv, fetchurl, writeText }:
|
||||
{ src, overrideAttrs ? null, ... } @ args:
|
||||
|
||||
let
|
||||
|
||||
yarnPath = @@YARN_PATH@@;
|
||||
yarnPath = ./@@YARN_PATH@@;
|
||||
lockfile = ./@@LOCKFILE@@;
|
||||
cacheFolder = @@CACHE_FOLDER@@;
|
||||
cacheEntries = @@CACHE_ENTRIES@@;
|
||||
|
||||
# Fetch a single dependency.
|
||||
fetchOne = let
|
||||
# Call overrideAttrs on a derivation if a function is provided.
|
||||
optionalOverride = fn: drv:
|
||||
if fn == null then drv else drv.overrideAttrs fn;
|
||||
|
||||
# Common attributes between Yarn derivations.
|
||||
drvCommon = {
|
||||
# Make sure the build uses the right Node.js version everywhere.
|
||||
buildInputs = [ nodejs ];
|
||||
# Tell node-gyp to use the provided Node.js headers for native code builds.
|
||||
npm_config_nodedir = nodejs;
|
||||
# Tell node-pre-gyp to never fetch binaries / always build from source.
|
||||
npm_config_build_from_source = "true";
|
||||
# Defines the shell alias to run Yarn.
|
||||
postHook = ''
|
||||
yarn() {
|
||||
CI=1 node "${yarnPath}" "$@"
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# Create derivations for fetching dependencies.
|
||||
cacheDrvs = let
|
||||
builder = builtins.toFile "builder.sh" ''
|
||||
source $stdenv/setup
|
||||
cd "$src"
|
||||
HOME="$TMP" yarn_cache_folder="$TMP" CI=1 \
|
||||
node '${yarnPath}' nixify fetch-one $locatorHash
|
||||
node '${yarnPath}' nixify fetch-one $locator
|
||||
mv "$TMP/$outputFilename" $out
|
||||
'';
|
||||
in { name, filename, sha512, locatorHash }: stdenv.mkDerivation {
|
||||
inherit name src builder locatorHash;
|
||||
in lib.mapAttrs (locator: { filename, sha512 }: stdenv.mkDerivation {
|
||||
inherit src builder locator;
|
||||
name = lib.strings.sanitizeDerivationName locator;
|
||||
buildInputs = [ nodejs ];
|
||||
outputFilename = filename;
|
||||
outputHashMode = "flat";
|
||||
outputHashAlgo = "sha512";
|
||||
outputHash = sha512;
|
||||
};
|
||||
}) cacheEntries;
|
||||
|
||||
# Shell snippet to collect all project dependencies.
|
||||
collectCacheScript = writeText "collect-cache.sh" (
|
||||
lib.concatMapStrings (args: ''
|
||||
cp ${fetchOne args} '${args.filename}'
|
||||
'') cacheEntries
|
||||
);
|
||||
# Create a shell snippet to copy dependencies from a list of derivations.
|
||||
mkCacheBuilderForDrvs = drvs:
|
||||
writeText "collect-cache.sh" (lib.concatMapStrings (drv: ''
|
||||
cp ${drv} '${drv.outputFilename}'
|
||||
'') drvs);
|
||||
|
||||
in stdenv.mkDerivation {
|
||||
name = @@PROJECT_NAME@@;
|
||||
inherit src;
|
||||
#@@ 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);
|
||||
|
||||
# Disable Nixify plugin to save on some unnecessary processing.
|
||||
yarn_enable_nixify = "false";
|
||||
# Tell node-gyp to use the provided Node.js headers for native code builds.
|
||||
npm_config_nodedir = nodejs;
|
||||
# Tell node-pre-gyp to never fetch binaries / always build from source.
|
||||
npm_config_build_from_source = "true";
|
||||
# Create a derivation that builds a node-pre-gyp module in isolation.
|
||||
mkIsolatedBuild = { pname, version, locators }: stdenv.mkDerivation (drvCommon // {
|
||||
inherit pname version;
|
||||
phases = [ "buildPhase" "installPhase" ];
|
||||
|
||||
# Make sure the build uses the right Node.js version everywhere.
|
||||
buildInputs = [ nodejs ];
|
||||
buildPhase = ''
|
||||
mkdir -p .yarn/cache
|
||||
pushd .yarn/cache > /dev/null
|
||||
source ${mkCacheBuilderForLocators locators}
|
||||
popd > /dev/null
|
||||
|
||||
# Defines the shell alias to run Yarn.
|
||||
postHook = ''
|
||||
yarn() {
|
||||
CI=1 node "$NIX_YARN_PATH" "$@"
|
||||
}
|
||||
'';
|
||||
echo '{ "dependencies": { "${pname}": "${version}" } }' > package.json
|
||||
install -m 0600 ${lockfile} ./yarn.lock
|
||||
yarn --immutable-cache
|
||||
'';
|
||||
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
installPhase = ''
|
||||
unplugged=( .yarn/unplugged/${pname}-*/node_modules/* )
|
||||
if [[ ! -e "''${unplugged[@]}" ]]; then
|
||||
echo >&2 "Could not find the unplugged path for ${pname}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy over the Yarn cache.
|
||||
rm -fr '${cacheFolder}'
|
||||
mkdir -p '${cacheFolder}'
|
||||
pushd '${cacheFolder}' > /dev/null
|
||||
source ${collectCacheScript}
|
||||
popd > /dev/null
|
||||
mv "$unplugged" $out
|
||||
'';
|
||||
});
|
||||
#@@ ENDIF NEED_ISOLATED_BUILD_SUPPRORT
|
||||
|
||||
# Store the absolute path to Yarn for the 'yarn' alias.
|
||||
export NIX_YARN_PATH="$(readlink -f '${yarnPath}')"
|
||||
# Main project derivation.
|
||||
project = stdenv.mkDerivation (drvCommon // {
|
||||
inherit src;
|
||||
name = @@PROJECT_NAME@@;
|
||||
# Disable Nixify plugin to save on some unnecessary processing.
|
||||
yarn_enable_nixify = "false";
|
||||
|
||||
# Run normal Yarn install to complete dependency installation.
|
||||
yarn install --immutable --immutable-cache
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
# Copy over the Yarn cache.
|
||||
rm -fr '${cacheFolder}'
|
||||
mkdir -p '${cacheFolder}'
|
||||
pushd '${cacheFolder}' > /dev/null
|
||||
source ${mkCacheBuilderForDrvs (lib.attrValues cacheDrvs)}
|
||||
popd > /dev/null
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
runHook postBuild
|
||||
'';
|
||||
@@ISOLATED_INTEGRATION@@
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
# Run normal Yarn install to complete dependency installation.
|
||||
yarn install --immutable --immutable-cache
|
||||
|
||||
mkdir -p $out/libexec $out/bin
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
# Move the entire project to the output directory.
|
||||
mv $PWD "$out/libexec/$sourceRoot"
|
||||
cd "$out/libexec/$sourceRoot"
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
# Update the path to Yarn.
|
||||
export NIX_YARN_PATH="$(readlink -f '${yarnPath}')"
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
# Invoke a plugin internal command to setup binaries.
|
||||
yarn nixify install-bin $out/bin
|
||||
mkdir -p $out/libexec $out/bin
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
# Move the entire project to the output directory.
|
||||
mv $PWD "$out/libexec/$sourceRoot"
|
||||
cd "$out/libexec/$sourceRoot"
|
||||
|
||||
passthru = {
|
||||
inherit nodejs;
|
||||
};
|
||||
}
|
||||
# Invoke a plugin internal command to setup binaries.
|
||||
yarn nixify install-bin $out/bin
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit nodejs;
|
||||
};
|
||||
});
|
||||
|
||||
@@CACHE_ENTRIES@@
|
||||
@@ISOLATED@@
|
||||
in optionalOverride overrideAttrs project
|
||||
|
||||
Reference in New Issue
Block a user