Skip to content

Commit

Permalink
feat(cli): Add verbosity, return Hugr from run. (#1116)
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-q authored May 29, 2024
1 parent f757cc8 commit 3298a6a
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 12 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ typetag = "0.2.7"
urlencoding = "2.1.2"
webbrowser = "1.0.0"
clap = { version = "4.5.4"}
clap-stdin = "0.4.0"
clap-verbosity-flag = "2.2.0"
assert_cmd = "2.0.14"
assert_fs = "1.1.1"
clap-stdin = "0.4.0"
predicates = "3.1.0"

[profile.dev.package]
Expand Down
3 changes: 2 additions & 1 deletion hugr-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ categories = ["compilers"]

[dependencies]
clap = {workspace = true, features = ["derive"]}
clap-stdin = { workspace = true }
clap-stdin.workspace = true
clap-verbosity-flag.workspace = true
hugr-core = { path = "../hugr-core", version = "0.0.0" }
serde_json.workspace = true
thiserror.workspace = true
Expand Down
26 changes: 20 additions & 6 deletions hugr-cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
//! Standard command line tools, used by the hugr binary.
pub use clap::Parser;
use clap_stdin::FileOrStdin;
use hugr_core::{extension::ExtensionRegistry, Hugr, HugrView};
use clap_verbosity_flag::{InfoLevel, Verbosity};
use thiserror::Error;
/// We reexport some clap types that are used in the public API.
pub use {clap::Parser, clap_verbosity_flag::Level};

use hugr_core::{extension::ExtensionRegistry, Hugr, HugrView};

/// Validate and visualise a HUGR file.
#[derive(Parser, Debug)]
#[clap(version = "1.0", long_about = None)]
#[clap(about = "Validate a HUGR.")]
#[group(id = "hugr")]
pub struct CmdLineArgs {
input: FileOrStdin,
/// Visualise with mermaid.
Expand All @@ -16,6 +21,9 @@ pub struct CmdLineArgs {
/// Skip validation.
#[arg(short, long, help = "Skip validation.")]
no_validate: bool,
/// Verbosity.
#[command(flatten)]
verbose: Verbosity<InfoLevel>,
// TODO YAML extensions
}

Expand All @@ -38,17 +46,23 @@ pub const VALID_PRINT: &str = "HUGR valid!";

impl CmdLineArgs {
/// Run the HUGR cli and validate against an extension registry.
pub fn run(&self, registry: &ExtensionRegistry) -> Result<(), CliError> {
pub fn run(&self, registry: &ExtensionRegistry) -> Result<Hugr, CliError> {
let mut hugr: Hugr = serde_json::from_reader(self.input.into_reader()?)?;
if self.mermaid {
println!("{}", hugr.mermaid_string());
}

if !self.no_validate {
hugr.update_validate(registry)?;

println!("{}", VALID_PRINT);
if self.verbosity(Level::Info) {
eprintln!("{}", VALID_PRINT);
}
}
Ok(())
Ok(hugr)
}

/// Test whether a `level` message should be output.
pub fn verbosity(&self, level: Level) -> bool {
self.verbose.log_level_filter() >= level
}
}
6 changes: 4 additions & 2 deletions hugr/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use hugr::std_extensions::logic::EXTENSION as LOGICS_EXTENSION;

use hugr::extension::{ExtensionRegistry, PRELUDE};

use hugr_cli::{CmdLineArgs, Parser};
use hugr_cli::{CmdLineArgs, Level, Parser};

fn main() {
let opts = CmdLineArgs::parse();
Expand All @@ -27,7 +27,9 @@ fn main() {
.unwrap();

if let Err(e) = opts.run(&reg) {
eprintln!("{}", e);
if opts.verbosity(Level::Error) {
eprintln!("{}", e);
}
std::process::exit(1);
}
}
22 changes: 20 additions & 2 deletions hugr/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,23 @@ fn test_doesnt_exist(mut cmd: Command) {
#[rstest]
fn test_validate(test_hugr_file: NamedTempFile, mut cmd: Command) {
cmd.arg(test_hugr_file.path());
cmd.assert().success().stdout(contains(VALID_PRINT));
cmd.assert().success().stderr(contains(VALID_PRINT));
}

#[rstest]
fn test_stdin(test_hugr_string: String, mut cmd: Command) {
cmd.write_stdin(test_hugr_string);
cmd.arg("-");

cmd.assert().success().stdout(contains(VALID_PRINT));
cmd.assert().success().stderr(contains(VALID_PRINT));
}

#[rstest]
fn test_stdin_silent(test_hugr_string: String, mut cmd: Command) {
cmd.args(["-", "-q"]);
cmd.write_stdin(test_hugr_string);

cmd.assert().success().stderr(contains(VALID_PRINT).not());
}

#[rstest]
Expand Down Expand Up @@ -91,3 +99,13 @@ fn test_bad_json(mut cmd: Command) {
.failure()
.stderr(contains("Error parsing input"));
}

#[rstest]
fn test_bad_json_silent(mut cmd: Command) {
cmd.write_stdin(r#"{"foo": "bar"}"#);
cmd.args(["-", "-qqq"]);

cmd.assert()
.failure()
.stderr(contains("Error parsing input").not());
}

0 comments on commit 3298a6a

Please sign in to comment.