From 01999190e58ead4f05d02b8caec92a4886091aa1 Mon Sep 17 00:00:00 2001 From: n-dusan Date: Tue, 28 Nov 2023 19:56:56 +0100 Subject: [PATCH] fix: resolve path issues on Windows Running `cargo test` on Windows gets flaky when calling `canonicalize()` on Path. This is because on Windows, the disk pathing for an absolute path starts with `//?/C:/foo/bar/`. See Rust GitHub issue and discussion here [1]. To resolve, add a helper function that remove the `//?/` from the canonical path. [1] - https://github.com/rust-lang/rust/issues/42869 --- src/utils/archive.rs | 6 +++--- src/utils/mod.rs | 1 + src/utils/paths.rs | 17 +++++++++++++++++ tests/archive_testtools/mod.rs | 11 +++-------- 4 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 src/utils/paths.rs diff --git a/src/utils/archive.rs b/src/utils/archive.rs index 0aa2ffd..6d34990 100644 --- a/src/utils/archive.rs +++ b/src/utils/archive.rs @@ -1,15 +1,15 @@ //! The archive module contains structs for interacting with a Stele archive -use std::path::{Path, PathBuf}; - +use super::paths::fix_unc_path; use anyhow::Context; +use std::path::{Path, PathBuf}; /// given a &Path `path`, return the path to the containing archive. /// /// # Errors /// Error if the path doesn't exist or isn't inside a Stele archive. pub fn find_archive_path(path: &Path) -> anyhow::Result { - let abs_path = path.canonicalize()?; + let abs_path = fix_unc_path(&path.canonicalize()?); for working_path in abs_path.ancestors() { if working_path.join(".stelae").exists() { return Ok(working_path.to_owned()); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 35b9787..6d83fe0 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -4,3 +4,4 @@ pub mod archive; pub mod cli; pub mod git; pub mod http; +pub mod paths; \ No newline at end of file diff --git a/src/utils/paths.rs b/src/utils/paths.rs new file mode 100644 index 0000000..e795798 --- /dev/null +++ b/src/utils/paths.rs @@ -0,0 +1,17 @@ +//! Utility functions for working with paths +use std::path::{Path, PathBuf}; +/// On Windows removes the `\\?\\` prefix to UNC paths. +/// For other OS'es just turns the `Path` into a `PathBuf` +#[must_use] +pub fn fix_unc_path(res: &Path) -> PathBuf { + if cfg!(windows) { + let res_str = res.display().to_string(); + if res_str.starts_with(r#"\\?"#) { + PathBuf::from(res_str.replace(r#"\\?\"#, "")) + } else { + res.to_path_buf() + } + } else { + res.to_path_buf() + } +} diff --git a/tests/archive_testtools/mod.rs b/tests/archive_testtools/mod.rs index 5a498a2..e3ef7b2 100644 --- a/tests/archive_testtools/mod.rs +++ b/tests/archive_testtools/mod.rs @@ -1,6 +1,7 @@ use anyhow::{bail, Result}; use lazy_static::lazy_static; use std::path::{Path, PathBuf}; +use stelae::utils::paths::fix_unc_path; lazy_static! { static ref SCRIPT_PATH: PathBuf = { @@ -11,21 +12,16 @@ lazy_static! { } pub fn execute_script(script_name: &str, mut script_result_directory: PathBuf) -> Result<()> { - let script_absolute_path = SCRIPT_PATH.join(script_name).canonicalize()?; + let script_absolute_path = fix_unc_path(&SCRIPT_PATH.join(script_name).canonicalize()?); let env_path = std::env::current_dir()?.join(script_name); - dbg!(&env_path); - dbg!(&script_absolute_path); - dbg!(&script_result_directory); let mut cmd = std::process::Command::new(&script_absolute_path); let output = match configure_command(&mut cmd, &script_result_directory).output() { Ok(out) => out, Err(err) if err.kind() == std::io::ErrorKind::PermissionDenied || err.raw_os_error() == Some(193) /* windows */ => { - dbg!("Running script with bash"); cmd = std::process::Command::new("bash"); - let output = configure_command(cmd.arg(script_absolute_path), &script_result_directory).output().unwrap(); - dbg!(&output); + let output = configure_command(cmd.arg(&script_absolute_path), &script_result_directory).output().unwrap(); output } Err(err) => return Err(err.into()), @@ -54,5 +50,4 @@ fn configure_command<'a>( .env("GIT_COMMITTER_DATE", "2000-01-02 00:00:00 +0000") .env("GIT_COMMITTER_EMAIL", "committer@openlawlib.org") .env("GIT_COMMITTER_NAME", "committer") - }