Skip to content

Commit

Permalink
Uv install python into tools path
Browse files Browse the repository at this point in the history
  • Loading branch information
j178 committed Dec 14, 2024
1 parent 75e7f4c commit 704964c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 28 deletions.
3 changes: 3 additions & 0 deletions src/env_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
16 changes: 11 additions & 5 deletions src/languages/python/impl.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
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;
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;
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/languages/python/uv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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");
Expand Down
67 changes: 46 additions & 21 deletions src/store.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::path::{Path, PathBuf};
use std::sync::LazyLock;

use anyhow::Result;
use rusqlite::Connection;
Expand Down Expand Up @@ -29,6 +30,28 @@ pub enum Error {
Git(#[from] crate::git::Error),
}

static STORE_HOME: LazyLock<Option<PathBuf>> = 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 {
Expand All @@ -38,25 +61,9 @@ pub struct Store {

impl Store {
pub fn from_settings() -> Result<Self, Error> {
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<PathBuf>) -> Self {
Expand Down Expand Up @@ -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",
}
}
}

Expand Down

0 comments on commit 704964c

Please sign in to comment.