Add compatibility arguments for pip sync (#1185)

## Summary

As with `pip compile`, we can provide useful error messages and warnings
when people pass `pip sync` arguments.

Closes https://github.com/astral-sh/puffin/issues/1184.
This commit is contained in:
Charlie Marsh 2024-01-30 05:48:55 -08:00 committed by GitHub
parent ab27913f68
commit c479c26cab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 114 additions and 0 deletions

View file

@ -56,6 +56,9 @@ pub(crate) struct PipCompileCompatArgs {
#[clap(long, hide = true)]
unsafe_package: Vec<String>,
#[clap(long, hide = true)]
config: Option<String>,
#[clap(long, hide = true)]
no_config: bool,
@ -76,6 +79,9 @@ pub(crate) struct PipCompileCompatArgs {
#[clap(long, hide = true)]
no_strip_extras: bool,
#[clap(long, hide = true)]
pip_args: Option<String>,
}
impl PipCompileCompatArgs {
@ -183,6 +189,12 @@ impl PipCompileCompatArgs {
));
}
if self.config.is_some() {
return Err(anyhow!(
"pip-compile's `--config` is unsupported (Puffin does not use a configuration file)."
));
}
if self.no_config {
warn_user!(
"pip-compile's `--no-config` has no effect (Puffin does not use a configuration file)."
@ -225,6 +237,103 @@ impl PipCompileCompatArgs {
));
}
if self.pip_args.is_some() {
return Err(anyhow!(
"pip-compile's `--pip-args` is unsupported (try passing arguments to Puffin directly)."
));
}
Ok(())
}
}
/// Arguments for `pip-sync` compatibility.
///
/// These represent a subset of the `pip-sync` interface that Puffin supports by default.
#[derive(Args)]
#[allow(clippy::struct_excessive_bools)]
pub(crate) struct PipSyncCompatArgs {
#[clap(short, long, hide = true)]
ask: bool,
#[clap(long, hide = true)]
trusted_host: Option<String>,
#[clap(long, hide = true)]
python_executable: Option<String>,
#[clap(long, hide = true)]
user: bool,
#[clap(long, hide = true)]
cert: Option<String>,
#[clap(long, hide = true)]
client_cert: Option<String>,
#[clap(long, hide = true)]
config: Option<String>,
#[clap(long, hide = true)]
no_config: bool,
#[clap(long, hide = true)]
pip_args: Option<String>,
}
impl PipSyncCompatArgs {
/// 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
/// behavior. If an argument is passed that does _not_ match Puffin's behavior, this method will
/// return an error.
pub(crate) fn validate(&self) -> Result<()> {
if self.ask {
return Err(anyhow!(
"pip-sync's `--ask` is unsupported (Puffin never asks for confirmation)."
));
}
if self.python_executable.is_some() {
return Err(anyhow!(
"pip-sync's `--python-executable` is unsupported (to install into a separate Python environment, try setting `VIRTUAL_ENV` instead)."
));
}
if self.user {
return Err(anyhow!("pip-sync's `--user` is unsupported."));
}
if self.client_cert.is_some() {
return Err(anyhow!(
"pip-sync's `--client-cert` is unsupported (Puffin doesn't support dedicated client certificates)."
));
}
if self.trusted_host.is_some() {
return Err(anyhow!(
"pip-sync's `--trusted-host` is unsupported (Puffin always requires HTTPS)."
));
}
if self.config.is_some() {
return Err(anyhow!(
"pip-sync's `--config` is unsupported (Puffin does not use a configuration file)."
));
}
if self.no_config {
warn_user!(
"pip-sync's `--no-config` has no effect (Puffin does not use a configuration file)."
);
}
if self.pip_args.is_some() {
return Err(anyhow!(
"pip-sync's `--pip-args` is unsupported (try passing arguments to Puffin directly)."
));
}
Ok(())
}
}

View file

@ -377,6 +377,9 @@ struct PipSyncArgs {
/// missing dependencies or other issues.
#[clap(long)]
strict: bool,
#[command(flatten)]
compat_args: compat::PipSyncCompatArgs,
}
#[derive(Args)]
@ -724,6 +727,8 @@ async fn run() -> Result<ExitStatus> {
Commands::Pip(PipArgs {
command: PipCommand::Sync(args),
}) => {
args.compat_args.validate()?;
let cache = cache.with_refresh(Refresh::from_args(args.refresh, args.refresh_package));
let index_urls = IndexLocations::from_args(
args.index_url,