Skip to content

Commit f099fe9

Browse files
committed
Auto merge of #6655 - Eh2406:conservative-updates, r=ehuss
[BackPort] Conservative updates This is a back port of #6611 as discussed in #6609
2 parents 735f49f + 63412be commit f099fe9

File tree

17 files changed

+274
-60
lines changed

17 files changed

+274
-60
lines changed

src/cargo/core/package_id.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ impl PackageId {
155155
PackageId::pure(self.inner.name, self.inner.version.clone(), source)
156156
}
157157

158+
pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Self {
159+
if self.source_id() == to_replace {
160+
self.with_source_id(replace_with)
161+
} else {
162+
self
163+
}
164+
}
165+
158166
pub fn stable_hash(self, workspace: &Path) -> PackageIdStableHash<'_> {
159167
PackageIdStableHash(self, workspace)
160168
}

src/cargo/core/registry.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::collections::{HashMap, HashSet};
22

33
use log::{debug, trace};
44
use semver::VersionReq;
@@ -71,6 +71,7 @@ pub struct PackageRegistry<'cfg> {
7171
source_ids: HashMap<SourceId, (SourceId, Kind)>,
7272

7373
locked: LockedMap,
74+
yanked_whitelist: HashSet<PackageId>,
7475
source_config: SourceConfigMap<'cfg>,
7576

