Skip to content

Commit

Permalink
Move version file reading to uv-toolchain
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb committed Jun 17, 2024
1 parent 05d79f8 commit 9f711ec
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 34 deletions.
2 changes: 2 additions & 0 deletions crates/uv-toolchain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub use crate::prefix::Prefix;
pub use crate::python_version::PythonVersion;
pub use crate::target::Target;
pub use crate::toolchain::Toolchain;
pub use crate::version_files::{request_from_version_files, requests_from_version_files};
pub use crate::virtualenv::{Error as VirtualEnvError, PyVenvConfiguration, VirtualEnvironment};

mod discovery;
Expand All @@ -28,6 +29,7 @@ mod py_launcher;
mod python_version;
mod target;
mod toolchain;
mod version_files;
mod virtualenv;

#[cfg(not(test))]
Expand Down
67 changes: 67 additions & 0 deletions crates/uv-toolchain/src/version_files.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use fs_err as fs;
use std::{io, path::PathBuf};
use tracing::debug;

use crate::ToolchainRequest;

/// Read [`ToolchainRequest`]s from a version file, if present.
///
/// Prefers `.python-versions` then `.python-version`.
/// If only one Python version is desired, use [`request_from_version_files`] which prefers the `.python-version` file.
pub async fn requests_from_version_files() -> Result<Option<Vec<ToolchainRequest>>, io::Error> {
if let Some(versions) = read_versions_file().await? {
Ok(Some(
versions
.into_iter()
.map(|version| ToolchainRequest::parse(&version))
.collect(),
))
} else if let Some(version) = read_version_file().await? {
Ok(Some(vec![ToolchainRequest::parse(&version)]))
} else {
Ok(None)
}
}

/// Read a [`ToolchainRequest`] from a version file, if present.
///
/// Prefers `.python-version` then the first entry of `.python-versions`.
/// If multiple Python versions are desired, use [`requests_from_version_files`] instead.
pub async fn request_from_version_files() -> Result<Option<ToolchainRequest>, io::Error> {
if let Some(version) = read_version_file().await? {
Ok(Some(ToolchainRequest::parse(&version)))
} else if let Some(versions) = read_versions_file().await? {
Ok(versions
.into_iter()
.next()
.inspect(|_| debug!("Using the first version from `.python-versions`"))
.map(|version| ToolchainRequest::parse(&version)))
} else {
Ok(None)
}
}

async fn read_versions_file() -> Result<Option<Vec<String>>, io::Error> {
if !PathBuf::from(".python-versions").try_exists()? {
return Ok(None);
}
debug!("Reading requests from `.python-versions`");
let lines: Vec<String> = fs::tokio::read_to_string(".python-versions")
.await?
.lines()
.map(ToString::to_string)
.collect();
Ok(Some(lines))
}

async fn read_version_file() -> Result<Option<String>, io::Error> {
if !PathBuf::from(".python-version").try_exists()? {
return Ok(None);
}
debug!("Reading requests from `.python-version`");
Ok(fs::tokio::read_to_string(".python-version")
.await?
.lines()
.next()
.map(ToString::to_string))
}
38 changes: 4 additions & 34 deletions crates/uv/src/commands/toolchain/install.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use anyhow::Result;
use fs_err as fs;
use futures::StreamExt;
use itertools::Itertools;
use std::fmt::Write;
use std::path::PathBuf;
use uv_cache::Cache;
use uv_client::Connectivity;
use uv_configuration::PreviewMode;
use uv_fs::Simplified;
use uv_toolchain::downloads::{self, DownloadResult, PythonDownload, PythonDownloadRequest};
use uv_toolchain::managed::{InstalledToolchain, InstalledToolchains};
use uv_toolchain::ToolchainRequest;
use uv_toolchain::{requests_from_version_files, ToolchainRequest};
use uv_warnings::warn_user;

use crate::commands::ExitStatus;
Expand All @@ -37,15 +35,10 @@ pub(crate) async fn install(
let toolchain_dir = toolchains.root();

let requests: Vec<_> = if targets.is_empty() {
if let Some(versions) = read_versions_file().await? {
versions
.into_iter()
.map(|version| ToolchainRequest::parse(&version))
.collect()
} else if let Some(version) = read_version_file().await? {
vec![ToolchainRequest::parse(&version)]
if let Some(requests) = requests_from_version_files().await? {
requests
} else {
vec![ToolchainRequest::default()]
vec![ToolchainRequest::Any]
}
} else {
targets
Expand Down Expand Up @@ -162,26 +155,3 @@ pub(crate) async fn install(

Ok(ExitStatus::Success)
}

async fn read_versions_file() -> Result<Option<Vec<String>>> {
if !PathBuf::from(".python-versions").try_exists()? {
return Ok(None);
}
let lines: Vec<String> = fs::tokio::read_to_string(".python-versions")
.await?
.lines()
.map(ToString::to_string)
.collect();
Ok(Some(lines))
}

async fn read_version_file() -> Result<Option<String>> {
if !PathBuf::from(".python-version").try_exists()? {
return Ok(None);
}
Ok(fs::tokio::read_to_string(".python-version")
.await?
.lines()
.next()
.map(ToString::to_string))
}

0 comments on commit 9f711ec

Please sign in to comment.