Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read ui verbosity from env var #1245

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ toml_edit = { version = "0.22", features = ["serde"] }
tower-http = { version = "0.4", features = ["fs"] }
tracing = "0.1"
tracing-log = "0.2"
tracing-core = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
typed-builder = ">=0.17"
url = { version = "2", features = ["serde"] }
Expand Down
18 changes: 10 additions & 8 deletions extensions/scarb-cairo-run/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use serde::Serializer;
use scarb_metadata::{
CompilationUnitMetadata, Metadata, MetadataCommand, PackageId, PackageMetadata, ScarbCommand,
};
use scarb_ui::args::PackagesFilter;
use scarb_ui::args::{PackagesFilter, VerbositySpec};
use scarb_ui::components::Status;
use scarb_ui::{Message, OutputFormat, Ui, Verbosity};
use scarb_ui::{Message, OutputFormat, Ui};

mod deserialization;

Expand All @@ -39,6 +39,10 @@ struct Args {
#[arg(long, default_value_t = false)]
no_build: bool,

/// Logging verbosity.
#[command(flatten)]
pub verbose: VerbositySpec,

/// Program arguments.
///
/// This should be a JSON array of numbers, decimal bigints or recursive arrays of those. For example, pass `[1]`
Expand All @@ -49,18 +53,16 @@ struct Args {
}

fn main() -> Result<()> {
let ui = Ui::new(Verbosity::default(), OutputFormat::Text);

if let Err(err) = main_inner(&ui) {
let args: Args = Args::parse();
let ui = Ui::new(args.verbose.clone().into(), OutputFormat::Text);
if let Err(err) = main_inner(&ui, args) {
ui.anyhow(&err);
std::process::exit(1);
}
Ok(())
}

fn main_inner(ui: &Ui) -> Result<()> {
let args: Args = Args::parse();

fn main_inner(ui: &Ui, args: Args) -> Result<()> {
let metadata = MetadataCommand::new().inherit_stderr().exec()?;

let package = args.packages_filter.match_one(&metadata)?;
Expand Down
23 changes: 23 additions & 0 deletions extensions/scarb-cairo-run/tests/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,26 @@ fn cannot_set_gas_limit_for_package_with_disabled_gas_calculation() {
error: gas calculation disabled for package `hello`, cannot define custom gas limit
"#});
}

#[test]
fn can_control_verbosity() {
maciektr marked this conversation as resolved.
Show resolved Hide resolved
let t = TempDir::new().unwrap();
ProjectBuilder::start()
.name("hello")
.version("0.1.0")
.lib_cairo(indoc! {r#"
fn main() {
println!("something");
}
"#})
.build(&t);
Scarb::quick_snapbox()
.arg("--quiet")
.arg("cairo-run")
.current_dir(&t)
.assert()
.success()
.stdout_matches(indoc! {r#"
something
"#});
}
18 changes: 2 additions & 16 deletions scarb/src/bin/scarb/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ use camino::Utf8PathBuf;
use clap::{CommandFactory, Parser, Subcommand};
use scarb::ops::EmitTarget;
use smol_str::SmolStr;
use tracing::level_filters::LevelFilter;
use tracing_log::AsTrace;
use url::Url;

use scarb::compiler::Profile;
use scarb::core::PackageName;
use scarb::manifest_editor::DepId;
use scarb::manifest_editor::SectionArgs;
use scarb::version;
use scarb_ui::args::{FeaturesSpec, PackagesFilter};
use scarb_ui::args::{FeaturesSpec, PackagesFilter, VerbositySpec};
use scarb_ui::OutputFormat;

/// The Cairo package manager.
Expand Down Expand Up @@ -62,7 +60,7 @@ pub struct ScarbArgs {

/// Logging verbosity.
#[command(flatten)]
pub verbose: clap_verbosity_flag::Verbosity,
pub verbose: VerbositySpec,

/// Print machine-readable output in NDJSON format.
#[arg(long)]
Expand Down Expand Up @@ -118,18 +116,6 @@ impl ScarbArgs {
}
}

/// Get [`ui::Verbosity`] out of these arguments.
pub fn ui_verbosity(&self) -> scarb_ui::Verbosity {
let filter = self.verbose.log_level_filter().as_trace();
if filter >= LevelFilter::WARN {
scarb_ui::Verbosity::Verbose
} else if filter > LevelFilter::OFF {
scarb_ui::Verbosity::Normal
} else {
scarb_ui::Verbosity::Quiet
}
}

pub fn get_builtin_subcommands() -> BTreeMap<String, Option<String>> {
Self::command()
.get_subcommands()
Expand Down
2 changes: 1 addition & 1 deletion scarb/src/bin/scarb/commands/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn run(args: MetadataArgs, config: &Config) -> Result<()> {

let metadata = ops::collect_metadata(&opts, &ws)?;

config.ui().print(MachineMessage(metadata));
config.ui().force_print(MachineMessage(metadata));

Ok(())
}
8 changes: 3 additions & 5 deletions scarb/src/bin/scarb/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::env;
use anyhow::{Error, Result};
use clap::Parser;
use tracing::debug;
use tracing_log::AsTrace;
use tracing_subscriber::EnvFilter;

use args::ScarbArgs;
Expand All @@ -22,13 +21,13 @@ fn main() {
let args = ScarbArgs::parse();

// Pre-create Ui used in logging & error reporting, because we will move `args` to `cli_main`.
let ui = Ui::new(args.ui_verbosity(), args.output_format());
let ui = Ui::new(args.verbose.clone().into(), args.output_format());

tracing_subscriber::fmt()
.with_writer(std::io::stderr)
.with_env_filter(
EnvFilter::builder()
.with_default_directive(args.verbose.log_level_filter().as_trace().into())
.with_default_directive(args.verbose.as_trace().into())
.with_env_var("SCARB_LOG")
.from_env_lossy(),
)
Expand Down Expand Up @@ -59,7 +58,6 @@ fn exit_with_error(err: Error, ui: &Ui) {
}

fn cli_main(args: ScarbArgs) -> Result<()> {
let ui_verbosity = args.ui_verbosity();
let ui_output_format = args.output_format();

let manifest_path = ops::find_manifest_path(args.manifest_path.as_deref())?;
Expand All @@ -68,7 +66,7 @@ fn cli_main(args: ScarbArgs) -> Result<()> {
.global_cache_dir_override(args.global_cache_dir)
.global_config_dir_override(args.global_config_dir)
.target_dir_override(args.target_dir)
.ui_verbosity(ui_verbosity)
.ui_verbosity(args.verbose.clone().into())
.ui_output_format(ui_output_format)
.offline(args.offline)
.log_filter_directive(env::var_os("SCARB_LOG"))
Expand Down
31 changes: 30 additions & 1 deletion scarb/tests/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::process::{Child, Command};
use std::{env, io};

use assert_fs::TempDir;
#[cfg(unix)]
use indoc::indoc;
use scarb_test_support::cargo::cargo_bin;

Expand Down Expand Up @@ -215,3 +214,33 @@ fn can_list_scarb_directory_scripts() {
let stdout = String::from_utf8(output).unwrap();
assert!(stdout.contains("hello"))
}

#[test]
fn scarb_reads_verbosity_from_env() {
let p = TempDir::new().unwrap();
ProjectBuilder::start().build(&p);
Scarb::quick_snapbox()
.current_dir(&p)
.arg("check")
.env("SCARB_UI_VERBOSITY", "quiet")
.assert()
.success()
.stdout_eq("");
}

#[test]
fn cli_verbosity_overrides_env() {
let p = TempDir::new().unwrap();
ProjectBuilder::start().build(&p);
Scarb::quick_snapbox()
.current_dir(&p)
.arg("check")
.arg("--verbose")
.env("SCARB_UI_VERBOSITY", "quiet")
.assert()
.success()
.stdout_matches(indoc! {r#"
[..]Checking pkg0 v1.0.0 ([..]Scarb.toml)
[..]Finished checking release target(s) in [..]
"#});
}
1 change: 1 addition & 0 deletions utils/scarb-ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ indicatif.workspace = true
scarb-metadata = { version = "1", path = "../../scarb-metadata" }
serde.workspace = true
serde_json.workspace = true
tracing-core.workspace = true
2 changes: 2 additions & 0 deletions utils/scarb-ui/src/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

pub use features::*;
pub use packages_filter::*;
pub use verbosity::*;

mod features;
mod packages_filter;
mod verbosity;
85 changes: 85 additions & 0 deletions utils/scarb-ui/src/args/verbosity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use crate::Verbosity;

/// [`clap`] structured arguments that provide Scarb UI verbosity selection.
#[derive(clap::Args, Debug, Clone, Default)]
#[command(about = None, long_about = None)]
pub struct VerbositySpec {
#[arg(
long,
short = 'v',
action = clap::ArgAction::Count,
global = true,
help = "Increase logging verbosity.",
)]
verbose: u8,

#[arg(
long,
short = 'q',
action = clap::ArgAction::Count,
global = true,
help = "Decrease logging verbosity.",
conflicts_with = "verbose",
)]
quiet: u8,

#[arg(
long,
global = true,
help = "Set UI verbosity level by name.",
env = "SCARB_UI_VERBOSITY"
)]
verbosity: Option<Verbosity>,
}

impl Verbosity {
fn level_value(level: Self) -> i8 {
match level {
Self::Quiet => 0,
Self::Normal => 2,
Self::Verbose => 4,
}
}
}

impl VerbositySpec {
/// Whether any verbosity flags (either `--verbose` or `--quiet`)
/// are present on the command line.
pub fn is_present(&self) -> bool {
self.verbose != 0 || self.quiet != 0
}

/// Convert the verbosity specification to a [`tracing_core::LevelFilter`].
pub fn as_trace(&self) -> tracing_core::LevelFilter {
match self.integer_verbosity() {
i8::MIN..=-1 => tracing_core::LevelFilter::OFF,
0 => tracing_core::LevelFilter::ERROR,
1 => tracing_core::LevelFilter::WARN,
2 => tracing_core::LevelFilter::INFO,
3 => tracing_core::LevelFilter::DEBUG,
4..=i8::MAX => tracing_core::LevelFilter::TRACE,
}
}

fn integer_verbosity(&self) -> i8 {
let int_level = Verbosity::level_value(Verbosity::default()) - (self.quiet as i8)
+ (self.verbose as i8);
if self.is_present() {
int_level
} else {
self.verbosity
.map(Verbosity::level_value)
.unwrap_or(int_level)
}
}
}

impl From<VerbositySpec> for Verbosity {
fn from(spec: VerbositySpec) -> Self {
match spec.integer_verbosity() {
v if v < 2 => Verbosity::Quiet,
2 => Verbosity::Normal,
_ => Verbosity::Verbose,
}
}
}
5 changes: 5 additions & 0 deletions utils/scarb-ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ impl Ui {
}
}

/// Print the message to standard output regardless of the verbosity mode.
pub fn force_print<T: Message>(&self, message: T) {
self.do_print(message);
}

/// Print the message to the standard output only in verbose mode.
pub fn verbose<T: Message>(&self, message: T) {
if self.verbosity >= Verbosity::Verbose {
Expand Down
Loading