diff --git a/Cargo.lock b/Cargo.lock index e654fec..e7abb4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -818,7 +818,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hit-cli" -version = "0.5.0" +version = "0.5.1" dependencies = [ "arboard", "array_tool", @@ -835,6 +835,7 @@ dependencies = [ "flatten-json-object", "getopts", "handlebars", + "human-panic", "hyper", "inquire", "insta", @@ -900,6 +901,22 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "human-panic" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80b84a66a325082740043a6c28bbea400c129eac0d3a27673a1de971e44bf1f7" +dependencies = [ + "anstream", + "anstyle", + "backtrace", + "os_info", + "serde", + "serde_derive", + "toml", + "uuid", +] + [[package]] name = "hyper" version = "1.6.0" @@ -1509,6 +1526,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "os_info" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -1988,6 +2016,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2341,11 +2378,26 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml_datetime" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -2354,10 +2406,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap 2.9.0", + "serde", + "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + [[package]] name = "tower" version = "0.5.2" @@ -2481,6 +2542,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +dependencies = [ + "getrandom 0.3.2", +] + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 966ee01..0ca395e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,11 @@ [package] name = "hit-cli" -version = "0.5.0" +version = "0.5.1" edition = "2021" +authors = ["Mehmood S. Deshmukh "] +homepage = "https://usehit.dev" +repository = "https://github.com/meshde/hit-cli" +license-file = "LICENSE" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -20,6 +24,7 @@ edit = "0.1.5" flatten-json-object = "0.6.1" getopts = "0.2.21" handlebars = "5.1.2" +human-panic = "2.0.2" hyper = "1.3.1" inquire = "0.7.5" openapiv3 = "1.0.1" diff --git a/src/cli/mod.rs b/src/cli/mod.rs index b2f63d7..c11bdd7 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -6,6 +6,7 @@ mod run; use crate::core::command::Command as ConfigCommand; use crate::core::config::{CommandType as ConfigCommandType, Config}; +use crate::utils::error::CliError; use clap::{command, Arg, ArgMatches, Command, FromArgMatches as _, Parser, Subcommand}; use clap_complete::CompleteEnv; use convert_case::{Case, Casing}; @@ -129,6 +130,11 @@ pub async fn init() -> ExitCode { }; if let Err(_e) = output { + if let Some(e) = _e.downcast_ref::() { + eprintln!("{}", e); + } else { + panic!("{}", _e); + } ExitCode::FAILURE } else { ExitCode::SUCCESS diff --git a/src/cli/run.rs b/src/cli/run.rs index a816240..838cfc6 100644 --- a/src/cli/run.rs +++ b/src/cli/run.rs @@ -3,6 +3,7 @@ use crate::core::command::Command; use crate::core::config::Config; use crate::core::env::get_env; use crate::core::ephenv::get_ephenvs; +use crate::utils::error::CliError; use crate::utils::http::handle_request; use colored_json; use edit::edit; @@ -31,8 +32,24 @@ pub async fn run( let url = api_call.url.as_str(); - let current_env = get_env().expect("env not set"); - let env_data = config.envs.get(¤t_env).expect("env not recognized"); + let current_env = match get_env() { + Some(e) => e, + None => { + return Err(Box::new(CliError { + message: "env not set".to_string(), + help: None, + })) + } + }; + let env_data = match config.envs.get(¤t_env) { + Some(d) => d, + None => { + return Err(Box::new(CliError { + message: "env not recognized".to_string(), + help: None, + })) + } + }; let ephenv_data = get_ephenvs(); let merged_data = env_data .clone() @@ -76,7 +93,8 @@ pub async fn run( .collect::>(), input, ) - .await?; + .await + .unwrap(); get_app_config().set_prev_request(response.clone()); diff --git a/src/main.rs b/src/main.rs index 92ae9a5..5b129f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,14 @@ mod constants; mod core; mod utils; -use reqwest; +use human_panic; +use std::process; use tokio; #[tokio::main] -async fn main() -> Result<(), reqwest::Error> { - cli::init().await; - Ok(()) +async fn main() -> process::ExitCode { + human_panic::setup_panic!(human_panic::Metadata::new("hit", env!("CARGO_PKG_VERSION")) + .authors("Mehmood S. Deshmukh ") + .homepage("https://github.com/meshde/hit-cli/issues")); + cli::init().await } diff --git a/src/utils/error.rs b/src/utils/error.rs new file mode 100644 index 0000000..c5152dc --- /dev/null +++ b/src/utils/error.rs @@ -0,0 +1,15 @@ +use std::error::Error; +use std::fmt; + +#[derive(Debug)] +pub struct CliError { + pub message: String, + pub help: Option, +} + +impl fmt::Display for CliError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.message) + } +} +impl Error for CliError {} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 3a1385b..ff65772 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,2 +1,3 @@ +pub mod error; pub mod http; pub mod input; diff --git a/tests/fixtures/mod.rs b/tests/fixtures/mod.rs index f9bf17c..7f357e7 100644 --- a/tests/fixtures/mod.rs +++ b/tests/fixtures/mod.rs @@ -27,7 +27,12 @@ impl SetupFixture { "API_URL": "https://staging-api.example.com" } }, - "commands": {} + "commands": { + "get-by-id": { + "method": "GET", + "url": "{{API_URL}}/items/:id", + } + } }); fs::write(&config_path, test_config.to_string()).unwrap(); diff --git a/tests/run_tests.rs b/tests/run_tests.rs new file mode 100644 index 0000000..af3cf0d --- /dev/null +++ b/tests/run_tests.rs @@ -0,0 +1,26 @@ +mod fixtures; +use assert_cmd::prelude::*; +use fixtures::{get_hit_command_for_setup, hit_setup, SetupFixture}; +use rstest::*; + +#[rstest] +fn test_failure_when_env_not_set( + hit_setup: SetupFixture, +) -> Result<(), Box> { + let mut cmd = get_hit_command_for_setup(&hit_setup); + cmd.args(["run", "get-by-id", "--id", "meshde"]); + cmd.assert().failure().stderr("env not set\n"); + + Ok(()) +} + +#[rstest] +fn test_failure_when_env_not_recognized(hit_setup: SetupFixture) -> () { + let mut use_cmd = get_hit_command_for_setup(&hit_setup); + use_cmd.args(["env", "use", "something"]); + use_cmd.assert().success(); + + let mut cmd = get_hit_command_for_setup(&hit_setup); + cmd.args(["run", "get-by-id", "--id", "meshde"]); + cmd.assert().failure().stderr("env not recognized\n"); +}