diff --git a/Cargo.lock b/Cargo.lock index 14d12a80f..a402dfd6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -870,6 +870,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo-util", "cargo_metadata", "ctor", diff --git a/examples/experimental/derive_opportunity/Cargo.lock b/examples/experimental/derive_opportunity/Cargo.lock index 9367b9d63..c5d43947c 100644 --- a/examples/experimental/derive_opportunity/Cargo.lock +++ b/examples/experimental/derive_opportunity/Cargo.lock @@ -271,6 +271,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata", "git2", "home", diff --git a/examples/experimental/missing_doc_comment_openai/Cargo.lock b/examples/experimental/missing_doc_comment_openai/Cargo.lock index c4f624581..4e4af7c3b 100644 --- a/examples/experimental/missing_doc_comment_openai/Cargo.lock +++ b/examples/experimental/missing_doc_comment_openai/Cargo.lock @@ -286,6 +286,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata", "git2", "home", diff --git a/examples/general/Cargo.lock b/examples/general/Cargo.lock index 3a1171803..260cb3e7f 100644 --- a/examples/general/Cargo.lock +++ b/examples/general/Cargo.lock @@ -324,6 +324,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata", "git2", "home", diff --git a/examples/restriction/Cargo.lock b/examples/restriction/Cargo.lock index 89ac97fc0..8bda0f0c1 100644 --- a/examples/restriction/Cargo.lock +++ b/examples/restriction/Cargo.lock @@ -354,6 +354,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata", "git2", "home", diff --git a/examples/supplementary/Cargo.lock b/examples/supplementary/Cargo.lock index 28fb5e041..5864f02bf 100644 --- a/examples/supplementary/Cargo.lock +++ b/examples/supplementary/Cargo.lock @@ -307,6 +307,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata", "git2", "home", diff --git a/examples/testing/clippy/Cargo.lock b/examples/testing/clippy/Cargo.lock index e49706a7c..242d4760c 100644 --- a/examples/testing/clippy/Cargo.lock +++ b/examples/testing/clippy/Cargo.lock @@ -321,6 +321,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata 0.18.1", "git2", "home", diff --git a/examples/testing/marker/Cargo.lock b/examples/testing/marker/Cargo.lock index e7710dedc..ad5cf58a9 100644 --- a/examples/testing/marker/Cargo.lock +++ b/examples/testing/marker/Cargo.lock @@ -137,6 +137,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata", "git2", "home", diff --git a/examples/testing/straggler/Cargo.lock b/examples/testing/straggler/Cargo.lock index 19f6a4c42..effa91d06 100644 --- a/examples/testing/straggler/Cargo.lock +++ b/examples/testing/straggler/Cargo.lock @@ -256,6 +256,7 @@ version = "2.6.0" dependencies = [ "ansi_term", "anyhow", + "bitflags 2.4.1", "cargo_metadata", "git2", "home", diff --git a/internal/Cargo.toml b/internal/Cargo.toml index ed75d4d1f..8301e796d 100644 --- a/internal/Cargo.toml +++ b/internal/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/trailofbits/dylint" anyhow = "1.0" ansi_term = { version = "0.12", optional = true } +bitflags = { version = "2.4", optional = true } cargo-util = { version = "0.2", optional = true } cargo_metadata = { version = "0.18", optional = true } ctor = { version = "0.2", optional = true } @@ -35,6 +36,7 @@ toml_edit = "0.21" [features] cargo = [ "ansi_term", + "bitflags", "cargo_metadata", "command", "home", diff --git a/internal/src/cargo.rs b/internal/src/cargo.rs index 619085b8d..45073469e 100644 --- a/internal/src/cargo.rs +++ b/internal/src/cargo.rs @@ -1,6 +1,7 @@ use crate::CommandExt; use ansi_term::Style; use anyhow::{anyhow, ensure, Result}; +use bitflags::bitflags; use cargo_metadata::{Metadata, MetadataCommand, Package, PackageId}; use is_terminal::IsTerminal; use once_cell::sync::Lazy; @@ -22,6 +23,23 @@ static STABLE_CARGO: Lazy = Lazy::new(|| { PathBuf::from(stdout.trim_end()) }); +bitflags! { + pub struct Quiet: u8 { + const MESSAGE = 1 << 0; + const STDERR = 1 << 1; + } +} + +impl From for Quiet { + fn from(value: bool) -> Self { + if value { + Quiet::all() + } else { + Quiet::empty() + } + } +} + /// A `cargo` command builder /// /// Note that [`std::process::Command`]is itself a builder. So technically that makes this a @@ -30,8 +48,8 @@ pub struct Builder { subcommand: String, verb: String, description: String, + quiet: Quiet, stable: bool, - quiet: bool, } #[must_use] @@ -80,15 +98,16 @@ impl Builder { subcommand: subcommand.to_owned(), verb: verb.to_owned(), description: description.to_owned(), - quiet: false, + quiet: Quiet::empty(), stable: false, } } /// Whether to allow the command to write to standard error. - pub fn quiet(&mut self, value: bool) -> &mut Self { + pub fn quiet(&mut self, value: impl Into) -> &mut Self { + let value = value.into(); // smoelius: `cargo check` and `cargo fix` are never silenced. - if value { + if !value.is_empty() { assert!(!matches!(self.subcommand.as_str(), "check" | "fix")); } self.quiet = value; @@ -104,7 +123,7 @@ impl Builder { /// Consumes the builder and returns a [`std::process::Command`]. pub fn build(&mut self) -> Command { - if !self.quiet { + if !self.quiet.contains(Quiet::MESSAGE) { // smoelius: Writing directly to `stderr` prevents capture by `libtest`. let message = format!("{} {}", self.verb, self.description); std::io::stderr() @@ -137,7 +156,7 @@ impl Builder { command.envs(vec![(crate::env::PATH, new_path)]); } command.args([&self.subcommand]); - if self.quiet { + if !self.quiet.contains(Quiet::STDERR) { command.stderr(Stdio::null()); } command