Merge pull request #243458 from lilyinstarlight/fix/prefetch-npm-deps-error-when-no-cached-deps

This commit is contained in:
Janik 2023-11-23 13:55:03 +01:00 committed by GitHub
commit 8e2c9abca8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 7 deletions

View file

@ -21,6 +21,9 @@
# Whether to force the usage of Git dependencies that have install scripts, but not a lockfile.
# Use with care.
, forceGitDeps ? false
# Whether to force allow an empty dependency cache.
# This can be enabled if there are truly no remote dependencies, but generally an empty cache indicates something is wrong.
, forceEmptyCache ? false
# Whether to make the cache writable prior to installing dependencies.
# Don't set this unless npm tries to write to the cache directory, as it can slow down the build.
, makeCacheWritable ? false
@ -42,7 +45,7 @@
, npmWorkspace ? null
, nodejs ? topLevelArgs.nodejs
, npmDeps ? fetchNpmDeps {
inherit forceGitDeps src srcs sourceRoot prePatch patches postPatch;
inherit forceGitDeps forceEmptyCache src srcs sourceRoot prePatch patches postPatch;
name = "${name}-npm-deps";
hash = npmDepsHash;
}

View file

@ -36,8 +36,8 @@
'';
};
makeTest = { name, src, hash, forceGitDeps ? false }: testers.invalidateFetcherByDrvHash fetchNpmDeps {
inherit name hash forceGitDeps;
makeTest = { name, src, hash, forceGitDeps ? false, forceEmptyCache ? false }: testers.invalidateFetcherByDrvHash fetchNpmDeps {
inherit name hash forceGitDeps forceEmptyCache;
src = makeTestSrc { inherit name src; };
};
@ -98,6 +98,20 @@
hash = "sha256-VzQhArHoznYSXUT7l9HkJV4yoSOmoP8eYTLel1QwmB4=";
};
# This package has no resolved deps whatsoever, which will not actually work but does test the forceEmptyCache option.
emptyCache = makeTest {
name = "empty-cache";
src = fetchurl {
url = "https://raw.githubusercontent.com/bufbuild/protobuf-es/v1.2.1/package-lock.json";
hash = "sha256-UdBUEb4YRHsbvyjymIyjemJEiaI9KQRirqt+SFSK0wA=";
};
hash = "sha256-Cdv40lQjRszzJtJydZt25uYfcJVeJGwH54A+agdH9wI=";
forceEmptyCache = true;
};
# This package contains both hosted Git shorthand, and a bundled dependency that happens to override an existing one.
etherpadLite1818 = makeTest {
name = "etherpad-lite-1.8.18";
@ -124,6 +138,7 @@
{ name ? "npm-deps"
, hash ? ""
, forceGitDeps ? false
, forceEmptyCache ? false
, ...
} @ args:
let
@ -136,6 +151,7 @@
};
forceGitDeps_ = lib.optionalAttrs forceGitDeps { FORCE_GIT_DEPS = true; };
forceEmptyCache_ = lib.optionalAttrs forceEmptyCache { FORCE_EMPTY_CACHE = true; };
in
stdenvNoCC.mkDerivation (args // {
inherit name;
@ -174,5 +190,5 @@
else "/no-cert-file.crt";
outputHashMode = "recursive";
} // hash_ // forceGitDeps_);
} // hash_ // forceGitDeps_ // forceEmptyCache_);
}

View file

@ -43,6 +43,13 @@ impl Cache {
Cache(path)
}
pub fn init(&self) -> anyhow::Result<()> {
fs::create_dir_all(self.0.join("content-v2"))?;
fs::create_dir_all(self.0.join("index-v5"))?;
Ok(())
}
pub fn put(
&self,
key: String,

View file

@ -234,9 +234,14 @@ fn main() -> anyhow::Result<()> {
(out_tempdir.path(), true)
};
let packages = parse::lockfile(&lock_content, env::var("FORCE_GIT_DEPS").is_ok())?;
let packages = parse::lockfile(
&lock_content,
env::var("FORCE_GIT_DEPS").is_ok(),
env::var("FORCE_EMPTY_CACHE").is_ok(),
)?;
let cache = Cache::new(out.join("_cacache"));
cache.init()?;
packages.into_par_iter().try_for_each(|package| {
eprintln!("{}", package.name);

View file

@ -14,7 +14,11 @@ use crate::util;
pub mod lock;
pub fn lockfile(content: &str, force_git_deps: bool) -> anyhow::Result<Vec<Package>> {
pub fn lockfile(
content: &str,
force_git_deps: bool,
force_empty_cache: bool,
) -> anyhow::Result<Vec<Package>> {
let mut packages = lock::packages(content)
.context("failed to extract packages from lockfile")?
.into_par_iter()
@ -25,6 +29,10 @@ pub fn lockfile(content: &str, force_git_deps: bool) -> anyhow::Result<Vec<Packa
})
.collect::<anyhow::Result<Vec<_>>>()?;
if packages.is_empty() && !force_empty_cache {
bail!("No cacheable dependencies were found. Please inspect the upstream `package-lock.json` file and ensure that remote dependencies have `resolved` URLs and `integrity` hashes. If the lockfile is missing this data, attempt to get upstream to fix it via a tool like <https://github.com/jeslie0/npm-lockfile-fix>. If generating an empty cache is intentional and you would like to do it anyways, set `forceEmptyCache = true`.");
}
let mut new = Vec::new();
for pkg in packages
@ -64,7 +72,13 @@ pub fn lockfile(content: &str, force_git_deps: bool) -> anyhow::Result<Vec<Packa
}
if let Ok(lockfile_contents) = lockfile_contents {
new.append(&mut lockfile(&lockfile_contents, force_git_deps)?);
new.append(&mut lockfile(
&lockfile_contents,
force_git_deps,
// force_empty_cache is turned on here since recursively parsed lockfiles should be
// allowed to have an empty cache without erroring by default
true,
)?);
}
}