Skip to content
56 changes: 47 additions & 9 deletions crates/turborepo-lib/src/run/scope/change_detector.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::collections::{HashMap, HashSet};
use std::{
collections::{HashMap, HashSet},
process,
};

use tracing::debug;
use turbopath::{AbsoluteSystemPath, AnchoredSystemPathBuf};
Expand All @@ -9,7 +12,7 @@ use turborepo_repository::{
},
package_graph::{PackageGraph, PackageName},
};
use turborepo_scm::{git::InvalidRange, SCM};
use turborepo_scm::{Error as ScmError, SCM, git::InvalidRange};

use crate::run::scope::ResolutionError;

Expand Down Expand Up @@ -80,6 +83,28 @@ impl<'a> ScopeChangeDetector<'a> {
debug!("lockfile changed, have the previous content");
LockfileContents::Changed(content)
}

fn all_packages_changed_due_to_error(
&self,
from_ref: Option<&str>,
to_ref: Option<&str>,
error_message: &str,
) -> Result<HashMap<PackageName, PackageInclusionReason>, ResolutionError> {
debug!("{}, defaulting to all packages changed", error_message);
Ok(self
.pkg_graph
.packages()
.map(|(name, _)| {
(
name.to_owned(),
PackageInclusionReason::All(AllPackageChangeReason::GitRefNotFound {
from_ref: from_ref.map(String::from),
to_ref: to_ref.map(String::from),
}),
)
})
.collect())
}
}

impl<'a> GitChangeDetector for ScopeChangeDetector<'a> {
Expand All @@ -99,8 +124,9 @@ impl<'a> GitChangeDetector for ScopeChangeDetector<'a> {
include_uncommitted,
allow_unknown_objects,
merge_base,
)? {
Err(InvalidRange { from_ref, to_ref }) => {
) {
Ok(Ok(changed_files)) => changed_files,
Ok(Err(InvalidRange { from_ref, to_ref })) => {
debug!("invalid ref range, defaulting to all packages changed");
return Ok(self
.pkg_graph
Expand All @@ -116,17 +142,29 @@ impl<'a> GitChangeDetector for ScopeChangeDetector<'a> {
})
.collect());
}
Ok(changed_files) => changed_files,
Err(ScmError::Path(err, _)) => {
eprintln!(
"error: failed to process file paths from SCM: {}.\nThis repository has file \
paths that could not be anchored to the turbo root.\nPlease remove/rename \
the problematic file(s) or fix repository layout and try again.",
err
);
process::exit(1);
}
Err(err) => {
eprintln!(
"error: unexpected SCM error while detecting changed files: {}.\n
err
);
process::exit(1);
}
};

let lockfile_contents = self.get_lockfile_contents(from_ref, &changed_files);

debug!(
"changed files: {:?}",
&changed_files
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
changed_files.iter().map(|x| x.as_str()).collect::<Vec<_>>()
);

match self
Expand Down
26 changes: 13 additions & 13 deletions crates/turborepo-scm/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{
backtrace::Backtrace,
collections::HashSet,
env::{self, VarError},
fs::{self},
fs,
path::PathBuf,
process::Command,
};
Expand Down Expand Up @@ -201,10 +201,10 @@ impl GitRepo {
*
* So environment variable is empty in a regular commit
*/
if let Ok(pr) = base_ref_env.github_base_ref
&& !pr.is_empty()
{
return Some(pr);
if let Ok(pr) = base_ref_env.github_base_ref {
if !pr.is_empty() {
return Some(pr);
}
}

// we must be in a push event
Expand Down Expand Up @@ -303,7 +303,7 @@ impl GitRepo {
}

let output = self.execute_git_command(&args, pathspec)?;
self.add_files_from_stdout(&mut files, turbo_root, output);
self.add_files_from_stdout(&mut files, turbo_root, output)?;

// We only care about non-tracked files if we haven't specified both ends up the
// comparison
Expand All @@ -314,11 +314,11 @@ impl GitRepo {
&["ls-files", "--others", "--modified", "--exclude-standard"],
pathspec,
)?;
self.add_files_from_stdout(&mut files, turbo_root, ls_files_output);
self.add_files_from_stdout(&mut files, turbo_root, ls_files_output)?;
// Include any files that have been staged, but not committed
let diff_output =
self.execute_git_command(&["diff", "--name-only", "--cached"], pathspec)?;
self.add_files_from_stdout(&mut files, turbo_root, diff_output);
self.add_files_from_stdout(&mut files, turbo_root, diff_output)?;
}

Ok(files)
Expand Down Expand Up @@ -350,15 +350,15 @@ impl GitRepo {
files: &mut HashSet<AnchoredSystemPathBuf>,
turbo_root: &AbsoluteSystemPath,
stdout: Vec<u8>,
) {
let stdout = String::from_utf8(stdout).unwrap();
) -> Result<(), Error> {
let stdout = String::from_utf8(stdout)?;
for line in stdout.lines() {
let path = RelativeUnixPath::new(line).unwrap();
let anchored_to_turbo_root_file_path = self
.reanchor_path_from_git_root_to_turbo_root(turbo_root, path)
.unwrap();
let anchored_to_turbo_root_file_path =
self.reanchor_path_from_git_root_to_turbo_root(turbo_root, path)?;
files.insert(anchored_to_turbo_root_file_path);
}
Ok(())
}

fn reanchor_path_from_git_root_to_turbo_root(
Expand Down