From bb5548c669f442a80995c85acb4b66d68d3efeda Mon Sep 17 00:00:00 2001 From: Ofek Lev Date: Tue, 23 Apr 2024 20:49:10 -0400 Subject: [PATCH] Fix non-Windows systems --- docs/changelog.md | 4 ++++ src/compression.rs | 32 ++++++++++++++++++++++++++------ src/distribution.rs | 37 +++++++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index e432004..71ef32a 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased +***Fixed:*** + +- Fix UV and the `VIRTUAL_ENV` environment variable on non-Windows systems + ## 0.18.0 - 2024-04-22 ***Added:*** diff --git a/src/compression.rs b/src/compression.rs index a12f51a..7cfc9d3 100644 --- a/src/compression.rs +++ b/src/compression.rs @@ -1,11 +1,15 @@ use std::fs::File; -use std::path::PathBuf; +use std::path::Path; use anyhow::{bail, Result}; use crate::terminal; -pub fn unpack(format: String, archive: &PathBuf, destination: &PathBuf) -> Result<()> { +pub fn unpack( + format: String, + archive: impl AsRef, + destination: impl AsRef, +) -> Result<()> { let wait_message = format!("Unpacking distribution ({})", format); match format.as_ref() { "tar|bzip2" => unpack_tar_bzip2(archive, destination, wait_message)?, @@ -18,7 +22,11 @@ pub fn unpack(format: String, archive: &PathBuf, destination: &PathBuf) -> Resul Ok(()) } -fn unpack_tar_bzip2(path: &PathBuf, destination: &PathBuf, wait_message: String) -> Result<()> { +fn unpack_tar_bzip2( + path: impl AsRef, + destination: impl AsRef, + wait_message: String, +) -> Result<()> { let bz = bzip2::read::BzDecoder::new(File::open(path)?); let mut archive = tar::Archive::new(bz); @@ -30,7 +38,11 @@ fn unpack_tar_bzip2(path: &PathBuf, destination: &PathBuf, wait_message: String) Ok(()) } -pub fn unpack_tar_gzip(path: &PathBuf, destination: &PathBuf, wait_message: String) -> Result<()> { +pub fn unpack_tar_gzip( + path: impl AsRef, + destination: impl AsRef, + wait_message: String, +) -> Result<()> { let gz = flate2::read::GzDecoder::new(File::open(path)?); let mut archive = tar::Archive::new(gz); @@ -42,7 +54,11 @@ pub fn unpack_tar_gzip(path: &PathBuf, destination: &PathBuf, wait_message: Stri Ok(()) } -fn unpack_tar_zstd(path: &PathBuf, destination: &PathBuf, wait_message: String) -> Result<()> { +fn unpack_tar_zstd( + path: impl AsRef, + destination: impl AsRef, + wait_message: String, +) -> Result<()> { let zst = zstd::stream::read::Decoder::new(File::open(path)?)?; let mut archive = tar::Archive::new(zst); @@ -54,7 +70,11 @@ fn unpack_tar_zstd(path: &PathBuf, destination: &PathBuf, wait_message: String) Ok(()) } -pub fn unpack_zip(path: &PathBuf, destination: &PathBuf, wait_message: String) -> Result<()> { +pub fn unpack_zip( + path: impl AsRef, + destination: impl AsRef, + wait_message: String, +) -> Result<()> { let mut archive = zip::ZipArchive::new(File::open(path)?)?; let spinner = terminal::spinner(wait_message); diff --git a/src/distribution.rs b/src/distribution.rs index 7b93cfb..e4d6fe4 100644 --- a/src/distribution.rs +++ b/src/distribution.rs @@ -1,7 +1,8 @@ use std::env; +use std::ffi::OsStr; use std::fs; use std::io::Write; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::process::{exit, Command, ExitStatus}; use anyhow::{bail, Context, Result}; @@ -41,7 +42,7 @@ fn apply_env_vars(command: &mut Command) { } if !app::full_isolation() { - command.env("VIRTUAL_ENV", python_dir); + command.env("VIRTUAL_ENV", python_dir.parent().unwrap()); } else if app::uv_as_installer() { command.env("UV_SYSTEM_PYTHON", "true"); } @@ -59,7 +60,7 @@ fn apply_env_vars(command: &mut Command) { } } -pub fn python_command(python: &PathBuf) -> Command { +pub fn python_command(python: &impl AsRef) -> Command { let mut command = Command::new(python); apply_env_vars(&mut command); command.arg(app::python_isolation_flag()); @@ -485,17 +486,33 @@ fn ensure_uv_available() -> Result<()> { ) }; - network::download( - &url, - &mut f, - managed_uv.file_name().unwrap().to_str().unwrap(), - )?; + network::download(&url, &mut f, "UV")?; if artifact_name.ends_with(".zip") { - compression::unpack_zip(&temp_path, &managed_uv_cache, "Unpacking UV".to_string()) + compression::unpack_zip(temp_path, dir.path(), "Unpacking UV".to_string()) } else { - compression::unpack_tar_gzip(&temp_path, &managed_uv_cache, "Unpacking UV".to_string()) + compression::unpack_tar_gzip(temp_path, dir.path(), "Unpacking UV".to_string()) } + .or_else(|err| { + bail!("unable to unpack to {}\n{}", dir.path().display(), err); + })?; + + let uv_file_name = managed_uv.file_name().unwrap(); + let mut binary_path = dir.path().join(uv_file_name); + + // Binary is nested in a directory with the same name as the artifact stem + if !binary_path.is_file() { + binary_path = dir + .path() + .join( + artifact_name + .trim_end_matches(".zip") + .trim_end_matches(".tar.gz"), + ) + .join(uv_file_name); + } + + fs_utils::move_temp_file(&binary_path, &managed_uv) } fn run_setup_command(command: Command, message: String) -> Result<(ExitStatus, String)> {