diff --git a/crates/turborepo-lib/src/run/mod.rs b/crates/turborepo-lib/src/run/mod.rs index 2b8d352e03227..0d9a814dfa926 100644 --- a/crates/turborepo-lib/src/run/mod.rs +++ b/crates/turborepo-lib/src/run/mod.rs @@ -266,7 +266,8 @@ impl Run { get_internal_deps_hash( &self.scm, &self.repo_root, - self.pkg_dep_graph.root_internal_package_dependencies(), + self.pkg_dep_graph + .root_internal_package_dependencies_paths(), ) }) .transpose()?; diff --git a/crates/turborepo-repository/src/change_mapper/mod.rs b/crates/turborepo-repository/src/change_mapper/mod.rs index c31f96b26010d..02aca3a9cf6e4 100644 --- a/crates/turborepo-repository/src/change_mapper/mod.rs +++ b/crates/turborepo-repository/src/change_mapper/mod.rs @@ -103,9 +103,14 @@ impl<'a, PD: PackageChangeMapper> ChangeMapper<'a, PD> { &self, files: impl Iterator, ) -> PackageChanges { + let root_internal_deps = self.pkg_graph.root_internal_package_dependencies(); let mut changed_packages = HashSet::new(); for file in files { match self.package_detector.detect_package(file) { + // Internal root dependency changed so global hash has changed + PackageMapping::Package(pkg) if root_internal_deps.contains(&pkg) => { + return PackageChanges::All; + } PackageMapping::Package(pkg) => { changed_packages.insert(pkg); } diff --git a/crates/turborepo-repository/src/package_graph/mod.rs b/crates/turborepo-repository/src/package_graph/mod.rs index c711cfe9fde9f..aafb9682013f5 100644 --- a/crates/turborepo-repository/src/package_graph/mod.rs +++ b/crates/turborepo-repository/src/package_graph/mod.rs @@ -279,7 +279,26 @@ impl PackageGraph { dependents } - pub fn root_internal_package_dependencies(&self) -> Vec<&AnchoredSystemPath> { + pub fn root_internal_package_dependencies(&self) -> HashSet { + let dependencies = self.dependencies(&PackageNode::Workspace(PackageName::Root)); + dependencies + .into_iter() + .filter_map(|package| match package { + PackageNode::Workspace(package) => { + let path = self + .package_dir(package) + .expect("packages in graph should have info"); + Some(WorkspacePackage { + name: package.clone(), + path: path.to_owned(), + }) + } + PackageNode::Root => None, + }) + .collect() + } + + pub fn root_internal_package_dependencies_paths(&self) -> Vec<&AnchoredSystemPath> { let dependencies = self.dependencies(&PackageNode::Workspace(PackageName::Root)); dependencies .into_iter() diff --git a/turborepo-tests/integration/tests/run-caching/root-deps.t b/turborepo-tests/integration/tests/run-caching/root-deps.t index 646f5b5ebd3bc..7e76ecbe70bb9 100644 --- a/turborepo-tests/integration/tests/run-caching/root-deps.t +++ b/turborepo-tests/integration/tests/run-caching/root-deps.t @@ -1,6 +1,10 @@ Setup $ . ${TESTDIR}/../../../helpers/setup_integration_test.sh root_deps +Verify that no packages are in scope + $ ${TURBO} build --filter='[HEAD]' --dry=json | jq '.packages' + [] + Warm the cache $ ${TURBO} build --filter=another --output-logs=hash-only \xe2\x80\xa2 Packages in scope: another (esc) @@ -40,6 +44,16 @@ All tasks should be a cache miss, even ones that don't depend on changed package Time:\s+[.0-9]+m?s (re) +Verify that all packages are in scope on a internal root dep change + $ ${TURBO} build --filter='[HEAD]' --dry=json | jq '.packages' + [ + "//", + "another", + "my-app", + "util", + "yet-another" + ] + Change a file that is git ignored $ mkdir packages/util/dist $ touch packages/util/dist/unused.txt