Add UV_CONSTRAINT environment variable to provide value for `--constraint` (#3162)

## Summary

This PR is adding `UV_CONSTRAINT` environment variable as analogous to
`PIP_CONSTRAINT` to allow providing constraint file via environment
variable. Implementing this will simplify adoption of uv in testing
procedure in projects that I'm involved (testing using tox).

This was my motivation for opening #1841 that is closed in favor of
#1789 which was closed without implementing this feature.

In this implementation, I have used space as a separator as analogous to
`pip`. This introduces an obvious problem if the path contains space.
Another option could be to use standard separator (`:` - UNIX like, `;`
- Windows). Which one did you prefer?

## Test Plan

It is my first contribution and first rust coding experience. It will be
nice if one could point how I should implement testing this.
This commit is contained in:
Grzegorz Bokota 2024-04-20 23:32:28 +02:00 committed by GitHub
parent bf1036832f
commit 7efd13ca33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 6 deletions

View File

@ -502,6 +502,8 @@ uv accepts the following command-line arguments as environment variables:
index URLs, rather than limiting its search to the first index URL that contains the package. index URLs, rather than limiting its search to the first index URL that contains the package.
- `UV_REQUIRE_HASHES`: Equivalent to the `--require-hashes` command-line argument. If set to `true`, - `UV_REQUIRE_HASHES`: Equivalent to the `--require-hashes` command-line argument. If set to `true`,
uv will require that all dependencies have a hash specified in the requirements file. uv will require that all dependencies have a hash specified in the requirements file.
- 'UV_CONSTRAINT': Equivalent to the `--constraint` command-line argument. If set, uv will use this
file as the constraints file. Uses space-separated list of files.
In each case, the corresponding command-line argument takes precedence over an environment variable. In each case, the corresponding command-line argument takes precedence over an environment variable.

View File

@ -224,6 +224,18 @@ fn parse_index_url(input: &str) -> Result<Maybe<IndexUrl>, String> {
} }
} }
/// Parse a string into a [`PathBuf`], mapping the empty string to `None`.
fn parse_file_path(input: &str) -> Result<Maybe<PathBuf>, String> {
if input.is_empty() {
Ok(Maybe::None)
} else {
match PathBuf::from_str(input) {
Ok(path) => Ok(Maybe::Some(path)),
Err(err) => Err(err.to_string()),
}
}
}
#[derive(Args)] #[derive(Args)]
#[allow(clippy::struct_excessive_bools)] #[allow(clippy::struct_excessive_bools)]
pub(crate) struct PipCompileArgs { pub(crate) struct PipCompileArgs {
@ -240,8 +252,8 @@ pub(crate) struct PipCompileArgs {
/// trigger the installation of that package. /// trigger the installation of that package.
/// ///
/// This is equivalent to pip's `--constraint` option. /// This is equivalent to pip's `--constraint` option.
#[arg(long, short)] #[arg(long, short, env = "UV_CONSTRAINT", value_delimiter = ' ', value_parser = parse_file_path)]
pub(crate) constraint: Vec<PathBuf>, pub(crate) constraint: Vec<Maybe<PathBuf>>,
/// Override versions using the given requirements files. /// Override versions using the given requirements files.
/// ///
@ -869,8 +881,8 @@ pub(crate) struct PipInstallArgs {
/// trigger the installation of that package. /// trigger the installation of that package.
/// ///
/// This is equivalent to pip's `--constraint` option. /// This is equivalent to pip's `--constraint` option.
#[arg(long, short)] #[arg(long, short, env = "UV_CONSTRAINT", value_delimiter = ' ', value_parser = parse_file_path)]
pub(crate) constraint: Vec<PathBuf>, pub(crate) constraint: Vec<Maybe<PathBuf>>,
/// Override versions using the given requirements files. /// Override versions using the given requirements files.
/// ///

View File

@ -154,7 +154,10 @@ impl PipCompileSettings {
Self { Self {
// CLI-only settings. // CLI-only settings.
src_file, src_file,
constraint, constraint: constraint
.into_iter()
.filter_map(Maybe::into_option)
.collect(),
r#override, r#override,
refresh: Refresh::from_args(refresh, refresh_package), refresh: Refresh::from_args(refresh, refresh_package),
upgrade: Upgrade::from_args(upgrade, upgrade_package), upgrade: Upgrade::from_args(upgrade, upgrade_package),
@ -393,7 +396,10 @@ impl PipInstallSettings {
package, package,
requirement, requirement,
editable, editable,
constraint, constraint: constraint
.into_iter()
.filter_map(Maybe::into_option)
.collect(),
r#override, r#override,
upgrade: Upgrade::from_args(upgrade, upgrade_package), upgrade: Upgrade::from_args(upgrade, upgrade_package),
reinstall: Reinstall::from_args(reinstall, reinstall_package), reinstall: Reinstall::from_args(reinstall, reinstall_package),