mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Use a cross-platform representation for relative paths in pip compile
(#3804)
## Summary I haven't tested on Windows yet, but the idea here is that we should use a portable representation when printing paths. I decided to limit the scope here to paths that we write to output files. Closes https://github.com/astral-sh/uv/issues/3800.
This commit is contained in:
parent
a7d486bc71
commit
8d566e553d
10 changed files with 75 additions and 26 deletions
|
@ -18,11 +18,13 @@ uv-warnings = { workspace = true }
|
|||
backoff = { workspace = true }
|
||||
cachedir = { workspace = true }
|
||||
dunce = { workspace = true }
|
||||
either = { workspace = true }
|
||||
encoding_rs_io = { workspace = true }
|
||||
fs-err = { workspace = true }
|
||||
fs2 = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
path-absolutize = { workspace = true }
|
||||
path-slash = { workspace = true }
|
||||
tempfile = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
urlencoding = { workspace = true }
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use either::Either;
|
||||
use std::borrow::Cow;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use path_slash::PathExt;
|
||||
|
||||
/// The current working directory.
|
||||
pub static CWD: Lazy<PathBuf> =
|
||||
|
@ -25,7 +27,7 @@ pub trait Simplified {
|
|||
///
|
||||
/// On Windows, this will strip the `\\?\` prefix from paths. On other platforms, it's
|
||||
/// equivalent to [`std::path::Display`].
|
||||
fn simplified_display(&self) -> std::path::Display;
|
||||
fn simplified_display(&self) -> impl std::fmt::Display;
|
||||
|
||||
/// Canonicalize a path without a `\\?\` prefix on Windows.
|
||||
fn simple_canonicalize(&self) -> std::io::Result<PathBuf>;
|
||||
|
@ -33,7 +35,18 @@ pub trait Simplified {
|
|||
/// Render a [`Path`] for user-facing display.
|
||||
///
|
||||
/// Like [`simplified_display`], but relativizes the path against the current working directory.
|
||||
fn user_display(&self) -> std::path::Display;
|
||||
fn user_display(&self) -> impl std::fmt::Display;
|
||||
|
||||
/// Render a [`Path`] for user-facing display, where the [`Path`] is relative to a base path.
|
||||
///
|
||||
/// If the [`Path`] is not relative to the base path, will attempt to relativize the path
|
||||
/// against the current working directory.
|
||||
fn user_display_from(&self, base: impl AsRef<Path>) -> impl std::fmt::Display;
|
||||
|
||||
/// Render a [`Path`] for user-facing display using a portable representation.
|
||||
///
|
||||
/// Like [`user_display`], but uses a portable representation for relative paths.
|
||||
fn portable_display(&self) -> impl std::fmt::Display;
|
||||
}
|
||||
|
||||
impl<T: AsRef<Path>> Simplified for T {
|
||||
|
@ -41,7 +54,7 @@ impl<T: AsRef<Path>> Simplified for T {
|
|||
dunce::simplified(self.as_ref())
|
||||
}
|
||||
|
||||
fn simplified_display(&self) -> std::path::Display {
|
||||
fn simplified_display(&self) -> impl std::fmt::Display {
|
||||
dunce::simplified(self.as_ref()).display()
|
||||
}
|
||||
|
||||
|
@ -49,17 +62,48 @@ impl<T: AsRef<Path>> Simplified for T {
|
|||
dunce::canonicalize(self.as_ref())
|
||||
}
|
||||
|
||||
fn user_display(&self) -> std::path::Display {
|
||||
fn user_display(&self) -> impl std::fmt::Display {
|
||||
let path = dunce::simplified(self.as_ref());
|
||||
|
||||
// Attempt to strip the current working directory, then the canonicalized current working
|
||||
// directory, in case they differ.
|
||||
path.strip_prefix(CWD.simplified())
|
||||
.unwrap_or_else(|_| {
|
||||
let path = path.strip_prefix(CWD.simplified()).unwrap_or_else(|_| {
|
||||
path.strip_prefix(CANONICAL_CWD.simplified())
|
||||
.unwrap_or(path)
|
||||
});
|
||||
|
||||
path.display()
|
||||
}
|
||||
|
||||
fn user_display_from(&self, base: impl AsRef<Path>) -> impl std::fmt::Display {
|
||||
let path = dunce::simplified(self.as_ref());
|
||||
|
||||
// Attempt to strip the base, then the current working directory, then the canonicalized
|
||||
// current working directory, in case they differ.
|
||||
let path = path.strip_prefix(base.as_ref()).unwrap_or_else(|_| {
|
||||
path.strip_prefix(CWD.simplified()).unwrap_or_else(|_| {
|
||||
path.strip_prefix(CANONICAL_CWD.simplified())
|
||||
.unwrap_or(path)
|
||||
})
|
||||
.display()
|
||||
});
|
||||
|
||||
path.display()
|
||||
}
|
||||
|
||||
fn portable_display(&self) -> impl std::fmt::Display {
|
||||
let path = dunce::simplified(self.as_ref());
|
||||
|
||||
// Attempt to strip the current working directory, then the canonicalized current working
|
||||
// directory, in case they differ.
|
||||
let path = path.strip_prefix(CWD.simplified()).unwrap_or_else(|_| {
|
||||
path.strip_prefix(CANONICAL_CWD.simplified())
|
||||
.unwrap_or(path)
|
||||
});
|
||||
|
||||
// Use a portable representation for relative paths.
|
||||
path.to_slash()
|
||||
.map(Either::Left)
|
||||
.unwrap_or_else(|| Either::Right(path.display()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue