Add ability to silence Source updates.

This adds the ability to silence Source status messages and progress bars.
This is intended to be used with the publish "wait for available"
system, which causes sources to repeatedly update which ends up spamming
the terminal.
This commit is contained in:
Eric Huss 2023-02-14 12:46:30 -08:00
parent 261249a5e4
commit 5bea4abb72
9 changed files with 81 additions and 16 deletions

View File

@ -44,6 +44,9 @@ pub trait Source {
/// Ensure that the source is fully up-to-date for the current session on the next query.
fn invalidate_cache(&mut self);
/// If quiet, the source should not display any progress or status messages.
fn set_quiet(&mut self, quiet: bool);
/// Fetches the full package for each name and version specified.
fn download(&mut self, package: PackageId) -> CargoResult<MaybePackage>;
@ -163,6 +166,10 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
(**self).invalidate_cache()
}
fn set_quiet(&mut self, quiet: bool) {
(**self).set_quiet(quiet)
}
/// Forwards to `Source::download`.
fn download(&mut self, id: PackageId) -> CargoResult<MaybePackage> {
(**self).download(id)
@ -233,6 +240,10 @@ impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T {
(**self).invalidate_cache()
}
fn set_quiet(&mut self, quiet: bool) {
(**self).set_quiet(quiet)
}
fn download(&mut self, id: PackageId) -> CargoResult<MaybePackage> {
(**self).download(id)
}

View File

@ -217,6 +217,10 @@ impl<'cfg> Source for DirectorySource<'cfg> {
}
fn invalidate_cache(&mut self) {
// Path source has no local cache.
// Directory source has no local cache.
}
fn set_quiet(&mut self, _quiet: bool) {
// Directory source does not display status
}
}

View File

@ -21,6 +21,7 @@ pub struct GitSource<'cfg> {
path_source: Option<PathSource<'cfg>>,
ident: String,
config: &'cfg Config,
quiet: bool,
}
impl<'cfg> GitSource<'cfg> {
@ -43,6 +44,7 @@ impl<'cfg> GitSource<'cfg> {
path_source: None,
ident,
config,
quiet: false,
};
Ok(source)
@ -162,10 +164,12 @@ impl<'cfg> Source for GitSource<'cfg> {
self.remote.url()
);
}
self.config.shell().status(
"Updating",
format!("git repository `{}`", self.remote.url()),
)?;
if !self.quiet {
self.config.shell().status(
"Updating",
format!("git repository `{}`", self.remote.url()),
)?;
}
trace!("updating git source `{:?}`", self.remote);
@ -233,6 +237,10 @@ impl<'cfg> Source for GitSource<'cfg> {
}
fn invalidate_cache(&mut self) {}
fn set_quiet(&mut self, quiet: bool) {
self.quiet = quiet;
}
}
#[cfg(test)]

View File

@ -574,4 +574,8 @@ impl<'cfg> Source for PathSource<'cfg> {
fn invalidate_cache(&mut self) {
// Path source has no local cache.
}
fn set_quiet(&mut self, _quiet: bool) {
// Path source does not display status
}
}

View File

