diff --git a/cargo-dist/src/errors.rs b/cargo-dist/src/errors.rs index 02bd10319..5b8436051 100644 --- a/cargo-dist/src/errors.rs +++ b/cargo-dist/src/errors.rs @@ -266,6 +266,14 @@ pub enum DistError { #[error("We failed to generate a source tarball for your project")] #[diagnostic(help("This is probably not your fault, please file an issue!"))] GitArchiveError {}, + + /// A required tool is missing + #[error("{tool}, required to run this task, is missing")] + #[diagnostic(help("Ensure {tool} is installed"))] + ToolMissing { + /// the name of the missing tool + tool: String, + }, } impl From for DistError { diff --git a/cargo-dist/src/lib.rs b/cargo-dist/src/lib.rs index 77a3e5af7..b994c60ea 100644 --- a/cargo-dist/src/lib.rs +++ b/cargo-dist/src/lib.rs @@ -137,7 +137,9 @@ fn run_build_step( committish, prefix, target, - }) => Ok(generate_source_tarball(committish, prefix, target)?), + }) => Ok(generate_source_tarball( + dist_graph, committish, prefix, target, + )?), BuildStep::Extra(target) => run_extra_artifacts_build(dist_graph, target), } } @@ -185,8 +187,21 @@ fn generate_checksum(checksum: &ChecksumStyle, src_path: &Utf8Path) -> DistResul /// Creates a source code tarball from the git archive from /// tag/ref/commit `committish`, with the directory prefix `prefix`, /// at the output file `target`. -fn generate_source_tarball(committish: &str, prefix: &str, target: &Utf8Path) -> DistResult<()> { - let status = Command::new("git") +fn generate_source_tarball( + graph: &DistGraph, + committish: &str, + prefix: &str, + target: &Utf8Path, +) -> DistResult<()> { + let git = if let Some(tool) = &graph.tools.git { + tool.cmd.to_owned() + } else { + return Err(DistError::ToolMissing { + tool: "git".to_owned(), + }); + }; + + let status = Command::new(git) .arg("archive") .arg(committish) .arg("--format=tar.gz") diff --git a/cargo-dist/src/tasks.rs b/cargo-dist/src/tasks.rs index 83a33cd28..290bb20cf 100644 --- a/cargo-dist/src/tasks.rs +++ b/cargo-dist/src/tasks.rs @@ -235,6 +235,8 @@ pub struct Tools { pub rustup: Option, /// homebrew, only available on macOS pub brew: Option, + /// git, used if the repository is a git repo + pub git: Option, } /// Info about the cargo toolchain we're using @@ -1202,13 +1204,20 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { return; } + let git = if let Some(tool) = &self.inner.tools.git { + tool.cmd.to_owned() + } else { + warn!("skipping source tarball; git not installed"); + return; + }; + // It's possible to run cargo-dist in something that's not a git // repo, including a brand-new repo that hasn't been `git init`ted yet; // we can't act on those. // // Note we don't need the output of --show-toplevel, // just the exit status. - let status = Command::new("git") + let status = Command::new(git) .arg("rev-parse") .arg("--show-toplevel") .stdout(std::process::Stdio::piped()) @@ -2679,6 +2688,7 @@ fn tool_info() -> Result { cargo, rustup: find_tool("rustup", "-V"), brew: find_tool("brew", "--version"), + git: find_tool("git", "--version"), }) } diff --git a/cargo-dist/src/tests/mock.rs b/cargo-dist/src/tests/mock.rs index 5b0b66e4d..5ad5c71fd 100644 --- a/cargo-dist/src/tests/mock.rs +++ b/cargo-dist/src/tests/mock.rs @@ -48,6 +48,7 @@ pub fn mock_tools() -> Tools { }, rustup: None, brew: None, + git: None, } }