/// Query if a package is yanked. Only registry sources can mark packages
/// as yanked. This ignores the yanked whitelist.
- fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool>;
+ fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>>;
/// Block until all outstanding Poll::Pending requests are `Poll::Ready`.
///
(**self).add_to_yanked_whitelist(pkgs);
}
- fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
+ fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
(**self).is_yanked(pkg)
}
(**self).add_to_yanked_whitelist(pkgs);
}
- fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
+ fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
(**self).is_yanked(pkg)
}
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::sync::Arc;
+use std::task::Poll;
use std::{env, fs};
use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, Freshness, UnitOutput};
// duplicate "Updating", but since `source` is taken by value, then it
// wouldn't be available for `compile_ws`.
let (pkg_set, resolve) = ops::resolve_ws(&self.ws)?;
- let mut sources = pkg_set.sources_mut();
// Checking the yanked status involves taking a look at the registry and
// maybe updating files, so be sure to lock it here.
let _lock = self.ws.config().acquire_package_cache_lock()?;
- for pkg_id in resolve.iter() {
- if let Some(source) = sources.get_mut(pkg_id.source_id()) {
- if source.is_yanked(pkg_id)? {
- self.ws.config().shell().warn(format!(
- "package `{}` in Cargo.lock is yanked in registry `{}`, \
- consider running without --locked",
- pkg_id,
- pkg_id.source_id().display_registry_name()
- ))?;
+ let mut sources = pkg_set.sources_mut();
+ let mut pending: Vec<PackageId> = resolve.iter().collect();
+ let mut results = Vec::new();
+ for (_id, source) in sources.sources_mut() {
+ source.invalidate_cache();
+ }
+ while !pending.is_empty() {
+ pending.retain(|pkg_id| {
+ if let Some(source) = sources.get_mut(pkg_id.source_id()) {
+ match source.is_yanked(*pkg_id) {
+ Poll::Ready(result) => results.push((*pkg_id, result)),
+ Poll::Pending => return true,
+ }
}
+ false
+ });
+ for (_id, source) in sources.sources_mut() {
+ source.block_until_ready()?;
+ }
+ }
+
+ for (pkg_id, is_yanked) in results {
+ if is_yanked? {
+ self.ws.config().shell().warn(format!(
+ "package `{}` in Cargo.lock is yanked in registry `{}`, \
+ consider running without --locked",
+ pkg_id,
+ pkg_id.source_id().display_registry_name()
+ ))?;
}
}
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
+use std::task::Poll;
use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor};
use crate::core::resolver::CliFeatures;
let _lock = config.acquire_package_cache_lock()?;
let mut sources = pkg_set.sources_mut();
- for pkg_id in resolve.iter() {
- if let Some(source) = sources.get_mut(pkg_id.source_id()) {
- if source.is_yanked(pkg_id)? {
- config.shell().warn(format!(
- "package `{}` in Cargo.lock is yanked in registry `{}`, \
- consider updating to a version that is not yanked",
- pkg_id,
- pkg_id.source_id().display_registry_name()
- ))?;
+ let mut pending: Vec<PackageId> = resolve.iter().collect();
+ let mut results = Vec::new();
+ for (_id, source) in sources.sources_mut() {
+ source.invalidate_cache();
+ }
+ while !pending.is_empty() {
+ pending.retain(|pkg_id| {
+ if let Some(source) = sources.get_mut(pkg_id.source_id()) {
+ match source.is_yanked(*pkg_id) {
+ Poll::Ready(result) => results.push((*pkg_id, result)),
+ Poll::Pending => return true,
+ }
}
+ false
+ });
+ for (_id, source) in sources.sources_mut() {
+ source.block_until_ready()?;
+ }
+ }
+
+ for (pkg_id, is_yanked) in results {
+ if is_yanked? {
+ config.shell().warn(format!(
+ "package `{}` in Cargo.lock is yanked in registry `{}`, \
+ consider updating to a version that is not yanked",
+ pkg_id,
+ pkg_id.source_id().display_registry_name()
+ ))?;
}
}
Ok(())
None => {
let is_yanked: bool = if dep.version_req().is_exact() {
let version: String = dep.version_req().to_string();
- PackageId::new(dep.package_name(), &version[1..], source.source_id())
- .map_or(false, |pkg_id| source.is_yanked(pkg_id).unwrap_or(false))
+ if let Ok(pkg_id) =
+ PackageId::new(dep.package_name(), &version[1..], source.source_id())
+ {
+ source.invalidate_cache();
+ loop {
+ match source.is_yanked(pkg_id) {
+ Poll::Ready(Ok(is_yanked)) => break is_yanked,
+ Poll::Ready(Err(_)) => break false,
+ Poll::Pending => source.block_until_ready()?,
+ }
+ }
+ } else {
+ false
+ }
} else {
false
};
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
- fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
- Ok(false)
+ fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
+ Poll::Ready(Ok(false))
}
fn invalidate_cache(&mut self) {
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
- fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
- Ok(false)
+ fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
+ Poll::Ready(Ok(false))
}
fn invalidate_cache(&mut self) {}
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
- fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
- Ok(false)
+ fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
+ Poll::Ready(Ok(false))
}
fn block_until_ready(&mut self) -> CargoResult<()> {
self.yanked_whitelist.extend(pkgs);
}
- fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
- self.invalidate_cache();
- loop {
- match self.index.is_yanked(pkg, &mut *self.ops)? {
- Poll::Ready(yanked) => return Ok(yanked),
- Poll::Pending => self.block_until_ready()?,
- }
- }
+ fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
+ self.index.is_yanked(pkg, &mut *self.ops)
}
fn block_until_ready(&mut self) -> CargoResult<()> {
self.inner.add_to_yanked_whitelist(&pkgs);
}
- fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
+ fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
self.inner.is_yanked(pkg)
}