Skip to content

Commit

Permalink
fix: Use dunce crate to get non-UNC paths when calling canonicalize (#…
Browse files Browse the repository at this point in the history
…3502)

Call `dunce::canonicalize` rather than `Path::canonicalize`.  On Linux/Macos, this just calls `std::fs::canonicalize()`, so no change there.

PathBuf::canonicalize on Windows generally returns Windows NT UNC paths like `\\?\C:\Users\you\`.  Lots of programs, including Microsoft's, don't work with these kinds of paths. For example, `npm` will print out a message something like `The current working directory is a UNC path.  I'm going to use C:\Windows instead.`.

dunce:
> ... converts paths to legacy format whenever possible, but leaves UNC paths as-is when they can’t be unambiguously expressed in a simpler way. This allows legacy programs to access all paths they can possibly access, and UNC-aware programs to access all paths.

rust-lang/rust#42869 (comment)

Part of https://dfinity.atlassian.net/browse/SDK-1343
  • Loading branch information
ericswanson-dfinity authored Jan 12, 2024
1 parent 4aa1c83 commit 2fcc47b
Show file tree
Hide file tree
Showing 7 changed files with 14 additions and 15 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/canisters/frontend/ic-asset/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ pub(crate) fn gather_asset_descriptors(
let entries = WalkDir::new(&dir)
.into_iter()
.filter_entry(|entry| {
if let Ok(canonical_path) = &entry.path().canonicalize() {
if let Ok(canonical_path) = &dfx_core::fs::canonicalize(entry.path()) {
let config = configuration
.get_asset_config(canonical_path)
.unwrap_or_default();
Expand Down
1 change: 1 addition & 0 deletions src/dfx-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ candid = { workspace = true, features = ["random"] }
clap = { workspace = true, features = ["string"] }
dialoguer = "0.10.0"
directories-next.workspace = true
dunce = "1.0"
flate2 = { workspace = true, default-features = false, features = ["zlib-ng"] }
hex = { workspace = true, features = ["serde"] }
humantime-serde = "1.1.1"
Expand Down
2 changes: 1 addition & 1 deletion src/dfx-core/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::fs::{Metadata, Permissions, ReadDir};
use std::path::{Path, PathBuf};

pub fn canonicalize(path: &Path) -> Result<PathBuf, FsError> {
path.canonicalize()
dunce::canonicalize(path)
.map_err(|err| FsError::new(CanonicalizePathFailed(path.to_path_buf(), err)))
}

Expand Down
17 changes: 8 additions & 9 deletions src/dfx/src/lib/builders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ pub trait CanisterBuilder {
.context("`output` must not be None")?;

if generate_output_dir.exists() {
let generate_output_dir = generate_output_dir.canonicalize().with_context(|| {
format!(
"Failed to canonicalize output dir {}.",
generate_output_dir.to_string_lossy()
)
})?;
let generate_output_dir = dfx_core::fs::canonicalize(generate_output_dir)
.with_context(|| {
format!(
"Failed to canonicalize output dir {}.",
generate_output_dir.to_string_lossy()
)
})?;
if !generate_output_dir.starts_with(info.get_workspace_root()) {
bail!(
"Directory at '{}' is outside the workspace root.",
Expand Down Expand Up @@ -321,9 +322,7 @@ fn ensure_trailing_newline(s: String) -> String {

pub fn run_command(args: Vec<String>, vars: &[Env<'_>], cwd: &Path) -> DfxResult<()> {
let (command_name, arguments) = args.split_first().unwrap();
let canonicalized = cwd
.join(command_name)
.canonicalize()
let canonicalized = dfx_core::fs::canonicalize(&cwd.join(command_name))
.or_else(|_| which::which(command_name))
.map_err(|_| anyhow!("Cannot find command or file {command_name}"))?;
let mut cmd = Command::new(&canonicalized);
Expand Down
2 changes: 1 addition & 1 deletion src/dfx/src/lib/canister_info/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl AssetsCanisterInfo {
let input_root = &self.input_root;
let source_paths: Vec<PathBuf> = source_paths.iter().map(|x| input_root.join(x)).collect();
for source_path in &source_paths {
let canonical = source_path.canonicalize().with_context(|| {
let canonical = dfx_core::fs::canonicalize(source_path).with_context(|| {
format!(
"Unable to determine canonical location of asset source path {}",
source_path.to_string_lossy()
Expand Down
4 changes: 1 addition & 3 deletions src/dfx/src/lib/operations/canister/install_canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,7 @@ fn run_post_install_task(
let cwd = canister.get_workspace_root();
let words = shell_words::split(task)
.with_context(|| format!("Error interpreting post-install task `{task}`"))?;
let canonicalized = cwd
.join(&words[0])
.canonicalize()
let canonicalized = dfx_core::fs::canonicalize(&cwd.join(&words[0]))
.or_else(|_| which::which(&words[0]))
.map_err(|_| anyhow!("Cannot find command or file {}", &words[0]))?;
let mut command = Command::new(&canonicalized);
Expand Down

0 comments on commit 2fcc47b

Please sign in to comment.