From 24e15e81595bff5c071e4644d55ad42c877c752f Mon Sep 17 00:00:00 2001 From: Michael Chernicoff Date: Mon, 20 May 2024 10:20:32 -0400 Subject: [PATCH 1/8] chore: Small fixes; still panics with no argument --- hipcheck/src/cli.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hipcheck/src/cli.rs b/hipcheck/src/cli.rs index 881d3af0..afab794e 100644 --- a/hipcheck/src/cli.rs +++ b/hipcheck/src/cli.rs @@ -79,6 +79,12 @@ pub enum Commands { Schema(SchemaArgs), } +impl Default for Commands { + fn default() -> Commands { + Commands::Help(HelpArgs { command: None }) + } +} + #[derive(Debug, clap::Args)] pub struct CheckArgs { /// print help text From 7073cd85ed7a147e3446988e0215e964da267c2b Mon Sep 17 00:00:00 2001 From: Michael Chernicoff Date: Tue, 21 May 2024 11:27:32 -0400 Subject: [PATCH 2/8] feat(cli): Adds simple hc doctor command to print all three directory locations --- hipcheck/src/cli.rs | 3 +++ hipcheck/src/main.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/hipcheck/src/cli.rs b/hipcheck/src/cli.rs index afab794e..fd587dbd 100644 --- a/hipcheck/src/cli.rs +++ b/hipcheck/src/cli.rs @@ -71,6 +71,9 @@ pub enum Commands { /// Analyzes a repository or pull/merge request #[command(disable_help_subcommand = true)] Check(CheckArgs), + /// Check if Hipcheck is ready to execute and reports status to user + #[command(disable_help_subcommand = true)] + Doctor, /// Print help information, optionally for a given subcommand #[command(disable_help_subcommand = true)] Help(HelpArgs), diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index 48d4d816..59ffde64 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -217,6 +217,13 @@ impl CliArgs { Some(HelpCommand::Check) => print_check_help(), Some(HelpCommand::Schema) => print_schema_help(), }, + Some(Commands::Doctor) => { + print_readiness( + home_dir.as_deref(), + config_path.as_deref(), + data_path.as_deref(), + ); + } Some(Commands::Check(args)) => { if args.extra_help { print_check_help(); @@ -460,6 +467,35 @@ fn print_pypi_schema() -> ! { print_missing() } +fn print_readiness( + home_dir: Option<&Path>, + config_path: Option<&Path>, + data_path: Option<&Path>, +) -> ! { + let hipcheck_home = resolve_home(home_dir); + + let hipcheck_config = resolve_config(config_path); + + let hipcheck_data = resolve_data(data_path); + + let exit_code = match (hipcheck_home, hipcheck_config, hipcheck_data) { + (Ok(home_path), Ok(config_path), Ok(data_path)) => { + println!( + "{}, {}, {}", + home_path.display(), + config_path.display(), + data_path.display() + ); + Outcome::Ok.exit_code() + } + _ => { + //print_error(&err); + Outcome::Err.exit_code() + } + }; + + exit(exit_code); +} /// Print the current home directory for Hipcheck. /// /// Exits `Ok` if home directory is specified, `Err` otherwise. From e403f6f0dc9cf27ae66e3b1318a30a80234f0ade Mon Sep 17 00:00:00 2001 From: Michael Chernicoff Date: Tue, 21 May 2024 11:48:13 -0400 Subject: [PATCH 3/8] test(cli): Adds test for CLI commands --- hipcheck/src/main.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index 59ffde64..9d41a337 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -788,3 +788,14 @@ impl Outcome { } } } + +#[cfg(test)] +mod tests { + use super::Args; + use clap::CommandFactory; + + #[test] + fn verify_cli() { + Args::command().debug_assert() + } +} From 4571ee8b5dda1269cc62a750482298b399979d3f Mon Sep 17 00:00:00 2001 From: Michael Chernicoff Date: Tue, 21 May 2024 14:00:47 -0400 Subject: [PATCH 4/8] feat(cli): Add check for GitHub token --- hipcheck/src/main.rs | 48 +++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index 9d41a337..3eff9e64 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -44,6 +44,7 @@ use clap::Parser as _; use cli::CheckCommand; use cli::HelpCommand; use cli::SchemaCommand; +use dotenv::var; use env_logger::Builder; use env_logger::Env; use schemars::schema_for; @@ -472,26 +473,44 @@ fn print_readiness( config_path: Option<&Path>, data_path: Option<&Path>, ) -> ! { + let mut failed = false; + let hipcheck_home = resolve_home(home_dir); + match hipcheck_home { + Ok(path_buffer) => println!("Hipcheck home directory: {}", path_buffer.display()), + Err(err) => { + failed = true; + print_error(&err); + } + } let hipcheck_config = resolve_config(config_path); + match hipcheck_config { + Ok(path_buffer) => println!("Hipcheck config directory: {}", path_buffer.display()), + Err(err) => { + failed = true; + print_error(&err); + } + } let hipcheck_data = resolve_data(data_path); - - let exit_code = match (hipcheck_home, hipcheck_config, hipcheck_data) { - (Ok(home_path), Ok(config_path), Ok(data_path)) => { - println!( - "{}, {}, {}", - home_path.display(), - config_path.display(), - data_path.display() - ); - Outcome::Ok.exit_code() - } - _ => { - //print_error(&err); - Outcome::Err.exit_code() + match hipcheck_data { + Ok(path_buffer) => println!("Hipcheck data directory: {}", path_buffer.display()), + Err(err) => { + failed = true; + print_error(&err); } + } + + match var("HC_GITHUB_TOKEN") { + Ok(_) => println!("HC_GITHUB_TOKEN system environment variable found."), + Err(_) => println!("Missing HC_GITHUB_TOKEN system environment variable. Some analyses will not run without this token set."), + } + + let exit_code = if failed { + Outcome::Err.exit_code() + } else { + Outcome::Ok.exit_code() }; exit(exit_code); @@ -790,6 +809,7 @@ impl Outcome { } #[cfg(test)] +/// Test CLI mod tests { use super::Args; use clap::CommandFactory; From eda752c966ed3b2f9530fbb518083fc83b1b7f9b Mon Sep 17 00:00:00 2001 From: Michael Chernicoff Date: Wed, 22 May 2024 08:39:27 -0400 Subject: [PATCH 5/8] feat(cli): Adds git and npm checks. Removes deprecated CLI flags. Changes command name to hc ready and adds help text. --- hipcheck/src/cli.rs | 16 +---- hipcheck/src/main.rs | 144 ++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 105 deletions(-) diff --git a/hipcheck/src/cli.rs b/hipcheck/src/cli.rs index fd587dbd..973766dd 100644 --- a/hipcheck/src/cli.rs +++ b/hipcheck/src/cli.rs @@ -7,25 +7,13 @@ #[command(about, disable_help_flag=true, disable_version_flag=true, long_about=None)] pub struct Args { /// print help text - #[arg(name="extra-help", short = 'h', long = "help")] + #[arg(name = "extra-help", short = 'h', long = "help")] pub extra_help: bool, /// print version information #[arg(short = 'V', long, global = true)] pub version: bool, - /// print the home directory for Hipcheck - #[arg(long = "print-home", global = true)] - pub print_home: bool, - - /// print the config file path for Hipcheck - #[arg(long = "print-config", global = true)] - pub print_config: bool, - - /// print the data folder path for Hipcheck - #[arg(long = "print-data", global = true)] - pub print_data: bool, - /// silences progress reporting #[arg(short = 'q', long = "quiet", global = true)] pub verbosity: bool, @@ -73,7 +61,7 @@ pub enum Commands { Check(CheckArgs), /// Check if Hipcheck is ready to execute and reports status to user #[command(disable_help_subcommand = true)] - Doctor, + Ready, /// Print help information, optionally for a given subcommand #[command(disable_help_subcommand = true)] Help(HelpArgs), diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index 3eff9e64..d07a16ef 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -31,6 +31,7 @@ use crate::analysis::session::Check; use crate::analysis::session::CheckType; use crate::analysis::session::Session; use crate::cli::Commands; +use crate::command_util::DependentProgram; use crate::context::Context as _; use crate::error::Error; use crate::error::Result; @@ -179,10 +180,6 @@ impl CliArgs { path.map(PathBuf::from) }; - if args.print_home { - print_home(home_dir.as_deref()); - } - // PANIC: Optional but has a default value, so unwrap() should never panic. let color_choice = { let color: &String = &args.color.unwrap(); @@ -194,19 +191,11 @@ impl CliArgs { config.map(PathBuf::from) }; - if args.print_config { - print_config(config_path.as_deref()); - } - let data_path = { let data: Option<&String> = args.data.as_ref(); data.map(PathBuf::from) }; - if args.print_data { - print_data(data_path.as_deref()); - } - let format = Format::use_json(args.json); // initialized later when the "check" subcommand is called @@ -218,7 +207,7 @@ impl CliArgs { Some(HelpCommand::Check) => print_check_help(), Some(HelpCommand::Schema) => print_schema_help(), }, - Some(Commands::Doctor) => { + Some(Commands::Ready) => { print_readiness( home_dir.as_deref(), config_path.as_deref(), @@ -315,9 +304,6 @@ impl CliArgs { const GLOBAL_HELP: &str = "\ FLAGS: -V, --version print version information - --print-config print the config file path for Hipcheck - --print-data print the data folder path for Hipcheck - --print-home print the home directory for Hipcheck OPTIONS (CONFIGURATION): -c, --config path to the configuration file [default: ./Hipcheck.toml] @@ -344,6 +330,7 @@ USAGE: TASKS: check analyzes a repository or pull/merge request + ready print a report of whether or not Hipcheck is ready to run schema print the schema for JSON-format output for a specified subtarget help [] print help information, optionally for a given subcommand @@ -468,6 +455,8 @@ fn print_pypi_schema() -> ! { print_missing() } +/// Prints a "readiness report" for Hipcheck, indicating if any dependent programs are missing or our of date +/// or if any necessary folders or files are missing. It then returns a final readiness status. fn print_readiness( home_dir: Option<&Path>, config_path: Option<&Path>, @@ -475,6 +464,43 @@ fn print_readiness( ) -> ! { let mut failed = false; + // Check that git is installed and that its version is up to date + // Print the version number either way + let git_check = data::git::get_git_version(); + match git_check { + Ok(git_version) => match DependentProgram::Git.check_version(&git_version) { + // No need to check Boolean value, because currentl check_version() only returns Ok(true) or Err() + Ok(_) => print!("Found installed {}", git_version), + Err(err) => { + print_error(&err); + failed = true; + } + }, + Err(err) => { + print_error(&err); + failed = true; + } + } + + // Check that git is installed and that its version is up to date + // Print the version number either way + let npm_check = data::npm::get_npm_version(); + match npm_check { + Ok(npm_version) => match DependentProgram::Npm.check_version(&npm_version) { + // No need to check Boolean value, because currently check_version() only returns Ok(true) or Err() + Ok(_) => print!("Found installed NPM version {}", npm_version), + Err(err) => { + print_error(&err); + failed = true; + } + }, + Err(err) => { + print_error(&err); + failed = true; + } + } + + // Check that the Hipcheck home folder is findable let hipcheck_home = resolve_home(home_dir); match hipcheck_home { Ok(path_buffer) => println!("Hipcheck home directory: {}", path_buffer.display()), @@ -484,6 +510,7 @@ fn print_readiness( } } + // Check that the Hipcheck config TOML exists in the designated location let hipcheck_config = resolve_config(config_path); match hipcheck_config { Ok(path_buffer) => println!("Hipcheck config directory: {}", path_buffer.display()), @@ -493,6 +520,7 @@ fn print_readiness( } } + // Check that Hipcheck data folder is findable let hipcheck_data = resolve_data(data_path); match hipcheck_data { Ok(path_buffer) => println!("Hipcheck data directory: {}", path_buffer.display()), @@ -502,76 +530,22 @@ fn print_readiness( } } + // Check that a GitHub token has been provided as an environment variable + // This does not check if the token is valid or not + // The absence of a token does not trigger the failure state for the readiness check, because + // Hipcheck *can* run without a token, but some analyses will not. match var("HC_GITHUB_TOKEN") { Ok(_) => println!("HC_GITHUB_TOKEN system environment variable found."), Err(_) => println!("Missing HC_GITHUB_TOKEN system environment variable. Some analyses will not run without this token set."), } - let exit_code = if failed { - Outcome::Err.exit_code() + if failed { + println!("One or more dependencies or configuration settings are missing. Hipcheck is not ready to run."); } else { - Outcome::Ok.exit_code() - }; - - exit(exit_code); -} -/// Print the current home directory for Hipcheck. -/// -/// Exits `Ok` if home directory is specified, `Err` otherwise. -fn print_home(path: Option<&Path>) -> ! { - let hipcheck_home = resolve_home(path); - - let exit_code = match hipcheck_home { - Ok(path_buffer) => { - println!("{}", path_buffer.display()); - Outcome::Ok.exit_code() - } - Err(err) => { - print_error(&err); - Outcome::Err.exit_code() - } - }; - - exit(exit_code); -} - -/// Print the current config path for Hipcheck. -/// -/// Exits `Ok` if config path is specified, `Err` otherwise. -fn print_config(config_path: Option<&Path>) -> ! { - let hipcheck_config = resolve_config(config_path); - - let exit_code = match hipcheck_config { - Ok(path_buffer) => { - println!("{}", path_buffer.display()); - Outcome::Ok.exit_code() - } - Err(err) => { - print_error(&err); - Outcome::Err.exit_code() - } - }; - - exit(exit_code); -} - -/// Print the current data folder path for Hipcheck. -/// -/// Exits `Ok` if config path is specified, `Err` otherwise. -fn print_data(data_path: Option<&Path>) -> ! { - let hipcheck_data = resolve_data(data_path); - - let exit_code = match hipcheck_data { - Ok(path_buffer) => { - println!("{}", path_buffer.display()); - Outcome::Ok.exit_code() - } - Err(err) => { - print_error(&err); - Outcome::Err.exit_code() - } - }; + println!("Hipcheck is ready to run!"); + } + let exit_code = Outcome::Err.exit_code(); exit(exit_code); } @@ -807,15 +781,3 @@ impl Outcome { } } } - -#[cfg(test)] -/// Test CLI -mod tests { - use super::Args; - use clap::CommandFactory; - - #[test] - fn verify_cli() { - Args::command().debug_assert() - } -} From 4b64fbecb6f78e48f85592e4f7ca1292e1baa6ef Mon Sep 17 00:00:00 2001 From: Michael Chernicoff Date: Wed, 22 May 2024 11:05:37 -0400 Subject: [PATCH 6/8] chore(cli): hc ready now prints Hipcheck version --- hipcheck/src/main.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index d07a16ef..b39f0429 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -464,6 +464,16 @@ fn print_readiness( ) -> ! { let mut failed = false; + // Print Hipcheck version + let raw_version = env!("CARGO_PKG_VERSION", "can't find Hipcheck package version"); + + let version_text = format!( + "{} {}", + env!("CARGO_PKG_NAME"), + version::get_version(raw_version).unwrap() + ); + println!("{}", version_text); + // Check that git is installed and that its version is up to date // Print the version number either way let git_check = data::git::get_git_version(); From 97b14673775357f80045779d3aae6419134e84ec Mon Sep 17 00:00:00 2001 From: Michael Chernicoff Date: Fri, 24 May 2024 10:19:13 -0400 Subject: [PATCH 7/8] fix: Fixes language about config file --- hipcheck/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index b39f0429..fce84ff7 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -523,7 +523,7 @@ fn print_readiness( // Check that the Hipcheck config TOML exists in the designated location let hipcheck_config = resolve_config(config_path); match hipcheck_config { - Ok(path_buffer) => println!("Hipcheck config directory: {}", path_buffer.display()), + Ok(path_buffer) => println!("Hipcheck config file: {}", path_buffer.display()), Err(err) => { failed = true; print_error(&err); From 6327087be3a5afb0a8028632f7014256aa392ecc Mon Sep 17 00:00:00 2001 From: Andrew Lilley Brinker Date: Thu, 30 May 2024 07:55:34 -0700 Subject: [PATCH 8/8] chore: Mark `ready` command as experimental. This is just to make it clear we're not committing to stability for it yet. Signed-off-by: Andrew Lilley Brinker --- hipcheck/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index fce84ff7..0765fce3 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -330,7 +330,7 @@ USAGE: TASKS: check analyzes a repository or pull/merge request - ready print a report of whether or not Hipcheck is ready to run + ready print a report of whether or not Hipcheck is ready to run (experimental) schema print the schema for JSON-format output for a specified subtarget help [] print help information, optionally for a given subcommand @@ -473,7 +473,7 @@ fn print_readiness( version::get_version(raw_version).unwrap() ); println!("{}", version_text); - + // Check that git is installed and that its version is up to date // Print the version number either way let git_check = data::git::get_git_version();