@ -89,10 +89,13 @@ pub struct HttpRegistry<'cfg> {
/// Url to get a token for the registry.
login_url: Option<Url>,
/// Disables status messages.
quiet: bool,
}
/// Helper for downloading crates.
pub struct Downloads<'cfg> {
struct Downloads<'cfg> {
/// When a download is started, it is added to this map. The key is a
/// "token" (see `Download::token`). It is removed once the download is
/// finished.
@ -196,6 +199,7 @@ impl<'cfg> HttpRegistry<'cfg> {
registry_config: None,
auth_required: false,
login_url: None,
quiet: false,
})
}
@ -231,9 +235,11 @@ impl<'cfg> HttpRegistry<'cfg> {
// let's not flood the server with connections
self.multi.set_max_host_connections(2)?;
self.config
.shell()
.status("Updating", self.source_id.display_index())?;
if !self.quiet {
self.config
.shell()
.status("Updating", self.source_id.display_index())?;
}
Ok(())
}
@ -681,6 +687,11 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
self.requested_update = true;
}
fn set_quiet(&mut self, quiet: bool) {
self.quiet = quiet;
self.downloads.progress.replace(None);
}
fn download(&mut self, pkg: PackageId, checksum: &str) -> CargoResult<MaybeLock> {
let registry_config = loop {
match self.config()? {
@ -747,7 +758,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
impl<'cfg> Downloads<'cfg> {
fn tick(&self) -> CargoResult<()> {
let mut progress = self.progress.borrow_mut();
let progress = progress.as_mut().unwrap();
let Some(progress) = progress.as_mut() else { return Ok(()); };
// Since the sparse protocol discovers dependencies as it goes,
// it's not possible to get an accurate progress indication.
@ -780,7 +791,7 @@ mod tls {
thread_local!(static PTR: Cell<usize> = Cell::new(0));
pub(crate) fn with<R>(f: impl FnOnce(Option<&Downloads<'_>>) -> R) -> R {
pub(super) fn with<R>(f: impl FnOnce(Option<&Downloads<'_>>) -> R) -> R {
let ptr = PTR.with(|p| p.get());
if ptr == 0 {
f(None)
@ -791,7 +802,7 @@ mod tls {
}
}
pub(crate) fn set<R>(dl: &Downloads<'_>, f: impl FnOnce() -> R) -> R {
pub(super) fn set<R>(dl: &Downloads<'_>, f: impl FnOnce() -> R) -> R {
struct Reset<'a, T: Copy>(&'a Cell<T>, T);
impl<'a, T: Copy> Drop for Reset<'a, T> {

View File

@ -18,6 +18,7 @@ pub struct LocalRegistry<'cfg> {
src_path: Filesystem,
config: &'cfg Config,
updated: bool,
quiet: bool,
}
impl<'cfg> LocalRegistry<'cfg> {
@ -28,6 +29,7 @@ impl<'cfg> LocalRegistry<'cfg> {
root: Filesystem::new(root.to_path_buf()),
config,
updated: false,
quiet: false,
}
}
}
@ -104,6 +106,10 @@ impl<'cfg> RegistryData for LocalRegistry<'cfg> {
// Local registry has no cache - just reads from disk.
}
fn set_quiet(&mut self, _quiet: bool) {
self.quiet = true;
}
fn is_updated(&self) -> bool {
self.updated
}
@ -124,7 +130,9 @@ impl<'cfg> RegistryData for LocalRegistry<'cfg> {
return Ok(MaybeLock::Ready(crate_file));
}
self.config.shell().status("Unpacking", pkg)?;
if !self.quiet {
self.config.shell().status("Unpacking", pkg)?;
}
// We don't actually need to download anything per-se, we just need to
// verify the checksum matches the .crate file itself.

View File

@ -474,6 +474,9 @@ pub trait RegistryData {
/// Invalidates locally cached data.
fn invalidate_cache(&mut self);
/// If quiet, the source should not display any progress or status messages.
fn set_quiet(&mut self, quiet: bool);
/// Is the local cached data up-to-date?
fn is_updated(&self) -> bool;
@ -832,6 +835,10 @@ impl<'cfg> Source for RegistrySource<'cfg> {
self.ops.invalidate_cache();
}
fn set_quiet(&mut self, quiet: bool) {
self.ops.set_quiet(quiet);
}
fn download(&mut self, package: PackageId) -> CargoResult<MaybePackage> {
let hash = loop {
match self.index.hash(package, &mut *self.ops)? {

View File

@ -32,6 +32,7 @@ pub struct RemoteRegistry<'cfg> {
head: Cell<Option<git2::Oid>>,
current_sha: Cell<Option<InternedString>>,
needs_update: bool, // Does this registry need to be updated?
quiet: bool,
}
impl<'cfg> RemoteRegistry<'cfg> {
@ -48,6 +49,7 @@ impl<'cfg> RemoteRegistry<'cfg> {
head: Cell::new(None),
current_sha: Cell::new(None),
needs_update: false,
quiet: false,
}
}
@ -292,9 +294,11 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
*self.tree.borrow_mut() = None;
self.current_sha.set(None);
let path = self.config.assert_package_cache_locked(&self.index_path);
self.config
.shell()
.status("Updating", self.source_id.display_index())?;
if !self.quiet {
self.config
.shell()
.status("Updating", self.source_id.display_index())?;
}
// Fetch the latest version of our `index_git_ref` into the index
// checkout.
@ -315,6 +319,10 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
self.needs_update = true;
}
fn set_quiet(&mut self, quiet: bool) {
self.quiet = quiet;
}
fn is_updated(&self) -> bool {
self.is_updated()
}

View File

@ -67,6 +67,10 @@ impl<'cfg> Source for ReplacedSource<'cfg> {
self.inner.invalidate_cache()
}
fn set_quiet(&mut self, quiet: bool) {
self.inner.set_quiet(quiet);
}
fn download(&mut self, id: PackageId) -> CargoResult<MaybePackage> {
let id = id.with_source_id(self.replace_with);
let pkg = self