Skip to content

Commit

Permalink
Flag for persisting variables
Browse files Browse the repository at this point in the history
Add --persist flag which will result in changed variables being saved to
the variables-file.
  • Loading branch information
agraven committed Oct 22, 2023
1 parent 186114b commit 9c8fdad
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 2 deletions.
8 changes: 8 additions & 0 deletions packages/hurl/src/cli/options/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,11 @@ pub fn very_verbose() -> clap::Arg {
.help("Turn on verbose output, including HTTP response and libcurl logs")
.action(ArgAction::SetTrue)
}

pub fn persist() -> clap::Arg {
clap::Arg::new("persist")
.long("persist")
.short('p')
.help("Persist changed variables in the variable file")
.action(ArgAction::SetTrue)
}
8 changes: 8 additions & 0 deletions packages/hurl/src/cli/options/matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ pub fn path_as_is(arg_matches: &ArgMatches) -> bool {
has_flag(arg_matches, "path_as_is")
}

pub fn persist(arg_matches: &ArgMatches) -> bool {
has_flag(arg_matches, "persist")
}

pub fn progress_bar(arg_matches: &ArgMatches) -> bool {
let verbose = verbose(arg_matches) || very_verbose(arg_matches);
test(arg_matches)
Expand Down Expand Up @@ -381,6 +385,10 @@ pub fn variables(matches: &ArgMatches) -> Result<HashMap<String, Value>, Options
Ok(variables)
}

pub fn variables_file(arg_matches: &ArgMatches) -> Option<String> {
get_string(arg_matches, "varables_file")
}

pub fn verbose(arg_matches: &ArgMatches) -> bool {
has_flag(arg_matches, "verbose")
}
Expand Down
9 changes: 8 additions & 1 deletion packages/hurl/src/cli/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub struct Options {
pub output: Option<String>,
pub output_type: OutputType,
pub path_as_is: bool,
pub persist: bool,
pub progress_bar: bool,
pub proxy: Option<String>,
pub resolves: Vec<String>,
Expand All @@ -78,6 +79,7 @@ pub struct Options {
pub user: Option<String>,
pub user_agent: Option<String>,
pub variables: HashMap<String, Value>,
pub variables_file: Option<String>,
pub verbose: bool,
pub very_verbose: bool,
}
Expand Down Expand Up @@ -200,6 +202,7 @@ pub fn parse() -> Result<Options, OptionsError> {
.arg(commands::noproxy())
.arg(commands::output())
.arg(commands::path_as_is())
.arg(commands::persist())
.arg(commands::proxy())
.arg(commands::report_html())
.arg(commands::report_junit())
Expand All @@ -220,7 +223,7 @@ pub fn parse() -> Result<Options, OptionsError> {
let arg_matches = command.try_get_matches_from_mut(env::args_os())?;
let opts = parse_matches(&arg_matches)?;

// If we've no file input (either from the standard input or from the command line arguments),
// If don't have file input (either from the standard input or from the command line arguments),
// we just print help and exit.
if opts.input_files.is_empty() {
let help = command.render_help().to_string();
Expand Down Expand Up @@ -264,6 +267,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result<Options, OptionsError> {
let no_proxy = matches::no_proxy(arg_matches);
let progress_bar = matches::progress_bar(arg_matches);
let path_as_is = matches::path_as_is(arg_matches);
let persist = matches::persist(arg_matches);
let proxy = matches::proxy(arg_matches);
let output = matches::output(arg_matches);
let output_type = matches::output_type(arg_matches);
Expand All @@ -278,6 +282,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result<Options, OptionsError> {
let user = matches::user(arg_matches);
let user_agent = matches::user_agent(arg_matches);
let variables = matches::variables(arg_matches)?;
let variables_file = matches::variables_file(arg_matches);
let verbose = matches::verbose(arg_matches);
let very_verbose = matches::very_verbose(arg_matches);
Ok(Options {
Expand Down Expand Up @@ -308,6 +313,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result<Options, OptionsError> {
max_redirect,
no_proxy,
path_as_is,
persist,
progress_bar,
proxy,
output,
Expand All @@ -323,6 +329,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result<Options, OptionsError> {
user,
user_agent,
variables,
variables_file,
verbose,
very_verbose,
})
Expand Down
39 changes: 38 additions & 1 deletion packages/hurl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
mod cli;

use std::collections::HashMap;
use std::io::prelude::*;
use std::path::Path;
use std::time::Instant;
Expand Down Expand Up @@ -50,7 +51,7 @@ struct HurlRun {
fn main() {
init_colored();

let opts = match cli::options::parse() {
let mut opts = match cli::options::parse() {
Ok(v) => v,
Err(e) => match e {
OptionsError::Info(message) => {
Expand Down Expand Up @@ -132,6 +133,8 @@ fn main() {
unwrap_or_exit(result, EXIT_ERROR_RUNTIME, &base_logger);
}

opts.variables = hurl_result.variables.clone();

let run = HurlRun {
content,
filename: filename.to_string(),
Expand Down Expand Up @@ -164,6 +167,13 @@ fn main() {
unwrap_or_exit(result, EXIT_ERROR_UNDEFINED, &base_logger);
}

if opts.persist {
let variables_file = opts.variables_file.as_deref().unwrap_or("vars");
base_logger.debug(format!("Writing variables to {variables_file}").as_str());
let result = create_variables_file(&opts.variables, &variables_file);
unwrap_or_exit(result, EXIT_ERROR_UNDEFINED, &base_logger);
}

if opts.test {
let duration = start.elapsed().as_millis();
let summary = get_summary(&runs, duration);
Expand Down Expand Up @@ -309,6 +319,33 @@ fn create_cookies_file(runs: &[HurlRun], filename: &str) -> Result<(), cli::CliE
Ok(())
}

fn create_variables_file(
variables: &HashMap<String, runner::Value>,
filename: &str,
) -> Result<(), cli::CliError> {
let mut file = match std::fs::File::create(filename) {
Err(why) => {
return Err(cli::CliError {
message: format!("Issue writing to {filename}: {why:?}"),
});
}
Ok(file) => file,
};
let mut s = String::new();
for (key, value) in variables {
s.push_str(key);
s.push('=');
s.push_str(&value.to_string());
s.push('\n');
}
if let Err(why) = file.write_all(s.as_bytes()) {
return Err(cli::CliError {
message: format!("Issue writing to {filename}: {why:?}"),
});
}
Ok(())
}

/// Returns the text summary of this Hurl runs.
fn get_summary(runs: &[HurlRun], duration: u128) -> String {
let total = runs.len();
Expand Down
2 changes: 2 additions & 0 deletions packages/hurl/src/runner/core.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
/*
* Hurl (https://hurl.dev)
* Copyright (C) 2023 Orange
Expand Down Expand Up @@ -28,6 +29,7 @@ pub struct HurlResult {
pub time_in_ms: u128,
pub success: bool,
pub cookies: Vec<Cookie>,
pub variables: HashMap<String, Value>,
pub timestamp: i64,
}

Expand Down
1 change: 1 addition & 0 deletions packages/hurl/src/runner/hurl_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ pub fn run(
success,
cookies,
timestamp,
variables,
})
}

Expand Down

0 comments on commit 9c8fdad

Please sign in to comment.