Support isolated builds with a combined cache

This commit is contained in:
Stéphan Kochen
2024-02-11 13:27:49 +01:00
parent ab15ad6804
commit 56e3459543
4 changed files with 41 additions and 24 deletions
+22 -17
View File
@@ -52,13 +52,6 @@ export default async (
return;
}
// Config validation.
const isolatedBuilds = configuration.get(`isolatedNixBuilds`);
const individualDrvs = configuration.get(`individualNixPackaging`);
if (isolatedBuilds.length > 0 && !individualDrvs) {
throw Error(`isolatedNixBuilds requires individualNixPackaging to be set`);
}
// Determine relative paths for Nix path literals.
const nixExprPath = configuration.get(`nixExprPath`);
@@ -157,6 +150,7 @@ export default async (
hash: string;
}
const cacheEntries = new Map<string, CacheEntry>();
const individualDrvs = configuration.get(`individualNixPackaging`);
let cacheEntriesCode = "";
let combinedHash = "";
if (individualDrvs) {
@@ -217,6 +211,7 @@ export default async (
}
// Generate Nix code for isolated builds.
const isolatedBuilds = configuration.get(`isolatedNixBuilds`);
let isolatedPackages = new Set<Package>();
let isolatedIntegration = [];
let isolatedCode = [];
@@ -332,19 +327,29 @@ export default async (
if (!isolatedPackages.has(devirtPkg)) {
isolatedPackages.add(devirtPkg);
const locators = [...collectTree(pkg)]
.sort()
.map((v) => `${json(v)}\n`)
.join(``);
const args = [
`pname = ${json(pkg.name)};`,
`version = ${json(pkg.version)};`,
`reference = ${json(devirtPkg.reference)};`,
];
// If packaging deps individually, depend on just
// the deps used during this isolated build.
if (individualDrvs) {
const locators = [...collectTree(pkg)]
.sort()
.map((v) => `${json(v)}\n`)
.join(``);
if (locators) {
args.push(`locators = [\n${locators}];`);
}
}
const overrideArg = `override${upperCamelize(pkg.name)}Attrs`;
isolatedCode.push(
`${isolatedProp} = optionalOverride (args.${overrideArg} or null) (mkIsolatedBuild { ${[
`pname = ${json(pkg.name)};`,
`version = ${json(pkg.version)};`,
`reference = ${json(devirtPkg.reference)};`,
`locators = [\n${locators}];`,
].join(` `)} });`,
`${isolatedProp} = optionalOverride (args.${overrideArg} or null) (mkIsolatedBuild { ${args.join(
` `,
)} });`,
);
}
+12 -3
View File
@@ -24,6 +24,8 @@ let
drvCommon = {
# Make sure the build uses the right Node.js version everywhere.
buildInputs = [ nodejs yarn ];
# All dependencies should already be cached.
yarn_enable_network = "0";
# Tell node-gyp to use the provided Node.js headers for native code builds.
npm_config_nodedir = nodejs;
};
@@ -80,14 +82,16 @@ let
#@@ ENDIF INDIVIDUAL_DRVS
#@@ IF NEED_ISOLATED_BUILD_SUPPRORT
#@@ IF INDIVIDUAL_DRVS
# Create a shell snippet to copy dependencies from a list of locators.
mkCacheBuilderForLocators = let
pickCacheDrvs = map (locator: cacheDrvs.${locator});
in locators:
mkCacheBuilderForDrvs (pickCacheDrvs locators);
#@@ ENDIF INDIVIDUAL_DRVS
# Create a derivation that builds a node-pre-gyp module in isolation.
mkIsolatedBuild = { pname, version, reference, locators }: stdenv.mkDerivation (drvCommon // {
# Create a derivation that builds a module in isolation.
mkIsolatedBuild = { pname, version, reference, locators ? [] }: stdenv.mkDerivation (drvCommon // {
inherit pname version;
dontUnpack = true;
@@ -98,16 +102,21 @@ let
buildPhase = ''
mkdir -p .yarn/cache
#@@ IF COMBINED_DRV
cp --reflink=auto --recursive ${cacheDrv}/* .yarn/cache/
#@@ ENDIF COMBINED_DRV
#@@ IF INDIVIDUAL_DRVS
pushd .yarn/cache > /dev/null
source ${mkCacheBuilderForLocators locators}
popd > /dev/null
#@@ ENDIF INDIVIDUAL_DRVS
echo '{ "dependencies": { "${pname}": "${reference}" } }' > package.json
install -m 0600 ${lockfile} ./yarn.lock
export yarn_global_folder="$TMP"
export yarn_enable_global_cache=false
export yarn_enable_immutable_installs=false
yarn --immutable-cache
yarn
'';
installPhase = ''