fix: Normalize filesystem paths with `dunce`
Microsoft Windows has Universal Naming Convention (UNC) paths, see <https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths> The Rust standard library normalizes paths to this form when calling `std::fs::canonicalize`, see <https://doc.rust-lang.org/std/fs/fn.canonicalize.html> However, some programs, do not parse these paths correctly, including our ally `git`: $ git clone \\?\C:\Users\lorenz\tmp Cloning into 'tmp'... ssh: Could not resolve hostname \\\\?\\c: No such host is known. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. The `dunce` crate solves the problem of having to deal with normalization and avoiding weird UNC paths for us. Note that on non-Windows platforms, it *behaves exactly like* `std::fs::canonicalize`!
This commit is contained in:
parent
31039bbceb
commit
5229fb8a59
|
|
@ -758,6 +758,12 @@ dependencies = [
|
||||||
"litrs",
|
"litrs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dunce"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dyn-clone"
|
name = "dyn-clone"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
|
|
@ -2662,6 +2668,7 @@ dependencies = [
|
||||||
"colored",
|
"colored",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"cyphernet",
|
"cyphernet",
|
||||||
|
"dunce",
|
||||||
"emojis",
|
"emojis",
|
||||||
"fast-glob",
|
"fast-glob",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
|
|
@ -2698,6 +2705,7 @@ version = "0.15.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"dunce",
|
||||||
"git-ref-format",
|
"git-ref-format",
|
||||||
"human-panic",
|
"human-panic",
|
||||||
"lexopt",
|
"lexopt",
|
||||||
|
|
@ -2901,6 +2909,7 @@ dependencies = [
|
||||||
name = "radicle-remote-helper"
|
name = "radicle-remote-helper"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"dunce",
|
||||||
"log",
|
"log",
|
||||||
"radicle",
|
"radicle",
|
||||||
"radicle-cli",
|
"radicle-cli",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ chrono = { version = "0.4.26", default-features = false }
|
||||||
colored = "2.1.0"
|
colored = "2.1.0"
|
||||||
crossbeam-channel = "0.5.6"
|
crossbeam-channel = "0.5.6"
|
||||||
cyphernet = "0.5.2"
|
cyphernet = "0.5.2"
|
||||||
|
dunce = "1.0.5"
|
||||||
fastrand = { version = "2.0.0", default-features = false }
|
fastrand = { version = "2.0.0", default-features = false }
|
||||||
git2 = { version = "0.19.0", default-features = false }
|
git2 = { version = "0.19.0", default-features = false }
|
||||||
human-panic = "2"
|
human-panic = "2"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ path = "src/main.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
chrono = { workspace = true, features = ["clock", "std"] }
|
chrono = { workspace = true, features = ["clock", "std"] }
|
||||||
|
dunce = { workspace = true }
|
||||||
git-ref-format = { version = "0.3.0", features = ["macro"] }
|
git-ref-format = { version = "0.3.0", features = ["macro"] }
|
||||||
human-panic.workspace = true
|
human-panic.workspace = true
|
||||||
lexopt = { workspace = true }
|
lexopt = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -212,10 +212,7 @@ pub fn init(
|
||||||
options: Options,
|
options: Options,
|
||||||
profile: &profile::Profile,
|
profile: &profile::Profile,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let path = repo
|
let path = dunce::canonicalize(repo.workdir().unwrap_or_else(|| repo.path()))?;
|
||||||
.workdir()
|
|
||||||
.unwrap_or_else(|| repo.path())
|
|
||||||
.canonicalize()?;
|
|
||||||
let interactive = options.interactive;
|
let interactive = options.interactive;
|
||||||
|
|
||||||
let default_branch = match find_default_branch(&repo) {
|
let default_branch = match find_default_branch(&repo) {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ name = "git-remote-rad"
|
||||||
path = "src/git-remote-rad.rs"
|
path = "src/git-remote-rad.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
dunce = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
radicle = { workspace = true }
|
radicle = { workspace = true }
|
||||||
radicle-cli = { workspace = true }
|
radicle-cli = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
|
||||||
|
|
||||||
// N.b. `working` is the `.git` folder and `fetch::run`
|
// N.b. `working` is the `.git` folder and `fetch::run`
|
||||||
// requires the working directory.
|
// requires the working directory.
|
||||||
let working = working.map_err(|_| Error::NoGitDir)?.canonicalize()?;
|
let working = dunce::canonicalize(working.map_err(|_| Error::NoGitDir)?)?;
|
||||||
let working = working.parent().ok_or_else(|| Error::NoWorkingCopy {
|
let working = working.parent().ok_or_else(|| Error::NoWorkingCopy {
|
||||||
path: working.clone(),
|
path: working.clone(),
|
||||||
})?;
|
})?;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ chrono = { workspace = true, features = ["clock"], optional = true }
|
||||||
colored = { workspace = true, optional = true }
|
colored = { workspace = true, optional = true }
|
||||||
crossbeam-channel = { workspace = true }
|
crossbeam-channel = { workspace = true }
|
||||||
cyphernet = { workspace = true, features = ["tor", "dns", "p2p-ed25519"] }
|
cyphernet = { workspace = true, features = ["tor", "dns", "p2p-ed25519"] }
|
||||||
|
dunce = { workspace = true }
|
||||||
fast-glob = { version = "0.3.2" }
|
fast-glob = { version = "0.3.2" }
|
||||||
fastrand = { workspace = true }
|
fastrand = { workspace = true }
|
||||||
git2 = { workspace = true, features = ["vendored-libgit2"] }
|
git2 = { workspace = true, features = ["vendored-libgit2"] }
|
||||||
|
|
|
||||||
|
|
@ -541,7 +541,7 @@ impl Home {
|
||||||
fs::create_dir_all(path.clone())?;
|
fs::create_dir_all(path.clone())?;
|
||||||
}
|
}
|
||||||
let home = Self {
|
let home = Self {
|
||||||
path: path.canonicalize()?,
|
path: dunce::canonicalize(path)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
for dir in &[home.storage(), home.keys(), home.node(), home.cobs()] {
|
for dir in &[home.storage(), home.keys(), home.node(), home.cobs()] {
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ where
|
||||||
})?,
|
})?,
|
||||||
[
|
[
|
||||||
"push",
|
"push",
|
||||||
&format!("{}", stored.path().canonicalize()?.display()),
|
&format!("{}", dunce::canonicalize(stored.path())?.display()),
|
||||||
&pushspec.to_string(),
|
&pushspec.to_string(),
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
|
@ -295,9 +295,7 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
|
||||||
"fetch",
|
"fetch",
|
||||||
&format!(
|
&format!(
|
||||||
"{}",
|
"{}",
|
||||||
stored
|
dunce::canonicalize(stored.path())
|
||||||
.path()
|
|
||||||
.canonicalize()
|
|
||||||
.map_err(CheckoutError::Fetch)?
|
.map_err(CheckoutError::Fetch)?
|
||||||
.display()
|
.display()
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue