mirror of https://github.com/astral-sh/uv
Misc. tweaks
This commit is contained in:
parent
32bcfdff0a
commit
7d9446450b
|
|
@ -80,10 +80,12 @@ impl Password {
|
|||
Self(password)
|
||||
}
|
||||
|
||||
/// Return the [`Password`] as a string slice.
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
|
||||
/// Convert the [`Password`] into its underlying [`String`].
|
||||
pub fn into_string(self) -> String {
|
||||
self.0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,11 +159,11 @@ impl KeyringProvider {
|
|||
// Validate the request
|
||||
debug_assert!(
|
||||
url.host_str().is_some(),
|
||||
"Should only use keyring for urls with host"
|
||||
"Should only use keyring for URLs with host"
|
||||
);
|
||||
debug_assert!(
|
||||
url.password().is_none(),
|
||||
"Should only use keyring for urls without a password"
|
||||
"Should only use keyring for URLs without a password"
|
||||
);
|
||||
debug_assert!(
|
||||
!username.map(str::is_empty).unwrap_or(false),
|
||||
|
|
@ -286,7 +286,7 @@ impl KeyringProvider {
|
|||
// N.B. We do not show the `service_name` here because we'll show the warning twice
|
||||
// otherwise, once for the URL and once for the realm.
|
||||
warn_user_once!(
|
||||
"Attempted to fetch credentials using the `keyring` command, but it does not support `--mode creds`; upgrade to `keyring>=v25.2.1` for support or provide a username"
|
||||
"Attempted to fetch credentials using the `keyring` command, but it does not support `--mode creds`; upgrade to `keyring>=v25.2.1` or provide a username"
|
||||
);
|
||||
} else if username.is_none() {
|
||||
// If we captured stderr, display it in case it's helpful to the user
|
||||
|
|
@ -314,8 +314,7 @@ impl KeyringProvider {
|
|||
}
|
||||
Err(err) => {
|
||||
warn_user_once!(
|
||||
"Unable to fetch credentials for {service} from system keyring: {}",
|
||||
err
|
||||
"Unable to fetch credentials for {service} from system keyring: {err}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ impl Default for TextStoreMode {
|
|||
}
|
||||
|
||||
impl TextStoreMode {
|
||||
/// Get the parsed credential store if enabled.
|
||||
/// Get the parsed credential store, if enabled.
|
||||
fn get(&self) -> Option<&TextCredentialStore> {
|
||||
match self {
|
||||
Self::Automatic(lock) => lock.as_ref(),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
use uv_redacted::DisplaySafeUrl;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ServiceParseError {
|
||||
#[error("failed to parse URL: {0}")]
|
||||
#[error(transparent)]
|
||||
InvalidUrl(#[from] url::ParseError),
|
||||
#[error("only HTTPS is supported")]
|
||||
UnsupportedScheme,
|
||||
|
|
@ -31,7 +32,7 @@ impl Service {
|
|||
}
|
||||
|
||||
/// Validate that the URL scheme is supported.
|
||||
fn check_scheme(url: &DisplaySafeUrl) -> Result<(), ServiceParseError> {
|
||||
fn check_scheme(url: &Url) -> Result<(), ServiceParseError> {
|
||||
match url.scheme() {
|
||||
"https" => Ok(()),
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -18,12 +18,13 @@ use crate::realm::Realm;
|
|||
use crate::service::Service;
|
||||
|
||||
/// Authentication scheme to use.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum AuthScheme {
|
||||
/// HTTP Basic Authentication
|
||||
///
|
||||
/// Uses a username and password.
|
||||
#[default]
|
||||
Basic,
|
||||
/// Bearer token authentication.
|
||||
///
|
||||
|
|
@ -31,12 +32,6 @@ pub enum AuthScheme {
|
|||
Bearer,
|
||||
}
|
||||
|
||||
impl Default for AuthScheme {
|
||||
fn default() -> Self {
|
||||
Self::Basic
|
||||
}
|
||||
}
|
||||
|
||||
/// Errors that can occur when working with TOML credential storage.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum TomlCredentialError {
|
||||
|
|
@ -75,11 +70,11 @@ pub enum BearerAuthError {
|
|||
}
|
||||
|
||||
/// A single credential entry in a TOML credentials file.
|
||||
// TODO(zanieb): It's a little clunky that we need don't nest the scheme-specific fields under a
|
||||
// TODO(zanieb): It's a little clunky that we need don't nest the scheme-specific fields under
|
||||
// that scheme, but I want the username / password case to be easily accessible without
|
||||
// understanding authentication schemes. We should consider a better structure here, e.g., by
|
||||
// adding an internal type that we cast to after validation.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TomlCredential {
|
||||
/// The service URL for this credential.
|
||||
pub service: Service,
|
||||
|
|
@ -172,10 +167,10 @@ impl TomlCredential {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct TomlCredentials {
|
||||
struct TomlCredentials {
|
||||
/// Array of credential entries.
|
||||
#[serde(rename = "credential")]
|
||||
pub credentials: Vec<TomlCredential>,
|
||||
credentials: Vec<TomlCredential>,
|
||||
}
|
||||
|
||||
/// A credential store with a plain text storage backend.
|
||||
|
|
@ -215,8 +210,8 @@ impl TextCredentialStore {
|
|||
// TODO(zanieb): Determine a better strategy for invalid credential entries
|
||||
if let Err(err) = credential.validate() {
|
||||
debug!(
|
||||
"Skipping invalid credential for {}: {}",
|
||||
credential.service, err
|
||||
"Skipping invalid credential for {}: {err}",
|
||||
credential.service
|
||||
);
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5548,7 +5548,7 @@ pub struct AuthLogoutArgs {
|
|||
|
||||
#[derive(Args)]
|
||||
pub struct AuthLoginArgs {
|
||||
/// The service to login to.
|
||||
/// The service to log into.
|
||||
pub service: Service,
|
||||
|
||||
/// The username to use for the service.
|
||||
|
|
|
|||
|
|
@ -24,15 +24,14 @@ pub(crate) async fn login(
|
|||
printer: Printer,
|
||||
preview: Preview,
|
||||
) -> Result<ExitStatus> {
|
||||
let service_clone = service.clone();
|
||||
let url = service_clone.url();
|
||||
let backend = AuthBackend::from_settings(keyring_provider.as_ref(), preview)?;
|
||||
|
||||
// If the URL includes a known index URL suffix, strip it
|
||||
// TODO(zanieb): Use a shared abstraction across `login` and `logout`?
|
||||
let url = service.url().clone();
|
||||
let (service, url) = match IndexUrl::from(VerbatimUrl::from_url(url.clone())).root() {
|
||||
Some(root) => (Service::try_from(root.clone())?, root),
|
||||
None => (service, url.clone()),
|
||||
None => (service, url),
|
||||
};
|
||||
|
||||
// Extract credentials from URL if present
|
||||
|
|
@ -125,7 +124,7 @@ pub(crate) async fn login(
|
|||
writeln!(
|
||||
printer.stderr(),
|
||||
"Stored credentials for {}",
|
||||
display_url.cyan()
|
||||
display_url.bold().cyan()
|
||||
)?;
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,14 +23,13 @@ pub(crate) async fn logout(
|
|||
printer: Printer,
|
||||
preview: Preview,
|
||||
) -> Result<ExitStatus> {
|
||||
let service_clone = service.clone();
|
||||
let url = service_clone.url();
|
||||
let backend = AuthBackend::from_settings(keyring_provider.as_ref(), preview)?;
|
||||
|
||||
// TODO(zanieb): Use a shared abstraction across `login` and `logout`?
|
||||
let url = service.url().clone();
|
||||
let (service, url) = match IndexUrl::from(VerbatimUrl::from_url(url.clone())).root() {
|
||||
Some(root) => (Service::try_from(root.clone())?, root),
|
||||
None => (service, url.clone()),
|
||||
None => (service, url),
|
||||
};
|
||||
|
||||
// Extract credentials from URL if present
|
||||
|
|
@ -75,7 +74,7 @@ pub(crate) async fn logout(
|
|||
writeln!(
|
||||
printer.stderr(),
|
||||
"Removed credentials for {}",
|
||||
display_url.cyan()
|
||||
display_url.bold().cyan()
|
||||
)?;
|
||||
|
||||
Ok(ExitStatus::Success)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ pub(crate) async fn token(
|
|||
printer: Printer,
|
||||
preview: Preview,
|
||||
) -> Result<ExitStatus> {
|
||||
let url = service.url();
|
||||
let backend = AuthBackend::from_settings(keyring_provider.as_ref(), preview)?;
|
||||
let url = service.url();
|
||||
|
||||
// Extract credentials from URL if present
|
||||
let url_credentials = Credentials::from_url(url);
|
||||
|
|
|
|||
|
|
@ -815,7 +815,7 @@ fn login_native_keyring_url() {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: invalid value 'not a valid url' for '<SERVICE>': failed to parse URL: invalid international domain name
|
||||
error: invalid value 'not a valid url' for '<SERVICE>': invalid international domain name
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
|
|
|||
|
|
@ -21067,7 +21067,7 @@ fn lock_keyring_credentials_always_authenticate_unsupported_mode() -> Result<()>
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
warning: Attempted to fetch credentials using the `keyring` command, but it does not support `--mode creds`; upgrade to `keyring>=v25.2.1` for support or provide a username
|
||||
warning: Attempted to fetch credentials using the `keyring` command, but it does not support `--mode creds`; upgrade to `keyring>=v25.2.1` or provide a username
|
||||
error: Failed to fetch: `https://pypi-proxy.fly.dev/basic-auth/simple/iniconfig/`
|
||||
Caused by: Missing credentials for https://pypi-proxy.fly.dev/basic-auth/simple/iniconfig/
|
||||
");
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ uv auth login [OPTIONS] <SERVICE>
|
|||
|
||||
<h3 class="cli-reference">Arguments</h3>
|
||||
|
||||
<dl class="cli-reference"><dt id="uv-auth-login--service"><a href="#uv-auth-login--service"<code>SERVICE</code></a></dt><dd><p>The service to login to</p>
|
||||
<dl class="cli-reference"><dt id="uv-auth-login--service"><a href="#uv-auth-login--service"<code>SERVICE</code></a></dt><dd><p>The service to log into</p>
|
||||
</dd></dl>
|
||||
|
||||
<h3 class="cli-reference">Options</h3>
|
||||
|
|
|
|||
Loading…
Reference in New Issue