Skip to content

Commit

Permalink
Use custom type
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Aug 24, 2024
1 parent e014bfb commit 0c76816
Show file tree
Hide file tree
Showing 16 changed files with 145 additions and 75 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 14 additions & 14 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use clap::{Args, Parser, Subcommand};
use distribution_types::{FlatIndexLocation, IndexUrl};
use pep508_rs::Requirement;
use pypi_types::VerbatimParsedUrl;
use url::Url;
use uv_cache::CacheArgs;
use uv_configuration::{
ConfigSettingEntry, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple,
TrustedHost,
};
use uv_normalize::{ExtraName, PackageName};
use uv_python::{PythonDownloads, PythonPreference, PythonVersion};
Expand Down Expand Up @@ -679,12 +679,12 @@ fn parse_index_url(input: &str) -> Result<Maybe<IndexUrl>, String> {
}

/// Parse a string into an [`Url`], mapping the empty string to `None`.
fn parse_maybe_url(input: &str) -> Result<Maybe<Url>, String> {
fn parse_trusted_host(input: &str) -> Result<Maybe<TrustedHost>, String> {
if input.is_empty() {
Ok(Maybe::None)
} else {
match Url::parse(input) {
Ok(url) => Ok(Maybe::Some(url)),
match TrustedHost::from_str(input) {
Ok(host) => Ok(Maybe::Some(host)),
Err(err) => Err(err.to_string()),
}
}
Expand Down Expand Up @@ -1579,9 +1579,9 @@ pub struct PipUninstallArgs {
long,
env = "UV_TRUSTED_HOST",
value_delimiter = ' ',
value_parser = parse_maybe_url,
value_parser = parse_trusted_host,
)]
pub trusted_host: Option<Vec<Maybe<Url>>>,
pub trusted_host: Option<Vec<Maybe<TrustedHost>>>,

/// Use the system Python to uninstall packages.
///
Expand Down Expand Up @@ -2017,9 +2017,9 @@ pub struct VenvArgs {
long,
env = "UV_TRUSTED_HOST",
value_delimiter = ' ',
value_parser = parse_maybe_url,
value_parser = parse_trusted_host,
)]
pub trusted_host: Option<Vec<Maybe<Url>>>,
pub trusted_host: Option<Vec<Maybe<TrustedHost>>>,

/// Limit candidate packages to those that were uploaded prior to the given date.
///
Expand Down Expand Up @@ -3368,10 +3368,10 @@ pub struct InstallerArgs {
long,
env = "UV_TRUSTED_HOST",
value_delimiter = ' ',
value_parser = parse_maybe_url,
value_parser = parse_trusted_host,
help_heading = "Index options"
)]
pub trusted_host: Option<Vec<Maybe<Url>>>,
pub trusted_host: Option<Vec<Maybe<TrustedHost>>>,

/// Settings to pass to the PEP 517 build backend, specified as `KEY=VALUE` pairs.
#[arg(
Expand Down Expand Up @@ -3523,10 +3523,10 @@ pub struct ResolverArgs {
long,
env = "UV_TRUSTED_HOST",
value_delimiter = ' ',
value_parser = parse_maybe_url,
value_parser = parse_trusted_host,
help_heading = "Index options"
)]
pub trusted_host: Option<Vec<Maybe<Url>>>,
pub trusted_host: Option<Vec<Maybe<TrustedHost>>>,

/// The strategy to use when selecting between the different compatible versions for a given
/// package requirement.
Expand Down Expand Up @@ -3708,10 +3708,10 @@ pub struct ResolverInstallerArgs {
long,
env = "UV_TRUSTED_HOST",
value_delimiter = ' ',
value_parser = parse_maybe_url,
value_parser = parse_trusted_host,
help_heading = "Index options"
)]
pub trusted_host: Option<Vec<Maybe<Url>>>,
pub trusted_host: Option<Vec<Maybe<TrustedHost>>>,

