diff --git a/src/cargo/core/compiler/future_incompat.rs b/src/cargo/core/compiler/future_incompat.rs index 0df342b4b6c..d8c70ae61d2 100644 --- a/src/cargo/core/compiler/future_incompat.rs +++ b/src/cargo/core/compiler/future_incompat.rs @@ -319,7 +319,7 @@ fn get_updates(ws: &Workspace<'_>, package_ids: &BTreeSet) -> Option< let sources: HashMap<_, _> = source_ids .into_iter() .filter_map(|sid| { - let source = map.load(sid, &HashSet::new()).ok()?; + let source = map.load(sid).ok()?; Some((sid, source)) }) .collect(); diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index 055b3b63ff3..60fa0badfd2 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -533,10 +533,16 @@ impl<'gctx> PackageRegistry<'gctx> { debug!("loading source {}", source_id); let source = self .source_config - .load(source_id, &self.yanked_whitelist.borrow()) + .load(source_id) .with_context(|| format!("unable to update {}", source_id))?; assert_eq!(source.source_id(), source_id); + let yanked_whitelist = self.yanked_whitelist.borrow(); + if !yanked_whitelist.is_empty() { + let pkgs: Vec<_> = yanked_whitelist.iter().copied().collect(); + source.add_to_yanked_whitelist(&pkgs); + } + if kind == Kind::Override { self.overrides.borrow_mut().push(source_id); } diff --git a/src/cargo/core/source_id.rs b/src/cargo/core/source_id.rs index dade72b5a4b..0d27e3b5441 100644 --- a/src/cargo/core/source_id.rs +++ b/src/cargo/core/source_id.rs @@ -1,5 +1,4 @@ use crate::core::GitReference; -use crate::core::PackageId; use crate::core::SourceKind; use crate::sources::registry::CRATES_IO_HTTP_INDEX; use crate::sources::source::Source; @@ -389,12 +388,9 @@ impl SourceId { /// Creates an implementation of `Source` corresponding to this ID. /// - /// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked. - pub fn load<'a>( - self, - gctx: &'a GlobalContext, - yanked_whitelist: &HashSet, - ) -> CargoResult> { + /// To allow yanked packages through queries, + /// call [`Source::add_to_yanked_whitelist`] on the returned source. + pub fn load<'a>(self, gctx: &'a GlobalContext) -> CargoResult> { trace!("loading SourceId; {}", self); match self.inner.kind { SourceKind::Git(..) => Ok(Box::new(GitSource::new(self, gctx)?)), @@ -409,21 +405,16 @@ impl SourceId { } Ok(Box::new(PathSource::new(&path, self, gctx))) } - SourceKind::Registry | SourceKind::SparseRegistry => Ok(Box::new( - RegistrySource::remote(self, yanked_whitelist, gctx)?, - )), + SourceKind::Registry | SourceKind::SparseRegistry => { + Ok(Box::new(RegistrySource::remote(self, gctx)?)) + } SourceKind::LocalRegistry => { let path = self .inner .url .to_file_path() .expect("path sources cannot be remote"); - Ok(Box::new(RegistrySource::local( - self, - &path, - yanked_whitelist, - gctx, - ))) + Ok(Box::new(RegistrySource::local(self, &path, gctx))) } SourceKind::Directory => { let path = self diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 14c22a2201c..0cdba3aa558 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -1,4 +1,6 @@ -use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use std::collections::BTreeMap; +use std::collections::BTreeSet; +use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::{env, fmt, fs}; @@ -184,7 +186,7 @@ impl<'gctx> InstallablePackage<'gctx> { current_rust_version, )? } else if let Some(dep) = dep { - let mut source = map.load(source_id, &HashSet::new())?; + let mut source = map.load(source_id)?; if let Ok(Some(pkg)) = installed_exact_package( dep.clone(), &mut *source, diff --git a/src/cargo/ops/registry/mod.rs b/src/cargo/ops/registry/mod.rs index 62320da2527..cc63efb2df7 100644 --- a/src/cargo/ops/registry/mod.rs +++ b/src/cargo/ops/registry/mod.rs @@ -135,7 +135,7 @@ fn registry<'gctx>( auth::cache_token_from_commandline(gctx, &source_ids.original, token); } - let src = RegistrySource::remote(source_ids.replacement, &HashSet::new(), gctx)?; + let src = RegistrySource::remote(source_ids.replacement, gctx)?; let cfg = { let _lock = gctx.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?; // Only update the index if `force_update` is set. @@ -265,11 +265,9 @@ fn get_replacement_source_ids( sid: SourceId, ) -> CargoResult<(SourceId, SourceId)> { let builtin_replacement_sid = SourceConfigMap::empty(gctx)? - .load(sid, &HashSet::new())? - .replaced_source_id(); - let replacement_sid = SourceConfigMap::new(gctx)? - .load(sid, &HashSet::new())? + .load(sid)? .replaced_source_id(); + let replacement_sid = SourceConfigMap::new(gctx)?.load(sid)?.replaced_source_id(); Ok((builtin_replacement_sid, replacement_sid)) } @@ -279,7 +277,7 @@ fn is_replacement_for_package_source( package_source_id: SourceId, ) -> CargoResult { let pkg_source_replacement_sid = SourceConfigMap::new(gctx)? - .load(package_source_id, &HashSet::new())? + .load(package_source_id)? .replaced_source_id(); Ok(pkg_source_replacement_sid == sid) } diff --git a/src/cargo/ops/registry/publish.rs b/src/cargo/ops/registry/publish.rs index 48908d02e73..599b3be5453 100644 --- a/src/cargo/ops/registry/publish.rs +++ b/src/cargo/ops/registry/publish.rs @@ -5,7 +5,6 @@ use std::collections::BTreeMap; use std::collections::BTreeSet; use std::collections::HashMap; -use std::collections::HashSet; use std::fs::File; use std::io::Seek; use std::io::SeekFrom; @@ -390,7 +389,7 @@ fn wait_for_any_publish_confirmation( pkgs: &BTreeSet, timeout: Duration, ) -> CargoResult> { - let mut source = SourceConfigMap::empty(gctx)?.load(registry_src, &HashSet::new())?; + let mut source = SourceConfigMap::empty(gctx)?.load(registry_src)?; // Disable the source's built-in progress bars. Repeatedly showing a bunch // of independent progress bars can be a little confusing. There is an // overall progress bar managed here. diff --git a/src/cargo/ops/vendor.rs b/src/cargo/ops/vendor.rs index 87080ff0862..41f352661a5 100644 --- a/src/cargo/ops/vendor.rs +++ b/src/cargo/ops/vendor.rs @@ -110,7 +110,7 @@ impl SourceReplacementCache<'_> { match self.cache.entry(id) { Entry::Occupied(e) => Ok(e.get().clone()), Entry::Vacant(e) => { - let replaced = self.map.load(id, &HashSet::new())?.replaced_source_id(); + let replaced = self.map.load(id)?.replaced_source_id(); Ok(e.insert(replaced).clone()) } } @@ -246,11 +246,11 @@ fn sync( // we'll do a direct extraction into the vendor directory. let registry = match sid.kind() { SourceKind::Registry | SourceKind::SparseRegistry => { - RegistrySource::remote(sid, &Default::default(), gctx)? + RegistrySource::remote(sid, gctx)? } SourceKind::LocalRegistry => { let path = sid.url().to_file_path().expect("local path"); - RegistrySource::local(sid, &path, &Default::default(), gctx) + RegistrySource::local(sid, &path, gctx) } _ => unreachable!("not registry source: {sid}"), }; diff --git a/src/cargo/sources/config.rs b/src/cargo/sources/config.rs index 9dbfe56f2e4..3b77ab4d5d1 100644 --- a/src/cargo/sources/config.rs +++ b/src/cargo/sources/config.rs @@ -4,15 +4,18 @@ //! structure usable by Cargo itself. Currently, this is primarily used to map //! sources to one another via the `replace-with` key in `.cargo/config`. -use crate::core::{GitReference, PackageId, SourceId}; +use std::collections::HashMap; + +use crate::core::GitReference; +use crate::core::SourceId; use crate::sources::overlay::DependencyConfusionThreatOverlaySource; use crate::sources::source::Source; use crate::sources::{CRATES_IO_REGISTRY, ReplacedSource}; use crate::util::context::{self, ConfigRelativePath, OptValue}; use crate::util::errors::CargoResult; use crate::util::{GlobalContext, IntoUrl}; + use anyhow::{Context as _, bail}; -use std::collections::{HashMap, HashSet}; use tracing::debug; use url::Url; @@ -142,17 +145,11 @@ impl<'gctx> SourceConfigMap<'gctx> { } /// Gets the [`Source`] for a given [`SourceId`]. - /// - /// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked. - pub fn load( - &self, - id: SourceId, - yanked_whitelist: &HashSet, - ) -> CargoResult> { + pub fn load(&self, id: SourceId) -> CargoResult> { debug!("loading: {}", id); let Some(mut name) = self.id2name.get(&id) else { - return self.load_overlaid(id, yanked_whitelist); + return self.load_overlaid(id); }; let mut cfg_loc = ""; let orig_name = name; @@ -177,7 +174,7 @@ impl<'gctx> SourceConfigMap<'gctx> { name = s; cfg_loc = c; } - None if id == cfg.id => return self.load_overlaid(id, yanked_whitelist), + None if id == cfg.id => return self.load_overlaid(id), None => { break cfg.id.with_precise_from(id); } @@ -194,14 +191,8 @@ impl<'gctx> SourceConfigMap<'gctx> { } }; - let new_src = self.load_overlaid( - new_id, - &yanked_whitelist - .iter() - .map(|p| p.map_source(id, new_id)) - .collect(), - )?; - let old_src = id.load(self.gctx, yanked_whitelist)?; + let new_src = self.load_overlaid(new_id)?; + let old_src = id.load(self.gctx)?; if !new_src.supports_checksums() && old_src.supports_checksums() { bail!( "\ @@ -232,14 +223,10 @@ restore the source replacement configuration to continue the build } /// Gets the [`Source`] for a given [`SourceId`] without performing any source replacement. - fn load_overlaid( - &self, - id: SourceId, - yanked_whitelist: &HashSet, - ) -> CargoResult> { - let src = id.load(self.gctx, yanked_whitelist)?; + fn load_overlaid(&self, id: SourceId) -> CargoResult> { + let src = id.load(self.gctx)?; if let Some(overlay_id) = self.overlays.get(&id) { - let overlay = overlay_id.load(self.gctx(), yanked_whitelist)?; + let overlay = overlay_id.load(self.gctx())?; Ok(Box::new(DependencyConfusionThreatOverlaySource::new( overlay, src, ))) diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index 441278fc058..bd38dc1c195 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -480,11 +480,8 @@ impl<'gctx> RegistrySource<'gctx> { /// Creates a [`Source`] of a "remote" registry. /// It could be either an HTTP-based [`http_remote::HttpRegistry`] or /// a Git-based [`remote::RemoteRegistry`]. - /// - /// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked. pub fn remote( source_id: SourceId, - yanked_whitelist: &HashSet, gctx: &'gctx GlobalContext, ) -> CargoResult> { assert!(source_id.is_remote_registry()); @@ -501,28 +498,20 @@ impl<'gctx> RegistrySource<'gctx> { Box::new(remote::RemoteRegistry::new(source_id, gctx, &name)) as Box<_> }; - Ok(RegistrySource::new( - source_id, - gctx, - &name, - ops, - yanked_whitelist, - )) + Ok(RegistrySource::new(source_id, gctx, &name, ops)) } /// Creates a [`Source`] of a local registry, with [`local::LocalRegistry`] under the hood. /// /// * `path` --- The root path of a local registry on the file system. - /// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked. pub fn local( source_id: SourceId, path: &Path, - yanked_whitelist: &HashSet, gctx: &'gctx GlobalContext, ) -> RegistrySource<'gctx> { let name = short_name(source_id, false); let ops = local::LocalRegistry::new(path, gctx, &name); - RegistrySource::new(source_id, gctx, &name, Box::new(ops), yanked_whitelist) + RegistrySource::new(source_id, gctx, &name, Box::new(ops)) } /// Creates a source of a registry. This is a inner helper function. @@ -530,13 +519,11 @@ impl<'gctx> RegistrySource<'gctx> { /// * `name` --- Name of a path segment which may affect where `.crate` /// tarballs, the registry index and cache are stored. Expect to be unique. /// * `ops` --- The underlying [`RegistryData`] type. - /// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked. fn new( source_id: SourceId, gctx: &'gctx GlobalContext, name: &str, ops: Box, - yanked_whitelist: &HashSet, ) -> RegistrySource<'gctx> { // Before starting to work on the registry, make sure that // `/registry` is marked as excluded from indexing and @@ -559,7 +546,7 @@ impl<'gctx> RegistrySource<'gctx> { gctx, source_id, index: index::RegistryIndex::new(source_id, ops.index_path(), gctx), - yanked_whitelist: RefCell::new(yanked_whitelist.clone()), + yanked_whitelist: RefCell::new(HashSet::new()), ops, selected_precise_yanked: RefCell::new(HashSet::new()), }