Unverified Commit 8e2c9abc authored by Janik's avatar Janik Committed by GitHub
Browse files

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

parents f880f6ba 8e3009d9
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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;
}
+19 −3
Original line number Diff line number Diff line
@@ -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_);
}
+7 −0
Original line number Diff line number Diff line
@@ -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,
+6 −1
Original line number Diff line number Diff line
@@ -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);
+16 −2
Original line number Diff line number Diff line
@@ -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,
            )?);
        }
    }