mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-26 20:19:08 +00:00
Support for wildcard in UV_INSECURE_HOST (#8052)
Allow '*' as a value to match all hosts, and provide `reqwest_blocking_get` for uv tests, so that they also respect UV_INSECURE_HOST (since they respect `ALL_PROXY`). This lets those tests pass with a forward proxy - we can think about setting a root certificate later so that we don't need to disable certificate verification at all. --- I tested this locally by running: ```bash GIT_SSL_NO_VERIFY=true ALL_PROXY=localhost:8080 UV_INSECURE_HOST="*" cargo nextest run sync_wheel_path_source_error ``` With my forward proxy showing: ``` 2024-10-09T18:20:16.300188Z INFO fopro: Proxied GETcc2fedbd88/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl
(headers 480.024958ms + body 92.345666ms) 2024-10-09T18:20:16.913298Z INFO fopro: Proxied GET https://pypi.org/simple/pycparser/ (headers 509.664834ms + body 269.291µs) 2024-10-09T18:20:17.383975Z INFO fopro: Proxied GET5f610ebe42/pycparser-2.21-py2.py3-none-any.whl.metadata
(headers 443.184208ms + body 2.094792ms) ```
This commit is contained in:
parent
9351652e32
commit
a3b11dacb8
8 changed files with 137 additions and 81 deletions
|
@ -2,34 +2,39 @@ use serde::{Deserialize, Deserializer};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
/// A trusted host, which could be a host or a host-port pair.
|
/// A host specification (wildcard, or host, with optional scheme and/or port) for which
|
||||||
|
/// certificates are not verified when making HTTPS requests.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct TrustedHost {
|
pub enum TrustedHost {
|
||||||
scheme: Option<String>,
|
Wildcard,
|
||||||
host: String,
|
Host {
|
||||||
port: Option<u16>,
|
scheme: Option<String>,
|
||||||
|
host: String,
|
||||||
|
port: Option<u16>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrustedHost {
|
impl TrustedHost {
|
||||||
/// Returns `true` if the [`Url`] matches this trusted host.
|
/// Returns `true` if the [`Url`] matches this trusted host.
|
||||||
pub fn matches(&self, url: &Url) -> bool {
|
pub fn matches(&self, url: &Url) -> bool {
|
||||||
if self
|
match self {
|
||||||
.scheme
|
TrustedHost::Wildcard => true,
|
||||||
.as_ref()
|
TrustedHost::Host { scheme, host, port } => {
|
||||||
.is_some_and(|scheme| scheme != url.scheme())
|
if scheme.as_ref().is_some_and(|scheme| scheme != url.scheme()) {
|
||||||
{
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if self.port.is_some_and(|port| url.port() != Some(port)) {
|
if port.is_some_and(|port| url.port() != Some(port)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if Some(self.host.as_ref()) != url.host_str() {
|
if Some(host.as_str()) != url.host_str() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +53,7 @@ impl<'de> Deserialize<'de> for TrustedHost {
|
||||||
serde_untagged::UntaggedEnumVisitor::new()
|
serde_untagged::UntaggedEnumVisitor::new()
|
||||||
.string(|string| TrustedHost::from_str(string).map_err(serde::de::Error::custom))
|
.string(|string| TrustedHost::from_str(string).map_err(serde::de::Error::custom))
|
||||||
.map(|map| {
|
.map(|map| {
|
||||||
map.deserialize::<Inner>().map(|inner| TrustedHost {
|
map.deserialize::<Inner>().map(|inner| TrustedHost::Host {
|
||||||
scheme: inner.scheme,
|
scheme: inner.scheme,
|
||||||
host: inner.host,
|
host: inner.host,
|
||||||
port: inner.port,
|
port: inner.port,
|
||||||
|
@ -80,6 +85,10 @@ impl std::str::FromStr for TrustedHost {
|
||||||
type Err = TrustedHostError;
|
type Err = TrustedHostError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if s == "*" {
|
||||||
|
return Ok(Self::Wildcard);
|
||||||
|
}
|
||||||
|
|
||||||
// Detect scheme.
|
// Detect scheme.
|
||||||
let (scheme, s) = if let Some(s) = s.strip_prefix("https://") {
|
let (scheme, s) = if let Some(s) = s.strip_prefix("https://") {
|
||||||
(Some("https".to_string()), s)
|
(Some("https".to_string()), s)
|
||||||
|
@ -105,20 +114,27 @@ impl std::str::FromStr for TrustedHost {
|
||||||
.transpose()
|
.transpose()
|
||||||
.map_err(|_| TrustedHostError::InvalidPort(s.to_string()))?;
|
.map_err(|_| TrustedHostError::InvalidPort(s.to_string()))?;
|
||||||
|
|
||||||
Ok(Self { scheme, host, port })
|
Ok(Self::Host { scheme, host, port })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for TrustedHost {
|
impl std::fmt::Display for TrustedHost {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
if let Some(scheme) = &self.scheme {
|
match self {
|
||||||
write!(f, "{}://{}", scheme, self.host)?;
|
TrustedHost::Wildcard => {
|
||||||
} else {
|
write!(f, "*")?;
|
||||||
write!(f, "{}", self.host)?;
|
}
|
||||||
}
|
TrustedHost::Host { scheme, host, port } => {
|
||||||
|
if let Some(scheme) = &scheme {
|
||||||
|
write!(f, "{scheme}://{host}")?;
|
||||||
|
} else {
|
||||||
|
write!(f, "{host}")?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(port) = self.port {
|
if let Some(port) = port {
|
||||||
write!(f, ":{port}")?;
|
write!(f, ":{port}")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
#[test]
|
#[test]
|
||||||
fn parse() {
|
fn parse() {
|
||||||
|
assert_eq!(
|
||||||
|
"*".parse::<super::TrustedHost>().unwrap(),
|
||||||
|
super::TrustedHost::Wildcard
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"example.com".parse::<super::TrustedHost>().unwrap(),
|
"example.com".parse::<super::TrustedHost>().unwrap(),
|
||||||
super::TrustedHost {
|
super::TrustedHost::Host {
|
||||||
scheme: None,
|
scheme: None,
|
||||||
host: "example.com".to_string(),
|
host: "example.com".to_string(),
|
||||||
port: None
|
port: None
|
||||||
|
@ -11,7 +16,7 @@ fn parse() {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"example.com:8080".parse::<super::TrustedHost>().unwrap(),
|
"example.com:8080".parse::<super::TrustedHost>().unwrap(),
|
||||||
super::TrustedHost {
|
super::TrustedHost::Host {
|
||||||
scheme: None,
|
scheme: None,
|
||||||
host: "example.com".to_string(),
|
host: "example.com".to_string(),
|
||||||
port: Some(8080)
|
port: Some(8080)
|
||||||
|
@ -20,7 +25,7 @@ fn parse() {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"https://example.com".parse::<super::TrustedHost>().unwrap(),
|
"https://example.com".parse::<super::TrustedHost>().unwrap(),
|
||||||
super::TrustedHost {
|
super::TrustedHost::Host {
|
||||||
scheme: Some("https".to_string()),
|
scheme: Some("https".to_string()),
|
||||||
host: "example.com".to_string(),
|
host: "example.com".to_string(),
|
||||||
port: None
|
port: None
|
||||||
|
@ -31,7 +36,7 @@ fn parse() {
|
||||||
"https://example.com/hello/world"
|
"https://example.com/hello/world"
|
||||||
.parse::<super::TrustedHost>()
|
.parse::<super::TrustedHost>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
super::TrustedHost {
|
super::TrustedHost::Host {
|
||||||
scheme: Some("https".to_string()),
|
scheme: Some("https".to_string()),
|
||||||
host: "example.com".to_string(),
|
host: "example.com".to_string(),
|
||||||
port: None
|
port: None
|
||||||
|
|
|
@ -14,11 +14,13 @@ use assert_fs::assert::PathAssert;
|
||||||
use assert_fs::fixture::{ChildPath, PathChild, PathCopy, PathCreateDir, SymlinkToFile};
|
use assert_fs::fixture::{ChildPath, PathChild, PathCopy, PathCreateDir, SymlinkToFile};
|
||||||
use base64::{prelude::BASE64_STANDARD as base64, Engine};
|
use base64::{prelude::BASE64_STANDARD as base64, Engine};
|
||||||
use etcetera::BaseStrategy;
|
use etcetera::BaseStrategy;
|
||||||
|
use futures::StreamExt;
|
||||||
use indoc::formatdoc;
|
use indoc::formatdoc;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use predicates::prelude::predicate;
|
use predicates::prelude::predicate;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
use uv_python::managed::ManagedPythonInstallations;
|
use uv_python::managed::ManagedPythonInstallations;
|
||||||
|
@ -1279,6 +1281,31 @@ pub fn decode_token(content: &[&str]) -> String {
|
||||||
token
|
token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simulates `reqwest::blocking::get` but returns bytes directly, and disables
|
||||||
|
/// certificate verification, passing through the `BaseClient`
|
||||||
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
pub async fn download_to_disk(url: &str, path: &Path) {
|
||||||
|
let trusted_hosts: Vec<_> = std::env::var("UV_INSECURE_HOST")
|
||||||
|
.unwrap_or_default()
|
||||||
|
.split(' ')
|
||||||
|
.map(|h| uv_configuration::TrustedHost::from_str(h).unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let client = uv_client::BaseClientBuilder::new()
|
||||||
|
.allow_insecure_host(trusted_hosts)
|
||||||
|
.build();
|
||||||
|
let url: reqwest::Url = url.parse().unwrap();
|
||||||
|
let client = client.for_host(&url);
|
||||||
|
let response = client.request(http::Method::GET, url).send().await.unwrap();
|
||||||
|
|
||||||
|
let mut file = tokio::fs::File::create(path).await.unwrap();
|
||||||
|
let mut stream = response.bytes_stream();
|
||||||
|
while let Some(chunk) = stream.next().await {
|
||||||
|
file.write_all(&chunk.unwrap()).await.unwrap();
|
||||||
|
}
|
||||||
|
file.sync_all().await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
/// Utility macro to return the name of the current function.
|
/// Utility macro to return the name of the current function.
|
||||||
///
|
///
|
||||||
/// https://stackoverflow.com/a/40234666/3549270
|
/// https://stackoverflow.com/a/40234666/3549270
|
||||||
|
|
|
@ -7,7 +7,8 @@ use std::io::BufReader;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::common::{
|
use crate::common::{
|
||||||
self, build_vendor_links_url, decode_token, packse_index_url, uv_snapshot, TestContext,
|
self, build_vendor_links_url, decode_token, download_to_disk, packse_index_url, uv_snapshot,
|
||||||
|
TestContext,
|
||||||
};
|
};
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
|
|
||||||
|
@ -7967,11 +7968,11 @@ fn lock_sources_archive() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download the source.
|
// Download the source.
|
||||||
let response =
|
|
||||||
reqwest::blocking::get("https://github.com/user-attachments/files/16592193/workspace.zip")?;
|
|
||||||
let workspace_archive = context.temp_dir.child("workspace.zip");
|
let workspace_archive = context.temp_dir.child("workspace.zip");
|
||||||
let mut workspace_archive_file = fs_err::File::create(&*workspace_archive)?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut workspace_archive_file)?;
|
"https://github.com/user-attachments/files/16592193/workspace.zip",
|
||||||
|
&workspace_archive,
|
||||||
|
);
|
||||||
|
|
||||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
pyproject_toml.write_str(&formatdoc! {
|
pyproject_toml.write_str(&formatdoc! {
|
||||||
|
@ -8106,11 +8107,11 @@ fn lock_sources_source_tree() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download the source.
|
// Download the source.
|
||||||
let response =
|
|
||||||
reqwest::blocking::get("https://github.com/user-attachments/files/16592193/workspace.zip")?;
|
|
||||||
let workspace_archive = context.temp_dir.child("workspace.zip");
|
let workspace_archive = context.temp_dir.child("workspace.zip");
|
||||||
let mut workspace_archive_file = fs_err::File::create(&*workspace_archive)?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut workspace_archive_file)?;
|
"https://github.com/user-attachments/files/16592193/workspace.zip",
|
||||||
|
&workspace_archive,
|
||||||
|
);
|
||||||
|
|
||||||
// Unzip the file.
|
// Unzip the file.
|
||||||
let file = fs_err::File::open(&*workspace_archive)?;
|
let file = fs_err::File::open(&*workspace_archive)?;
|
||||||
|
|
|
@ -8,9 +8,9 @@ use anyhow::{bail, Context, Result};
|
||||||
use assert_fs::prelude::*;
|
use assert_fs::prelude::*;
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use uv_fs::Simplified;
|
|
||||||
|
|
||||||
use crate::common::{uv_snapshot, TestContext};
|
use crate::common::{download_to_disk, uv_snapshot, TestContext};
|
||||||
|
use uv_fs::Simplified;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compile_requirements_in() -> Result<()> {
|
fn compile_requirements_in() -> Result<()> {
|
||||||
|
@ -2592,10 +2592,11 @@ fn compile_wheel_path_dependency() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?;
|
|
||||||
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
||||||
let mut flask_wheel_file = fs::File::create(&flask_wheel)?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
"https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl",
|
||||||
|
&flask_wheel,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_in = context.temp_dir.child("requirements.in");
|
let requirements_in = context.temp_dir.child("requirements.in");
|
||||||
requirements_in.write_str(&format!(
|
requirements_in.write_str(&format!(
|
||||||
|
@ -2842,10 +2843,11 @@ fn compile_wheel_path_dependency() -> Result<()> {
|
||||||
fn compile_source_distribution_path_dependency() -> Result<()> {
|
fn compile_source_distribution_path_dependency() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
// Download a source distribution.
|
// Download a source distribution.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz")?;
|
|
||||||
let flask_wheel = context.temp_dir.child("flask-3.0.0.tar.gz");
|
let flask_wheel = context.temp_dir.child("flask-3.0.0.tar.gz");
|
||||||
let mut flask_wheel_file = std::fs::File::create(&flask_wheel)?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
"https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz",
|
||||||
|
&flask_wheel,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_in = context.temp_dir.child("requirements.in");
|
let requirements_in = context.temp_dir.child("requirements.in");
|
||||||
requirements_in.write_str(&format!(
|
requirements_in.write_str(&format!(
|
||||||
|
@ -3517,10 +3519,11 @@ fn preserve_url() -> Result<()> {
|
||||||
fn preserve_project_root() -> Result<()> {
|
fn preserve_project_root() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?;
|
|
||||||
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
||||||
let mut flask_wheel_file = std::fs::File::create(flask_wheel)?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
"https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl",
|
||||||
|
&flask_wheel,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_in = context.temp_dir.child("requirements.in");
|
let requirements_in = context.temp_dir.child("requirements.in");
|
||||||
requirements_in.write_str("flask @ file://${PROJECT_ROOT}/flask-3.0.0-py3-none-any.whl")?;
|
requirements_in.write_str("flask @ file://${PROJECT_ROOT}/flask-3.0.0-py3-none-any.whl")?;
|
||||||
|
@ -3670,10 +3673,11 @@ fn error_missing_unnamed_env_var() -> Result<()> {
|
||||||
fn respect_file_env_var() -> Result<()> {
|
fn respect_file_env_var() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?;
|
|
||||||
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
||||||
let mut flask_wheel_file = std::fs::File::create(flask_wheel)?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
"https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl",
|
||||||
|
&flask_wheel,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_in = context.temp_dir.child("requirements.in");
|
let requirements_in = context.temp_dir.child("requirements.in");
|
||||||
requirements_in.write_str("flask @ ${FILE_PATH}")?;
|
requirements_in.write_str("flask @ ${FILE_PATH}")?;
|
||||||
|
|
|
@ -12,7 +12,8 @@ use predicates::Predicate;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::common::{
|
use crate::common::{
|
||||||
copy_dir_all, site_packages_path, uv_snapshot, venv_to_interpreter, TestContext,
|
copy_dir_all, download_to_disk, site_packages_path, uv_snapshot, venv_to_interpreter,
|
||||||
|
TestContext,
|
||||||
};
|
};
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
|
|
||||||
|
@ -1069,10 +1070,8 @@ fn install_local_wheel() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
|
||||||
let archive = context.temp_dir.child("tomli-2.0.1-py3-none-any.whl");
|
let archive = context.temp_dir.child("tomli-2.0.1-py3-none-any.whl");
|
||||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
download_to_disk("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", &archive);
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
|
||||||
|
|
||||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||||
requirements_txt.write_str(&format!(
|
requirements_txt.write_str(&format!(
|
||||||
|
@ -1208,10 +1207,8 @@ fn mismatched_version() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
|
||||||
let archive = context.temp_dir.child("tomli-3.7.2-py3-none-any.whl");
|
let archive = context.temp_dir.child("tomli-3.7.2-py3-none-any.whl");
|
||||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
download_to_disk("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", &archive);
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
|
||||||
|
|
||||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||||
requirements_txt.write_str(&format!(
|
requirements_txt.write_str(&format!(
|
||||||
|
@ -1243,10 +1240,11 @@ fn mismatched_name() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
|
||||||
let archive = context.temp_dir.child("foo-2.0.1-py3-none-any.whl");
|
let archive = context.temp_dir.child("foo-2.0.1-py3-none-any.whl");
|
||||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
"https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
|
||||||
|
&archive,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||||
requirements_txt.write_str(&format!(
|
requirements_txt.write_str(&format!(
|
||||||
|
@ -1279,10 +1277,11 @@ fn install_local_source_distribution() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a source distribution.
|
// Download a source distribution.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/b0/b4/bc2baae3970c282fae6c2cb8e0f179923dceb7eaffb0e76170628f9af97b/wheel-0.42.0.tar.gz")?;
|
|
||||||
let archive = context.temp_dir.child("wheel-0.42.0.tar.gz");
|
let archive = context.temp_dir.child("wheel-0.42.0.tar.gz");
|
||||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
"https://files.pythonhosted.org/packages/b0/b4/bc2baae3970c282fae6c2cb8e0f179923dceb7eaffb0e76170628f9af97b/wheel-0.42.0.tar.gz",
|
||||||
|
&archive,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||||
requirements_txt.write_str(&format!(
|
requirements_txt.write_str(&format!(
|
||||||
|
@ -1639,10 +1638,11 @@ fn install_path_source_dist_cached() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a source distribution.
|
// Download a source distribution.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz")?;
|
|
||||||
let archive = context.temp_dir.child("source_distribution-0.0.1.tar.gz");
|
let archive = context.temp_dir.child("source_distribution-0.0.1.tar.gz");
|
||||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
"https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz",
|
||||||
|
&archive,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||||
requirements_txt.write_str(&format!(
|
requirements_txt.write_str(&format!(
|
||||||
|
@ -1734,10 +1734,11 @@ fn install_path_built_dist_cached() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
|
||||||
let archive = context.temp_dir.child("tomli-2.0.1-py3-none-any.whl");
|
let archive = context.temp_dir.child("tomli-2.0.1-py3-none-any.whl");
|
||||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
"https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
|
||||||
|
&archive,
|
||||||
|
);
|
||||||
|
|
||||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||||
let url = Url::from_file_path(archive.path()).unwrap();
|
let url = Url::from_file_path(archive.path()).unwrap();
|
||||||
|
|
|
@ -3552,12 +3552,12 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
||||||
index_strategy: FirstIndex,
|
index_strategy: FirstIndex,
|
||||||
keyring_provider: Disabled,
|
keyring_provider: Disabled,
|
||||||
allow_insecure_host: [
|
allow_insecure_host: [
|
||||||
TrustedHost {
|
Host {
|
||||||
scheme: None,
|
scheme: None,
|
||||||
host: "google.com",
|
host: "google.com",
|
||||||
port: None,
|
port: None,
|
||||||
},
|
},
|
||||||
TrustedHost {
|
Host {
|
||||||
scheme: None,
|
scheme: None,
|
||||||
host: "example.com",
|
host: "example.com",
|
||||||
port: None,
|
port: None,
|
||||||
|
|
|
@ -2,10 +2,11 @@ use anyhow::Result;
|
||||||
use assert_cmd::prelude::*;
|
use assert_cmd::prelude::*;
|
||||||
use assert_fs::{fixture::ChildPath, prelude::*};
|
use assert_fs::{fixture::ChildPath, prelude::*};
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
|
|
||||||
|
use predicates::prelude::predicate;
|
||||||
use tempfile::tempdir_in;
|
use tempfile::tempdir_in;
|
||||||
|
|
||||||
use crate::common::{uv_snapshot, venv_bin_path, TestContext};
|
use crate::common::{download_to_disk, uv_snapshot, venv_bin_path, TestContext};
|
||||||
use predicates::prelude::predicate;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sync() -> Result<()> {
|
fn sync() -> Result<()> {
|
||||||
|
@ -2309,12 +2310,13 @@ fn sync_wheel_path_source_error() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
// Download a wheel.
|
// Download a wheel.
|
||||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl")?;
|
|
||||||
let archive = context
|
let archive = context
|
||||||
.temp_dir
|
.temp_dir
|
||||||
.child("cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl");
|
.child("cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl");
|
||||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
download_to_disk(
|
||||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
"https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl",
|
||||||
|
&archive,
|
||||||
|
);
|
||||||
|
|
||||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
pyproject_toml.write_str(
|
pyproject_toml.write_str(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue