From ef150982883e517f46c253ef43b20b51fc74e71f Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 28 Feb 2024 20:44:50 -0500 Subject: [PATCH] Use `Simplified` instead of `Normalized` for path prefix stripping (#2071) ## Summary This directly matches the naming of the `dunce` methods. --- crates/distribution-types/src/installed.rs | 4 +-- crates/gourgeist/src/bare.rs | 4 +-- crates/install-wheel-rs/src/lib.rs | 6 ++-- crates/install-wheel-rs/src/wheel.rs | 20 +++++------ crates/requirements-txt/src/lib.rs | 36 +++++++++---------- crates/uv-build/src/lib.rs | 6 ++-- crates/uv-fs/src/lib.rs | 6 ++-- crates/uv-fs/src/path.rs | 14 ++++---- crates/uv-git/src/git.rs | 6 ++-- crates/uv-installer/src/plan.rs | 4 +-- .../uv-interpreter/src/python_environment.rs | 6 ++-- crates/uv/src/commands/cache_clean.rs | 8 ++--- crates/uv/src/commands/cache_dir.rs | 4 +-- crates/uv/src/commands/pip_compile.rs | 6 ++-- crates/uv/src/commands/pip_freeze.rs | 4 +-- crates/uv/src/commands/pip_install.rs | 8 ++--- crates/uv/src/commands/pip_list.rs | 4 +-- crates/uv/src/commands/pip_sync.rs | 8 ++--- crates/uv/src/commands/pip_uninstall.rs | 8 ++--- crates/uv/src/commands/venv.rs | 10 +++--- crates/uv/src/requirements.rs | 8 ++--- crates/uv/tests/common/mod.rs | 6 ++-- crates/uv/tests/pip_compile.rs | 22 ++++++------ crates/uv/tests/pip_sync.rs | 18 +++++----- crates/uv/tests/pip_uninstall.rs | 4 +-- crates/uv/tests/venv.rs | 28 +++++++-------- 26 files changed, 129 insertions(+), 129 deletions(-) diff --git a/crates/distribution-types/src/installed.rs b/crates/distribution-types/src/installed.rs index 6a31ed0ed..880d0f7f7 100644 --- a/crates/distribution-types/src/installed.rs +++ b/crates/distribution-types/src/installed.rs @@ -7,7 +7,7 @@ use tracing::warn; use url::Url; use pep440_rs::Version; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_normalize::PackageName; use crate::{InstalledMetadata, InstalledVersion, Name}; @@ -117,7 +117,7 @@ impl InstalledDist { pypi_types::Metadata21::parse(&contents).with_context(|| { format!( "Failed to parse METADATA file at: {}", - path.normalized_display() + path.simplified_display() ) }) } diff --git a/crates/gourgeist/src/bare.rs b/crates/gourgeist/src/bare.rs index b12da9b28..0ebaa5852 100644 --- a/crates/gourgeist/src/bare.rs +++ b/crates/gourgeist/src/bare.rs @@ -9,7 +9,7 @@ use camino::{FromPathBufError, Utf8Path, Utf8PathBuf}; use fs_err as fs; use fs_err::File; use tracing::info; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_interpreter::Interpreter; @@ -181,7 +181,7 @@ pub fn create_bare_venv( .replace( "{{ VIRTUAL_ENV_DIR }}", // SAFETY: `unwrap` is guaranteed to succeed because `location` is an `Utf8PathBuf`. - location.normalized().to_str().unwrap(), + location.simplified().to_str().unwrap(), ) .replace("{{ BIN_NAME }}", bin_name) .replace( diff --git a/crates/install-wheel-rs/src/lib.rs b/crates/install-wheel-rs/src/lib.rs index b6e6bd93a..2a8918593 100644 --- a/crates/install-wheel-rs/src/lib.rs +++ b/crates/install-wheel-rs/src/lib.rs @@ -14,7 +14,7 @@ use distribution_filename::WheelFilename; use pep440_rs::Version; use platform_host::{Arch, Os}; pub use uninstall::{uninstall_wheel, Uninstall}; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_normalize::PackageName; pub mod linker; @@ -47,7 +47,7 @@ pub enum Error { #[error(transparent)] Io(#[from] io::Error), /// Custom error type to add a path to error reading a file from a zip - #[error("Failed to reflink {} to {}", from.normalized_display(), to.normalized_display())] + #[error("Failed to reflink {} to {}", from.simplified_display(), to.simplified_display())] Reflink { from: PathBuf, to: PathBuf, @@ -88,7 +88,7 @@ pub enum Error { DirectUrlJson(#[from] serde_json::Error), #[error("No .dist-info directory found")] MissingDistInfo, - #[error("Cannot uninstall package; RECORD file not found at: {}", _0.normalized_display())] + #[error("Cannot uninstall package; RECORD file not found at: {}", _0.simplified_display())] MissingRecord(PathBuf), #[error("Multiple .dist-info directories found: {0}")] MultipleDistInfo(String), diff --git a/crates/install-wheel-rs/src/wheel.rs b/crates/install-wheel-rs/src/wheel.rs index 4e8ae63ba..32518dc98 100644 --- a/crates/install-wheel-rs/src/wheel.rs +++ b/crates/install-wheel-rs/src/wheel.rs @@ -15,7 +15,7 @@ use zip::write::FileOptions; use zip::ZipWriter; use pypi_types::DirectUrl; -use uv_fs::Normalized; +use uv_fs::Simplified; use crate::record::RecordEntry; use crate::script::Script; @@ -115,7 +115,7 @@ fn copy_and_hash(reader: &mut impl Read, writer: &mut impl Write) -> io::Result< } fn get_shebang(python_executable: impl AsRef) -> String { - format!("#!{}", python_executable.as_ref().normalized().display()) + format!("#!{}", python_executable.as_ref().simplified().display()) } /// A Windows script is a minimal .exe launcher binary with the python entrypoint script appended as @@ -176,7 +176,7 @@ pub(crate) fn windows_script_launcher( } let python = python_executable.as_ref(); - let python_path = python.normalized().to_string_lossy(); + let python_path = python.simplified().to_string_lossy(); let mut launcher: Vec = Vec::with_capacity(launcher_bin.len() + payload.len()); launcher.extend_from_slice(launcher_bin); @@ -222,7 +222,7 @@ pub(crate) fn write_script_entrypoints( io::ErrorKind::Other, format!( "Could not find relative path for: {}", - entrypoint_absolute.normalized_display() + entrypoint_absolute.simplified_display() ), )) })?; @@ -344,8 +344,8 @@ pub(crate) fn relative_to(path: &Path, base: &Path) -> Result { io::ErrorKind::Other, format!( "Trivial strip failed: {} vs. {}", - path.normalized_display(), - base.normalized_display() + path.simplified_display(), + base.simplified_display() ), )) })?; @@ -387,8 +387,8 @@ pub(crate) fn move_folder_recorded( .ok_or_else(|| { Error::RecordFile(format!( "Could not find entry for {} ({})", - relative_to_site_packages.normalized_display(), - src.normalized_display() + relative_to_site_packages.simplified_display(), + src.simplified_display() )) })?; entry.path = relative_to(&target, site_packages)?.display().to_string(); @@ -460,8 +460,8 @@ fn install_script( // This should be possible to occur at this point, but filesystems and such Error::RecordFile(format!( "Could not find entry for {} ({})", - relative_to_site_packages.normalized_display(), - path.normalized_display() + relative_to_site_packages.simplified_display(), + path.simplified_display() )) })?; entry.path = target_path.display().to_string(); diff --git a/crates/requirements-txt/src/lib.rs b/crates/requirements-txt/src/lib.rs index 9f0272a40..f28e2658e 100644 --- a/crates/requirements-txt/src/lib.rs +++ b/crates/requirements-txt/src/lib.rs @@ -48,7 +48,7 @@ use uv_warnings::warn_user; use pep508_rs::{ split_scheme, Extras, Pep508Error, Pep508ErrorSource, Requirement, Scheme, VerbatimUrl, }; -use uv_fs::{normalize_url_path, Normalized}; +use uv_fs::{normalize_url_path, Simplified}; use uv_normalize::ExtraName; /// We emit one of those for each requirements.txt entry @@ -872,63 +872,63 @@ impl Display for RequirementsTxtFileError { write!( f, "Invalid URL in `{}` at position {start}: `{url}`", - self.file.normalized_display(), + self.file.simplified_display(), ) } RequirementsTxtParserError::InvalidEditablePath(given) => { write!( f, "Invalid editable path in `{}`: {given}", - self.file.normalized_display() + self.file.simplified_display() ) } RequirementsTxtParserError::UnsupportedUrl(url) => { write!( f, "Unsupported URL (expected a `file://` scheme) in `{}`: `{url}`", - self.file.normalized_display(), + self.file.simplified_display(), ) } RequirementsTxtParserError::MissingRequirementPrefix(given) => { write!( f, "Requirement `{given}` in `{}` looks like a requirements file but was passed as a package name. Did you mean `-r {given}`?", - self.file.normalized_display(), + self.file.simplified_display(), ) } RequirementsTxtParserError::MissingEditablePrefix(given) => { write!( f, "Requirement `{given}` in `{}` looks like a directory but was passed as a package name. Did you mean `-e {given}`?", - self.file.normalized_display(), + self.file.simplified_display(), ) } RequirementsTxtParserError::Parser { message, location } => { write!( f, "{message} in `{}` at position {location}", - self.file.normalized_display(), + self.file.simplified_display(), ) } RequirementsTxtParserError::UnsupportedRequirement { start, .. } => { write!( f, "Unsupported requirement in {} at position {start}", - self.file.normalized_display(), + self.file.simplified_display(), ) } RequirementsTxtParserError::Pep508 { start, .. } => { write!( f, "Couldn't parse requirement in `{}` at position {start}", - self.file.normalized_display(), + self.file.simplified_display(), ) } RequirementsTxtParserError::Subfile { start, .. } => { write!( f, "Error parsing included file in `{}` at position {start}", - self.file.normalized_display(), + self.file.simplified_display(), ) } } @@ -958,7 +958,7 @@ mod test { use itertools::Itertools; use tempfile::tempdir; use test_case::test_case; - use uv_fs::Normalized; + use uv_fs::Simplified; use crate::{EditableRequirement, RequirementsTxt}; @@ -1044,8 +1044,8 @@ mod test { .join("\n"); let requirement_txt = - regex::escape(&requirements_txt.path().normalized_display().to_string()); - let missing_txt = regex::escape(&missing_txt.path().normalized_display().to_string()); + regex::escape(&requirements_txt.path().simplified_display().to_string()); + let missing_txt = regex::escape(&missing_txt.path().simplified_display().to_string()); let filters = vec![ (requirement_txt.as_str(), ""), (missing_txt.as_str(), ""), @@ -1075,7 +1075,7 @@ mod test { let errors = anyhow::Error::new(error).chain().join("\n"); let requirement_txt = - regex::escape(&requirements_txt.path().normalized_display().to_string()); + regex::escape(&requirements_txt.path().simplified_display().to_string()); let filters = vec![ (requirement_txt.as_str(), ""), (r"\\", "/"), @@ -1106,7 +1106,7 @@ mod test { let errors = anyhow::Error::new(error).chain().join("\n"); let requirement_txt = - regex::escape(&requirements_txt.path().normalized_display().to_string()); + regex::escape(&requirements_txt.path().simplified_display().to_string()); let filters = vec![ (requirement_txt.as_str(), ""), (r"\\", "/"), @@ -1132,7 +1132,7 @@ mod test { let errors = anyhow::Error::new(error).chain().join("\n"); let requirement_txt = - regex::escape(&requirements_txt.path().normalized_display().to_string()); + regex::escape(&requirements_txt.path().simplified_display().to_string()); let filters = vec![(requirement_txt.as_str(), "")]; insta::with_settings!({ filters => filters @@ -1160,7 +1160,7 @@ mod test { let errors = anyhow::Error::new(error).chain().join("\n"); let requirement_txt = - regex::escape(&requirements_txt.path().normalized_display().to_string()); + regex::escape(&requirements_txt.path().simplified_display().to_string()); let filters = vec![ (requirement_txt.as_str(), ""), (r"\\", "/"), @@ -1194,7 +1194,7 @@ mod test { let errors = anyhow::Error::new(error).chain().join("\n"); let requirement_txt = - regex::escape(&requirements_txt.path().normalized_display().to_string()); + regex::escape(&requirements_txt.path().simplified_display().to_string()); let filters = vec![ (requirement_txt.as_str(), ""), (r"\\", "/"), diff --git a/crates/uv-build/src/lib.rs b/crates/uv-build/src/lib.rs index 803241bf6..576c8c7de 100644 --- a/crates/uv-build/src/lib.rs +++ b/crates/uv-build/src/lib.rs @@ -28,7 +28,7 @@ use tracing::{debug, info_span, instrument, Instrument}; use distribution_types::Resolution; use pep508_rs::Requirement; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_interpreter::{Interpreter, PythonEnvironment}; use uv_traits::{BuildContext, BuildKind, ConfigSettings, SetupPyStrategy, SourceBuildTrait}; @@ -642,7 +642,7 @@ impl SourceBuild { ); let output = Command::new(python_interpreter) .args(["setup.py", "bdist_wheel"]) - .current_dir(self.source_tree.normalized()) + .current_dir(self.source_tree.simplified()) .output() .instrument(span) .await @@ -859,7 +859,7 @@ async fn run_python_script( }; Command::new(venv.python_executable()) .args(["-c", script]) - .current_dir(source_tree.normalized()) + .current_dir(source_tree.simplified()) // Activate the venv .env("VIRTUAL_ENV", venv.root()) .env("PATH", new_path) diff --git a/crates/uv-fs/src/lib.rs b/crates/uv-fs/src/lib.rs index bb7d280b6..11db64995 100644 --- a/crates/uv-fs/src/lib.rs +++ b/crates/uv-fs/src/lib.rs @@ -96,7 +96,7 @@ pub async fn write_atomic(path: impl AsRef, data: impl AsRef<[u8]>) -> std std::io::ErrorKind::Other, format!( "Failed to persist temporary file to {}: {}", - path.normalized_display(), + path.simplified_display(), err.error ), ) @@ -117,7 +117,7 @@ pub fn write_atomic_sync(path: impl AsRef, data: impl AsRef<[u8]>) -> std: std::io::ErrorKind::Other, format!( "Failed to persist temporary file to {}: {}", - path.normalized_display(), + path.simplified_display(), err.error ), ) @@ -229,7 +229,7 @@ impl LockedFile { warn_user!( "Waiting to acquire lock for {} (lockfile: {})", resource, - path.normalized_display(), + path.simplified_display(), ); file.file().lock_exclusive()?; Ok(Self(file)) diff --git a/crates/uv-fs/src/path.rs b/crates/uv-fs/src/path.rs index 14ef90b0a..4fec75af7 100644 --- a/crates/uv-fs/src/path.rs +++ b/crates/uv-fs/src/path.rs @@ -1,25 +1,25 @@ use std::borrow::Cow; use std::path::Path; -pub trait Normalized { - /// Normalize a [`Path`]. +pub trait Simplified { + /// Simplify a [`Path`]. /// /// On Windows, this will strip the `\\?\` prefix from paths. On other platforms, it's a no-op. - fn normalized(&self) -> &Path; + fn simplified(&self) -> &Path; /// Render a [`Path`] for user-facing display. /// /// On Windows, this will strip the `\\?\` prefix from paths. On other platforms, it's /// equivalent to [`std::path::Display`]. - fn normalized_display(&self) -> std::path::Display; + fn simplified_display(&self) -> std::path::Display; } -impl> Normalized for T { - fn normalized(&self) -> &Path { +impl> Simplified for T { + fn simplified(&self) -> &Path { dunce::simplified(self.as_ref()) } - fn normalized_display(&self) -> std::path::Display { + fn simplified_display(&self) -> std::path::Display { dunce::simplified(self.as_ref()).display() } } diff --git a/crates/uv-git/src/git.rs b/crates/uv-git/src/git.rs index b98b692f4..9bde40bba 100644 --- a/crates/uv-git/src/git.rs +++ b/crates/uv-git/src/git.rs @@ -13,7 +13,7 @@ use reqwest::Client; use reqwest::StatusCode; use tracing::{debug, warn}; use url::Url; -use uv_fs::Normalized; +use uv_fs::Simplified; use crate::util::retry; use crate::FetchStrategy; @@ -170,7 +170,7 @@ impl GitRemote { let reference = locked_ref.as_ref().unwrap_or(reference); if let Some(mut db) = db { fetch(&mut db.repo, self.url.as_str(), reference, strategy, client) - .with_context(|| format!("failed to fetch into: {}", into.normalized_display()))?; + .with_context(|| format!("failed to fetch into: {}", into.simplified_display()))?; let resolved_commit_hash = match locked_rev { Some(rev) => db.contains(rev).then_some(rev), @@ -190,7 +190,7 @@ impl GitRemote { paths::create_dir_all(into)?; let mut repo = init(into, true)?; fetch(&mut repo, self.url.as_str(), reference, strategy, client) - .with_context(|| format!("failed to clone into: {}", into.normalized_display()))?; + .with_context(|| format!("failed to clone into: {}", into.simplified_display()))?; let rev = match locked_rev { Some(rev) => rev, None => reference.resolve(&repo)?, diff --git a/crates/uv-installer/src/plan.rs b/crates/uv-installer/src/plan.rs index 65ef7f55e..dd8358801 100644 --- a/crates/uv-installer/src/plan.rs +++ b/crates/uv-installer/src/plan.rs @@ -15,7 +15,7 @@ use pep508_rs::{Requirement, VersionOrUrl}; use platform_tags::Tags; use uv_cache::{ArchiveTimestamp, Cache, CacheBucket, CacheEntry, Timestamp, WheelCache}; use uv_distribution::{BuiltWheelIndex, RegistryWheelIndex}; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_interpreter::PythonEnvironment; use uv_normalize::PackageName; use uv_traits::NoBinary; @@ -299,7 +299,7 @@ impl<'a> Planner<'a> { if !wheel.filename.is_compatible(tags) { bail!( "A path dependency is incompatible with the current platform: {}", - wheel.path.normalized_display() + wheel.path.simplified_display() ); } diff --git a/crates/uv-interpreter/src/python_environment.rs b/crates/uv-interpreter/src/python_environment.rs index 36c9545d5..fb688eadf 100644 --- a/crates/uv-interpreter/src/python_environment.rs +++ b/crates/uv-interpreter/src/python_environment.rs @@ -5,7 +5,7 @@ use tracing::debug; use platform_host::Platform; use uv_cache::Cache; -use uv_fs::{LockedFile, Normalized}; +use uv_fs::{LockedFile, Simplified}; use crate::cfg::PyVenvConfiguration; use crate::virtualenv_layout::VirtualenvLayout; @@ -109,12 +109,12 @@ impl PythonEnvironment { pub fn lock(&self) -> Result { if self.interpreter.is_virtualenv() { // If the environment a virtualenv, use a virtualenv-specific lock file. - LockedFile::acquire(self.root.join(".lock"), self.root.normalized_display()) + LockedFile::acquire(self.root.join(".lock"), self.root.simplified_display()) } else { // Otherwise, use a global lock file. LockedFile::acquire( env::temp_dir().join(format!("uv-{}.lock", cache_key::digest(&self.root))), - self.root.normalized_display(), + self.root.simplified_display(), ) } } diff --git a/crates/uv/src/commands/cache_clean.rs b/crates/uv/src/commands/cache_clean.rs index bfbf37669..99f5975fc 100644 --- a/crates/uv/src/commands/cache_clean.rs +++ b/crates/uv/src/commands/cache_clean.rs @@ -4,7 +4,7 @@ use anyhow::{Context, Result}; use owo_colors::OwoColorize; use uv_cache::Cache; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_normalize::PackageName; use crate::commands::ExitStatus; @@ -20,7 +20,7 @@ pub(crate) fn cache_clean( writeln!( printer, "No cache found at: {}", - cache.root().normalized_display().cyan() + cache.root().simplified_display().cyan() )?; return Ok(ExitStatus::Success); } @@ -29,13 +29,13 @@ pub(crate) fn cache_clean( writeln!( printer, "Clearing cache at: {}", - cache.root().normalized_display().cyan() + cache.root().simplified_display().cyan() )?; let summary = cache.clear().with_context(|| { format!( "Failed to clear cache at: {}", - cache.root().normalized_display() + cache.root().simplified_display() ) })?; diff --git a/crates/uv/src/commands/cache_dir.rs b/crates/uv/src/commands/cache_dir.rs index c406671af..2ff797733 100644 --- a/crates/uv/src/commands/cache_dir.rs +++ b/crates/uv/src/commands/cache_dir.rs @@ -1,8 +1,8 @@ use owo_colors::OwoColorize; use uv_cache::Cache; -use uv_fs::Normalized; +use uv_fs::Simplified; /// Show the cache directory. pub(crate) fn cache_dir(cache: &Cache) { - anstream::println!("{}", cache.root().normalized_display().cyan()); + anstream::println!("{}", cache.root().simplified_display().cyan()); } diff --git a/crates/uv/src/commands/pip_compile.rs b/crates/uv/src/commands/pip_compile.rs index 23c9619d9..f8e23986a 100644 --- a/crates/uv/src/commands/pip_compile.rs +++ b/crates/uv/src/commands/pip_compile.rs @@ -23,7 +23,7 @@ use requirements_txt::EditableRequirement; use uv_cache::Cache; use uv_client::{Connectivity, FlatIndex, FlatIndexClient, RegistryClientBuilder}; use uv_dispatch::BuildDispatch; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_installer::{Downloader, NoBinary}; use uv_interpreter::{Interpreter, PythonVersion}; use uv_normalize::{ExtraName, PackageName}; @@ -146,7 +146,7 @@ pub(crate) async fn pip_compile( debug!( "Using Python {} interpreter at {} for builds", interpreter.python_version(), - interpreter.sys_executable().normalized_display().cyan() + interpreter.sys_executable().simplified_display().cyan() ); if let Some(python_version) = python_version.as_ref() { // If the requested version does not match the version we're using warn the user @@ -416,7 +416,7 @@ pub(crate) async fn pip_compile( fn cmd(include_index_url: bool, include_find_links: bool) -> String { let args = env::args_os() .skip(1) - .map(|arg| arg.normalized_display().to_string()) + .map(|arg| arg.simplified_display().to_string()) .scan(None, move |skip_next, arg| { if matches!(skip_next, Some(true)) { // Reset state; skip this iteration. diff --git a/crates/uv/src/commands/pip_freeze.rs b/crates/uv/src/commands/pip_freeze.rs index a88465c1a..1c4f6848c 100644 --- a/crates/uv/src/commands/pip_freeze.rs +++ b/crates/uv/src/commands/pip_freeze.rs @@ -9,7 +9,7 @@ use tracing::debug; use distribution_types::{InstalledDist, Name}; use platform_host::Platform; use uv_cache::Cache; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_installer::SitePackages; use uv_interpreter::PythonEnvironment; @@ -43,7 +43,7 @@ pub(crate) fn pip_freeze( debug!( "Using Python {} environment at {}", venv.interpreter().python_version(), - venv.python_executable().normalized_display().cyan() + venv.python_executable().simplified_display().cyan() ); // Build the installed index. diff --git a/crates/uv/src/commands/pip_install.rs b/crates/uv/src/commands/pip_install.rs index 65ceb9210..f2dbf2e1e 100644 --- a/crates/uv/src/commands/pip_install.rs +++ b/crates/uv/src/commands/pip_install.rs @@ -22,7 +22,7 @@ use requirements_txt::EditableRequirement; use uv_cache::Cache; use uv_client::{Connectivity, FlatIndex, FlatIndexClient, RegistryClient, RegistryClientBuilder}; use uv_dispatch::BuildDispatch; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_installer::{ BuiltEditable, Downloader, NoBinary, Plan, Planner, Reinstall, ResolvedEditable, SitePackages, }; @@ -116,7 +116,7 @@ pub(crate) async fn pip_install( debug!( "Using Python {} environment at {}", venv.interpreter().python_version(), - venv.python_executable().normalized_display().cyan() + venv.python_executable().simplified_display().cyan() ); // If the environment is externally managed, abort. @@ -124,13 +124,13 @@ pub(crate) async fn pip_install( return if let Some(error) = externally_managed.into_error() { Err(anyhow::anyhow!( "The interpreter at {} is externally managed, and indicates the following:\n\n{}\n\nConsider creating a virtual environment with `uv venv`.", - venv.root().normalized_display().cyan(), + venv.root().simplified_display().cyan(), textwrap::indent(&error, " ").green(), )) } else { Err(anyhow::anyhow!( "The interpreter at {} is externally managed. Instead, create a virtual environment with `uv venv`.", - venv.root().normalized_display().cyan() + venv.root().simplified_display().cyan() )) }; } diff --git a/crates/uv/src/commands/pip_list.rs b/crates/uv/src/commands/pip_list.rs index 2ca1d9c18..ccb12f62c 100644 --- a/crates/uv/src/commands/pip_list.rs +++ b/crates/uv/src/commands/pip_list.rs @@ -11,7 +11,7 @@ use unicode_width::UnicodeWidthStr; use distribution_types::Name; use platform_host::Platform; use uv_cache::Cache; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_installer::SitePackages; use uv_interpreter::PythonEnvironment; use uv_normalize::PackageName; @@ -50,7 +50,7 @@ pub(crate) fn pip_list( debug!( "Using Python {} environment at {}", venv.interpreter().python_version(), - venv.python_executable().normalized_display().cyan() + venv.python_executable().simplified_display().cyan() ); // Build the installed index. diff --git a/crates/uv/src/commands/pip_sync.rs b/crates/uv/src/commands/pip_sync.rs index 09877894c..3ba139452 100644 --- a/crates/uv/src/commands/pip_sync.rs +++ b/crates/uv/src/commands/pip_sync.rs @@ -14,7 +14,7 @@ use requirements_txt::EditableRequirement; use uv_cache::Cache; use uv_client::{Connectivity, FlatIndex, FlatIndexClient, RegistryClient, RegistryClientBuilder}; use uv_dispatch::BuildDispatch; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_installer::{ is_dynamic, not_modified, Downloader, NoBinary, Plan, Planner, Reinstall, ResolvedEditable, SitePackages, @@ -84,7 +84,7 @@ pub(crate) async fn pip_sync( debug!( "Using Python {} environment at {}", venv.interpreter().python_version(), - venv.python_executable().normalized_display().cyan() + venv.python_executable().simplified_display().cyan() ); // If the environment is externally managed, abort. @@ -92,13 +92,13 @@ pub(crate) async fn pip_sync( return if let Some(error) = externally_managed.into_error() { Err(anyhow::anyhow!( "The interpreter at {} is externally managed, and indicates the following:\n\n{}\n\nConsider creating a virtual environment with `uv venv`.", - venv.root().normalized_display().cyan(), + venv.root().simplified_display().cyan(), textwrap::indent(&error, " ").green(), )) } else { Err(anyhow::anyhow!( "The interpreter at {} is externally managed. Instead, create a virtual environment with `uv venv`.", - venv.root().normalized_display().cyan() + venv.root().simplified_display().cyan() )) }; } diff --git a/crates/uv/src/commands/pip_uninstall.rs b/crates/uv/src/commands/pip_uninstall.rs index bcf55b218..96be3d62b 100644 --- a/crates/uv/src/commands/pip_uninstall.rs +++ b/crates/uv/src/commands/pip_uninstall.rs @@ -7,7 +7,7 @@ use tracing::debug; use distribution_types::{InstalledMetadata, Name}; use platform_host::Platform; use uv_cache::Cache; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_interpreter::PythonEnvironment; use crate::commands::{elapsed, ExitStatus}; @@ -50,7 +50,7 @@ pub(crate) async fn pip_uninstall( debug!( "Using Python {} environment at {}", venv.interpreter().python_version(), - venv.python_executable().normalized_display().cyan(), + venv.python_executable().simplified_display().cyan(), ); // If the environment is externally managed, abort. @@ -58,13 +58,13 @@ pub(crate) async fn pip_uninstall( return if let Some(error) = externally_managed.into_error() { Err(anyhow::anyhow!( "The interpreter at {} is externally managed, and indicates the following:\n\n{}\n\nConsider creating a virtual environment with `uv venv`.", - venv.root().normalized_display().cyan(), + venv.root().simplified_display().cyan(), textwrap::indent(&error, " ").green(), )) } else { Err(anyhow::anyhow!( "The interpreter at {} is externally managed. Instead, create a virtual environment with `uv venv`.", - venv.root().normalized_display().cyan() + venv.root().simplified_display().cyan() )) }; } diff --git a/crates/uv/src/commands/venv.rs b/crates/uv/src/commands/venv.rs index 412a2e66e..04e7da5a3 100644 --- a/crates/uv/src/commands/venv.rs +++ b/crates/uv/src/commands/venv.rs @@ -18,7 +18,7 @@ use platform_host::Platform; use uv_cache::Cache; use uv_client::{Connectivity, FlatIndex, FlatIndexClient, RegistryClientBuilder}; use uv_dispatch::BuildDispatch; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_installer::NoBinary; use uv_interpreter::{find_default_python, find_requested_python, Error}; use uv_resolver::{InMemoryIndex, OptionsBuilder}; @@ -108,14 +108,14 @@ async fn venv_impl( printer, "Using Python {} interpreter at: {}", interpreter.python_version(), - interpreter.sys_executable().normalized_display().cyan() + interpreter.sys_executable().simplified_display().cyan() ) .into_diagnostic()?; writeln!( printer, "Creating virtualenv at: {}", - path.normalized_display().cyan() + path.simplified_display().cyan() ) .into_diagnostic()?; @@ -214,7 +214,7 @@ async fn venv_impl( "Activate with: {}", path.join("Scripts") .join("activate") - .normalized_display() + .simplified_display() .green() ) .into_diagnostic()?; @@ -224,7 +224,7 @@ async fn venv_impl( "Activate with: {}", format!( "source {}", - path.join("bin").join("activate").normalized_display() + path.join("bin").join("activate").simplified_display() ) .green() ) diff --git a/crates/uv/src/requirements.rs b/crates/uv/src/requirements.rs index 287456331..f7d9fb0c9 100644 --- a/crates/uv/src/requirements.rs +++ b/crates/uv/src/requirements.rs @@ -12,7 +12,7 @@ use distribution_types::{FlatIndexLocation, IndexUrl}; use pep508_rs::Requirement; use requirements_txt::{EditableRequirement, FindLink, RequirementsTxt}; use tracing::{instrument, Level}; -use uv_fs::Normalized; +use uv_fs::Simplified; use uv_normalize::{ExtraName, PackageName}; use crate::confirm; @@ -208,7 +208,7 @@ impl RequirementsSpecification { RequirementsSource::PyprojectToml(path) => { let contents = uv_fs::read_to_string(path)?; let pyproject_toml = toml::from_str::(&contents) - .with_context(|| format!("Failed to parse `{}`", path.normalized_display()))?; + .with_context(|| format!("Failed to parse `{}`", path.simplified_display()))?; let mut used_extras = FxHashSet::default(); let mut requirements = Vec::new(); let mut project_name = None; @@ -217,7 +217,7 @@ impl RequirementsSpecification { // Parse the project name. let parsed_project_name = PackageName::new(project.name).with_context(|| { - format!("Invalid `project.name` in {}", path.normalized_display()) + format!("Invalid `project.name` in {}", path.simplified_display()) })?; // Include the default dependencies. @@ -253,7 +253,7 @@ impl RequirementsSpecification { .any(|v| v.name.as_dist_info_name().starts_with("poetry")) }) { - warn_user!("`{}` does not contain any dependencies (hint: specify dependencies in the `project.dependencies` section; `tool.poetry.dependencies` is not currently supported)", path.normalized_display()); + warn_user!("`{}` does not contain any dependencies (hint: specify dependencies in the `project.dependencies` section; `tool.poetry.dependencies` is not currently supported)", path.simplified_display()); } Self { diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index dbc927e94..e9e9609f4 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -15,7 +15,7 @@ use std::env; use std::ffi::OsString; use std::path::{Path, PathBuf}; use std::process::Output; -use uv_fs::Normalized; +use uv_fs::Simplified; use platform_host::Platform; use uv_cache::Cache; @@ -139,7 +139,7 @@ impl TestContext { .canonicalize() .expect("Failed to create canonical path") // Normalize the path to match display and remove UNC prefixes on Windows - .normalized() + .simplified() .display() .to_string(), ) @@ -150,7 +150,7 @@ impl TestContext { // Include a non-canonicalized version format!( r"{}\\?/?", - regex::escape(&path.as_ref().normalized().display().to_string()) + regex::escape(&path.as_ref().simplified().display().to_string()) .replace(r"\\", r"(\\|\/)") ), ] diff --git a/crates/uv/tests/pip_compile.rs b/crates/uv/tests/pip_compile.rs index 0b5721e28..72d1fb9f4 100644 --- a/crates/uv/tests/pip_compile.rs +++ b/crates/uv/tests/pip_compile.rs @@ -12,7 +12,7 @@ use indoc::indoc; use url::Url; use common::{uv_snapshot, TestContext, INSTA_FILTERS}; -use uv_fs::Normalized; +use uv_fs::Simplified; use crate::common::{get_bin, EXCLUDE_NEWER}; @@ -1917,7 +1917,7 @@ fn compile_wheel_path_dependency() -> Result<()> { requirements_in.write_str(&format!("flask @ {}", flask_wheel.path().display()))?; // In addition to the standard filters, remove the temporary directory from the snapshot. - let filter_path = regex::escape(&flask_wheel.normalized_display().to_string()); + let filter_path = regex::escape(&flask_wheel.simplified_display().to_string()); let filters: Vec<_> = [(filter_path.as_str(), "/[TEMP_DIR]/")] .into_iter() .chain(INSTA_FILTERS.to_vec()) @@ -2345,7 +2345,7 @@ fn compile_editable() -> Result<()> { " })?; - let filter_path = regex::escape(&requirements_in.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_in.simplified_display().to_string()); let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")] .into_iter() .chain(INSTA_FILTERS.to_vec()) @@ -2406,7 +2406,7 @@ fn recursive_extras_direct_url() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black[dev] @ ../../scripts/editable-installs/black_editable")?; - let filter_path = regex::escape(&requirements_in.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_in.simplified_display().to_string()); let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")] .into_iter() .chain(INSTA_FILTERS.to_vec()) @@ -2469,7 +2469,7 @@ fn compile_editable_url_requirement() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("-e ../../scripts/editable-installs/hatchling_editable")?; - let filter_path = regex::escape(&requirements_in.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_in.simplified_display().to_string()); let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")] .into_iter() .chain(INSTA_FILTERS.to_vec()) @@ -2560,7 +2560,7 @@ fn cache_errors_are_non_fatal() -> Result<()> { for file in &cache_files { let file = context.cache_dir.join(file); if !file.is_file() { - bail!("Missing cache file {}", file.normalized_display()); + bail!("Missing cache file {}", file.simplified_display()); } fs_err::write(file, "I borken you cache")?; } @@ -2575,7 +2575,7 @@ fn cache_errors_are_non_fatal() -> Result<()> { for file in cache_files { let file = context.cache_dir.join(file); if !file.is_file() { - bail!("Missing cache file {}", file.normalized_display()); + bail!("Missing cache file {}", file.simplified_display()); } fs_err::OpenOptions::new() @@ -2876,7 +2876,7 @@ fn find_links_directory() -> Result<()> { "})?; let project_root = fs_err::canonicalize(std::env::current_dir()?.join("..").join(".."))?; - let project_root_string = regex::escape(&project_root.normalized_display().to_string()); + let project_root_string = regex::escape(&project_root.simplified_display().to_string()); let filters: Vec<_> = [ (project_root_string.as_str(), "[PROJECT_ROOT]"), // Unify trailing (back)slash between Windows and Unix. @@ -3941,7 +3941,7 @@ fn editable_invalid_extra() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("-e ../../scripts/editable-installs/black_editable[empty]")?; - let requirements_path = regex::escape(&requirements_in.normalized_display().to_string()); + let requirements_path = regex::escape(&requirements_in.simplified_display().to_string()); let filters: Vec<_> = [ (r" file://.*/", " file://[TEMP_DIR]/"), (requirements_path.as_str(), "requirements.in"), @@ -4125,8 +4125,8 @@ fn override_editable() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("black==23.10.1")?; - let requirements_path = regex::escape(&requirements_in.normalized_display().to_string()); - let overrides_path = regex::escape(&overrides_txt.normalized_display().to_string()); + let requirements_path = regex::escape(&requirements_in.simplified_display().to_string()); + let overrides_path = regex::escape(&overrides_txt.simplified_display().to_string()); let filters: Vec<_> = [ (requirements_path.as_str(), "requirements.in"), (overrides_path.as_str(), "overrides.txt"), diff --git a/crates/uv/tests/pip_sync.rs b/crates/uv/tests/pip_sync.rs index e0f53d973..bcb1fd55e 100644 --- a/crates/uv/tests/pip_sync.rs +++ b/crates/uv/tests/pip_sync.rs @@ -14,7 +14,7 @@ use url::Url; use common::{ create_bin_with_executables, create_venv, uv_snapshot, venv_to_interpreter, INSTA_FILTERS, }; -use uv_fs::Normalized; +use uv_fs::Simplified; use crate::common::{get_bin, TestContext}; @@ -2193,10 +2193,10 @@ fn sync_editable() -> Result<()> { # via poetry-editable -e file://{current_dir}/../../scripts/editable-installs/poetry_editable ", - current_dir = current_dir.normalized_display(), + current_dir = current_dir.simplified_display(), })?; - let filter_path = regex::escape(&requirements_txt.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_txt.simplified_display().to_string()); let filters = INSTA_FILTERS .iter() .chain(&[ @@ -2334,7 +2334,7 @@ fn sync_editable_and_registry() -> Result<()> { " })?; - let filter_path = regex::escape(&requirements_txt.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_txt.simplified_display().to_string()); let filters = INSTA_FILTERS .iter() .chain(&[ @@ -2377,7 +2377,7 @@ fn sync_editable_and_registry() -> Result<()> { " })?; - let filter_path = regex::escape(&requirements_txt.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_txt.simplified_display().to_string()); let filters = INSTA_FILTERS .iter() .chain(&[ @@ -2416,7 +2416,7 @@ fn sync_editable_and_registry() -> Result<()> { " })?; - let filter_path = regex::escape(&requirements_txt.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_txt.simplified_display().to_string()); let filters = INSTA_FILTERS .iter() .chain(&[ @@ -2450,7 +2450,7 @@ fn sync_editable_and_registry() -> Result<()> { " })?; - let filter_path = regex::escape(&requirements_txt.normalized_display().to_string()); + let filter_path = regex::escape(&requirements_txt.simplified_display().to_string()); let filters = INSTA_FILTERS .iter() .chain(&[ @@ -2508,7 +2508,7 @@ fn incompatible_wheel() -> Result<()> { &wheel_dir .path() .canonicalize()? - .normalized_display() + .simplified_display() .to_string(), ); let filters: Vec<_> = [(wheel_dir.as_str(), "[TEMP_DIR]")] @@ -2597,7 +2597,7 @@ fn find_links() -> Result<()> { "})?; let project_root = fs_err::canonicalize(std::env::current_dir()?.join("../.."))?; - let project_root_string = regex::escape(&project_root.normalized_display().to_string()); + let project_root_string = regex::escape(&project_root.simplified_display().to_string()); let filters: Vec<_> = [(project_root_string.as_str(), "[PROJECT_ROOT]")] .into_iter() .chain(INSTA_FILTERS.to_vec()) diff --git a/crates/uv/tests/pip_uninstall.rs b/crates/uv/tests/pip_uninstall.rs index 1fd837464..18ee8d7cf 100644 --- a/crates/uv/tests/pip_uninstall.rs +++ b/crates/uv/tests/pip_uninstall.rs @@ -6,7 +6,7 @@ use assert_fs::prelude::*; use url::Url; use common::{uv_snapshot, INSTA_FILTERS}; -use uv_fs::Normalized; +use uv_fs::Simplified; use crate::common::{get_bin, venv_to_interpreter, TestContext}; @@ -332,7 +332,7 @@ fn missing_record() -> Result<()> { let dist_info_str = regex::escape(&format!( "RECORD file not found at: {}", - dist_info.normalized_display() + dist_info.simplified_display() )); let filters: Vec<_> = [( dist_info_str.as_str(), diff --git a/crates/uv/tests/venv.rs b/crates/uv/tests/venv.rs index 75eff3d65..ea3c213fa 100644 --- a/crates/uv/tests/venv.rs +++ b/crates/uv/tests/venv.rs @@ -5,7 +5,7 @@ use std::process::Command; use anyhow::Result; use assert_fs::prelude::*; -use uv_fs::Normalized; +use uv_fs::Simplified; use crate::common::{ create_bin_with_executables, get_bin, uv_snapshot, TestContext, EXCLUDE_NEWER, @@ -21,7 +21,7 @@ fn create_venv() -> Result<()> { let venv = temp_dir.child(".venv"); // Create a virtual environment at `.venv`. - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ ( @@ -59,7 +59,7 @@ fn create_venv() -> Result<()> { venv.assert(predicates::path::is_dir()); // Create a virtual environment at the same location, which should replace it. - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ ( @@ -107,7 +107,7 @@ fn create_venv_defaults_to_cwd() -> Result<()> { let bin = create_bin_with_executables(&temp_dir, &["3.12"]).expect("Failed to create bin dir"); let venv = temp_dir.child(".venv"); - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ ( @@ -151,7 +151,7 @@ fn seed() -> Result<()> { let bin = create_bin_with_executables(&temp_dir, &["3.12"]).expect("Failed to create bin dir"); let venv = temp_dir.child(".venv"); - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ ( @@ -201,7 +201,7 @@ fn seed_older_python_version() -> Result<()> { let bin = create_bin_with_executables(&temp_dir, &["3.10"]).expect("Failed to create bin dir"); let venv = temp_dir.child(".venv"); - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ ( @@ -300,7 +300,7 @@ fn create_venv_unknown_python_patch() -> Result<()> { let bin = create_bin_with_executables(&temp_dir, &["3.12"]).expect("Failed to create bin dir"); let venv = temp_dir.child(".venv"); - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filters = &[ ( r"Using Python 3\.\d+\.\d+ interpreter at: .+", @@ -346,7 +346,7 @@ fn create_venv_python_patch() -> Result<()> { create_bin_with_executables(&temp_dir, &["3.12.1"]).expect("Failed to create bin dir"); let venv = temp_dir.child(".venv"); - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ (r"interpreter at: .+", "interpreter at: [PATH]"), @@ -394,7 +394,7 @@ fn file_exists() -> Result<()> { // Create a file at `.venv`. Creating a virtualenv at the same path should fail. venv.touch()?; - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filters = &[ ( r"Using Python 3\.\d+\.\d+ interpreter at: .+", @@ -441,7 +441,7 @@ fn empty_dir_exists() -> Result<()> { // Create an empty directory at `.venv`. Creating a virtualenv at the same path should succeed. venv.create_dir_all()?; - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ ( @@ -493,7 +493,7 @@ fn non_empty_dir_exists() -> Result<()> { venv.create_dir_all()?; venv.child("file").touch()?; - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filters = &[ ( r"Using Python 3\.\d+\.\d+ interpreter at: .+", @@ -557,7 +557,7 @@ fn windows_shims() -> Result<()> { )?; // Create a virtual environment at `.venv`, passing the redundant `--clear` flag. - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ ( @@ -578,7 +578,7 @@ fn windows_shims() -> Result<()> { .arg(cache_dir.path()) .arg("--exclude-newer") .arg(EXCLUDE_NEWER) - .env("UV_TEST_PYTHON_PATH", format!("{};{}", shim_path.display(), bin.normalized_display())) + .env("UV_TEST_PYTHON_PATH", format!("{};{}", shim_path.display(), bin.simplified_display())) .current_dir(&temp_dir), @r###" success: true exit_code: 0 @@ -605,7 +605,7 @@ fn virtualenv_compatibility() -> Result<()> { let venv = temp_dir.child(".venv"); // Create a virtual environment at `.venv`, passing the redundant `--clear` flag. - let filter_venv = regex::escape(&venv.normalized_display().to_string()); + let filter_venv = regex::escape(&venv.simplified_display().to_string()); let filter_prompt = r"Activate with: (?:.*)\\Scripts\\activate"; let filters = &[ (