From 704964cbb794cfebc72e80fe5b796cd4725c1e18 Mon Sep 17 00:00:00 2001 From: j178 <10510431+j178@users.noreply.github.com> Date: Sat, 14 Dec 2024 15:13:34 +0800 Subject: [PATCH] Uv install python into tools path --- src/env_vars.rs | 3 ++ src/languages/python/impl.rs | 16 ++++++--- src/languages/python/uv.rs | 4 +-- src/store.rs | 67 +++++++++++++++++++++++++----------- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/env_vars.rs b/src/env_vars.rs index c4c7af1..0153223 100644 --- a/src/env_vars.rs +++ b/src/env_vars.rs @@ -9,4 +9,7 @@ impl EnvVars { pub const PRE_COMMIT_ALLOW_NO_CONFIG: &'static str = "PRE_COMMIT_ALLOW_NO_CONFIG"; pub const PRE_COMMIT_NO_CONCURRENCY: &'static str = "PRE_COMMIT_NO_CONCURRENCY"; pub const _PRE_COMMIT_SKIP_POST_CHECKOUT: &'static str = "_PRE_COMMIT_SKIP_POST_CHECKOUT"; + + pub const UV_NO_CACHE: &'static str = "UV_NO_CACHE"; + pub const UV_PYTHON_INSTALL_DIR: &'static str = "UV_PYTHON_INSTALL_DIR"; } diff --git a/src/languages/python/impl.rs b/src/languages/python/impl.rs index 08b1fca..c558770 100644 --- a/src/languages/python/impl.rs +++ b/src/languages/python/impl.rs @@ -1,3 +1,7 @@ +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use std::sync::Arc; + use crate::config::LanguageVersion; use crate::env_vars::EnvVars; use crate::hook::Hook; @@ -5,9 +9,7 @@ use crate::languages::python::uv::UvInstaller; use crate::languages::LanguageImpl; use crate::process::Cmd; use crate::run::run_by_batch; -use std::collections::HashMap; -use std::path::{Path, PathBuf}; -use std::sync::Arc; +use crate::store::{Store, ToolBucket}; #[derive(Debug, Copy, Clone)] pub struct Python; @@ -23,17 +25,21 @@ impl LanguageImpl for Python { let uv = UvInstaller::install().await?; + let store = Store::from_settings()?; + let python_install_dir = store.tools_path(ToolBucket::Python); + let uv_cmd = |summary| { #[allow(unused_mut)] let mut cmd = Cmd::new(&uv, summary); // Don't use cache in Windows, multiple uv instances will conflict with each other. // See https://github.com/astral-sh/uv/issues/8664 #[cfg(windows)] - cmd.env("UV_NO_CACHE", "1"); + cmd.env(EnvVars::UV_NO_CACHE, "1"); + + cmd.env(EnvVars::UV_PYTHON_INSTALL_DIR, &python_install_dir); cmd }; - // TODO: Set uv cache dir? tools dir? python dir? // Create venv let mut cmd = uv_cmd("create venv"); cmd.arg("venv").arg(&venv); diff --git a/src/languages/python/uv.rs b/src/languages/python/uv.rs index 3ec84f9..a94880d 100644 --- a/src/languages/python/uv.rs +++ b/src/languages/python/uv.rs @@ -9,7 +9,7 @@ use tracing::{debug, enabled, trace, warn}; use crate::fs::LockedFile; use crate::process::Cmd; -use crate::store::Store; +use crate::store::{Store, ToolBucket}; // The version of `uv` to install. Should update periodically. const UV_VERSION: &str = "0.5.8"; @@ -207,7 +207,7 @@ impl UvInstaller { // 2) Check if `uv` is installed by `prefligit` let store = Store::from_settings()?; - let uv_dir = store.uv_path(); + let uv_dir = store.tools_path(ToolBucket::Uv); let uv = uv_dir.join("uv").with_extension(env::consts::EXE_EXTENSION); if uv.is_file() { trace!(uv = %uv.display(), "Found managed uv"); diff --git a/src/store.rs b/src/store.rs index fdb385b..e6fc93c 100644 --- a/src/store.rs +++ b/src/store.rs @@ -1,4 +1,5 @@ use std::path::{Path, PathBuf}; +use std::sync::LazyLock; use anyhow::Result; use rusqlite::Connection; @@ -29,6 +30,28 @@ pub enum Error { Git(#[from] crate::git::Error), } +static STORE_HOME: LazyLock> = LazyLock::new(|| { + if let Some(path) = std::env::var_os(EnvVars::PRE_COMMIT_HOME) { + debug!( + path = %path.to_string_lossy(), + "Loading store from PRE_COMMIT_HOME", + ); + Some(path.into()) + } else if let Some(path) = std::env::var_os(EnvVars::XDG_CACHE_HOME) { + let path = PathBuf::from(path).join("pre-commit"); + debug!( + path = %path.to_string_lossy(), + "Loading store from XDG_CACHE_HOME", + ); + Some(path) + } else { + let home = home::home_dir()?; + let path = home.join(".cache").join("pre-commit"); + debug!(path = %path.display(), "Loading store from ~/.cache"); + Some(path) + } +}); + /// A store for managing repos. #[derive(Debug)] pub struct Store { @@ -38,25 +61,9 @@ pub struct Store { impl Store { pub fn from_settings() -> Result { - if let Some(path) = std::env::var_os(EnvVars::PRE_COMMIT_HOME) { - debug!( - path = %path.to_string_lossy(), - "Loading store from PRE_COMMIT_HOME", - ); - return Ok(Self::from_path(path)); - } else if let Some(path) = std::env::var_os(EnvVars::XDG_CACHE_HOME) { - let path = PathBuf::from(path).join("pre-commit"); - debug!( - path = %path.to_string_lossy(), - "Loading store from XDG_CACHE_HOME", - ); - return Ok(Self::from_path(path)); - } - - let home = home::home_dir().ok_or(Error::HomeNotFound)?; - let path = home.join(".cache").join("pre-commit"); - debug!(path = %path.display(), "Loading store from ~/.cache"); - Ok(Self::from_path(path)) + Ok(Self::from_path( + STORE_HOME.as_ref().ok_or(Error::HomeNotFound)?, + )) } pub fn from_path(path: impl Into) -> Self { @@ -267,8 +274,26 @@ impl Store { LockedFile::acquire(self.path.join(".lock"), "store").await } - pub fn uv_path(&self) -> PathBuf { - self.path.join("tools").join("uv") + /// The path to the tool directory in the store. + pub fn tools_path(&self, tool: ToolBucket) -> PathBuf { + self.path.join(tool.as_str()) + } +} + +#[derive(Copy, Clone)] +pub enum ToolBucket { + Uv, + Python, + Node, +} + +impl ToolBucket { + pub fn as_str(&self) -> &str { + match self { + ToolBucket::Uv => "uv", + ToolBucket::Python => "python", + ToolBucket::Node => "node", + } } }