/// The strategy to use when selecting between the different compatible versions for a given
/// package requirement.
Expand Down
17 changes: 11 additions & 6 deletions crates/uv-client/src/base_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use reqwest_retry::{
use tracing::debug;
use url::Url;
use uv_auth::AuthMiddleware;
use uv_configuration::KeyringProviderType;
use uv_configuration::{KeyringProviderType, TrustedHost};
use uv_fs::Simplified;
use uv_version::version;
use uv_warnings::warn_user_once;
Expand All @@ -29,7 +29,7 @@ use crate::Connectivity;
#[derive(Debug, Clone)]
pub struct BaseClientBuilder<'a> {
keyring: KeyringProviderType,
trusted_host: Vec<Url>,
trusted_host: Vec<TrustedHost>,
native_tls: bool,
retries: u32,
pub connectivity: Connectivity,
Expand Down Expand Up @@ -67,7 +67,7 @@ impl<'a> BaseClientBuilder<'a> {
}

#[must_use]
pub fn trusted_host(mut self, trusted_host: Vec<Url>) -> Self {
pub fn trusted_host(mut self, trusted_host: Vec<TrustedHost>) -> Self {
self.trusted_host = trusted_host;
self
}
Expand Down Expand Up @@ -175,10 +175,10 @@ impl<'a> BaseClientBuilder<'a> {

BaseClient {
connectivity: self.connectivity,
trusted_host: self.trusted_host.clone(),
client,
dangerous_client,
timeout,
trusted_host: vec![],
}
}

Expand Down Expand Up @@ -265,7 +265,7 @@ pub struct BaseClient {
/// Configured client timeout, in seconds.
timeout: u64,
/// The host that is trusted to use the insecure client.
trusted_host: Vec<Url>,
trusted_host: Vec<TrustedHost>,
}

#[derive(Debug, Clone, Copy)]
Expand All @@ -287,7 +287,12 @@ impl BaseClient {
if self
.trusted_host
.iter()
.any(|trusted| url.host() == trusted.host())
.any(|trusted_host| match trusted_host {
TrustedHost::Host(host) => url.host_str() == Some(host.as_str()),
TrustedHost::HostPort(host, port) => {
url.host_str() == Some(host.as_str()) && url.port() == Some(*port)
}
})
{
&self.dangerous_client
} else {
Expand Down
4 changes: 2 additions & 2 deletions crates/uv-client/src/registry_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use pep508_rs::MarkerEnvironment;
use platform_tags::Platform;
use pypi_types::{Metadata23, SimpleJson};
use uv_cache::{Cache, CacheBucket, CacheEntry, WheelCache};
use uv_configuration::IndexStrategy;
use uv_configuration::KeyringProviderType;
use uv_configuration::{IndexStrategy, TrustedHost};
use uv_normalize::PackageName;

use crate::base_client::BaseClientBuilder;
Expand Down Expand Up @@ -73,7 +73,7 @@ impl<'a> RegistryClientBuilder<'a> {
}

#[must_use]
pub fn trusted_host(mut self, trusted_host: Vec<Url>) -> Self {
pub fn trusted_host(mut self, trusted_host: Vec<TrustedHost>) -> Self {
self.base_client_builder = self.base_client_builder.trusted_host(trusted_host);
self
}
Expand Down
1 change: 1 addition & 0 deletions crates/uv-configuration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rustc-hash = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }

[dev-dependencies]
Expand Down
2 changes: 2 additions & 0 deletions crates/uv-configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub use package_options::*;
pub use preview::*;
pub use sources::*;
pub use target_triple::*;
pub use trusted_host::*;

mod authentication;
mod build_options;
Expand All @@ -25,3 +26,4 @@ mod package_options;
mod preview;
mod sources;
mod target_triple;
mod trusted_host;
56 changes: 56 additions & 0 deletions crates/uv-configuration/src/trusted_host.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use serde::{Deserialize, Serialize};

/// A trusted host, which could be a host or a host-port pair.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum TrustedHost {
Host(String),
HostPort(String, u16),
}

#[derive(Debug, thiserror::Error)]
pub enum TrustedHostError {
#[error("missing host for `--trusted-host`: `{0}`")]
MissingHost(String),
#[error("invalid port for `--trusted-host`: `{0}`")]
InvalidPort(String),
}

impl std::str::FromStr for TrustedHost {
type Err = TrustedHostError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.splitn(2, ':');
let host = parts
.next()
.ok_or_else(|| TrustedHostError::MissingHost(s.to_string()))?;
let port = parts
.next()
.map(str::parse)
.transpose()
.map_err(|_| TrustedHostError::InvalidPort(s.to_string()))?;

match port {
Some(port) => Ok(TrustedHost::HostPort(host.to_string(), port)),
None => Ok(TrustedHost::Host(host.to_string())),
}
}
}

#[cfg(feature = "schemars")]
impl schemars::JsonSchema for TrustedHost {
fn schema_name() -> String {
"TrustedHost".to_string()
}

fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
schemars::schema::SchemaObject {
instance_type: Some(schemars::schema::InstanceType::String.into()),
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some("A host or host-port pair.".to_string()),
..schemars::schema::Metadata::default()
})),
..schemars::schema::SchemaObject::default()
}
.into()
}
}
18 changes: 10 additions & 8 deletions crates/uv-settings/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use distribution_types::{FlatIndexLocation, IndexUrl};
use install_wheel_rs::linker::LinkMode;
use pep508_rs::Requirement;
use pypi_types::VerbatimParsedUrl;
use url::Url;
use uv_configuration::{
ConfigSettings, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple,
TrustedHost,
};
use uv_macros::{CombineOptions, OptionsMetadata};
use uv_normalize::{ExtraName, PackageName};
Expand Down Expand Up @@ -216,7 +216,7 @@ pub struct InstallerOptions {
pub find_links: Option<Vec<FlatIndexLocation>>,
pub index_strategy: Option<IndexStrategy>,
pub keyring_provider: Option<KeyringProviderType>,
pub trusted_host: Option<Vec<Url>>,
pub trusted_host: Option<Vec<TrustedHost>>,
pub config_settings: Option<ConfigSettings>,
pub exclude_newer: Option<ExcludeNewer>,
pub link_mode: Option<LinkMode>,
Expand All @@ -243,7 +243,7 @@ pub struct ResolverOptions {
pub find_links: Option<Vec<FlatIndexLocation>>,
pub index_strategy: Option<IndexStrategy>,
pub keyring_provider: Option<KeyringProviderType>,
pub trusted_host: Option<Vec<Url>>,
pub trusted_host: Option<Vec<TrustedHost>>,
pub resolution: Option<ResolutionMode>,
pub prerelease: Option<PrereleaseMode>,
pub config_settings: Option<ConfigSettings>,
Expand Down Expand Up @@ -355,7 +355,8 @@ pub struct ResolverInstallerOptions {
"#
)]
pub keyring_provider: Option<KeyringProviderType>,
/// A list of trusted hostnames for SSL connections.
/// A list of trusted hosts for SSL connections. Expects to receive either a hostname (e.g.,
/// `localhost`) or a host-port pair (e.g., `localhost:8080`).
///
/// WARNING: Hosts included in this list will not be verified against the system's certificate
/// store.
Expand All @@ -366,7 +367,7 @@ pub struct ResolverInstallerOptions {
trusted-host = ["localhost:8080"]
"#
)]
pub trusted_host: Option<Vec<Url>>,
pub trusted_host: Option<Vec<TrustedHost>>,
/// The strategy to use when selecting between the different compatible versions for a given
/// package requirement.
///
Expand Down Expand Up @@ -738,7 +739,8 @@ pub struct PipOptions {
"#
)]
pub keyring_provider: Option<KeyringProviderType>,
/// A list of trusted hostnames for SSL connections.
/// A list of trusted hosts for SSL connections. Expects to receive either a hostname (e.g.,
/// `localhost`) or a host-port pair (e.g., `localhost:8080`).
///
/// WARNING: Hosts included in this list will not be verified against the system's certificate
/// store.
Expand All @@ -749,7 +751,7 @@ pub struct PipOptions {
trusted-host = ["localhost:8080"]
"#
)]
pub trusted_host: Option<Vec<Url>>,
pub trusted_host: Option<Vec<TrustedHost>>,
/// Don't build source distributions.
///
/// When enabled, resolving will not run arbitrary Python code. The cached wheels of
Expand Down Expand Up @@ -1298,7 +1300,7 @@ pub struct ToolOptions {
pub find_links: Option<Vec<FlatIndexLocation>>,
pub index_strategy: Option<IndexStrategy>,
pub keyring_provider: Option<KeyringProviderType>,
pub trusted_host: Option<Vec<Url>>,
pub trusted_host: Option<Vec<TrustedHost>>,
pub resolution: Option<ResolutionMode>,
pub prerelease: Option<PrereleaseMode>,
pub config_settings: Option<ConfigSettings>,
Expand Down
12 changes: 6 additions & 6 deletions crates/uv/src/commands/pip/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ use std::path::Path;

use anstream::{eprint, AutoStream};
use anyhow::{anyhow, Result};
use distribution_types::{IndexLocations, UnresolvedRequirementSpecification, Verbatim};
use install_wheel_rs::linker::LinkMode;
use itertools::Itertools;
use owo_colors::OwoColorize;
use pypi_types::Requirement;
use tracing::debug;
use url::Url;

use distribution_types::{IndexLocations, UnresolvedRequirementSpecification, Verbatim};
use install_wheel_rs::linker::LinkMode;
use pypi_types::Requirement;
use uv_auth::store_credentials_from_url;
use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, IndexStrategy, NoBinary,
NoBuild, Reinstall, SourceStrategy, Upgrade,
NoBuild, Reinstall, SourceStrategy, TrustedHost, Upgrade,
};
use uv_configuration::{KeyringProviderType, TargetTriple};
use uv_dispatch::BuildDispatch;
Expand Down Expand Up @@ -74,7 +74,7 @@ pub(crate) async fn pip_compile(
index_locations: IndexLocations,
index_strategy: IndexStrategy,
keyring_provider: KeyringProviderType,
trusted_host: Vec<Url>,
trusted_host: Vec<TrustedHost>,
config_settings: ConfigSettings,
connectivity: Connectivity,
no_build_isolation: bool,
Expand Down
Loading

0 comments on commit 0c76816

Please sign in to comment.