diff --git a/rye/src/cli/install.rs b/rye/src/cli/install.rs index 64aeb49d8a..b1e59bb73e 100644 --- a/rye/src/cli/install.rs +++ b/rye/src/cli/install.rs @@ -7,6 +7,7 @@ use pep508_rs::Requirement; use crate::cli::add::ReqExtras; use crate::config::Config; use crate::installer::{install, resolve_local_requirement}; +use crate::lock::KeyringProvider; use crate::sources::py::PythonVersionRequest; use crate::utils::CommandOutput; @@ -29,6 +30,9 @@ pub struct Args { /// Force install the package even if it's already there. #[arg(short, long)] force: bool, + /// Attempt to use `keyring` for authentication for index URLs. + #[arg(long, value_enum, default_value_t)] + keyring_provider: KeyringProvider, /// Enables verbose diagnostics. #[arg(short, long)] verbose: bool, @@ -74,6 +78,7 @@ pub fn execute(mut cmd: Args) -> Result<(), Error> { &cmd.include_dep, &extra_requirements, output, + cmd.keyring_provider, )?; Ok(()) } diff --git a/rye/src/installer.rs b/rye/src/installer.rs index d93adda388..55fd8f4e51 100644 --- a/rye/src/installer.rs +++ b/rye/src/installer.rs @@ -14,6 +14,7 @@ use url::Url; use crate::bootstrap::{ensure_self_venv, fetch, FetchOptions}; use crate::config::Config; use crate::consts::VENV_BIN; +use crate::lock::KeyringProvider; use crate::platform::get_app_dir; use crate::pyproject::{normalize_package_name, read_venv_marker, ExpandedSources}; use crate::sources::py::PythonVersionRequest; @@ -109,6 +110,7 @@ pub fn install( include_deps: &[String], extra_requirements: &[Requirement], output: CommandOutput, + keyring_provider: KeyringProvider, ) -> Result<(), Error> { let config = Config::current(); let sources = ExpandedSources::from_sources(&config.sources()?)?; @@ -154,6 +156,7 @@ pub fn install( importlib_workaround: py_ver.major == 3 && py_ver.minor == 7, extras: extra_requirements.to_vec(), refresh: force, + keyring_provider, }, ); if result.is_err() { diff --git a/rye/src/lock.rs b/rye/src/lock.rs index d910401274..53eebb23b2 100644 --- a/rye/src/lock.rs +++ b/rye/src/lock.rs @@ -73,6 +73,17 @@ pub enum KeyringProvider { Subprocess, } +impl KeyringProvider { + pub fn add_as_pip_args(self, cmd: &mut Command) { + match self { + KeyringProvider::Disabled => {} + KeyringProvider::Subprocess => { + cmd.arg("--keyring-provider").arg("subprocess"); + } + } + } +} + /// Controls how locking should work. #[derive(Debug, Clone, Default, Serialize)] pub struct LockOptions { diff --git a/rye/src/sync.rs b/rye/src/sync.rs index 589680e775..9fb1d34413 100644 --- a/rye/src/sync.rs +++ b/rye/src/sync.rs @@ -23,7 +23,7 @@ use crate::utils::{ get_venv_python_bin, set_proxy_variables, symlink_dir, update_venv_sync_marker, CommandOutput, IoPathContext, }; -use crate::uv::UvBuilder; +use crate::uv::{UvBuilder, UvSyncOptions}; /// Controls the sync mode #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] @@ -257,6 +257,9 @@ pub fn sync(mut cmd: SyncOptions) -> Result<(), Error> { let tempdir = tempdir()?; let py_path = get_venv_python_bin(&venv); if Config::current().use_uv() { + let uv_options = UvSyncOptions { + keyring_provider: cmd.keyring_provider, + }; UvBuilder::new() .with_output(output.quieter()) .with_workdir(&pyproject.workspace_path()) @@ -264,7 +267,7 @@ pub fn sync(mut cmd: SyncOptions) -> Result<(), Error> { .ensure_exists()? .venv(&venv, &py_path, &py_ver, None)? .with_output(output) - .sync(&target_lockfile)?; + .sync(&target_lockfile, uv_options)?; } else { let mut pip_sync_cmd = Command::new(get_pip_sync(&py_ver, output)?); let root = pyproject.workspace_path(); diff --git a/rye/src/uv.rs b/rye/src/uv.rs index 9dbf87db42..f633cc061c 100644 --- a/rye/src/uv.rs +++ b/rye/src/uv.rs @@ -21,6 +21,7 @@ pub struct UvInstallOptions { pub importlib_workaround: bool, pub extras: Vec, pub refresh: bool, + pub keyring_provider: KeyringProvider, } pub enum UvPackageUpgrade { @@ -76,12 +77,7 @@ impl UvCompileOptions { UvPackageUpgrade::Nothing => {} } - match self.keyring_provider { - KeyringProvider::Disabled => {} - KeyringProvider::Subprocess => { - cmd.arg("--keyring-provider").arg("subprocess"); - } - } + self.keyring_provider.add_as_pip_args(cmd); } } @@ -99,6 +95,23 @@ impl Default for UvCompileOptions { } } +pub struct UvSyncOptions { + pub keyring_provider: KeyringProvider, +} + +impl UvSyncOptions { + pub fn add_as_pip_args(self, cmd: &mut Command) { + self.keyring_provider.add_as_pip_args(cmd); + } +} + +impl Default for UvSyncOptions { + fn default() -> Self { + Self { + keyring_provider: KeyringProvider::Disabled, + } + } +} pub struct UvBuilder { workdir: Option, sources: Option, @@ -502,6 +515,8 @@ impl UvWithVenv { cmd.arg("--refresh"); } + options.keyring_provider.add_as_pip_args(&mut cmd); + self.uv.sources.add_as_pip_args(&mut cmd); cmd.arg("--").arg(requirement.to_string()); @@ -537,10 +552,12 @@ impl UvWithVenv { } /// Syncs the venv - pub fn sync(&self, lockfile: &Path) -> Result<(), Error> { + pub fn sync(&self, lockfile: &Path, options: UvSyncOptions) -> Result<(), Error> { let mut cmd = self.venv_cmd(); cmd.arg("pip").arg("sync"); + options.add_as_pip_args(&mut cmd); + self.uv.sources.add_as_pip_args(&mut cmd); let status = cmd