Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions crates/uv-configuration/src/package_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,15 @@ impl Upgrade {
/// Combine a set of [`Upgrade`] values.
#[must_use]
pub fn combine(self, other: Self) -> Self {
// For `strategy`: `other` takes precedence for an explicit `All` or `None`; otherwise,
// For `strategy`: an explicit `All` or `None` in `self` takes precedence; otherwise,
// merge.
let strategy = match (self.strategy, other.strategy) {
(_, UpgradeStrategy::All) => UpgradeStrategy::All,
(_, UpgradeStrategy::None) => UpgradeStrategy::None,
(UpgradeStrategy::All, _) => UpgradeStrategy::All,
(UpgradeStrategy::None, _) => UpgradeStrategy::None,
(UpgradeStrategy::Some(_, _), UpgradeStrategy::All) => UpgradeStrategy::All,
(UpgradeStrategy::Some(packages, groups), UpgradeStrategy::None) => {
UpgradeStrategy::Some(packages, groups)
}
(
UpgradeStrategy::Some(mut self_packages, mut self_groups),
UpgradeStrategy::Some(other_packages, other_groups),
Expand All @@ -268,7 +272,6 @@ impl Upgrade {
self_groups.extend(other_groups);
UpgradeStrategy::Some(self_packages, self_groups)
}
(_, UpgradeStrategy::Some(packages, groups)) => UpgradeStrategy::Some(packages, groups),
};

// For `constraints`: always merge the constraints of `self` and `other`.
Expand Down
54 changes: 54 additions & 0 deletions crates/uv/tests/pip_install/pip_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4117,6 +4117,60 @@ fn install_upgrade() {
);
}

/// `--upgrade` takes precedence over `upgrade-package` in configuration.
#[test]
fn install_upgrade_overrides_configured_upgrade_package() -> Result<()> {
let context = uv_test::test_context!("3.12");

// Install old versions of two packages.
uv_snapshot!(context.filters(), context.pip_install()
.arg("anyio==3.6.2")
.arg("httpcore==0.16.3"), @"
success: true
exit_code: 0
----- stdout -----

----- stderr -----
Resolved 6 packages in [TIME]
Prepared 6 packages in [TIME]
Installed 6 packages in [TIME]
+ anyio==3.6.2
+ certifi==2024.2.2
+ h11==0.14.0
+ httpcore==0.16.3
+ idna==3.6
+ sniffio==1.3.1
");

let uv_toml = context.temp_dir.child("uv.toml");
uv_toml.write_str(indoc! {r#"
[pip]
upgrade-package = ["anyio"]
"#})?;

// Upgrade both packages, including `httpcore`, which is not selected in the configuration.
uv_snapshot!(context.filters(), context.pip_install()
.arg("anyio")
.arg("httpcore")
.arg("--upgrade"), @"
success: true
exit_code: 0
----- stdout -----

----- stderr -----
Resolved 6 packages in [TIME]
Prepared 2 packages in [TIME]
Uninstalled 2 packages in [TIME]
Installed 2 packages in [TIME]
- anyio==3.6.2
+ anyio==4.3.0
- httpcore==0.16.3
+ httpcore==1.0.4
");

Ok(())
}

/// Install a package from a `requirements.txt` file, with a `constraints.txt` file.
#[test]
fn install_constraints_txt() -> Result<()> {
Expand Down
176 changes: 94 additions & 82 deletions crates/uv/tests/sync/show_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4008,9 +4008,8 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("anyio>3.0.0")?;

// `--no-upgrade` overrides `--upgrade-package`.
// TODO(charlie): This should mark `sniffio` for upgrade, but it doesn't.
let no_upgrade = diff_uv_snapshot!(context.filters(), &baseline, add_shared_args(context.pip_compile())
// `--upgrade-package` takes precedence over `--no-upgrade`.
let upgrade_package = diff_uv_snapshot!(context.filters(), &baseline, add_shared_args(context.pip_compile())
.arg("--no-upgrade")
.arg("--upgrade-package")
.arg("sniffio")
Expand Down Expand Up @@ -4044,32 +4043,25 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
"})?;

// Despite `upgrade = false` in the configuration file, we should mark `idna` for upgrade.
// Compare against output before adding `upgrade = false`, with `--no-upgrade --upgrade-package sniffio`.
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(
context.filters(),
&no_upgrade,
&upgrade_package,
add_shared_args(context.pip_compile())
.arg("--upgrade-package")
.arg("idna")
.arg("--show-settings")
.arg("requirements.in"),
@r#"
...
Verify,
),
upgrade: Upgrade {
- strategy: Some(
- {
- PackageName(
strategy: Some(
{
PackageName(
- "sniffio",
- ),
- },
- {},
- ),
+ strategy: None,
constraints: {},
},
reinstall: None,
+ "idna",
),
},
{},
...
"#
);
Expand All @@ -4082,8 +4074,8 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
"})?;

// Despite `--upgrade-package idna` in the command line, we should upgrade all packages.
// Compare against output before adding `upgrade = true`, with `--no-upgrade --upgrade-package sniffio`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.pip_compile())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.pip_compile())
.arg("--upgrade-package")
.arg("idna")
.arg("--show-settings")
Expand Down Expand Up @@ -4115,46 +4107,60 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
"#})?;

// Despite `upgrade-package = ["idna"]` in the configuration file, we should disable upgrades.
// Compare against output before adding `upgrade-package = ["idna"]`, with `--upgrade-package sniffio`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.pip_compile())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.pip_compile())
.arg("--no-upgrade")
.arg("--show-settings")
.arg("requirements.in"), @r#"
...
strategy: Some(
{
PackageName(
Verify,
),
upgrade: Upgrade {
- strategy: Some(
- {
- PackageName(
- "sniffio",
+ "idna",
),
},
{},
- ),
- },
- {},
- ),
+ strategy: None,
constraints: {},
},
reinstall: None,
...
"#
);

// Despite `upgrade-package = ["idna"]` in the configuration file, we should enable all upgrades.
// Compare against output before adding `upgrade-package = ["idna"]`, with `--no-upgrade --upgrade-package sniffio`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.pip_compile())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.pip_compile())
.arg("--upgrade")
.arg("--show-settings")
.arg("requirements.in"), @r#"
...
strategy: Some(
{
PackageName(
Verify,
),
upgrade: Upgrade {
- strategy: Some(
- {
- PackageName(
- "sniffio",
+ "idna",
),
},
{},
- ),
- },
- {},
- ),
+ strategy: All,
constraints: {},
},
reinstall: None,
...
"#
);

// Mark both `sniffio` and `idna` for upgrade.
// Compare against output before adding `upgrade-package = ["idna"]`, with `--no-upgrade`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.pip_compile())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.pip_compile())
.arg("--upgrade-package")
.arg("sniffio")
.arg("--show-settings")
Expand Down Expand Up @@ -4199,9 +4205,8 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
dependencies = ["anyio>3.0.0"]
"#})?;

// `--no-upgrade` overrides `--upgrade-package`.
// TODO(charlie): This should mark `sniffio` for upgrade, but it doesn't.
let no_upgrade = diff_uv_snapshot!(context.filters(), &baseline, add_shared_args(context.lock())
// `--upgrade-package` takes precedence over `--no-upgrade`.
let upgrade_package = diff_uv_snapshot!(context.filters(), &baseline, add_shared_args(context.lock())
.arg("--no-upgrade")
.arg("--upgrade-package")
.arg("sniffio")
Expand Down Expand Up @@ -4238,31 +4243,24 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
"#})?;

// Despite `upgrade = false` in the configuration file, we should mark `idna` for upgrade.
// Compare against output before adding `upgrade = false`, with `--no-upgrade --upgrade-package sniffio`.
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(
context.filters(),
&no_upgrade,
&upgrade_package,
add_shared_args(context.lock())
.arg("--upgrade-package")
.arg("idna")
.arg("--show-settings"),
@r#"
...
cuda_driver_version: None,
amd_gpu_architecture: None,
upgrade: Upgrade {
- strategy: Some(
- {
- PackageName(
strategy: Some(
{
PackageName(
- "sniffio",
- ),
- },
- {},
- ),
+ strategy: None,
constraints: {},
},
},
+ "idna",
),
},
{},
...
"#
);
Expand All @@ -4279,8 +4277,8 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
"#})?;

// Despite `--upgrade-package idna` on the CLI, we should upgrade all packages.
// Compare against output before adding `upgrade = true`, with `--no-upgrade --upgrade-package sniffio`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.lock())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.lock())
.arg("--upgrade-package")
.arg("idna")
.arg("--show-settings"), @r#"
Expand Down Expand Up @@ -4315,44 +4313,58 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
"#})?;

// Despite `upgrade-package = ["idna"]` in the configuration file, we should disable upgrades.
// Compare against output before adding `upgrade-package = ["idna"]`, with `--upgrade-package sniffio`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.lock())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.lock())
.arg("--no-upgrade")
.arg("--show-settings"), @r#"
...
strategy: Some(
{
PackageName(
cuda_driver_version: None,
amd_gpu_architecture: None,
upgrade: Upgrade {
- strategy: Some(
- {
- PackageName(
- "sniffio",
+ "idna",
),
},
{},
- ),
- },
- {},
- ),
+ strategy: None,
constraints: {},
},
},
...
"#
);

// Despite `upgrade-package = ["idna"]` in the configuration file, we should enable all upgrades.
// Compare against output before adding `upgrade-package = ["idna"]`, with `--no-upgrade --upgrade-package sniffio`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.lock())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.lock())
.arg("--upgrade")
.arg("--show-settings"), @r#"
...
strategy: Some(
{
PackageName(
cuda_driver_version: None,
amd_gpu_architecture: None,
upgrade: Upgrade {
- strategy: Some(
- {
- PackageName(
- "sniffio",
+ "idna",
),
},
{},
- ),
- },
- {},
- ),
+ strategy: All,
constraints: {},
},
},
...
"#
);

// Mark both `sniffio` and `idna` for upgrade.
// Compare against output before adding `upgrade-package = ["idna"]`, with `--no-upgrade`.
diff_uv_snapshot!(context.filters(), &no_upgrade, add_shared_args(context.lock())
// Compare against the CLI `--no-upgrade --upgrade-package sniffio` baseline.
diff_uv_snapshot!(context.filters(), &upgrade_package, add_shared_args(context.lock())
.arg("--upgrade-package")
.arg("sniffio")
.arg("--show-settings"), @r#"
Expand Down
Loading