From 111da50beefb4f45d26761ea14cf9cb2f862722b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Kochen?= Date: Mon, 24 Aug 2020 20:31:05 +0200 Subject: [PATCH] Use a copy of the cache to avoid issues --- src/index.ts | 18 ++++++++++++++---- src/yarn-project.nix.in | 35 +++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index 196f7e6..dde3644 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,7 @@ import projectExprTmpl from "./yarn-project.nix.in"; const generate = async (project: Project, report: Report) => { const { configuration, cwd } = project; const yarnPathAbs = configuration.get(`yarnPath`); + const cacheFolderAbs = configuration.get(`cacheFolder`); const lockfileFilename = configuration.get(`lockfileFilename`); // TODO: Should try to remove this. Our binary wrappers currently do @@ -40,7 +41,16 @@ const generate = async (project: Project, report: Report) => { yarnPath = yarnPathAbs; report.reportWarning( 0, - `The Yarn path ${yarnPathAbs} is outside the project directory - it cannot be reached by the Nix build` + `The Yarn path ${yarnPathAbs} is outside the project - it may not be reachable by the Nix build` + ); + } + + let cacheFolder = ppath.relative(cwd, cacheFolderAbs); + if (cacheFolder.startsWith(`../`)) { + cacheFolder = cacheFolderAbs; + report.reportWarning( + 0, + `The cache folder ${cacheFolderAbs} is outside the project - it may not be reachable by the Nix build` ); } @@ -74,7 +84,7 @@ const generate = async (project: Project, report: Report) => { if (inputPath !== yarnPath) { report.reportWarning( 0, - `The path ${inputPath} is outside the project directory and was ignored - it may not be reachable in the Nix build` + `The path ${inputPath} is outside the project and was ignored - it may not be reachable in the Nix build` ); } continue; @@ -91,7 +101,6 @@ const generate = async (project: Project, report: Report) => { // Build the Nix output-hash by hashing the Yarn cache folder. The // derivation should build the exact same. - const cacheFolder = configuration.get(`cacheFolder`); let cacheHash = ``; try { const hasherResult = await execUtils.execvp( @@ -116,7 +125,8 @@ const generate = async (project: Project, report: Report) => { const projectName = ident ? structUtils.stringifyIdent(ident) : `workspace`; const projectExpr = projectExprTmpl .replace(`@@PROJECT_NAME@@`, JSON.stringify(projectName)) - .replace(`@@OFFLINE_CACHE_HASH@@`, JSON.stringify(cacheHash)) + .replace(`@@CACHE_FOLDER@@`, JSON.stringify(cacheFolder)) + .replace(`@@CACHE_HASH@@`, JSON.stringify(cacheHash)) .replace(`@@YARN_PATH@@`, JSON.stringify(yarnPath)) .replace( `@@YARN_CLOSURE_ENTRIES@@`, diff --git a/src/yarn-project.nix.in b/src/yarn-project.nix.in index cca2bcc..bef9021 100644 --- a/src/yarn-project.nix.in +++ b/src/yarn-project.nix.in @@ -9,7 +9,8 @@ let # Variables provided by the generator. project-name = @@PROJECT_NAME@@; - offline-cache-hash = @@OFFLINE_CACHE_HASH@@; + cache-folder = @@CACHE_FOLDER@@; + cache-hash = @@CACHE_HASH@@; yarn-path = @@YARN_PATH@@; yarn-closure-entries = @@YARN_CLOSURE_ENTRIES@@; @@ -30,13 +31,13 @@ let elem "${type}:${srcRel path}" yarn-closure-entries; }; - # Build just the offline cache for the project. + # Build just the cache for the project. offline-cache = stdenv.mkDerivation { name = "${project-name}-offline-cache"; buildInputs = [ nodejs ]; builder = writeText "builder.sh" '' source $stdenv/setup - cd ${yarn-closure} + cd '${yarn-closure}' # Yarn may need a writable home directory for the global cache mirror. # TODO: Can't disable the mirror, because it changes cache filenames. @@ -51,7 +52,7 @@ let ''; outputHashMode = "recursive"; outputHashAlgo = "sha256"; - outputHash = offline-cache-hash; + outputHash = cache-hash; }; in stdenv.mkDerivation { @@ -72,18 +73,15 @@ in stdenv.mkDerivation { configurePhase = '' runHook preConfigure - # Move the entire project to the output directory. - # TODO: Would rather do this in 'installPhase', - # but '.pnp.js' is generated with relative paths. - mkdir -p $out/libexec $out/bin - mv $PWD "$out/libexec/$sourceRoot" - cd "$out/libexec/$sourceRoot" + # Copy over the Yarn cache. + # TODO: Can we do without the copy somehow? + rm -fr '${cache-folder}' + mkdir -p "$(dirname '${cache-folder}')" + cp -r '${offline-cache}' '${cache-folder}' + chmod -R u+w '${cache-folder}' # Store the absolute path to Yarn for the 'yarn' alias. - export NIX_YARN_PATH="$(readlink -f ${yarn-path})" - - # Point Yarn to the offline cache built separately. - yarn config set cacheFolder '${offline-cache}' + export NIX_YARN_PATH="$(readlink -f '${yarn-path}')" # Run normal Yarn install to complete dependency installation. yarn install --immutable --immutable-cache @@ -99,6 +97,15 @@ in stdenv.mkDerivation { installPhase = '' runHook preInstall + mkdir -p $out/libexec $out/bin + + # Move the entire project to the output directory. + mv $PWD "$out/libexec/$sourceRoot" + cd "$out/libexec/$sourceRoot" + + # Update the path to Yarn. + export NIX_YARN_PATH="$(readlink -f '${yarn-path}')" + # Invoke a plugin internal command to setup binaries. yarn nixify install-bin $out/bin