mirror of https://github.com/astral-sh/uv
Add some compatibility arguments to `puffin venv` (#1282)
See: https://github.com/astral-sh/puffin/issues/1276.
This commit is contained in:
parent
93b7a1140f
commit
b386590b3c
|
|
@ -3,6 +3,10 @@ use clap::{Args, ValueEnum};
|
||||||
|
|
||||||
use puffin_warnings::warn_user;
|
use puffin_warnings::warn_user;
|
||||||
|
|
||||||
|
pub(crate) trait CompatArgs {
|
||||||
|
fn validate(&self) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Arguments for `pip-compile` compatibility.
|
/// Arguments for `pip-compile` compatibility.
|
||||||
///
|
///
|
||||||
/// These represent a subset of the `pip-compile` interface that Puffin supports by default.
|
/// These represent a subset of the `pip-compile` interface that Puffin supports by default.
|
||||||
|
|
@ -84,13 +88,13 @@ pub(crate) struct PipCompileCompatArgs {
|
||||||
pip_args: Option<String>,
|
pip_args: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipCompileCompatArgs {
|
impl CompatArgs for PipCompileCompatArgs {
|
||||||
/// Validate the arguments passed for `pip-compile` compatibility.
|
/// Validate the arguments passed for `pip-compile` compatibility.
|
||||||
///
|
///
|
||||||
/// This method will warn when an argument is passed that has no effect but matches Puffin's
|
/// This method will warn when an argument is passed that has no effect but matches Puffin's
|
||||||
/// behavior. If an argument is passed that does _not_ match Puffin's behavior (e.g.,
|
/// behavior. If an argument is passed that does _not_ match Puffin's behavior (e.g.,
|
||||||
/// `--no-build-isolation`), this method will return an error.
|
/// `--no-build-isolation`), this method will return an error.
|
||||||
pub(crate) fn validate(&self) -> Result<()> {
|
fn validate(&self) -> Result<()> {
|
||||||
if self.allow_unsafe {
|
if self.allow_unsafe {
|
||||||
warn_user!(
|
warn_user!(
|
||||||
"pip-compile's `--allow-unsafe` has no effect (Puffin can safely pin `pip` and other packages)."
|
"pip-compile's `--allow-unsafe` has no effect (Puffin can safely pin `pip` and other packages)."
|
||||||
|
|
@ -281,13 +285,13 @@ pub(crate) struct PipSyncCompatArgs {
|
||||||
pip_args: Option<String>,
|
pip_args: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipSyncCompatArgs {
|
impl CompatArgs for PipSyncCompatArgs {
|
||||||
/// Validate the arguments passed for `pip-sync` compatibility.
|
/// Validate the arguments passed for `pip-sync` compatibility.
|
||||||
///
|
///
|
||||||
/// This method will warn when an argument is passed that has no effect but matches Puffin's
|
/// This method will warn when an argument is passed that has no effect but matches Puffin's
|
||||||
/// behavior. If an argument is passed that does _not_ match Puffin's behavior, this method will
|
/// behavior. If an argument is passed that does _not_ match Puffin's behavior, this method will
|
||||||
/// return an error.
|
/// return an error.
|
||||||
pub(crate) fn validate(&self) -> Result<()> {
|
fn validate(&self) -> Result<()> {
|
||||||
if self.ask {
|
if self.ask {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"pip-sync's `--ask` is unsupported (Puffin never asks for confirmation)."
|
"pip-sync's `--ask` is unsupported (Puffin never asks for confirmation)."
|
||||||
|
|
@ -349,3 +353,64 @@ enum AnnotationStyle {
|
||||||
Line,
|
Line,
|
||||||
Split,
|
Split,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Arguments for `venv` compatibility.
|
||||||
|
///
|
||||||
|
/// These represent a subset of the `virtualenv` interface that Puffin supports by default.
|
||||||
|
#[derive(Args)]
|
||||||
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
|
pub(crate) struct VenvCompatArgs {
|
||||||
|
#[clap(long, hide = true)]
|
||||||
|
clear: bool,
|
||||||
|
|
||||||
|
#[clap(long, hide = true)]
|
||||||
|
no_seed: bool,
|
||||||
|
|
||||||
|
#[clap(long, hide = true)]
|
||||||
|
no_pip: bool,
|
||||||
|
|
||||||
|
#[clap(long, hide = true)]
|
||||||
|
no_setuptools: bool,
|
||||||
|
|
||||||
|
#[clap(long, hide = true)]
|
||||||
|
no_wheel: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompatArgs for VenvCompatArgs {
|
||||||
|
/// Validate the arguments passed for `venv` compatibility.
|
||||||
|
///
|
||||||
|
/// This method will warn when an argument is passed that has no effect but matches Puffin's
|
||||||
|
/// behavior. If an argument is passed that does _not_ match Puffin's behavior, this method will
|
||||||
|
/// return an error.
|
||||||
|
fn validate(&self) -> Result<()> {
|
||||||
|
if self.clear {
|
||||||
|
warn_user!(
|
||||||
|
"virtualenv's `--clear` has no effect (Puffin always clears the virtual environment)."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.no_seed {
|
||||||
|
warn_user!(
|
||||||
|
"virtualenv's `--no-seed` has no effect (Puffin omits seed packages by default)."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.no_pip {
|
||||||
|
warn_user!("virtualenv's `--no-pip` has no effect (Puffin omits `pip` by default).");
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.no_setuptools {
|
||||||
|
warn_user!(
|
||||||
|
"virtualenv's `--no-setuptools` has no effect (Puffin omits `setuptools` by default)."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.no_wheel {
|
||||||
|
warn_user!(
|
||||||
|
"virtualenv's `--no-wheel` has no effect (Puffin omits `wheel` by default)."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use puffin_traits::{NoBuild, PackageNameSpecifier, SetupPyStrategy};
|
||||||
use requirements::ExtrasSpecification;
|
use requirements::ExtrasSpecification;
|
||||||
|
|
||||||
use crate::commands::{extra_name_with_clap_error, ExitStatus, Upgrade};
|
use crate::commands::{extra_name_with_clap_error, ExitStatus, Upgrade};
|
||||||
|
use crate::compat::CompatArgs;
|
||||||
use crate::requirements::RequirementsSource;
|
use crate::requirements::RequirementsSource;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
|
|
@ -625,6 +626,9 @@ struct VenvArgs {
|
||||||
/// format (e.g., `2006-12-02`).
|
/// format (e.g., `2006-12-02`).
|
||||||
#[arg(long, value_parser = date_or_datetime, hide = true)]
|
#[arg(long, value_parser = date_or_datetime, hide = true)]
|
||||||
exclude_newer: Option<DateTime<Utc>>,
|
exclude_newer: Option<DateTime<Utc>>,
|
||||||
|
|
||||||
|
#[command(flatten)]
|
||||||
|
compat_args: compat::VenvCompatArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args)]
|
#[derive(Args)]
|
||||||
|
|
@ -928,6 +932,8 @@ async fn run() -> Result<ExitStatus> {
|
||||||
}) => commands::freeze(&cache, args.strict, printer),
|
}) => commands::freeze(&cache, args.strict, printer),
|
||||||
Commands::Clean(args) => commands::clean(&cache, &args.package, printer),
|
Commands::Clean(args) => commands::clean(&cache, &args.package, printer),
|
||||||
Commands::Venv(args) => {
|
Commands::Venv(args) => {
|
||||||
|
args.compat_args.validate()?;
|
||||||
|
|
||||||
let index_locations = IndexLocations::from_args(
|
let index_locations = IndexLocations::from_args(
|
||||||
args.index_url,
|
args.index_url,
|
||||||
args.extra_index_url,
|
args.extra_index_url,
|
||||||
|
|
|
||||||
|
|
@ -443,3 +443,47 @@ fn non_empty_dir_exists() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn virtualenv_compatibility() -> Result<()> {
|
||||||
|
let temp_dir = assert_fs::TempDir::new()?;
|
||||||
|
let cache_dir = assert_fs::TempDir::new()?;
|
||||||
|
let bin = create_bin_with_executables(&temp_dir, &["3.12"]).expect("Failed to create bin dir");
|
||||||
|
let venv = temp_dir.child(".venv");
|
||||||
|
|
||||||
|
// Create a virtual environment at `.venv`, passing the redundant `--clear` flag.
|
||||||
|
let filter_venv = regex::escape(&venv.normalized_display().to_string());
|
||||||
|
let filters = &[
|
||||||
|
(
|
||||||
|
r"Using Python 3\.\d+\.\d+ interpreter at .+",
|
||||||
|
"Using Python [VERSION] interpreter at [PATH]",
|
||||||
|
),
|
||||||
|
(&filter_venv, "/home/ferris/project/.venv"),
|
||||||
|
];
|
||||||
|
puffin_snapshot!(filters, Command::new(get_bin())
|
||||||
|
.arg("venv")
|
||||||
|
.arg(venv.as_os_str())
|
||||||
|
.arg("--clear")
|
||||||
|
.arg("--python")
|
||||||
|
.arg("3.12")
|
||||||
|
.arg("--cache-dir")
|
||||||
|
.arg(cache_dir.path())
|
||||||
|
.arg("--exclude-newer")
|
||||||
|
.arg(EXCLUDE_NEWER)
|
||||||
|
.env("PUFFIN_TEST_PYTHON_PATH", bin.clone())
|
||||||
|
.current_dir(&temp_dir), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
warning: virtualenv's `--clear` has no effect (Puffin always clears the virtual environment).
|
||||||
|
Using Python [VERSION] interpreter at [PATH]
|
||||||
|
Creating virtualenv at: /home/ferris/project/.venv
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
|
||||||
|
venv.assert(predicates::path::is_dir());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue