diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index 7fc1da57a86..23ed0ca53a3 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -1,5 +1,5 @@ use cargo::core::features; -use cargo::{self, CliResult, Config}; +use cargo::{self, drop_print, drop_println, CliResult, Config}; use clap::{AppSettings, Arg, ArgMatches}; use super::commands; @@ -25,7 +25,8 @@ pub fn main(config: &mut Config) -> CliResult { }; if args.value_of("unstable-features") == Some("help") { - println!( + drop_println!( + config, " Available unstable (nightly-only) flags: @@ -40,7 +41,8 @@ Available unstable (nightly-only) flags: Run with 'cargo -Z [FLAG] [SUBCOMMAND]'" ); if !features::nightly_features_allowed() { - println!( + drop_println!( + config, "\nUnstable flags are only available on the nightly channel \ of Cargo, but this is the `{}` channel.\n\ {}", @@ -48,7 +50,8 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'" features::SEE_CHANNELS ); } - println!( + drop_println!( + config, "\nSee https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \ for more information about these flags." ); @@ -58,7 +61,7 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'" let is_verbose = args.occurrences_of("verbose") > 0; if args.is_present("version") { let version = get_version_string(is_verbose); - print!("{}", version); + drop_print!(config, "{}", version); return Ok(()); } @@ -69,19 +72,19 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'" } if args.is_present("list") { - println!("Installed Commands:"); + drop_println!(config, "Installed Commands:"); for command in list_commands(config) { match command { CommandInfo::BuiltIn { name, about } => { let summary = about.unwrap_or_default(); let summary = summary.lines().next().unwrap_or(&summary); // display only the first line - println!(" {:<20} {}", name, summary) + drop_println!(config, " {:<20} {}", name, summary); } CommandInfo::External { name, path } => { if is_verbose { - println!(" {:<20} {}", name, path.display()) + drop_println!(config, " {:<20} {}", name, path.display()); } else { - println!(" {}", name) + drop_println!(config, " {}", name); } } } diff --git a/src/bin/cargo/commands/locate_project.rs b/src/bin/cargo/commands/locate_project.rs index df0c424aa4a..5897de108b3 100644 --- a/src/bin/cargo/commands/locate_project.rs +++ b/src/bin/cargo/commands/locate_project.rs @@ -1,6 +1,4 @@ use crate::command_prelude::*; - -use cargo::print_json; use serde::Serialize; pub fn cli() -> App { @@ -30,6 +28,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let location = ProjectLocation { root }; - print_json(&location); + config.shell().print_json(&location); Ok(()) } diff --git a/src/bin/cargo/commands/metadata.rs b/src/bin/cargo/commands/metadata.rs index 1130f074e8f..616df735379 100644 --- a/src/bin/cargo/commands/metadata.rs +++ b/src/bin/cargo/commands/metadata.rs @@ -1,7 +1,5 @@ use crate::command_prelude::*; - use cargo::ops::{self, OutputMetadataOptions}; -use cargo::print_json; pub fn cli() -> App { subcommand("metadata") @@ -54,6 +52,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { }; let result = ops::output_metadata(&ws, &options)?; - print_json(&result); + config.shell().print_json(&result); Ok(()) } diff --git a/src/bin/cargo/commands/pkgid.rs b/src/bin/cargo/commands/pkgid.rs index 57be0d11877..453c95a184d 100644 --- a/src/bin/cargo/commands/pkgid.rs +++ b/src/bin/cargo/commands/pkgid.rs @@ -37,6 +37,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let spec = args.value_of("spec").or_else(|| args.value_of("package")); let spec = ops::pkgid(&ws, spec)?; - println!("{}", spec); + cargo::drop_println!(config, "{}", spec); Ok(()) } diff --git a/src/bin/cargo/commands/read_manifest.rs b/src/bin/cargo/commands/read_manifest.rs index fe2528b18aa..96cba1e082a 100644 --- a/src/bin/cargo/commands/read_manifest.rs +++ b/src/bin/cargo/commands/read_manifest.rs @@ -1,7 +1,5 @@ use crate::command_prelude::*; -use cargo::print_json; - pub fn cli() -> App { subcommand("read-manifest") .about( @@ -17,6 +15,6 @@ Deprecated, use `cargo metadata --no-deps` instead.\ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; - print_json(&ws.current()?); + config.shell().print_json(&ws.current()?); Ok(()) } diff --git a/src/bin/cargo/commands/tree.rs b/src/bin/cargo/commands/tree.rs index 9cfff98fe48..7eeac6cb8e7 100644 --- a/src/bin/cargo/commands/tree.rs +++ b/src/bin/cargo/commands/tree.rs @@ -102,7 +102,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { if args.is_present("version") { let verbose = args.occurrences_of("verbose") > 0; let version = cli::get_version_string(verbose); - print!("{}", version); + cargo::drop_print!(config, "{}", version); return Ok(()); } let prefix = if args.is_present("no-indent") { diff --git a/src/bin/cargo/commands/verify_project.rs b/src/bin/cargo/commands/verify_project.rs index fe2b42aebed..ea5ac117803 100644 --- a/src/bin/cargo/commands/verify_project.rs +++ b/src/bin/cargo/commands/verify_project.rs @@ -3,8 +3,6 @@ use crate::command_prelude::*; use std::collections::HashMap; use std::process; -use cargo::print_json; - pub fn cli() -> App { subcommand("verify-project") .about("Check correctness of crate manifest") @@ -13,19 +11,15 @@ pub fn cli() -> App { } pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { - fn fail(reason: &str, value: &str) -> ! { + if let Err(e) = args.workspace(config) { let mut h = HashMap::new(); - h.insert(reason.to_string(), value.to_string()); - print_json(&h); + h.insert("invalid".to_string(), e.to_string()); + config.shell().print_json(&h); process::exit(1) } - if let Err(e) = args.workspace(config) { - fail("invalid", &e.to_string()) - } - let mut h = HashMap::new(); h.insert("success".to_string(), "true".to_string()); - print_json(&h); + config.shell().print_json(&h); Ok(()) } diff --git a/src/bin/cargo/commands/version.rs b/src/bin/cargo/commands/version.rs index 81c6838e7ab..73172826150 100644 --- a/src/bin/cargo/commands/version.rs +++ b/src/bin/cargo/commands/version.rs @@ -1,6 +1,5 @@ -use crate::command_prelude::*; - use crate::cli; +use crate::command_prelude::*; pub fn cli() -> App { subcommand("version") @@ -8,9 +7,9 @@ pub fn cli() -> App { .arg(opt("quiet", "No output printed to stdout").short("q")) } -pub fn exec(_config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let verbose = args.occurrences_of("verbose") > 0; let version = cli::get_version_string(verbose); - print!("{}", version); + cargo::drop_print!(config, "{}", version); Ok(()) } diff --git a/src/cargo/core/compiler/build_plan.rs b/src/cargo/core/compiler/build_plan.rs index a01fa19821b..b76e8028716 100644 --- a/src/cargo/core/compiler/build_plan.rs +++ b/src/cargo/core/compiler/build_plan.rs @@ -14,7 +14,7 @@ use serde::Serialize; use super::context::OutputFile; use super::{CompileKind, CompileMode, Context, Unit}; use crate::core::TargetKind; -use crate::util::{internal, CargoResult, ProcessBuilder}; +use crate::util::{internal, CargoResult, Config, ProcessBuilder}; #[derive(Debug, Serialize)] struct Invocation { @@ -146,9 +146,9 @@ impl BuildPlan { self.plan.inputs = inputs; } - pub fn output_plan(self) { + pub fn output_plan(self, config: &Config) { let encoded = serde_json::to_string(&self.plan).unwrap(); - println!("{}", encoded); + crate::drop_println!(config, "{}", encoded); } } diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index fbba329c2e1..602aba2cda8 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -157,7 +157,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { if build_plan { plan.set_inputs(self.build_plan_inputs()?); - plan.output_plan(); + plan.output_plan(self.bcx.config); } // Collect the result of the build into `self.compilation`. diff --git a/src/cargo/core/compiler/job_queue.rs b/src/cargo/core/compiler/job_queue.rs index 7a103b13d21..a1f2bba16d3 100644 --- a/src/cargo/core/compiler/job_queue.rs +++ b/src/cargo/core/compiler/job_queue.rs @@ -500,7 +500,7 @@ impl<'cfg> DrainState<'cfg> { plan.update(&module_name, &cmd, &filenames)?; } Message::Stdout(out) => { - cx.bcx.config.shell().stdout_println(out); + writeln!(cx.bcx.config.shell().out(), "{}", out)?; } Message::Stderr(err) => { let mut shell = cx.bcx.config.shell(); @@ -700,7 +700,7 @@ impl<'cfg> DrainState<'cfg> { success: error.is_none(), } .to_json_string(); - cx.bcx.config.shell().stdout_println(msg); + writeln!(cx.bcx.config.shell().out(), "{}", msg)?; } if let Some(e) = error { diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 8a22e4aa050..f662495a1a1 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -146,7 +146,7 @@ fn compile<'cfg>( &unit.target, cx.files().message_cache_path(unit), cx.bcx.build_config.message_format, - cx.bcx.config.shell().supports_color(), + cx.bcx.config.shell().err_supports_color(), ) } else { Work::noop() @@ -1109,7 +1109,7 @@ struct OutputOptions { impl OutputOptions { fn new(cx: &Context<'_, '_>, unit: &Unit) -> OutputOptions { let look_for_metadata_directive = cx.rmeta_required(unit); - let color = cx.bcx.config.shell().supports_color(); + let color = cx.bcx.config.shell().err_supports_color(); let path = cx.files().message_cache_path(unit); // Remove old cache, ignore ENOENT, which is the common case. drop(fs::remove_file(&path)); diff --git a/src/cargo/core/compiler/timings.rs b/src/cargo/core/compiler/timings.rs index 20b4c7f600b..8302475defd 100644 --- a/src/cargo/core/compiler/timings.rs +++ b/src/cargo/core/compiler/timings.rs @@ -245,7 +245,7 @@ impl<'cfg> Timings<'cfg> { rmeta_time: unit_time.rmeta_time, } .to_json_string(); - self.config.shell().stdout_println(msg); + crate::drop_println!(self.config, "{}", msg); } self.unit_times.push(unit_time); } diff --git a/src/cargo/core/compiler/unit_graph.rs b/src/cargo/core/compiler/unit_graph.rs index 350c040abad..d242f6b0497 100644 --- a/src/cargo/core/compiler/unit_graph.rs +++ b/src/cargo/core/compiler/unit_graph.rs @@ -113,6 +113,6 @@ pub fn emit_serialized_unit_graph(root_units: &[Unit], unit_graph: &UnitGraph) - let stdout = std::io::stdout(); let mut lock = stdout.lock(); serde_json::to_writer(&mut lock, &s)?; - writeln!(lock)?; + drop(writeln!(lock)); Ok(()) } diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 994603aca57..221b769295b 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -500,7 +500,7 @@ impl Manifest { pub fn print_teapot(&self, config: &Config) { if let Some(teapot) = self.im_a_teapot { if config.cli_unstable().print_im_a_teapot { - println!("im-a-teapot = {}", teapot); + crate::drop_println!(config, "im-a-teapot = {}", teapot); } } } diff --git a/src/cargo/core/resolver/features.rs b/src/cargo/core/resolver/features.rs index cea01d113a4..8f71007f610 100644 --- a/src/cargo/core/resolver/features.rs +++ b/src/cargo/core/resolver/features.rs @@ -573,9 +573,13 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> { for ((pkg_id, dep_kind), features) in &self.activated_features { let r_features = self.resolve.features(*pkg_id); if !r_features.iter().eq(features.iter()) { - eprintln!( + crate::drop_eprintln!( + self.ws.config(), "{}/{:?} features mismatch\nresolve: {:?}\nnew: {:?}\n", - pkg_id, dep_kind, r_features, features + pkg_id, + dep_kind, + r_features, + features ); found = true; } diff --git a/src/cargo/core/shell.rs b/src/cargo/core/shell.rs index eae8a70cc8d..e1198f17689 100644 --- a/src/cargo/core/shell.rs +++ b/src/cargo/core/shell.rs @@ -14,13 +14,13 @@ pub enum Verbosity { Quiet, } -/// An abstraction around a `Write`able object that remembers preferences for output verbosity and -/// color. +/// An abstraction around console output that remembers preferences for output +/// verbosity and color. pub struct Shell { - /// the `Write`able object, either with or without color support (represented by different enum - /// variants) - err: ShellOut, - /// How verbose messages should be + /// Wrapper around stdout/stderr. This helps with supporting sending + /// output to a memory buffer which is useful for tests. + output: ShellOut, + /// How verbose messages should be. verbosity: Verbosity, /// Flag that indicates the current line needs to be cleared before /// printing. Used when a progress bar is currently displayed. @@ -29,7 +29,7 @@ pub struct Shell { impl fmt::Debug for Shell { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.err { + match self.output { ShellOut::Write(_) => f .debug_struct("Shell") .field("verbosity", &self.verbosity) @@ -49,8 +49,9 @@ enum ShellOut { Write(Box), /// Color-enabled stdio, with information on whether color should be used Stream { - stream: StandardStream, - tty: bool, + stdout: StandardStream, + stderr: StandardStream, + stderr_tty: bool, color_choice: ColorChoice, }, } @@ -70,11 +71,13 @@ impl Shell { /// Creates a new shell (color choice and verbosity), defaulting to 'auto' color and verbose /// output. pub fn new() -> Shell { + let auto = ColorChoice::CargoAuto.to_termcolor_color_choice(); Shell { - err: ShellOut::Stream { - stream: StandardStream::stderr(ColorChoice::CargoAuto.to_termcolor_color_choice()), + output: ShellOut::Stream { + stdout: StandardStream::stdout(auto), + stderr: StandardStream::stderr(auto), color_choice: ColorChoice::CargoAuto, - tty: atty::is(atty::Stream::Stderr), + stderr_tty: atty::is(atty::Stream::Stderr), }, verbosity: Verbosity::Verbose, needs_clear: false, @@ -84,7 +87,7 @@ impl Shell { /// Creates a shell from a plain writable object, with no color, and max verbosity. pub fn from_write(out: Box) -> Shell { Shell { - err: ShellOut::Write(out), + output: ShellOut::Write(out), verbosity: Verbosity::Verbose, needs_clear: false, } @@ -105,18 +108,12 @@ impl Shell { if self.needs_clear { self.err_erase_line(); } - self.err.print(status, message, color, justified) + self.output + .message_stderr(status, message, color, justified) } } } - pub fn stdout_println(&mut self, message: impl fmt::Display) { - if self.needs_clear { - self.err_erase_line(); - } - println!("{}", message); - } - /// Sets whether the next print should clear the current line. pub fn set_needs_clear(&mut self, needs_clear: bool) { self.needs_clear = needs_clear; @@ -129,31 +126,44 @@ impl Shell { /// Returns the width of the terminal in spaces, if any. pub fn err_width(&self) -> Option { - match self.err { - ShellOut::Stream { tty: true, .. } => imp::stderr_width(), + match self.output { + ShellOut::Stream { + stderr_tty: true, .. + } => imp::stderr_width(), _ => None, } } /// Returns `true` if stderr is a tty. pub fn is_err_tty(&self) -> bool { - match self.err { - ShellOut::Stream { tty, .. } => tty, + match self.output { + ShellOut::Stream { stderr_tty, .. } => stderr_tty, _ => false, } } - /// Gets a reference to the underlying writer. + /// Gets a reference to the underlying stdout writer. + pub fn out(&mut self) -> &mut dyn Write { + if self.needs_clear { + self.err_erase_line(); + } + self.output.stdout() + } + + /// Gets a reference to the underlying stderr writer. pub fn err(&mut self) -> &mut dyn Write { if self.needs_clear { self.err_erase_line(); } - self.err.as_write() + self.output.stderr() } /// Erase from cursor to end of line. pub fn err_erase_line(&mut self) { - if let ShellOut::Stream { tty: true, .. } = self.err { + if let ShellOut::Stream { + stderr_tty: true, .. + } = self.output + { imp::err_erase_line(self); self.needs_clear = false; } @@ -216,7 +226,8 @@ impl Shell { if self.needs_clear { self.err_erase_line(); } - self.err.print(&"error", Some(&message), Red, false) + self.output + .message_stderr(&"error", Some(&message), Red, false) } /// Prints an amber 'warning' message. @@ -245,10 +256,11 @@ impl Shell { /// Updates the color choice (always, never, or auto) from a string.. pub fn set_color_choice(&mut self, color: Option<&str>) -> CargoResult<()> { if let ShellOut::Stream { - ref mut stream, + ref mut stdout, + ref mut stderr, ref mut color_choice, .. - } = self.err + } = self.output { let cfg = match color { Some("always") => ColorChoice::Always, @@ -263,7 +275,9 @@ impl Shell { ), }; *color_choice = cfg; - *stream = StandardStream::stderr(cfg.to_termcolor_color_choice()); + let choice = cfg.to_termcolor_color_choice(); + *stdout = StandardStream::stdout(choice); + *stderr = StandardStream::stderr(choice); } Ok(()) } @@ -273,17 +287,17 @@ impl Shell { /// If we are not using a color stream, this will always return `Never`, even if the color /// choice has been set to something else. pub fn color_choice(&self) -> ColorChoice { - match self.err { + match self.output { ShellOut::Stream { color_choice, .. } => color_choice, ShellOut::Write(_) => ColorChoice::Never, } } /// Whether the shell supports color. - pub fn supports_color(&self) -> bool { - match &self.err { + pub fn err_supports_color(&self) -> bool { + match &self.output { ShellOut::Write(_) => false, - ShellOut::Stream { stream, .. } => stream.supports_color(), + ShellOut::Stream { stderr, .. } => stderr.supports_color(), } } @@ -294,14 +308,19 @@ impl Shell { } #[cfg(windows)] { - if let ShellOut::Stream { stream, .. } = &mut self.err { - ::fwdansi::write_ansi(stream, message)?; + if let ShellOut::Stream { stderr, .. } = &mut self.output { + ::fwdansi::write_ansi(stderr, message)?; return Ok(()); } } self.err().write_all(message)?; Ok(()) } + + pub fn print_json(&mut self, obj: &T) { + let encoded = serde_json::to_string(&obj).unwrap(); + drop(writeln!(self.out(), "{}", encoded)); + } } impl Default for Shell { @@ -314,7 +333,7 @@ impl ShellOut { /// Prints out a message with a status. The status comes first, and is bold plus the given /// color. The status can be justified, in which case the max width that will right align is /// 12 chars. - fn print( + fn message_stderr( &mut self, status: &dyn fmt::Display, message: Option<&dyn fmt::Display>, @@ -322,20 +341,20 @@ impl ShellOut { justified: bool, ) -> CargoResult<()> { match *self { - ShellOut::Stream { ref mut stream, .. } => { - stream.reset()?; - stream.set_color(ColorSpec::new().set_bold(true).set_fg(Some(color)))?; + ShellOut::Stream { ref mut stderr, .. } => { + stderr.reset()?; + stderr.set_color(ColorSpec::new().set_bold(true).set_fg(Some(color)))?; if justified { - write!(stream, "{:>12}", status)?; + write!(stderr, "{:>12}", status)?; } else { - write!(stream, "{}", status)?; - stream.set_color(ColorSpec::new().set_bold(true))?; - write!(stream, ":")?; + write!(stderr, "{}", status)?; + stderr.set_color(ColorSpec::new().set_bold(true))?; + write!(stderr, ":")?; } - stream.reset()?; + stderr.reset()?; match message { - Some(message) => writeln!(stream, " {}", message)?, - None => write!(stream, " ")?, + Some(message) => writeln!(stderr, " {}", message)?, + None => write!(stderr, " ")?, } } ShellOut::Write(ref mut w) => { @@ -353,10 +372,18 @@ impl ShellOut { Ok(()) } - /// Gets this object as a `io::Write`. - fn as_write(&mut self) -> &mut dyn Write { + /// Gets stdout as a `io::Write`. + fn stdout(&mut self) -> &mut dyn Write { + match *self { + ShellOut::Stream { ref mut stdout, .. } => stdout, + ShellOut::Write(ref mut w) => w, + } + } + + /// Gets stderr as a `io::Write`. + fn stderr(&mut self) -> &mut dyn Write { match *self { - ShellOut::Stream { ref mut stream, .. } => stream, + ShellOut::Stream { ref mut stderr, .. } => stderr, ShellOut::Write(ref mut w) => w, } } @@ -404,7 +431,7 @@ mod imp { // This is the "EL - Erase in Line" sequence. It clears from the cursor // to the end of line. // https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences - let _ = shell.err.as_write().write_all(b"\x1B[K"); + let _ = shell.output.stderr().write_all(b"\x1B[K"); } } @@ -468,6 +495,6 @@ mod imp { fn default_err_erase_line(shell: &mut Shell) { if let Some(max_width) = imp::stderr_width() { let blank = " ".repeat(max_width); - drop(write!(shell.err.as_write(), "{}\r", blank)); + drop(write!(shell.output.stderr(), "{}\r", blank)); } } diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index b386ee7f558..19cbd49c101 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -34,7 +34,6 @@ use crate::core::shell::Verbosity::Verbose; use crate::core::Shell; use anyhow::Error; use log::debug; -use serde::ser; use std::fmt; pub use crate::util::errors::{InternalError, VerboseError}; @@ -93,11 +92,6 @@ impl fmt::Display for VersionInfo { } } -pub fn print_json(obj: &T) { - let encoded = serde_json::to_string(&obj).unwrap(); - println!("{}", encoded); -} - pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! { debug!("exit_with_error; err={:?}", err); if let Some(ref err) = err.error { diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 0406a56063d..e450f82f3de 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -9,11 +9,11 @@ use tempfile::Builder as TempFileBuilder; use crate::core::compiler::Freshness; use crate::core::compiler::{CompileKind, DefaultExecutor, Executor}; use crate::core::{Edition, Package, PackageId, Source, SourceId, Workspace}; -use crate::ops; use crate::ops::common_for_install_and_uninstall::*; use crate::sources::{GitSource, SourceConfigMap}; use crate::util::errors::{CargoResult, CargoResultExt}; use crate::util::{paths, Config, Filesystem}; +use crate::{drop_println, ops}; struct Transaction { bins: Vec, @@ -531,9 +531,9 @@ pub fn install_list(dst: Option<&str>, config: &Config) -> CargoResult<()> { let root = resolve_root(dst, config)?; let tracker = InstallTracker::load(config, &root)?; for (k, v) in tracker.all_installed_bins() { - println!("{}:", k); + drop_println!(config, "{}:", k); for bin in v { - println!(" {}", bin); + drop_println!(config, " {}", bin); } } Ok(()) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index b84e6b3caf1..4b59afdae1e 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -15,12 +15,12 @@ use tar::{Archive, Builder, EntryType, Header}; use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor}; use crate::core::{Feature, Shell, Verbosity, Workspace}; use crate::core::{Package, PackageId, PackageSet, Resolve, Source, SourceId}; -use crate::ops; use crate::sources::PathSource; use crate::util::errors::{CargoResult, CargoResultExt}; use crate::util::paths; use crate::util::toml::TomlManifest; use crate::util::{self, restricted_names, Config, FileLock}; +use crate::{drop_println, ops}; pub struct PackageOpts<'cfg> { pub config: &'cfg Config, @@ -102,7 +102,7 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult