Fix for the cargo-installed build script usage. (#4096)

Use both current directory and current exe location for deducing the repository root location.
This commit is contained in:
Michał Wawrzyniec Urbańczyk 2023-02-02 20:34:20 +01:00 committed by GitHub
parent 89dc7a5726
commit 29582b7ee1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 13 deletions

View File

@ -28,15 +28,31 @@ pub fn looks_like_enso_repository_root(path: impl AsRef<Path>) -> 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<PathBuf> {
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(&current_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()
)
})
}

View File

@ -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<C: IsCommandWrapper + ?Sized>(&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());
}
}
}
}

View File

@ -292,14 +292,17 @@ impl Paths {
}
pub async fn workspace_dir() -> Result<PathBuf> {
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())
}