7677
patches: HashMap<Url, Vec<Summary>>,
@@ -97,6 +98,7 @@ impl<'cfg> PackageRegistry<'cfg> {
9798
overrides: Vec::new(),
9899
source_config,
99100
locked: HashMap::new(),
101+
yanked_whitelist: HashSet::new(),
100102
patches: HashMap::new(),
101103
patches_locked: false,
102104
patches_available: HashMap::new(),
@@ -166,6 +168,14 @@ impl<'cfg> PackageRegistry<'cfg> {
166168
self.add_source(source, Kind::Override);
167169
}
168170

171+
pub fn add_to_yanked_whitelist(&mut self, iter: impl Iterator<Item = PackageId>) {
172+
let pkgs = iter.collect::<Vec<_>>();
173+
for (_, source) in self.sources.sources_mut() {
174+
source.add_to_yanked_whitelist(&pkgs);
175+
}
176+
self.yanked_whitelist.extend(pkgs);
177+
}
178+
169179
pub fn register_lock(&mut self, id: PackageId, deps: Vec<PackageId>) {
170180
trace!("register_lock: {}", id);
171181
for dep in deps.iter() {
@@ -301,7 +311,7 @@ impl<'cfg> PackageRegistry<'cfg> {
301311
fn load(&mut self, source_id: SourceId, kind: Kind) -> CargoResult<()> {
302312
(|| {
303313
debug!("loading source {}", source_id);
304-
let source = self.source_config.load(source_id)?;
314+
let source = self.source_config.load(source_id, &self.yanked_whitelist)?;
305315
assert_eq!(source.source_id(), source_id);
306316

307317
if kind == Kind::Override {

src/cargo/core/source/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ pub trait Source {
8383
fn is_replaced(&self) -> bool {
8484
false
8585
}
86+
87+
/// Add a number of crates that should be whitelisted for showing up during
88+
/// queries, even if they are yanked. Currently only applies to registry
89+
/// sources.
90+
fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]);
8691
}
8792

8893
pub enum MaybePackage {
@@ -152,6 +157,10 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
152157
fn is_replaced(&self) -> bool {
153158
(**self).is_replaced()
154159
}
160+
161+
fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) {
162+
(**self).add_to_yanked_whitelist(pkgs);
163+
}
155164
}
156165

157166
impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T {
@@ -206,6 +215,10 @@ impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T {
206215
fn is_replaced(&self) -> bool {
207216
(**self).is_replaced()
208217
}
218+
219+
fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) {
220+
(**self).add_to_yanked_whitelist(pkgs);
221+
}
209222
}
210223

211224
/// A `HashMap` of `SourceId` -> `Box<Source>`

src/cargo/core/source/source_id.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ use std::fmt::{self, Formatter};
44
use std::hash::{self, Hash};
55
use std::path::Path;
66
use std::ptr;
7-
use std::sync::atomic::Ordering::SeqCst;
87
use std::sync::atomic::AtomicBool;
8+
use std::sync::atomic::Ordering::SeqCst;
99
use std::sync::Mutex;
1010

1111
use log::trace;
1212
use serde::de;
1313
use serde::ser;
1414
use url::Url;
1515

16+
use crate::core::PackageId;
1617
use crate::ops;
1718
use crate::sources::git;
1819
use crate::sources::DirectorySource;
@@ -257,7 +258,11 @@ impl SourceId {
257258
}
258259

259260
/// Creates an implementation of `Source` corresponding to this ID.
260-
pub fn load<'a>(self, config: &'a Config) -> CargoResult<Box<dyn super::Source + 'a>> {
261+
pub fn load<'a>(
262+
self,
263+
config: &'a Config,
264+
yanked_whitelist: &HashSet<PackageId>,
265+
) -> CargoResult<Box<dyn super::Source + 'a>> {
261266
trace!("loading SourceId; {}", self);
262267
match self.inner.kind {
263268
Kind::Git(..) => Ok(Box::new(GitSource::new(self, config)?)),
@@ -268,7 +273,11 @@ impl SourceId {
268273
};
269274
Ok(Box::new(PathSource::new(&path, self, config)))
270275
}
271-
Kind::Registry => Ok(Box::new(RegistrySource::remote(self, config))),
276+
Kind::Registry => Ok(Box::new(RegistrySource::remote(
277+
self,
278+
yanked_whitelist,
279+
config,
280+
))),
272281
Kind::LocalRegistry => {
273282
let path = match self.inner.url.to_file_path() {
274283
Ok(p) => p,

src/cargo/ops/cargo_install.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::collections::btree_map::Entry;
2-
use std::collections::{BTreeMap, BTreeSet};
2+
use std::collections::{BTreeMap, BTreeSet, HashSet};
33
use std::io::prelude::*;
44
use std::io::SeekFrom;
55
use std::path::{Path, PathBuf};
@@ -187,7 +187,7 @@ fn install_one(
187187
})?
188188
} else {
189189
select_pkg(
190-
map.load(source_id)?,
190+
map.load(source_id, &HashSet::new())?,
191191
krate,
192192
vers,
193193
config,

src/cargo/ops/registry.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::BTreeMap;
1+
use std::collections::{BTreeMap, HashSet};
22
use std::fs::{self, File};
33
use std::io::{self, BufRead};
44
use std::iter::repeat;
@@ -350,7 +350,7 @@ pub fn registry(
350350
let token = token.or(token_config);
351351
let sid = get_source_id(config, index_config.or(index), registry)?;
352352
let api_host = {
353-
let mut src = RegistrySource::remote(sid, config);
353+
let mut src = RegistrySource::remote(sid, &HashSet::new(), config);
354354
// Only update the index if the config is not available or `force` is set.
355355
let cfg = src.config();
356356
let cfg = if force_update || cfg.is_err() {
@@ -696,7 +696,7 @@ fn get_source_id(
696696
(_, Some(i)) => SourceId::for_registry(&i.to_url()?),
697697
_ => {
698698
let map = SourceConfigMap::new(config)?;
699-
let src = map.load(SourceId::crates_io(config)?)?;
699+
let src = map.load(SourceId::crates_io(config)?, &HashSet::new())?;
700700
Ok(src.replaced_source_id())
701701
}
702702
}

src/cargo/ops/resolve.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ fn register_previous_locks(
471471
// package's dependencies here as that'll be covered below to poison those
472472
// if they changed.
473473
let mut avoid_locking = HashSet::new();
474+
registry.add_to_yanked_whitelist(resolve.iter().filter(keep));
474475
for node in resolve.iter() {
475476
if !keep(&node) {
476477
add_deps(resolve, node, &mut avoid_locking);

src/cargo/sources/config.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
//! structure usable by Cargo itself. Currently this is primarily used to map
55
//! sources to one another via the `replace-with` key in `.cargo/config`.
66
7-
use std::collections::HashMap;
7+
use std::collections::{HashMap, HashSet};
88
use std::path::{Path, PathBuf};
99

1010
use log::debug;
1111
use url::Url;
1212

13-
use crate::core::{GitReference, Source, SourceId};
13+
use crate::core::{GitReference, PackageId, Source, SourceId};
1414
use crate::sources::{ReplacedSource, CRATES_IO_REGISTRY};
1515
use crate::util::config::ConfigValue;
1616
use crate::util::errors::{CargoResult, CargoResultExt};
@@ -73,11 +73,15 @@ impl<'cfg> SourceConfigMap<'cfg> {
7373
self.config
7474
}
7575

76-
pub fn load(&self, id: SourceId) -> CargoResult<Box<dyn Source + 'cfg>> {
76+
pub fn load(
77+
&self,
78+
id: SourceId,
79+
yanked_whitelist: &HashSet<PackageId>,
80+
) -> CargoResult<Box<dyn Source + 'cfg>> {
7781
debug!("loading: {}", id);
7882
let mut name = match self.id2name.get(&id) {
7983
Some(name) => name,
80-
None => return Ok(id.load(self.config)?),
84+
None => return Ok(id.load(self.config, yanked_whitelist)?),
8185
};
8286
let mut path = Path::new("/");
8387
let orig_name = name;
@@ -99,7 +103,7 @@ impl<'cfg> SourceConfigMap<'cfg> {
99103
name = s;
100104
path = p;
101105
}
102-
None if id == cfg.id => return Ok(id.load(self.config)?),
106+
None if id == cfg.id => return Ok(id.load(self.config, yanked_whitelist)?),
103107
None => {
104108
new_id = cfg.id.with_precise(id.precise().map(|s| s.to_string()));
105109
break;
@@ -116,8 +120,15 @@ impl<'cfg> SourceConfigMap<'cfg> {
116120
)
117121
}
118122
}
119-
let new_src = new_id.load(self.config)?;
120-
let old_src = id.load(self.config)?;
123+
124+
let new_src = new_id.load(
125+
self.config,
126+
&yanked_whitelist
127+
.iter()
128+
.map(|p| p.map_source(id, new_id))
129+
.collect(),
130+
)?;
131+
let old_src = id.load(self.config, yanked_whitelist)?;
121132
if !new_src.supports_checksums() && old_src.supports_checksums() {
122133
failure::bail!(
123134
"\

src/cargo/sources/directory.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,6 @@ impl<'cfg> Source for DirectorySource<'cfg> {
214214
fn describe(&self) -> String {
215215
format!("directory source `{}`", self.root.display())
216216
}
217+
218+
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
217219
}

src/cargo/sources/git/source.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ impl<'cfg> Source for GitSource<'cfg> {
238238
fn describe(&self) -> String {
239239
format!("git repository {}", self.source_id)
240240
}
241+
242+
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
241243
}
242244

243245
#[cfg(test)]

src/cargo/sources/path.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,4 +569,6 @@ impl<'cfg> Source for PathSource<'cfg> {
569569
Err(_) => self.source_id.to_string(),
570570
}
571571
}
572+
573+
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
572574
}

src/cargo/sources/registry/index.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::collections::{HashMap, HashSet};
22
use std::path::Path;
33
use std::str;
44

@@ -273,14 +273,21 @@ impl<'cfg> RegistryIndex<'cfg> {
273273
&mut self,
274274
dep: &Dependency,
275275
load: &mut dyn RegistryData,
276+
yanked_whitelist: &HashSet<PackageId>,
276277
f: &mut dyn FnMut(Summary),
277278
) -> CargoResult<()> {
278279
let source_id = self.source_id;
279280
let name = dep.package_name().as_str();
280281
let summaries = self.summaries(name, load)?;
281282
let summaries = summaries
282283
.iter()
283-
.filter(|&&(_, yanked)| dep.source_id().precise().is_some() || !yanked)
284+
.filter(|&(summary, yanked)| {
285+
!yanked || {
286+
log::debug!("{:?}", yanked_whitelist);
287+
log::debug!("{:?}", summary.package_id());
288+
yanked_whitelist.contains(&summary.package_id())
289+
}
290+
})
284291
.map(|s| s.0.clone());
285292

286293
// Handle `cargo update --precise` here. If specified, our own source

0 commit comments

Comments
 (0)