Skip to content

Commit 9c84690

Browse files
committed
Pass install mirrors to other fetching commands
1 parent f831b50 commit 9c84690

File tree

22 files changed

+367
-78
lines changed

22 files changed

+367
-78
lines changed

crates/uv-cli/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3937,15 +3937,15 @@ pub struct PythonInstallArgs {
39373937
///
39383938
/// Distributions can be read from a local directory by using the `file://` URL scheme.
39393939
#[arg(long, env = EnvVars::UV_PYTHON_INSTALL_MIRROR)]
3940-
pub python_install_mirror: Option<String>,
3940+
pub mirror: Option<String>,
39413941

39423942
/// Set the URL to use as the source for downloading PyPy installations.
39433943
///
39443944
/// The provided URL will replace `https://downloads.python.org/pypy` in, e.g., `https://downloads.python.org/pypy/pypy3.8-v7.3.7-osx64.tar.bz2`.
39453945
///
39463946
/// Distributions can be read from a local directory by using the `file://` URL scheme.
39473947
#[arg(long, env = EnvVars::UV_PYPY_INSTALL_MIRROR)]
3948-
pub pypy_install_mirror: Option<String>,
3948+
pub pypy_mirror: Option<String>,
39493949

39503950
/// Reinstall the requested Python version, if it's already installed.
39513951
///

crates/uv-python/src/installation.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use tracing::{debug, info};
66
use uv_cache::Cache;
77
use uv_client::BaseClientBuilder;
88
use uv_pep440::{Prerelease, Version};
9-
use uv_static::EnvVars;
109

1110
use crate::discovery::{
1211
find_best_python_installation, find_python_installation, EnvironmentPreference, PythonRequest,
@@ -87,6 +86,8 @@ impl PythonInstallation {
8786
client_builder: &BaseClientBuilder<'a>,
8887
cache: &Cache,
8988
reporter: Option<&dyn Reporter>,
89+
python_install_mirror: Option<String>,
90+
pypy_install_mirror: Option<String>,
9091
) -> Result<Self, Error> {
9192
let request = request.unwrap_or_else(|| &PythonRequest::Default);
9293

@@ -101,7 +102,16 @@ impl PythonInstallation {
101102
{
102103
if let Some(request) = PythonDownloadRequest::from_request(request) {
103104
debug!("Requested Python not found, checking for available download...");
104-
match Self::fetch(request.fill()?, client_builder, cache, reporter).await {
105+
match Self::fetch(
106+
request.fill()?,
107+
client_builder,
108+
cache,
109+
reporter,
110+
python_install_mirror,
111+
pypy_install_mirror,
112+
)
113+
.await
114+
{
105115
Ok(installation) => Ok(installation),
106116
Err(Error::Download(downloads::Error::NoDownloadFound(_))) => {
107117
Err(Error::MissingPython(err))
@@ -122,6 +132,8 @@ impl PythonInstallation {
122132
client_builder: &BaseClientBuilder<'a>,
123133
cache: &Cache,
124134
reporter: Option<&dyn Reporter>,
135+
python_install_mirror: Option<String>,
136+
pypy_install_mirror: Option<String>,
125137
) -> Result<Self, Error> {
126138
let installations = ManagedPythonInstallations::from_settings()?.init()?;
127139
let installations_dir = installations.root();
@@ -130,8 +142,6 @@ impl PythonInstallation {
130142

131143
let download = ManagedPythonDownload::from_request(&request)?;
132144
let client = client_builder.build();
133-
let python_install_mirror = std::env::var(EnvVars::UV_PYTHON_INSTALL_MIRROR).ok();
134-
let pypy_install_mirror = std::env::var(EnvVars::UV_PYPY_INSTALL_MIRROR).ok();
135145

136146
info!("Fetching requested Python...");
137147
let result = download

crates/uv-settings/src/settings.rs

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use uv_pep508::Requirement;
1414
use uv_pypi_types::{SupportedEnvironments, VerbatimParsedUrl};
1515
use uv_python::{PythonDownloads, PythonPreference, PythonVersion};
1616
use uv_resolver::{AnnotationStyle, ExcludeNewer, PrereleaseMode, ResolutionMode};
17+
use uv_static::EnvVars;
1718

1819
/// A `pyproject.toml` with an (optional) `[tool.uv]` section.
1920
#[allow(dead_code)]
@@ -41,6 +42,9 @@ pub struct Options {
4142
#[serde(flatten)]
4243
pub top_level: ResolverInstallerOptions,
4344

45+
#[serde(flatten)]
46+
pub install_mirrors: InstallMirrorOptions,
47+
4448
#[serde(flatten)]
4549
pub publish: PublishOptions,
4650

@@ -224,37 +228,6 @@ pub struct GlobalOptions {
224228
"#
225229
)]
226230
pub concurrent_installs: Option<NonZeroUsize>,
227-
/// Mirror URL for downloading managed Python installations.
228-
///
229-
/// By default, managed Python installations are downloaded from [`python-build-standalone`](https://github.com/indygreg/python-build-standalone).
230-
/// This variable can be set to a mirror URL to use a different source for Python installations.
231-
/// The provided URL will replace `https://github.com/indygreg/python-build-standalone/releases/download` in, e.g., `https://github.com/indygreg/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz`.
232-
///
233-
/// Distributions can be read from a local directory by using the `file://` URL scheme.
234-
#[option(
235-
default = "None",
236-
value_type = "str",
237-
example = r#"
238-
python-install-mirror = "https://github.com/indygreg/python-build-standalone/releases/download"
239-
"#
240-
)]
241-
pub python_install_mirror: Option<String>,
242-
/// Mirror URL to use for downloading managed PyPy installations.
243-
///
244-
/// By default, managed PyPy installations are downloaded from [downloads.python.org](https://downloads.python.org/).
245-
/// This variable can be set to a mirror URL to use a different source for PyPy installations.
246-
/// The provided URL will replace `https://downloads.python.org/pypy` in, e.g., `https://downloads.python.org/pypy/pypy3.8-v7.3.7-osx64.tar.bz2`.
247-
///
248-
/// Distributions can be read from a
249-
/// local directory by using the `file://` URL scheme.
250-
#[option(
251-
default = "None",
252-
value_type = "str",
253-
example = r#"
254-
pypy-install-mirror = "https://downloads.python.org/pypy"
255-
"#
256-
)]
257-
pub pypy_install_mirror: Option<String>,
258231
}
259232

260233
/// Settings relevant to all installer operations.
@@ -684,6 +657,61 @@ pub struct ResolverInstallerOptions {
684657
pub no_binary_package: Option<Vec<PackageName>>,
685658
}
686659

660+
/// Shared settings, relevant to all operations that might create managed python installations.
661+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, CombineOptions, OptionsMetadata)]
662+
#[serde(rename_all = "kebab-case")]
663+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
664+
pub struct InstallMirrorOptions {
665+
/// Mirror URL for downloading managed Python installations.
666+
///
667+
/// By default, managed Python installations are downloaded from [`python-build-standalone`](https://github.com/indygreg/python-build-standalone).
668+
/// This variable can be set to a mirror URL to use a different source for Python installations.
669+
/// The provided URL will replace `https://github.com/indygreg/python-build-standalone/releases/download` in, e.g., `https://github.com/indygreg/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz`.
670+
///
671+
/// Distributions can be read from a local directory by using the `file://` URL scheme.
672+
#[option(
673+
default = "None",
674+
value_type = "str",
675+
example = r#"
676+
python-install-mirror = "https://github.com/indygreg/python-build-standalone/releases/download"
677+
"#
678+
)]
679+
pub python_install_mirror: Option<String>,
680+
/// Mirror URL to use for downloading managed PyPy installations.
681+
///
682+
/// By default, managed PyPy installations are downloaded from [downloads.python.org](https://downloads.python.org/).
683+
/// This variable can be set to a mirror URL to use a different source for PyPy installations.
684+
/// The provided URL will replace `https://downloads.python.org/pypy` in, e.g., `https://downloads.python.org/pypy/pypy3.8-v7.3.7-osx64.tar.bz2`.
685+
///
686+
/// Distributions can be read from a
687+
/// local directory by using the `file://` URL scheme.
688+
#[option(
689+
default = "None",
690+
value_type = "str",
691+
example = r#"
692+
pypy-install-mirror = "https://downloads.python.org/pypy"
693+
"#
694+
)]
695+
pub pypy_install_mirror: Option<String>,
696+
}
697+
698+
impl Default for InstallMirrorOptions {
699+
fn default() -> Self {
700+
InstallMirrorOptions::resolve(None, None)
701+
}
702+
}
703+
704+
impl InstallMirrorOptions {
705+
pub fn resolve(python_mirror: Option<String>, pypy_mirror: Option<String>) -> Self {
706+
let python_mirror_env = std::env::var(EnvVars::UV_PYTHON_INSTALL_MIRROR).ok();
707+
let pypy_mirror_env = std::env::var(EnvVars::UV_PYPY_INSTALL_MIRROR).ok();
708+
InstallMirrorOptions {
709+
python_install_mirror: python_mirror_env.or(python_mirror),
710+
pypy_install_mirror: pypy_mirror_env.or(pypy_mirror),
711+
}
712+
}
713+
}
714+
687715
/// Settings that are specific to the `uv pip` command-line interface.
688716
///
689717
/// These values will be ignored when running commands outside the `uv pip` namespace (e.g.,
@@ -1540,8 +1568,6 @@ pub struct OptionsWire {
15401568
preview: Option<bool>,
15411569
python_preference: Option<PythonPreference>,
15421570
python_downloads: Option<PythonDownloads>,
1543-
python_install_mirror: Option<String>,
1544-
pypy_install_mirror: Option<String>,
15451571
concurrent_downloads: Option<NonZeroUsize>,
15461572
concurrent_builds: Option<NonZeroUsize>,
15471573
concurrent_installs: Option<NonZeroUsize>,
@@ -1575,6 +1601,11 @@ pub struct OptionsWire {
15751601
no_binary: Option<bool>,
15761602
no_binary_package: Option<Vec<PackageName>>,
15771603

1604+
// #[serde(flatten)]
1605+
// install_mirror: InstallMirrorOptions,
1606+
python_install_mirror: Option<String>,
1607+
pypy_install_mirror: Option<String>,
1608+
15781609
// #[serde(flatten)]
15791610
// publish: PublishOptions
15801611
publish_url: Option<Url>,
@@ -1670,8 +1701,6 @@ impl From<OptionsWire> for Options {
16701701
preview,
16711702
python_preference,
16721703
python_downloads,
1673-
python_install_mirror,
1674-
pypy_install_mirror,
16751704
concurrent_downloads,
16761705
concurrent_builds,
16771706
concurrent_installs,
@@ -1713,6 +1742,10 @@ impl From<OptionsWire> for Options {
17131742
override_dependencies,
17141743
constraint_dependencies,
17151744
environments,
1745+
install_mirrors: InstallMirrorOptions::resolve(
1746+
python_install_mirror,
1747+
pypy_install_mirror,
1748+
),
17161749
}
17171750
}
17181751
}

crates/uv/src/commands/build_frontend.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use uv_python::{
2727
};
2828
use uv_requirements::RequirementsSource;
2929
use uv_resolver::{ExcludeNewer, FlatIndex, RequiresPython};
30+
use uv_settings::InstallMirrorOptions;
3031
use uv_types::{BuildContext, BuildIsolation, HashStrategy};
3132
use uv_workspace::{DiscoveryOptions, Workspace, WorkspaceError};
3233

@@ -51,6 +52,7 @@ pub(crate) async fn build_frontend(
5152
build_constraints: Vec<RequirementsSource>,
5253
hash_checking: Option<HashCheckingMode>,
5354
python: Option<String>,
55+
install_mirrors: InstallMirrorOptions,
5456
settings: ResolverSettings,
5557
no_config: bool,
5658
python_preference: PythonPreference,
@@ -73,6 +75,7 @@ pub(crate) async fn build_frontend(
7375
&build_constraints,
7476
hash_checking,
7577
python.as_deref(),
78+
install_mirrors,
7679
settings.as_ref(),
7780
no_config,
7881
python_preference,
@@ -113,6 +116,7 @@ async fn build_impl(
113116
build_constraints: &[RequirementsSource],
114117
hash_checking: Option<HashCheckingMode>,
115118
python_request: Option<&str>,
119+
install_mirrors: InstallMirrorOptions,
116120
settings: ResolverSettingsRef<'_>,
117121
no_config: bool,
118122
python_preference: PythonPreference,
@@ -247,6 +251,7 @@ async fn build_impl(
247251
source.clone(),
248252
output_dir,
249253
python_request,
254+
install_mirrors.clone(),
250255
no_config,
251256
workspace.as_ref(),
252257
python_preference,
@@ -342,6 +347,7 @@ async fn build_package(
342347
source: AnnotatedSource<'_>,
343348
output_dir: Option<&Path>,
344349
python_request: Option<&str>,
350+
install_mirrors: InstallMirrorOptions,
345351
no_config: bool,
346352
workspace: Result<&Workspace, &WorkspaceError>,
347353
python_preference: PythonPreference,
@@ -417,6 +423,8 @@ async fn build_package(
417423
client_builder,
418424
cache,
419425
Some(&PythonDownloadReporter::single(printer)),
426+
install_mirrors.python_install_mirror,
427+
install_mirrors.pypy_install_mirror,
420428
)
421429
.await?
422430
.into_interpreter();

crates/uv/src/commands/project/add.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use uv_python::{
3131
use uv_requirements::{NamedRequirementsResolver, RequirementsSource, RequirementsSpecification};
3232
use uv_resolver::{FlatIndex, InstallTarget};
3333
use uv_scripts::Pep723Script;
34+
use uv_settings::InstallMirrorOptions;
3435
use uv_types::{BuildIsolation, HashStrategy};
3536
use uv_warnings::warn_user_once;
3637
use uv_workspace::pyproject::{DependencyType, Source, SourceError};
@@ -67,6 +68,7 @@ pub(crate) async fn add(
6768
extras: Vec<ExtraName>,
6869
package: Option<PackageName>,
6970
python: Option<String>,
71+
install_mirrors: InstallMirrorOptions,
7072
settings: ResolverInstallerSettings,
7173
script: Option<PathBuf>,
7274
python_preference: PythonPreference,
@@ -133,6 +135,7 @@ pub(crate) async fn add(
133135
} else {
134136
let requires_python = script_python_requirement(
135137
python.as_deref(),
138+
install_mirrors.clone(),
136139
project_dir,
137140
false,
138141
python_preference,
@@ -176,6 +179,8 @@ pub(crate) async fn add(
176179
&client_builder,
177180
cache,
178181
Some(&reporter),
182+
install_mirrors.python_install_mirror,
183+
install_mirrors.pypy_install_mirror,
179184
)
180185
.await?
181186
.into_interpreter();
@@ -213,6 +218,7 @@ pub(crate) async fn add(
213218
let venv = project::get_or_init_environment(
214219
project.workspace(),
215220
python.as_deref().map(PythonRequest::parse),
221+
install_mirrors.clone(),
216222
python_preference,
217223
python_downloads,
218224
connectivity,

crates/uv/src/commands/project/export.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use anyhow::{Context, Result};
44
use itertools::Itertools;
55
use owo_colors::OwoColorize;
66
use std::path::{Path, PathBuf};
7+
use uv_settings::InstallMirrorOptions;
78

89
use uv_cache::Cache;
910
use uv_client::Connectivity;
@@ -42,6 +43,7 @@ pub(crate) async fn export(
4243
frozen: bool,
4344
include_header: bool,
4445
python: Option<String>,
46+
install_mirrors: InstallMirrorOptions,
4547
settings: ResolverSettings,
4648
python_preference: PythonPreference,
4749
python_downloads: PythonDownloads,
@@ -105,6 +107,7 @@ pub(crate) async fn export(
105107
native_tls,
106108
cache,
107109
printer,
110+
install_mirrors,
108111
)
109112
.await?
110113
.into_interpreter();

0 commit comments

Comments
 (0)