Skip to content

Commit

Permalink
Read ui verbosity from env var
Browse files Browse the repository at this point in the history
  • Loading branch information
maciektr committed Apr 8, 2024
1 parent 182180a commit a663e84
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 31 deletions.
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() {
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

0 comments on commit a663e84

Please sign in to comment.