mirror of https://github.com/astral-sh/uv
Allow templating the `UV_PROJECT_ENVIRONMENT` path
This commit is contained in:
parent
0a51489ec4
commit
9cec7486c8
|
|
@ -14,6 +14,7 @@ bitflags::bitflags! {
|
||||||
const JSON_OUTPUT = 1 << 2;
|
const JSON_OUTPUT = 1 << 2;
|
||||||
const PYLOCK = 1 << 3;
|
const PYLOCK = 1 << 3;
|
||||||
const ADD_BOUNDS = 1 << 4;
|
const ADD_BOUNDS = 1 << 4;
|
||||||
|
const TEMPLATE_PROJECT_ENVIRONMENT = 1 << 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ use glob::{GlobError, PatternError, glob};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use tracing::{debug, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
use uv_configuration::DependencyGroupsWithDefaults;
|
use uv_cache_key::cache_digest;
|
||||||
|
use uv_configuration::{DependencyGroupsWithDefaults, Preview, PreviewFeatures};
|
||||||
use uv_distribution_types::{Index, Requirement, RequirementSource};
|
use uv_distribution_types::{Index, Requirement, RequirementSource};
|
||||||
use uv_fs::{CWD, Simplified};
|
use uv_fs::{CWD, Simplified};
|
||||||
use uv_normalize::{DEV_DEPENDENCIES, GroupName, PackageName};
|
use uv_normalize::{DEV_DEPENDENCIES, GroupName, PackageName};
|
||||||
|
|
@ -631,16 +632,46 @@ impl Workspace {
|
||||||
/// If `active` is `true`, the `VIRTUAL_ENV` variable will be preferred. If it is `false`, any
|
/// If `active` is `true`, the `VIRTUAL_ENV` variable will be preferred. If it is `false`, any
|
||||||
/// warnings about mismatch between the active environment and the project environment will be
|
/// warnings about mismatch between the active environment and the project environment will be
|
||||||
/// silenced.
|
/// silenced.
|
||||||
pub fn venv(&self, active: Option<bool>) -> PathBuf {
|
pub fn venv(&self, active: Option<bool>, preview: Preview) -> PathBuf {
|
||||||
/// Resolve the `UV_PROJECT_ENVIRONMENT` value, if any.
|
/// Resolve the `UV_PROJECT_ENVIRONMENT` value, if any.
|
||||||
fn from_project_environment_variable(workspace: &Workspace) -> Option<PathBuf> {
|
fn from_project_environment_variable(
|
||||||
|
workspace: &Workspace,
|
||||||
|
preview: Preview,
|
||||||
|
) -> Option<PathBuf> {
|
||||||
let value = std::env::var_os(EnvVars::UV_PROJECT_ENVIRONMENT)?;
|
let value = std::env::var_os(EnvVars::UV_PROJECT_ENVIRONMENT)?;
|
||||||
|
|
||||||
if value.is_empty() {
|
if value.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = PathBuf::from(value);
|
let templated = value
|
||||||
|
.to_string_lossy()
|
||||||
|
.replace(
|
||||||
|
"{project_path_hash}",
|
||||||
|
&cache_digest(&workspace.install_path),
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"{project_name}",
|
||||||
|
&workspace
|
||||||
|
.pyproject_toml
|
||||||
|
.project
|
||||||
|
.as_ref()
|
||||||
|
.map(|project| project.name.to_string())
|
||||||
|
.unwrap_or("none".to_string()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let path = if templated != value.to_string_lossy() {
|
||||||
|
if !preview.is_enabled(PreviewFeatures::TEMPLATE_PROJECT_ENVIRONMENT) {
|
||||||
|
warn_user_once!(
|
||||||
|
"Templating the `UV_PROJECT_ENVIRONMENT` setting is in preview and may change without warning; use `--preview-features {}` to disable this warning",
|
||||||
|
PreviewFeatures::TEMPLATE_PROJECT_ENVIRONMENT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
PathBuf::from(templated)
|
||||||
|
} else {
|
||||||
|
PathBuf::from(value)
|
||||||
|
};
|
||||||
|
|
||||||
if path.is_absolute() {
|
if path.is_absolute() {
|
||||||
return Some(path);
|
return Some(path);
|
||||||
}
|
}
|
||||||
|
|
@ -668,7 +699,7 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the default value
|
// Determine the default value
|
||||||
let project_env = from_project_environment_variable(self)
|
let project_env = from_project_environment_variable(self, preview)
|
||||||
.unwrap_or_else(|| self.install_path.join(".venv"));
|
.unwrap_or_else(|| self.install_path.join(".venv"));
|
||||||
|
|
||||||
// Warn if it conflicts with `VIRTUAL_ENV`
|
// Warn if it conflicts with `VIRTUAL_ENV`
|
||||||
|
|
|
||||||
|
|
@ -904,7 +904,7 @@ impl ProjectInterpreter {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Read from the virtual environment first.
|
// Read from the virtual environment first.
|
||||||
let root = workspace.venv(active);
|
let root = workspace.venv(active, preview);
|
||||||
match PythonEnvironment::from_root(&root, cache) {
|
match PythonEnvironment::from_root(&root, cache) {
|
||||||
Ok(venv) => {
|
Ok(venv) => {
|
||||||
match environment_is_usable(
|
match environment_is_usable(
|
||||||
|
|
@ -1307,7 +1307,7 @@ impl ProjectEnvironment {
|
||||||
|
|
||||||
// Otherwise, create a virtual environment with the discovered interpreter.
|
// Otherwise, create a virtual environment with the discovered interpreter.
|
||||||
ProjectInterpreter::Interpreter(interpreter) => {
|
ProjectInterpreter::Interpreter(interpreter) => {
|
||||||
let root = workspace.venv(active);
|
let root = workspace.venv(active, preview);
|
||||||
|
|
||||||
// Avoid removing things that are not virtual environments
|
// Avoid removing things that are not virtual environments
|
||||||
let replace = match (root.try_exists(), root.join("pyvenv.cfg").try_exists()) {
|
let replace = match (root.try_exists(), root.join("pyvenv.cfg").try_exists()) {
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ pub(crate) async fn venv(
|
||||||
// This isn't strictly necessary and we may want to change it later, but this
|
// This isn't strictly necessary and we may want to change it later, but this
|
||||||
// avoids a breaking change when adding project environment support to `uv venv`.
|
// avoids a breaking change when adding project environment support to `uv venv`.
|
||||||
(project.workspace().install_path() == project_dir)
|
(project.workspace().install_path() == project_dir)
|
||||||
.then(|| project.workspace().venv(Some(false)))
|
.then(|| project.workspace().venv(Some(false), preview))
|
||||||
})
|
})
|
||||||
.unwrap_or(PathBuf::from(".venv")),
|
.unwrap_or(PathBuf::from(".venv")),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue