From b9d661012d43f6bbc416ba0a326f7e9353670ca8 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 8 Jul 2024 09:15:25 -0500 Subject: [PATCH] Initialize all `--prefix` subdirectories (#4895) ## Summary We need to initialize the same directories that we create in `bare.rs`, since the installer expects them to exist. Closes #4892. --- crates/uv-python/src/environment.rs | 18 ++++++++---------- crates/uv-python/src/interpreter.rs | 16 ++++++++-------- crates/uv-python/src/prefix.rs | 6 ++++-- crates/uv/src/commands/pip/install.rs | 6 ++---- crates/uv/src/commands/pip/sync.rs | 6 ++---- crates/uv/src/commands/pip/uninstall.rs | 6 ++---- crates/uv/tests/pip_sync.rs | 4 ---- 7 files changed, 26 insertions(+), 36 deletions(-) diff --git a/crates/uv-python/src/environment.rs b/crates/uv-python/src/environment.rs index 14b1bc15e..661c117b5 100644 --- a/crates/uv-python/src/environment.rs +++ b/crates/uv-python/src/environment.rs @@ -127,23 +127,21 @@ impl PythonEnvironment { } /// Create a [`PythonEnvironment`] from an existing [`Interpreter`] and `--target` directory. - #[must_use] - pub fn with_target(self, target: Target) -> Self { + pub fn with_target(self, target: Target) -> std::io::Result { let inner = Arc::unwrap_or_clone(self.0); - Self(Arc::new(PythonEnvironmentShared { - interpreter: inner.interpreter.with_target(target), + Ok(Self(Arc::new(PythonEnvironmentShared { + interpreter: inner.interpreter.with_target(target)?, ..inner - })) + }))) } /// Create a [`PythonEnvironment`] from an existing [`Interpreter`] and `--prefix` directory. - #[must_use] - pub fn with_prefix(self, prefix: Prefix) -> Self { + pub fn with_prefix(self, prefix: Prefix) -> std::io::Result { let inner = Arc::unwrap_or_clone(self.0); - Self(Arc::new(PythonEnvironmentShared { - interpreter: inner.interpreter.with_prefix(prefix), + Ok(Self(Arc::new(PythonEnvironmentShared { + interpreter: inner.interpreter.with_prefix(prefix)?, ..inner - })) + }))) } /// Returns the root (i.e., `prefix`) of the Python interpreter. diff --git a/crates/uv-python/src/interpreter.rs b/crates/uv-python/src/interpreter.rs index 1abf15cf9..3922dad38 100644 --- a/crates/uv-python/src/interpreter.rs +++ b/crates/uv-python/src/interpreter.rs @@ -124,21 +124,21 @@ impl Interpreter { } /// Return a new [`Interpreter`] to install into the given `--target` directory. - #[must_use] - pub fn with_target(self, target: Target) -> Self { - Self { + pub fn with_target(self, target: Target) -> io::Result { + target.init()?; + Ok(Self { target: Some(target), ..self - } + }) } /// Return a new [`Interpreter`] to install into the given `--prefix` directory. - #[must_use] - pub fn with_prefix(self, prefix: Prefix) -> Self { - Self { + pub fn with_prefix(self, prefix: Prefix) -> io::Result { + prefix.init(self.virtualenv())?; + Ok(Self { prefix: Some(prefix), ..self - } + }) } /// Return the [`Interpreter`] for the base executable, if it's available. diff --git a/crates/uv-python/src/prefix.rs b/crates/uv-python/src/prefix.rs index 4d678fdd6..b88dc00f2 100644 --- a/crates/uv-python/src/prefix.rs +++ b/crates/uv-python/src/prefix.rs @@ -25,8 +25,10 @@ impl Prefix { } /// Initialize the `--prefix` directory. - pub fn init(&self) -> std::io::Result<()> { - fs_err::create_dir_all(&self.0)?; + pub fn init(&self, virtualenv: &Scheme) -> std::io::Result<()> { + for site_packages in self.site_packages(virtualenv) { + fs_err::create_dir_all(site_packages)?; + } Ok(()) } diff --git a/crates/uv/src/commands/pip/install.rs b/crates/uv/src/commands/pip/install.rs index a60d3202b..de84e7dbf 100644 --- a/crates/uv/src/commands/pip/install.rs +++ b/crates/uv/src/commands/pip/install.rs @@ -136,15 +136,13 @@ pub(crate) async fn pip_install( "Using `--target` directory at {}", target.root().user_display() ); - target.init()?; - environment.with_target(target) + environment.with_target(target)? } else if let Some(prefix) = prefix { debug!( "Using `--prefix` directory at {}", prefix.root().user_display() ); - prefix.init()?; - environment.with_prefix(prefix) + environment.with_prefix(prefix)? } else { environment }; diff --git a/crates/uv/src/commands/pip/sync.rs b/crates/uv/src/commands/pip/sync.rs index a1970f4f5..7154d64bf 100644 --- a/crates/uv/src/commands/pip/sync.rs +++ b/crates/uv/src/commands/pip/sync.rs @@ -134,15 +134,13 @@ pub(crate) async fn pip_sync( "Using `--target` directory at {}", target.root().user_display() ); - target.init()?; - environment.with_target(target) + environment.with_target(target)? } else if let Some(prefix) = prefix { debug!( "Using `--prefix` directory at {}", prefix.root().user_display() ); - prefix.init()?; - environment.with_prefix(prefix) + environment.with_prefix(prefix)? } else { environment }; diff --git a/crates/uv/src/commands/pip/uninstall.rs b/crates/uv/src/commands/pip/uninstall.rs index 2d975a548..de24e4928 100644 --- a/crates/uv/src/commands/pip/uninstall.rs +++ b/crates/uv/src/commands/pip/uninstall.rs @@ -67,15 +67,13 @@ pub(crate) async fn pip_uninstall( "Using `--target` directory at {}", target.root().user_display() ); - target.init()?; - environment.with_target(target) + environment.with_target(target)? } else if let Some(prefix) = prefix { debug!( "Using `--prefix` directory at {}", prefix.root().user_display() ); - prefix.init()?; - environment.with_prefix(prefix) + environment.with_prefix(prefix)? } else { environment }; diff --git a/crates/uv/tests/pip_sync.rs b/crates/uv/tests/pip_sync.rs index 9fe22150a..b080fcbf0 100644 --- a/crates/uv/tests/pip_sync.rs +++ b/crates/uv/tests/pip_sync.rs @@ -5104,10 +5104,6 @@ fn target_no_build_isolation() -> Result<()> { /// Sync to a `--prefix` directory. #[test] -#[cfg_attr( - target_os = "macos", - ignore = "On macOS, we fail to reflink due to a non-existent site-packages directory" -)] fn prefix() -> Result<()> { let context = TestContext::new("3.12");