mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-17 13:58:29 +00:00
Enable mirror for python-build-standalone
downloads (#5719)
## Summary This came up again recently, so decided to do it real quick. Closes https://github.com/astral-sh/uv/issues/5224.
This commit is contained in:
parent
9081509715
commit
f7110e0a07
4 changed files with 67 additions and 8 deletions
10
README.md
10
README.md
|
@ -618,6 +618,16 @@ uv accepts the following command-line arguments as environment variables:
|
||||||
packages.
|
packages.
|
||||||
- `UV_EXCLUDE_NEWER`: Equivalent to the `--exclude-newer` command-line argument. If set, uv will
|
- `UV_EXCLUDE_NEWER`: Equivalent to the `--exclude-newer` command-line argument. If set, uv will
|
||||||
exclude distributions published after the specified date.
|
exclude distributions published after the specified date.
|
||||||
|
- `UV_PYTHON_INSTALL_MIRROR`: Managed Python installations are downloaded from
|
||||||
|
[`python-build-standalone`](https://github.com/indygreg/python-build-standalone). This variable
|
||||||
|
can be set to a mirror URL to use a different source for Python installations. 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`.
|
||||||
|
- `UV_PYPY_INSTALL_MIRROR`: Managed PyPy installations are downloaded from
|
||||||
|
[python.org](https://downloads.python.org/). This variable can be set to a mirror URL to use a
|
||||||
|
different source for PyPy installations. 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`.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,10 @@ pub enum Error {
|
||||||
InvalidPythonVersion(String),
|
InvalidPythonVersion(String),
|
||||||
#[error("Invalid request key (too many parts): {0}")]
|
#[error("Invalid request key (too many parts): {0}")]
|
||||||
TooManyParts(String),
|
TooManyParts(String),
|
||||||
#[error("Download failed")]
|
#[error(transparent)]
|
||||||
NetworkError(#[from] WrappedReqwestError),
|
NetworkError(#[from] WrappedReqwestError),
|
||||||
#[error("Download failed")]
|
#[error(transparent)]
|
||||||
NetworkMiddlewareError(#[source] anyhow::Error),
|
NetworkMiddlewareError(#[from] anyhow::Error),
|
||||||
#[error("Failed to extract archive: {0}")]
|
#[error("Failed to extract archive: {0}")]
|
||||||
ExtractError(String, #[source] uv_extract::Error),
|
ExtractError(String, #[source] uv_extract::Error),
|
||||||
#[error("Failed to hash installation")]
|
#[error("Failed to hash installation")]
|
||||||
|
@ -70,6 +70,10 @@ pub enum Error {
|
||||||
InvalidRequestPlatform(#[from] platform::Error),
|
InvalidRequestPlatform(#[from] platform::Error),
|
||||||
#[error("No download found for request: {}", _0.green())]
|
#[error("No download found for request: {}", _0.green())]
|
||||||
NoDownloadFound(PythonDownloadRequest),
|
NoDownloadFound(PythonDownloadRequest),
|
||||||
|
#[error(
|
||||||
|
"A mirror was provided via `{0}`, but the URL does not match the expected format: {0}"
|
||||||
|
)]
|
||||||
|
Mirror(&'static str, &'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
@ -410,7 +414,7 @@ impl ManagedPythonDownload {
|
||||||
cache: &Cache,
|
cache: &Cache,
|
||||||
reporter: Option<&dyn Reporter>,
|
reporter: Option<&dyn Reporter>,
|
||||||
) -> Result<DownloadResult, Error> {
|
) -> Result<DownloadResult, Error> {
|
||||||
let url = Url::parse(self.url)?;
|
let url = self.download_url()?;
|
||||||
let path = parent_path.join(self.key().to_string());
|
let path = parent_path.join(self.key().to_string());
|
||||||
|
|
||||||
// If it already exists, return it
|
// If it already exists, return it
|
||||||
|
@ -433,8 +437,8 @@ impl ManagedPythonDownload {
|
||||||
let temp_dir = tempfile::tempdir_in(cache.root()).map_err(Error::DownloadDirError)?;
|
let temp_dir = tempfile::tempdir_in(cache.root()).map_err(Error::DownloadDirError)?;
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"Downloading {url} to temporary location {}",
|
"Downloading {url} to temporary location: {}",
|
||||||
temp_dir.path().display()
|
temp_dir.path().simplified().display()
|
||||||
);
|
);
|
||||||
|
|
||||||
let stream = response
|
let stream = response
|
||||||
|
@ -525,6 +529,41 @@ impl ManagedPythonDownload {
|
||||||
pub fn python_version(&self) -> PythonVersion {
|
pub fn python_version(&self) -> PythonVersion {
|
||||||
self.key.version()
|
self.key.version()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the [`Url`] to use when downloading the distribution. If a mirror is set via the
|
||||||
|
/// appropriate environment variable, use it instead.
|
||||||
|
fn download_url(&self) -> Result<Url, Error> {
|
||||||
|
match self.key.implementation {
|
||||||
|
LenientImplementationName::Known(ImplementationName::CPython) => {
|
||||||
|
if let Ok(mirror) = std::env::var("UV_PYTHON_INSTALL_MIRROR") {
|
||||||
|
let Some(suffix) = self.url.strip_prefix(
|
||||||
|
"https://github.com/indygreg/python-build-standalone/releases/download/",
|
||||||
|
) else {
|
||||||
|
return Err(Error::Mirror("UV_PYTHON_INSTALL_MIRROR", self.url));
|
||||||
|
};
|
||||||
|
return Ok(Url::parse(
|
||||||
|
format!("{}/{}", mirror.trim_end_matches('/'), suffix).as_str(),
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LenientImplementationName::Known(ImplementationName::PyPy) => {
|
||||||
|
if let Ok(mirror) = std::env::var("UV_PYPY_INSTALL_MIRROR") {
|
||||||
|
let Some(suffix) = self.url.strip_prefix("https://downloads.python.org/pypy/")
|
||||||
|
else {
|
||||||
|
return Err(Error::Mirror("UV_PYPY_INSTALL_MIRROR", self.url));
|
||||||
|
};
|
||||||
|
return Ok(Url::parse(
|
||||||
|
format!("{}/{}", mirror.trim_end_matches('/'), suffix).as_str(),
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Url::parse(self.url)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<reqwest::Error> for Error {
|
impl From<reqwest::Error> for Error {
|
||||||
|
|
|
@ -235,9 +235,9 @@ pub(crate) async fn install(
|
||||||
for (key, err) in errors {
|
for (key, err) in errors {
|
||||||
writeln!(
|
writeln!(
|
||||||
printer.stderr(),
|
printer.stderr(),
|
||||||
"Failed to install {}: {}",
|
"{}: Failed to install {}: {err}",
|
||||||
|
"error".red().bold(),
|
||||||
key.green(),
|
key.green(),
|
||||||
err
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
return Ok(ExitStatus::Failure);
|
return Ok(ExitStatus::Failure);
|
||||||
|
|
|
@ -53,6 +53,16 @@ uv accepts the following command-line arguments as environment variables:
|
||||||
packages.
|
packages.
|
||||||
- `UV_EXCLUDE_NEWER`: Equivalent to the `--exclude-newer` command-line argument. If set, uv will
|
- `UV_EXCLUDE_NEWER`: Equivalent to the `--exclude-newer` command-line argument. If set, uv will
|
||||||
exclude distributions published after the specified date.
|
exclude distributions published after the specified date.
|
||||||
|
- `UV_PYTHON_INSTALL_MIRROR`: Managed Python installations are downloaded from
|
||||||
|
[`python-build-standalone`](https://github.com/indygreg/python-build-standalone). This variable
|
||||||
|
can be set to a mirror URL to use a different source for Python installations. 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`.
|
||||||
|
- `UV_PYPY_INSTALL_MIRROR`: Managed PyPy installations are downloaded from
|
||||||
|
[python.org](https://downloads.python.org/). This variable can be set to a mirror URL to use a
|
||||||
|
different source for PyPy installations. 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`.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue