Add support for global uv python pin (#12115)

These changes add support for

```
uv python pin 3.12 --global 
```

This adds the specified version to a `.python-version` file in the
user-level config directory. uv will now use the user-level version as a
fallback if no version is found in the project directory or its
ancestors.

Closes #4972
This commit is contained in:
John Mumm 2025-03-13 13:48:37 +01:00 committed by GitHub
parent b4eabf9a61
commit 797f1fbac0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 366 additions and 16 deletions

View file

@ -4,6 +4,7 @@ use std::path::{Path, PathBuf};
use fs_err as fs;
use itertools::Itertools;
use tracing::debug;
use uv_dirs::user_uv_config_dir;
use uv_fs::Simplified;
use crate::PythonRequest;
@ -69,7 +70,13 @@ impl PythonVersionFile {
options: &DiscoveryOptions<'_>,
) -> Result<Option<Self>, std::io::Error> {
let Some(path) = Self::find_nearest(working_directory, options) else {
return Ok(None);
// Not found in directory or its ancestors. Looking in user-level config.
return Ok(match user_uv_config_dir() {
Some(user_dir) => Self::discover_user_config(user_dir, options)
.await?
.or(None),
None => None,
});
};
if options.no_config {
@ -84,6 +91,22 @@ impl PythonVersionFile {
Self::try_from_path(path).await
}
pub async fn discover_user_config(
user_config_working_directory: impl AsRef<Path>,
options: &DiscoveryOptions<'_>,
) -> Result<Option<Self>, std::io::Error> {
if !options.no_config {
if let Some(path) =
Self::find_in_directory(user_config_working_directory.as_ref(), options)
.into_iter()
.find(|path| path.is_file())
{
return Self::try_from_path(path).await;
}
}
Ok(None)
}
fn find_nearest(path: impl AsRef<Path>, options: &DiscoveryOptions<'_>) -> Option<PathBuf> {
path.as_ref()
.ancestors()