From 29582b7ee16dfb9d79ad9effb78c5084348456aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Wawrzyniec=20Urba=C5=84czyk?= Date: Thu, 2 Feb 2023 20:34:20 +0100 Subject: [PATCH] Fix for the cargo-installed build script usage. (#4096) Use both current directory and current exe location for deducing the repository root location. --- build/build/src/repo.rs | 26 ++++++++++++++---- build/ci_utils/src/programs/cargo.rs | 41 ++++++++++++++++++++++++++-- lib/rust/ensogl/pack/src/lib.rs | 15 ++++++---- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/build/build/src/repo.rs b/build/build/src/repo.rs index 0d1c84bb7b..6c9eb3aefc 100644 --- a/build/build/src/repo.rs +++ b/build/build/src/repo.rs @@ -28,15 +28,31 @@ pub fn looks_like_enso_repository_root(path: impl AsRef) -> bool { .unwrap_or(false) } +/// Traverse the filesystem upwards, until we find a directory that looks like the root of the Enso. +pub fn lookup_upwards_for_repository_root(mut path: &Path) -> Option<&Path> { + while !looks_like_enso_repository_root(path) { + path = path.parent()?; + } + Some(path) +} + /// Deduce the path to the root of the Enso repository. /// /// This function will traverse the filesystem upwards from the binary location until it finds a /// directory that looks like the root of the Enso repository. #[instrument(ret, err)] pub fn deduce_repository_path() -> Result { - let mut path = ide_ci::env::current_exe()?; - while !looks_like_enso_repository_root(&path) { - ensure!(path.pop(), "Failed to deduce repository path."); - } - Ok(path) + // We check the current directory to support cases like using `cargo install` to reuse the + // build script binary. + let current_dir = ide_ci::env::current_dir()?; + let exe_path = ide_ci::env::current_exe()?; + let repo_root = lookup_upwards_for_repository_root(¤t_dir) + .or_else(|| lookup_upwards_for_repository_root(&exe_path)); + repo_root.map(PathBuf::from).with_context(|| { + format!( + "Failed to deduce repository path from current directory {} and executable path {}.", + current_dir.display(), + exe_path.display() + ) + }) } diff --git a/build/ci_utils/src/programs/cargo.rs b/build/ci_utils/src/programs/cargo.rs index 6c7f5e0593..584a9b13f7 100644 --- a/build/ci_utils/src/programs/cargo.rs +++ b/build/ci_utils/src/programs/cargo.rs @@ -39,6 +39,8 @@ impl Program for Cargo { #[derive(Clone, Copy, PartialEq, Eq, Debug, strum::AsRefStr)] #[strum(serialize_all = "kebab-case")] pub enum Command { + /// Run the benchmarks + Bench, /// Compile the current package Build, /// Analyze the current package and report errors, but don't build object files @@ -55,8 +57,6 @@ pub enum Command { Run, /// Run the tests Test, - /// Run the benchmarks - Bench, /// Update dependencies listed in Cargo.lock Update, /// Search registry for crates @@ -67,6 +67,8 @@ pub enum Command { Install, /// Uninstall a Rust binary Uninstall, + /// Print a JSON representation of a Cargo.toml file's location + LocateProject, } impl Manipulator for Command { @@ -135,3 +137,38 @@ impl Manipulator for RunOption { } } } + +/// The representation in which to print the project location. +#[derive(Clone, Copy, PartialEq, Eq, Debug, strum::AsRefStr)] +#[strum(serialize_all = "kebab-case")] +pub enum MessageFormat { + /// JSON object with the path under the key "root". + Json, + /// Just the path. + Plain, +} + +/// Options for the `cargo locate-project` command. +#[derive(Clone, Copy, PartialEq, Eq, Debug, strum::AsRefStr)] +#[strum(serialize_all = "kebab-case")] +pub enum LocateProjectOption { + /// Locate the Cargo.toml at the root of the workspace, as opposed to the current workspace + /// member. + Workspace, + /// The representation in which to print the project location. + MessageFormat(MessageFormat), +} + +impl Manipulator for LocateProjectOption { + fn apply(&self, command: &mut C) { + let base_arg = format!("--{}", self.as_ref()); + command.arg(base_arg); + use LocateProjectOption::*; + match self { + Workspace => {} + MessageFormat(format) => { + command.arg(format.as_ref()); + } + } + } +} diff --git a/lib/rust/ensogl/pack/src/lib.rs b/lib/rust/ensogl/pack/src/lib.rs index ba6e4b9104..12cc3f157b 100644 --- a/lib/rust/ensogl/pack/src/lib.rs +++ b/lib/rust/ensogl/pack/src/lib.rs @@ -292,14 +292,17 @@ impl Paths { } pub async fn workspace_dir() -> Result { - let output = Command::new(env!("CARGO")) - .arg("locate-project") - .arg("--workspace") - .arg("--message-format=plain") + use ide_ci::programs::cargo; + use ide_ci::programs::Cargo; + let output = Cargo + .cmd()? + .apply(&cargo::Command::LocateProject) + .apply(&cargo::LocateProjectOption::Workspace) + .apply(&cargo::LocateProjectOption::MessageFormat(cargo::MessageFormat::Plain)) .output_ok() .await? - .stdout; - let cargo_path = Path::new(std::str::from_utf8(&output)?.trim()); + .into_stdout_string()?; + let cargo_path = Path::new(output.trim()); Ok(cargo_path.try_parent()?.to_owned()) }