Skip to content

Commit

Permalink
Add color to python pin CLI (#5215)
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jul 19, 2024
1 parent 12dd450 commit 7762d78
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 43 deletions.
13 changes: 7 additions & 6 deletions crates/uv-python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ pub use crate::prefix::Prefix;
pub use crate::python_version::PythonVersion;
pub use crate::target::Target;
pub use crate::version_files::{
request_from_version_file, requests_from_version_file, PYTHON_VERSIONS_FILENAME,
PYTHON_VERSION_FILENAME,
request_from_version_file, requests_from_version_file, write_version_file,
PYTHON_VERSIONS_FILENAME, PYTHON_VERSION_FILENAME,
};
pub use crate::virtualenv::{Error as VirtualEnvError, PyVenvConfiguration, VirtualEnvironment};

mod discovery;
pub mod downloads;
mod environment;
Expand Down Expand Up @@ -83,19 +84,19 @@ pub enum Error {
// TODO(zanieb): We should write a mock interpreter script that works on Windows
#[cfg(all(test, unix))]
mod tests {
use anyhow::Result;
use indoc::{formatdoc, indoc};

use std::{
env,
ffi::{OsStr, OsString},
path::{Path, PathBuf},
str::FromStr,
};

use anyhow::Result;
use assert_fs::{fixture::ChildPath, prelude::*, TempDir};
use indoc::{formatdoc, indoc};
use temp_env::with_vars;
use test_log::test;

use assert_fs::{fixture::ChildPath, prelude::*, TempDir};
use uv_cache::Cache;

use crate::{
Expand Down
6 changes: 6 additions & 0 deletions crates/uv-python/src/version_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ pub async fn request_from_version_file() -> Result<Option<PythonRequest>, std::i
}
}

/// Write a version to a .`python-version` file.
pub async fn write_version_file(version: &str) -> Result<(), std::io::Error> {
debug!("Writing Python version `{version}` to `{PYTHON_VERSION_FILENAME}`");
fs::tokio::write(PYTHON_VERSION_FILENAME, format!("{version}\n")).await
}

async fn read_versions_file() -> Result<Option<Vec<String>>, std::io::Error> {
match fs::tokio::read_to_string(PYTHON_VERSIONS_FILENAME).await {
Ok(content) => {
Expand Down
37 changes: 24 additions & 13 deletions crates/uv/src/commands/python/pin.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use std::fmt::Write;
use std::path::PathBuf;

use anyhow::{bail, Result};
use owo_colors::OwoColorize;

use tracing::debug;
use uv_cache::Cache;
use uv_configuration::PreviewMode;
use uv_fs::Simplified;
use uv_python::{
requests_from_version_file, EnvironmentPreference, PythonInstallation, PythonPreference,
PythonRequest, PYTHON_VERSION_FILENAME,
request_from_version_file, requests_from_version_file, write_version_file,
EnvironmentPreference, PythonInstallation, PythonPreference, PythonRequest,
PYTHON_VERSION_FILENAME,
};
use uv_warnings::warn_user_once;

Expand Down Expand Up @@ -50,7 +50,7 @@ pub(crate) async fn pin(
Ok(python) => Some(python),
// If no matching Python version is found, don't fail unless `resolved` was requested
Err(uv_python::Error::MissingPython(err)) if !resolved => {
warn_user_once!("{}", err);
warn_user_once!("{err}");
None
}
Err(err) => return Err(err.into()),
Expand All @@ -68,16 +68,27 @@ pub(crate) async fn pin(
request.to_canonical_string()
};

debug!("Using pin `{}`", output);
let version_file = PathBuf::from(PYTHON_VERSION_FILENAME);
let exists = version_file.exists();
let existing = request_from_version_file().await.ok().flatten();
write_version_file(&output).await?;

debug!("Writing pin to {}", version_file.user_display());
fs_err::write(&version_file, format!("{output}\n"))?;
if exists {
writeln!(printer.stdout(), "Replaced existing pin with `{output}`")?;
if let Some(existing) = existing
.map(|existing| existing.to_canonical_string())
.filter(|existing| existing != &output)
{
writeln!(
printer.stdout(),
"Updated `{}` from `{}` -> `{}`",
PYTHON_VERSION_FILENAME.cyan(),
existing.green(),
output.green()
)?;
} else {
writeln!(printer.stdout(), "Pinned to `{output}`")?;
writeln!(
printer.stdout(),
"Pinned `{}` to `{}`",
PYTHON_VERSION_FILENAME.cyan(),
output.green()
)?;
}

Ok(ExitStatus::Success)
Expand Down
48 changes: 24 additions & 24 deletions crates/uv/tests/python_pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Pinned to `any`
Pinned `.python-version` to `any`
----- stderr -----
"###);
Expand Down Expand Up @@ -57,7 +57,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `3.12`
Updated `.python-version` from `any` -> `3.12`
----- stderr -----
"###);
Expand All @@ -73,7 +73,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `3.11`
Updated `.python-version` from `3.12` -> `3.11`
----- stderr -----
"###);
Expand All @@ -89,7 +89,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `cpython`
Updated `.python-version` from `3.11` -> `cpython`
----- stderr -----
"###);
Expand All @@ -105,7 +105,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[email protected]`
Updated `.python-version` from `cpython` -> `[email protected]`
----- stderr -----
"###);
Expand All @@ -121,7 +121,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[email protected]`
Pinned `.python-version` to `[email protected]`
----- stderr -----
"###);
Expand All @@ -137,7 +137,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `cpython-3.12-any-any-any`
Updated `.python-version` from `[email protected]` -> `cpython-3.12-any-any-any`
----- stderr -----
"###);
Expand All @@ -153,7 +153,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[PYTHON-3.11]`
Updated `.python-version` from `cpython-3.12-any-any-any` -> `[PYTHON-3.11]`
----- stderr -----
"###);
Expand All @@ -176,7 +176,7 @@ fn python_pin() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `pypy`
Updated `.python-version` from `[PYTHON-3.11]` -> `pypy`
----- stderr -----
warning: No interpreter found for PyPy in system path
Expand All @@ -194,14 +194,14 @@ fn python_pin() {
#[cfg(unix)]
{
uv_snapshot!(context.filters(), context.python_pin().arg("3.7"), @r###"
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `3.7`
success: true
exit_code: 0
----- stdout -----
Updated `.python-version` from `pypy` -> `3.7`
----- stderr -----
warning: No interpreter found for Python 3.7 in system path
"###);
----- stderr -----
warning: No interpreter found for Python 3.7 in system path
"###);

let python_version =
fs_err::read_to_string(context.temp_dir.join(PYTHON_VERSION_FILENAME)).unwrap();
Expand All @@ -222,7 +222,7 @@ fn python_pin_no_python() {
success: true
exit_code: 0
----- stdout -----
Pinned to `3.12`
Pinned `.python-version` to `3.12`
----- stderr -----
warning: No interpreter found for Python 3.12 in system path
Expand Down Expand Up @@ -264,7 +264,7 @@ fn python_pin_resolve() {
success: true
exit_code: 0
----- stdout -----
Pinned to `[PYTHON-3.11]`
Pinned `.python-version` to `[PYTHON-3.11]`
----- stderr -----
"###);
Expand All @@ -284,7 +284,7 @@ fn python_pin_resolve() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[PYTHON-3.12]`
Updated `.python-version` from `[PYTHON-3.11]` -> `[PYTHON-3.12]`
----- stderr -----
"###);
Expand All @@ -304,7 +304,7 @@ fn python_pin_resolve() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[PYTHON-3.11]`
Updated `.python-version` from `[PYTHON-3.12]` -> `[PYTHON-3.11]`
----- stderr -----
"###);
Expand All @@ -324,7 +324,7 @@ fn python_pin_resolve() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[PYTHON-3.11]`
Pinned `.python-version` to `[PYTHON-3.11]`
----- stderr -----
"###);
Expand All @@ -344,7 +344,7 @@ fn python_pin_resolve() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[PYTHON-3.12]`
Updated `.python-version` from `[PYTHON-3.11]` -> `[PYTHON-3.12]`
----- stderr -----
"###);
Expand All @@ -364,7 +364,7 @@ fn python_pin_resolve() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[PYTHON-3.12]`
Pinned `.python-version` to `[PYTHON-3.12]`
----- stderr -----
"###);
Expand All @@ -389,7 +389,7 @@ fn python_pin_resolve() {
success: true
exit_code: 0
----- stdout -----
Replaced existing pin with `[PYTHON-3.12]`
Pinned `.python-version` to `[PYTHON-3.12]`
----- stderr -----
"###);
Expand Down

0 comments on commit 7762d78

Please sign in to comment.