mirror of https://github.com/astral-sh/uv
Treat `--upgrade-package` on the command-line as overriding `upgrade = false` in configuration (#15395)
## Summary Right now, if you put `upgrade = false` in a `uv.toml`, then pass `--upgrade-package numpy` on the CLI, we won't upgrade NumPy. This PR fixes that interaction by ensuring that when we "combine", we look at those arguments holistically (i.e., we bundle `upgrade` and `upgrade-package` into a single struct, which then goes through the `.combine` logic), rather than combining `upgrade` and `upgrade-package` independently. If approved, I then need to add the same thing for `no-build-isolation`, `reinstall`, `no-build`, and `no-binary`.
This commit is contained in:
parent
b950453891
commit
0397595e53
|
|
@ -1,7 +1,8 @@
|
|||
use anstream::eprintln;
|
||||
|
||||
use uv_cache::Refresh;
|
||||
use uv_distribution_types::{ConfigSettings, PackageConfigSettings};
|
||||
use uv_configuration::UpgradeSelection;
|
||||
use uv_distribution_types::{ConfigSettings, PackageConfigSettings, Requirement};
|
||||
use uv_resolver::{ExcludeNewer, ExcludeNewerPackage, PrereleaseMode};
|
||||
use uv_settings::{Combine, PipOptions, ResolverInstallerOptions, ResolverOptions};
|
||||
use uv_warnings::owo_colors::OwoColorize;
|
||||
|
|
@ -333,8 +334,10 @@ pub fn resolver_options(
|
|||
.filter_map(Maybe::into_option)
|
||||
.collect()
|
||||
}),
|
||||
upgrade: flag(upgrade, no_upgrade, "no-upgrade"),
|
||||
upgrade_package: Some(upgrade_package),
|
||||
upgrade: UpgradeSelection::from_args(
|
||||
flag(upgrade, no_upgrade, "no-upgrade"),
|
||||
upgrade_package.into_iter().map(Requirement::from).collect(),
|
||||
),
|
||||
index_strategy,
|
||||
keyring_provider,
|
||||
resolution,
|
||||
|
|
@ -442,12 +445,10 @@ pub fn resolver_installer_options(
|
|||
.filter_map(Maybe::into_option)
|
||||
.collect()
|
||||
}),
|
||||
upgrade: flag(upgrade, no_upgrade, "upgrade"),
|
||||
upgrade_package: if upgrade_package.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(upgrade_package)
|
||||
},
|
||||
upgrade: UpgradeSelection::from_args(
|
||||
flag(upgrade, no_upgrade, "upgrade"),
|
||||
upgrade_package.into_iter().map(Requirement::from).collect(),
|
||||
),
|
||||
reinstall: flag(reinstall, no_reinstall, "reinstall"),
|
||||
reinstall_package: if reinstall_package.is_empty() {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -134,9 +134,57 @@ impl From<Reinstall> for Refresh {
|
|||
}
|
||||
}
|
||||
|
||||
/// An upgrade selection as specified by a user on the command line or in a configuration file.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub enum UpgradeSelection {
|
||||
/// Prefer pinned versions from the existing lockfile, if possible.
|
||||
#[default]
|
||||
None,
|
||||
|
||||
/// Allow package upgrades for all packages, ignoring the existing lockfile.
|
||||
All,
|
||||
|
||||
/// Allow package upgrades, but only for the specified packages.
|
||||
Packages(Vec<Requirement>),
|
||||
}
|
||||
|
||||
impl UpgradeSelection {
|
||||
/// Determine the upgrade selection strategy from the command-line arguments.
|
||||
pub fn from_args(upgrade: Option<bool>, upgrade_package: Vec<Requirement>) -> Option<Self> {
|
||||
match upgrade {
|
||||
Some(true) => Some(Self::All),
|
||||
// TODO(charlie): `--no-upgrade` with `--upgrade-package` should allow the specified
|
||||
// packages to be upgraded. Right now, `--upgrade-package` is silently ignored.
|
||||
Some(false) => Some(Self::None),
|
||||
None if upgrade_package.is_empty() => None,
|
||||
None => Some(Self::Packages(upgrade_package)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Combine a set of [`UpgradeSelection`] values.
|
||||
#[must_use]
|
||||
pub fn combine(self, other: Self) -> Self {
|
||||
match self {
|
||||
// Setting `--upgrade` or `--no-upgrade` should clear previous `--upgrade-package` selections.
|
||||
Self::All | Self::None => self,
|
||||
Self::Packages(self_packages) => match other {
|
||||
// If `--upgrade` was enabled previously, `--upgrade-package` is subsumed by upgrading all packages.
|
||||
Self::All => other,
|
||||
// If `--no-upgrade` was enabled previously, then `--upgrade-package` enables an explicit upgrade of those packages.
|
||||
Self::None => Self::Packages(self_packages),
|
||||
// If `--upgrade-package` was included twice, combine the requirements.
|
||||
Self::Packages(other_packages) => {
|
||||
let mut combined = self_packages;
|
||||
combined.extend(other_packages);
|
||||
Self::Packages(combined)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to allow package upgrades.
|
||||
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub enum Upgrade {
|
||||
/// Prefer pinned versions from the existing lockfile, if possible.
|
||||
#[default]
|
||||
|
|
@ -149,30 +197,28 @@ pub enum Upgrade {
|
|||
Packages(FxHashMap<PackageName, Vec<Requirement>>),
|
||||
}
|
||||
|
||||
impl Upgrade {
|
||||
/// Determine the [`Upgrade`] strategy from the command-line arguments.
|
||||
pub fn from_args(upgrade: Option<bool>, upgrade_package: Vec<Requirement>) -> Self {
|
||||
match upgrade {
|
||||
Some(true) => Self::All,
|
||||
Some(false) => Self::None,
|
||||
None => {
|
||||
if upgrade_package.is_empty() {
|
||||
Self::None
|
||||
} else {
|
||||
Self::Packages(upgrade_package.into_iter().fold(
|
||||
FxHashMap::default(),
|
||||
|mut map, requirement| {
|
||||
impl From<Option<UpgradeSelection>> for Upgrade {
|
||||
fn from(value: Option<UpgradeSelection>) -> Self {
|
||||
match value {
|
||||
None => Self::None,
|
||||
Some(UpgradeSelection::None) => Self::None,
|
||||
Some(UpgradeSelection::All) => Self::All,
|
||||
Some(UpgradeSelection::Packages(requirements)) => Self::Packages(
|
||||
requirements
|
||||
.into_iter()
|
||||
.fold(FxHashMap::default(), |mut map, requirement| {
|
||||
map.entry(requirement.name.clone())
|
||||
.or_default()
|
||||
.push(requirement);
|
||||
map
|
||||
},
|
||||
))
|
||||
}
|
||||
}),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Upgrade {
|
||||
/// Create an [`Upgrade`] strategy to upgrade a single package.
|
||||
pub fn package(package_name: PackageName) -> Self {
|
||||
Self::Packages({
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use uv_pep440::VersionSpecifiers;
|
|||
use uv_pep508::PackageName;
|
||||
use uv_pypi_types::VerbatimParsedUrl;
|
||||
use uv_redacted::DisplaySafeUrl;
|
||||
use uv_settings::{GlobalOptions, ResolverInstallerOptions};
|
||||
use uv_settings::{GlobalOptions, ResolverInstallerSchema};
|
||||
use uv_warnings::warn_user;
|
||||
use uv_workspace::pyproject::{ExtraBuildDependency, Sources};
|
||||
|
||||
|
|
@ -424,7 +424,7 @@ pub struct ToolUv {
|
|||
#[serde(flatten)]
|
||||
pub globals: GlobalOptions,
|
||||
#[serde(flatten)]
|
||||
pub top_level: ResolverInstallerOptions,
|
||||
pub top_level: ResolverInstallerSchema,
|
||||
pub override_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
pub constraint_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
pub build_constraint_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use url::Url;
|
|||
|
||||
use uv_configuration::{
|
||||
ExportFormat, IndexStrategy, KeyringProviderType, RequiredVersion, TargetTriple,
|
||||
TrustedPublishing,
|
||||
TrustedPublishing, UpgradeSelection,
|
||||
};
|
||||
use uv_distribution_types::{
|
||||
ConfigSettings, ExtraBuildVariables, Index, IndexUrl, PackageConfigSettings, PipExtraIndex,
|
||||
|
|
@ -181,6 +181,15 @@ impl Combine for Option<PackageConfigSettings> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Combine for Option<UpgradeSelection> {
|
||||
fn combine(self, other: Self) -> Self {
|
||||
match (self, other) {
|
||||
(Some(a), Some(b)) => Some(a.combine(b)),
|
||||
(a, b) => a.or(b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Combine for serde::de::IgnoredAny {
|
||||
fn combine(self, _other: Self) -> Self {
|
||||
self
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ fn warn_uv_toml_masked_fields(options: &Options) {
|
|||
allow_insecure_host,
|
||||
},
|
||||
top_level:
|
||||
ResolverInstallerOptions {
|
||||
ResolverInstallerSchema {
|
||||
index,
|
||||
index_url,
|
||||
extra_index_url,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||
use uv_cache_info::CacheKey;
|
||||
use uv_configuration::{
|
||||
IndexStrategy, KeyringProviderType, PackageNameSpecifier, RequiredVersion, TargetTriple,
|
||||
TrustedHost, TrustedPublishing,
|
||||
TrustedHost, TrustedPublishing, UpgradeSelection,
|
||||
};
|
||||
use uv_distribution_types::{
|
||||
ConfigSettings, ExtraBuildVariables, Index, IndexUrl, IndexUrlError, PackageConfigSettings,
|
||||
|
|
@ -52,7 +52,7 @@ pub struct Options {
|
|||
pub globals: GlobalOptions,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub top_level: ResolverInstallerOptions,
|
||||
pub top_level: ResolverInstallerSchema,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub install_mirrors: PythonInstallMirrors,
|
||||
|
|
@ -161,7 +161,7 @@ pub struct Options {
|
|||
|
||||
impl Options {
|
||||
/// Construct an [`Options`] with the given global and top-level settings.
|
||||
pub fn simple(globals: GlobalOptions, top_level: ResolverInstallerOptions) -> Self {
|
||||
pub fn simple(globals: GlobalOptions, top_level: ResolverInstallerSchema) -> Self {
|
||||
Self {
|
||||
globals,
|
||||
top_level,
|
||||
|
|
@ -369,8 +369,7 @@ pub struct ResolverOptions {
|
|||
pub config_settings_package: Option<PackageConfigSettings>,
|
||||
pub exclude_newer: ExcludeNewer,
|
||||
pub link_mode: Option<LinkMode>,
|
||||
pub upgrade: Option<bool>,
|
||||
pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||
pub upgrade: Option<UpgradeSelection>,
|
||||
pub no_build: Option<bool>,
|
||||
pub no_build_package: Option<Vec<PackageName>>,
|
||||
pub no_binary: Option<bool>,
|
||||
|
|
@ -384,10 +383,159 @@ pub struct ResolverOptions {
|
|||
|
||||
/// Shared settings, relevant to all operations that must resolve and install dependencies. The
|
||||
/// union of [`InstallerOptions`] and [`ResolverOptions`].
|
||||
#[derive(Debug, Clone, Default, CombineOptions)]
|
||||
pub struct ResolverInstallerOptions {
|
||||
pub index: Option<Vec<Index>>,
|
||||
pub index_url: Option<PipIndex>,
|
||||
pub extra_index_url: Option<Vec<PipExtraIndex>>,
|
||||
pub no_index: Option<bool>,
|
||||
pub find_links: Option<Vec<PipFindLinks>>,
|
||||
pub index_strategy: Option<IndexStrategy>,
|
||||
pub keyring_provider: Option<KeyringProviderType>,
|
||||
pub resolution: Option<ResolutionMode>,
|
||||
pub prerelease: Option<PrereleaseMode>,
|
||||
pub fork_strategy: Option<ForkStrategy>,
|
||||
pub dependency_metadata: Option<Vec<StaticMetadata>>,
|
||||
pub config_settings: Option<ConfigSettings>,
|
||||
pub config_settings_package: Option<PackageConfigSettings>,
|
||||
pub no_build_isolation: Option<bool>,
|
||||
pub no_build_isolation_package: Option<Vec<PackageName>>,
|
||||
pub extra_build_dependencies: Option<ExtraBuildDependencies>,
|
||||
pub extra_build_variables: Option<ExtraBuildVariables>,
|
||||
pub exclude_newer: Option<ExcludeNewerTimestamp>,
|
||||
pub exclude_newer_package: Option<ExcludeNewerPackage>,
|
||||
pub link_mode: Option<LinkMode>,
|
||||
pub compile_bytecode: Option<bool>,
|
||||
pub no_sources: Option<bool>,
|
||||
pub upgrade: Option<UpgradeSelection>,
|
||||
pub reinstall: Option<bool>,
|
||||
pub reinstall_package: Option<Vec<PackageName>>,
|
||||
pub no_build: Option<bool>,
|
||||
pub no_build_package: Option<Vec<PackageName>>,
|
||||
pub no_binary: Option<bool>,
|
||||
pub no_binary_package: Option<Vec<PackageName>>,
|
||||
}
|
||||
|
||||
impl From<ResolverInstallerSchema> for ResolverInstallerOptions {
|
||||
fn from(value: ResolverInstallerSchema) -> Self {
|
||||
let ResolverInstallerSchema {
|
||||
index,
|
||||
index_url,
|
||||
extra_index_url,
|
||||
no_index,
|
||||
find_links,
|
||||
index_strategy,
|
||||
keyring_provider,
|
||||
resolution,
|
||||
prerelease,
|
||||
fork_strategy,
|
||||
dependency_metadata,
|
||||
config_settings,
|
||||
config_settings_package,
|
||||
no_build_isolation,
|
||||
no_build_isolation_package,
|
||||
extra_build_dependencies,
|
||||
extra_build_variables,
|
||||
exclude_newer,
|
||||
exclude_newer_package,
|
||||
link_mode,
|
||||
compile_bytecode,
|
||||
no_sources,
|
||||
upgrade,
|
||||
upgrade_package,
|
||||
reinstall,
|
||||
reinstall_package,
|
||||
no_build,
|
||||
no_build_package,
|
||||
no_binary,
|
||||
no_binary_package,
|
||||
} = value;
|
||||
Self {
|
||||
index,
|
||||
index_url,
|
||||
extra_index_url,
|
||||
no_index,
|
||||
find_links,
|
||||
index_strategy,
|
||||
keyring_provider,
|
||||
resolution,
|
||||
prerelease,
|
||||
fork_strategy,
|
||||
dependency_metadata,
|
||||
config_settings,
|
||||
config_settings_package,
|
||||
no_build_isolation,
|
||||
no_build_isolation_package,
|
||||
extra_build_dependencies,
|
||||
extra_build_variables,
|
||||
exclude_newer,
|
||||
exclude_newer_package,
|
||||
link_mode,
|
||||
compile_bytecode,
|
||||
no_sources,
|
||||
upgrade: UpgradeSelection::from_args(
|
||||
upgrade,
|
||||
upgrade_package
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
),
|
||||
reinstall,
|
||||
reinstall_package,
|
||||
no_build,
|
||||
no_build_package,
|
||||
no_binary,
|
||||
no_binary_package,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResolverInstallerSchema {
|
||||
/// Resolve the [`ResolverInstallerSchema`] relative to the given root directory.
|
||||
pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
|
||||
Ok(Self {
|
||||
index: self
|
||||
.index
|
||||
.map(|index| {
|
||||
index
|
||||
.into_iter()
|
||||
.map(|index| index.relative_to(root_dir))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.transpose()?,
|
||||
index_url: self
|
||||
.index_url
|
||||
.map(|index_url| index_url.relative_to(root_dir))
|
||||
.transpose()?,
|
||||
extra_index_url: self
|
||||
.extra_index_url
|
||||
.map(|extra_index_url| {
|
||||
extra_index_url
|
||||
.into_iter()
|
||||
.map(|extra_index_url| extra_index_url.relative_to(root_dir))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.transpose()?,
|
||||
find_links: self
|
||||
.find_links
|
||||
.map(|find_links| {
|
||||
find_links
|
||||
.into_iter()
|
||||
.map(|find_link| find_link.relative_to(root_dir))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.transpose()?,
|
||||
..self
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The JSON schema for the `[tool.uv]` section of a `pyproject.toml` file.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ResolverInstallerOptions {
|
||||
pub struct ResolverInstallerSchema {
|
||||
/// The package indexes to use when resolving dependencies.
|
||||
///
|
||||
/// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
|
||||
|
|
@ -814,46 +962,6 @@ pub struct ResolverInstallerOptions {
|
|||
pub no_binary_package: Option<Vec<PackageName>>,
|
||||
}
|
||||
|
||||
impl ResolverInstallerOptions {
|
||||
/// Resolve the [`ResolverInstallerOptions`] relative to the given root directory.
|
||||
pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
|
||||
Ok(Self {
|
||||
index: self
|
||||
.index
|
||||
.map(|index| {
|
||||
index
|
||||
.into_iter()
|
||||
.map(|index| index.relative_to(root_dir))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.transpose()?,
|
||||
index_url: self
|
||||
.index_url
|
||||
.map(|index_url| index_url.relative_to(root_dir))
|
||||
.transpose()?,
|
||||
extra_index_url: self
|
||||
.extra_index_url
|
||||
.map(|extra_index_url| {
|
||||
extra_index_url
|
||||
.into_iter()
|
||||
.map(|extra_index_url| extra_index_url.relative_to(root_dir))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.transpose()?,
|
||||
find_links: self
|
||||
.find_links
|
||||
.map(|find_links| {
|
||||
find_links
|
||||
.into_iter()
|
||||
.map(|find_link| find_link.relative_to(root_dir))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
})
|
||||
.transpose()?,
|
||||
..self
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared settings, relevant to all operations that might create managed python installations.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
|
|
@ -1752,8 +1860,8 @@ impl PipOptions {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ResolverInstallerOptions> for ResolverOptions {
|
||||
fn from(value: ResolverInstallerOptions) -> Self {
|
||||
impl From<ResolverInstallerSchema> for ResolverOptions {
|
||||
fn from(value: ResolverInstallerSchema) -> Self {
|
||||
Self {
|
||||
index: value.index,
|
||||
index_url: value.index_url,
|
||||
|
|
@ -1778,8 +1886,15 @@ impl From<ResolverInstallerOptions> for ResolverOptions {
|
|||
.collect(),
|
||||
),
|
||||
link_mode: value.link_mode,
|
||||
upgrade: value.upgrade,
|
||||
upgrade_package: value.upgrade_package,
|
||||
upgrade: UpgradeSelection::from_args(
|
||||
value.upgrade,
|
||||
value
|
||||
.upgrade_package
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
),
|
||||
no_build: value.no_build,
|
||||
no_build_package: value.no_build_package,
|
||||
no_binary: value.no_binary,
|
||||
|
|
@ -1793,8 +1908,8 @@ impl From<ResolverInstallerOptions> for ResolverOptions {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ResolverInstallerOptions> for InstallerOptions {
|
||||
fn from(value: ResolverInstallerOptions) -> Self {
|
||||
impl From<ResolverInstallerSchema> for InstallerOptions {
|
||||
fn from(value: ResolverInstallerSchema) -> Self {
|
||||
Self {
|
||||
index: value.index,
|
||||
index_url: value.index_url,
|
||||
|
|
@ -1830,7 +1945,7 @@ impl From<ResolverInstallerOptions> for InstallerOptions {
|
|||
|
||||
/// The options persisted alongside an installed tool.
|
||||
///
|
||||
/// A mirror of [`ResolverInstallerOptions`], without upgrades and reinstalls, which shouldn't be
|
||||
/// A mirror of [`ResolverInstallerSchema`], without upgrades and reinstalls, which shouldn't be
|
||||
/// persisted in a tool receipt.
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, CombineOptions, OptionsMetadata,
|
||||
|
|
@ -1925,7 +2040,6 @@ impl From<ToolOptions> for ResolverInstallerOptions {
|
|||
compile_bytecode: value.compile_bytecode,
|
||||
no_sources: value.no_sources,
|
||||
upgrade: None,
|
||||
upgrade_package: None,
|
||||
reinstall: None,
|
||||
reinstall_package: None,
|
||||
no_build: value.no_build,
|
||||
|
|
@ -2120,7 +2234,7 @@ impl From<OptionsWire> for Options {
|
|||
// Used twice for backwards compatibility
|
||||
allow_insecure_host: allow_insecure_host.clone(),
|
||||
},
|
||||
top_level: ResolverInstallerOptions {
|
||||
top_level: ResolverInstallerSchema {
|
||||
index,
|
||||
index_url,
|
||||
extra_index_url,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use uv_configuration::{
|
|||
BuildOptions, Concurrency, DependencyGroups, DryRun, EditableMode, ExportFormat,
|
||||
ExtrasSpecification, HashCheckingMode, IndexStrategy, InstallOptions, KeyringProviderType,
|
||||
NoBinary, NoBuild, Preview, ProjectBuildBackend, Reinstall, RequiredVersion, SourceStrategy,
|
||||
TargetTriple, TrustedHost, TrustedPublishing, Upgrade, VersionControlSystem,
|
||||
TargetTriple, TrustedHost, TrustedPublishing, Upgrade, UpgradeSelection, VersionControlSystem,
|
||||
};
|
||||
use uv_distribution_types::{
|
||||
ConfigSettings, DependencyMetadata, ExtraBuildVariables, Index, IndexLocations, IndexUrl,
|
||||
|
|
@ -42,7 +42,7 @@ use uv_resolver::{
|
|||
};
|
||||
use uv_settings::{
|
||||
Combine, EnvironmentOptions, FilesystemOptions, Options, PipOptions, PublishOptions,
|
||||
PythonInstallMirrors, ResolverInstallerOptions, ResolverOptions,
|
||||
PythonInstallMirrors, ResolverInstallerOptions, ResolverInstallerSchema, ResolverOptions,
|
||||
};
|
||||
use uv_static::EnvVars;
|
||||
use uv_torch::TorchMode;
|
||||
|
|
@ -538,13 +538,14 @@ impl ToolRunSettings {
|
|||
}
|
||||
}
|
||||
|
||||
let options = resolver_installer_options(installer, build).combine(
|
||||
let options =
|
||||
resolver_installer_options(installer, build).combine(ResolverInstallerOptions::from(
|
||||
filesystem
|
||||
.clone()
|
||||
.map(FilesystemOptions::into_options)
|
||||
.map(|options| options.top_level)
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
));
|
||||
|
||||
let install_mirrors = filesystem
|
||||
.map(FilesystemOptions::into_options)
|
||||
|
|
@ -636,13 +637,14 @@ impl ToolInstallSettings {
|
|||
python,
|
||||
} = args;
|
||||
|
||||
let options = resolver_installer_options(installer, build).combine(
|
||||
let options =
|
||||
resolver_installer_options(installer, build).combine(ResolverInstallerOptions::from(
|
||||
filesystem
|
||||
.clone()
|
||||
.map(FilesystemOptions::into_options)
|
||||
.map(|options| options.top_level)
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
));
|
||||
|
||||
let install_mirrors = filesystem
|
||||
.map(FilesystemOptions::into_options)
|
||||
|
|
@ -777,9 +779,11 @@ impl ToolUpgradeSettings {
|
|||
.clone()
|
||||
.map(|options| options.install_mirrors)
|
||||
.unwrap_or_default();
|
||||
let top_level = filesystem
|
||||
let top_level = ResolverInstallerOptions::from(
|
||||
filesystem
|
||||
.map(|options| options.top_level)
|
||||
.unwrap_or_default();
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
|
||||
Self {
|
||||
names: if all { vec![] } else { name },
|
||||
|
|
@ -2798,6 +2802,8 @@ pub(crate) struct ResolverSettings {
|
|||
impl ResolverSettings {
|
||||
/// Resolve the [`ResolverSettings`] from the CLI and filesystem configuration.
|
||||
pub(crate) fn combine(args: ResolverOptions, filesystem: Option<FilesystemOptions>) -> Self {
|
||||
// The problem is that for `upgrade`... we want to combine the two `Upgrade` structs,
|
||||
// not the individual fields.
|
||||
let options = args.combine(ResolverOptions::from(
|
||||
filesystem
|
||||
.map(FilesystemOptions::into_options)
|
||||
|
|
@ -2846,15 +2852,7 @@ impl From<ResolverOptions> for ResolverSettings {
|
|||
exclude_newer: value.exclude_newer,
|
||||
link_mode: value.link_mode.unwrap_or_default(),
|
||||
sources: SourceStrategy::from_args(value.no_sources.unwrap_or_default()),
|
||||
upgrade: Upgrade::from_args(
|
||||
value.upgrade,
|
||||
value
|
||||
.upgrade_package
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Requirement::from)
|
||||
.collect(),
|
||||
),
|
||||
upgrade: Upgrade::from(value.upgrade),
|
||||
build_options: BuildOptions::new(
|
||||
NoBinary::from_args(value.no_binary, value.no_binary_package.unwrap_or_default()),
|
||||
NoBuild::from_args(value.no_build, value.no_build_package.unwrap_or_default()),
|
||||
|
|
@ -2881,12 +2879,12 @@ impl ResolverInstallerSettings {
|
|||
args: ResolverInstallerOptions,
|
||||
filesystem: Option<FilesystemOptions>,
|
||||
) -> Self {
|
||||
let options = args.combine(
|
||||
let options = args.combine(ResolverInstallerOptions::from(
|
||||
filesystem
|
||||
.map(FilesystemOptions::into_options)
|
||||
.map(|options| options.top_level)
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
));
|
||||
|
||||
Self::from(options)
|
||||
}
|
||||
|
|
@ -2945,15 +2943,7 @@ impl From<ResolverInstallerOptions> for ResolverInstallerSettings {
|
|||
prerelease: value.prerelease.unwrap_or_default(),
|
||||
resolution: value.resolution.unwrap_or_default(),
|
||||
sources: SourceStrategy::from_args(value.no_sources.unwrap_or_default()),
|
||||
upgrade: Upgrade::from_args(
|
||||
value.upgrade,
|
||||
value
|
||||
.upgrade_package
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Requirement::from)
|
||||
.collect(),
|
||||
),
|
||||
upgrade: Upgrade::from(value.upgrade),
|
||||
},
|
||||
compile_bytecode: value.compile_bytecode.unwrap_or_default(),
|
||||
reinstall: Reinstall::from_args(
|
||||
|
|
@ -3098,7 +3088,7 @@ impl PipSettings {
|
|||
exclude_newer_package,
|
||||
} = pip.unwrap_or_default();
|
||||
|
||||
let ResolverInstallerOptions {
|
||||
let ResolverInstallerSchema {
|
||||
index: top_level_index,
|
||||
index_url: top_level_index_url,
|
||||
extra_index_url: top_level_extra_index_url,
|
||||
|
|
@ -3327,14 +3317,23 @@ impl PipSettings {
|
|||
args.no_sources.combine(no_sources).unwrap_or_default(),
|
||||
),
|
||||
strict: args.strict.combine(strict).unwrap_or_default(),
|
||||
upgrade: Upgrade::from_args(
|
||||
args.upgrade.combine(upgrade),
|
||||
upgrade: Upgrade::from(
|
||||
UpgradeSelection::from_args(
|
||||
args.upgrade,
|
||||
args.upgrade_package
|
||||
.combine(upgrade_package)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Requirement::from)
|
||||
.collect(),
|
||||
)
|
||||
.combine(UpgradeSelection::from_args(
|
||||
upgrade,
|
||||
upgrade_package
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Requirement::from)
|
||||
.collect(),
|
||||
)),
|
||||
),
|
||||
reinstall: Reinstall::from_args(
|
||||
args.reinstall.combine(reinstall),
|
||||
|
|
@ -3418,7 +3417,7 @@ impl PublishSettings {
|
|||
trusted_publishing,
|
||||
check_url,
|
||||
} = publish;
|
||||
let ResolverInstallerOptions {
|
||||
let ResolverInstallerSchema {
|
||||
keyring_provider,
|
||||
index,
|
||||
extra_index_url,
|
||||
|
|
|
|||
|
|
@ -3514,7 +3514,6 @@ fn resolve_tool() -> anyhow::Result<()> {
|
|||
compile_bytecode: None,
|
||||
no_sources: None,
|
||||
upgrade: None,
|
||||
upgrade_package: None,
|
||||
reinstall: None,
|
||||
reinstall_package: None,
|
||||
no_build: None,
|
||||
|
|
@ -8569,7 +8568,6 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
"})?;
|
||||
|
||||
// Despite `upgrade = false` in the configuration file, we should mark `idna` for upgrade.
|
||||
// TODO(charlie): This doesn't mark `idna` for upgrade; it just disables upgrades.
|
||||
uv_snapshot!(context.filters(), add_shared_args(context.pip_compile(), context.temp_dir.path())
|
||||
.arg("--upgrade-package")
|
||||
.arg("idna")
|
||||
|
|
@ -8727,7 +8725,30 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
hash_checking: Some(
|
||||
Verify,
|
||||
),
|
||||
upgrade: None,
|
||||
upgrade: Packages(
|
||||
{
|
||||
PackageName(
|
||||
"idna",
|
||||
): [
|
||||
Requirement {
|
||||
name: PackageName(
|
||||
"idna",
|
||||
),
|
||||
extras: [],
|
||||
groups: [],
|
||||
marker: true,
|
||||
source: Registry {
|
||||
specifier: VersionSpecifiers(
|
||||
[],
|
||||
),
|
||||
index: None,
|
||||
conflict: None,
|
||||
},
|
||||
origin: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
reinstall: None,
|
||||
},
|
||||
}
|
||||
|
|
@ -9600,7 +9621,6 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
|||
"#})?;
|
||||
|
||||
// Despite `upgrade = false` in the configuration file, we should mark `idna` for upgrade.
|
||||
// TODO(charlie): This doesn't mark `idna` for upgrade; it just disables upgrades.
|
||||
uv_snapshot!(context.filters(), add_shared_args(context.lock(), context.temp_dir.path())
|
||||
.arg("--upgrade-package")
|
||||
.arg("idna")
|
||||
|
|
@ -9699,7 +9719,30 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
|||
prerelease: IfNecessaryOrExplicit,
|
||||
resolution: Highest,
|
||||
sources: Enabled,
|
||||
upgrade: None,
|
||||
upgrade: Packages(
|
||||
{
|
||||
PackageName(
|
||||
"idna",
|
||||
): [
|
||||
Requirement {
|
||||
name: PackageName(
|
||||
"idna",
|
||||
),
|
||||
extras: [],
|
||||
groups: [],
|
||||
marker: true,
|
||||
source: Registry {
|
||||
specifier: VersionSpecifiers(
|
||||
[],
|
||||
),
|
||||
index: None,
|
||||
conflict: None,
|
||||
},
|
||||
origin: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue