Adding --glob option

This commit is contained in:
Fabrice Reix 2021-12-04 11:15:46 +01:00 committed by Fabrice Reix
parent 5fd0751bd0
commit fba4357182
5 changed files with 80 additions and 13 deletions

7
Cargo.lock generated
View File

@ -356,6 +356,12 @@ dependencies = [
"wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.1.8"
@ -391,6 +397,7 @@ dependencies = [
"curl",
"encoding",
"float-cmp",
"glob",
"hex",
"hex-literal",
"hurl_core",

View File

@ -166,6 +166,11 @@ All the input files are executed independently. The result of one file does not
Set root filesystem to import files in Hurl. This is used for both files in multipart form data and request body.
When this is not explicitly defined, the files are relative to the current directory in which Hurl is running.
## --glob <glob> {#glob}
Specify input files that match the given blob.
Multiple glob flags may be used.
### -h, --help {#help}
Usage help. This lists all current command line options with a short description.

View File

@ -26,6 +26,7 @@ colored = "2.0.0"
curl = "0.4.41"
encoding = "0.2.33"
float-cmp = "0.9.0"
glob = "0.3.0"
hex = "0.4.3"
hex-literal = "0.3.4"
hurl_core = { version = "1.5.0-snapshot", path = "../hurl_core" }

View File

@ -39,6 +39,7 @@ pub struct CliOptions {
pub fail_fast: bool,
pub file_root: Option<String>,
pub follow_location: bool,
pub glob_files: Vec<String>,
pub html_dir: Option<PathBuf>,
pub ignore_asserts: bool,
pub include: bool,
@ -132,6 +133,14 @@ pub fn app() -> App<'static, 'static> {
.long("location")
.help("Follow redirects"),
)
.arg(
clap::Arg::with_name("glob")
.long("glob")
.value_name("GLOB")
.multiple(true)
.number_of_values(1)
.help("Specify input files that match the given blob. Multiple glob flags may be used."),
)
.arg(
clap::Arg::with_name("html")
.long("html")
@ -319,7 +328,7 @@ pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
let fail_fast = !matches.is_present("fail_at_end");
let file_root = matches.value_of("file_root").map(|value| value.to_string());
let follow_location = matches.is_present("follow_location");
let glob_files = match_glob_files(matches.clone())?;
// deprecated
// Support --report-html and --html only for the current version
if matches.is_present("html") {
@ -414,6 +423,7 @@ pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
fail_fast,
file_root,
follow_location,
glob_files,
html_dir,
ignore_asserts,
include,
@ -507,3 +517,39 @@ fn variables(matches: ArgMatches) -> Result<HashMap<String, Value>, CliError> {
Ok(variables)
}
pub fn match_glob_files(matches: ArgMatches) -> Result<Vec<String>, CliError> {
let mut filenames = vec![];
if matches.is_present("glob") {
let exprs: Vec<&str> = matches.values_of("glob").unwrap().collect();
for expr in exprs {
eprintln!("expr={}", expr);
let paths = match glob::glob(expr) {
Ok(paths) => paths,
Err(_) => {
return Err(CliError {
message: "Failed to read glob pattern".to_string(),
})
}
};
for entry in paths {
match entry {
Ok(path) => match path.into_os_string().into_string() {
Ok(filename) => filenames.push(filename),
Err(_) => {
return Err(CliError {
message: "Failed to read glob pattern".to_string(),
})
}
},
Err(_) => {
return Err(CliError {
message: "Failed to read glob pattern".to_string(),
})
}
}
}
}
}
Ok(filenames)
}

View File

@ -255,10 +255,21 @@ fn main() {
let matches = app.clone().get_matches();
init_colored();
let mut filenames = match matches.values_of("INPUT") {
None => vec![],
Some(v) => v.collect(),
let verbose = matches.is_present("verbose") || matches.is_present("interactive");
let log_verbose = cli::make_logger_verbose(verbose);
let color = cli::output_color(matches.clone());
let log_error_message = cli::make_logger_error_message(color);
let cli_options = unwrap_or_exit(&log_error_message, cli::parse_options(matches.clone()));
let mut filenames = vec![];
if let Some(values) = matches.values_of("INPUT") {
for value in values {
filenames.push(value.to_string());
}
};
for filename in &cli_options.glob_files {
filenames.push(filename.to_string());
}
if filenames.is_empty() && atty::is(Stream::Stdin) {
if app.clone().print_help().is_err() {
@ -267,18 +278,12 @@ fn main() {
println!();
std::process::exit(EXIT_ERROR_COMMANDLINE);
} else if filenames.is_empty() {
filenames.push("-");
filenames.push("-".to_string());
}
let current_dir_buf = std::env::current_dir().unwrap();
let current_dir = current_dir_buf.as_path();
let verbose = matches.is_present("verbose") || matches.is_present("interactive");
let log_verbose = cli::make_logger_verbose(verbose);
let color = cli::output_color(matches.clone());
let log_error_message = cli::make_logger_error_message(color);
let cli_options = unwrap_or_exit(&log_error_message, cli::parse_options(matches.clone()));
let mut hurl_results = vec![];
let cookies_output_file = match cli_options.cookie_output_file.clone() {
@ -389,7 +394,7 @@ fn main() {
cli::log_info("no response has been received");
}
} else {
let source = if *filename == "-" {
let source = if filename.as_str() == "-" {
"".to_string()
} else {
format!("for file {}", filename).to_string()
@ -438,7 +443,10 @@ fn main() {
);
for filename in filenames {
unwrap_or_exit(&log_error_message, format_html(filename, dir_path.clone()));
unwrap_or_exit(
&log_error_message,
format_html(filename.as_str(), dir_path.clone()),
);
}
}