Update clap 3.2.4.

This commit is contained in:
jcamiel 2022-06-14 21:56:29 +02:00 committed by Fabrice Reix
parent 56b1b13bad
commit aa78be771a
9 changed files with 147 additions and 93 deletions

30
Cargo.lock generated
View File

@ -139,15 +139,15 @@ dependencies = [
[[package]]
name = "clap"
version = "3.1.18"
version = "3.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b"
checksum = "6d20de3739b4fb45a17837824f40aa1769cc7655d7a83e68739a77fe7b30c87a"
dependencies = [
"atty",
"bitflags",
"clap_lex",
"indexmap",
"lazy_static",
"once_cell",
"strsim",
"termcolor",
"textwrap",
@ -155,9 +155,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.2.0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"
dependencies = [
"os_str_bytes",
]
@ -351,13 +351,13 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
@ -582,6 +582,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
[[package]]
name = "once_cell"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
[[package]]
name = "openssl-probe"
version = "0.1.5"
@ -882,7 +888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
@ -976,6 +982,12 @@ version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"

View File

@ -21,7 +21,7 @@ atty = "0.2.14"
base64 = "0.13.0"
brotli = "3.3.4"
chrono = "0.4.19"
clap = { version = "3.1.18", features = ["cargo"] }
clap = { version = "3.2.4", features = ["cargo"] }
colored = "2.0.0"
curl = "0.4.43"
encoding = "0.2.33"

View File

@ -35,6 +35,7 @@ pub mod interactive;
mod logger;
mod options;
mod variables;
pub use self::options::{get_strings, has_flag};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CliError {

View File

@ -23,7 +23,7 @@ use std::path::{Path, PathBuf};
use std::time::Duration;
use atty::Stream;
use clap::{AppSettings, ArgMatches, Command};
use clap::{AppSettings, ArgAction, ArgMatches, Command};
use crate::cli;
use crate::cli::CliError;
@ -80,7 +80,7 @@ pub fn app(version: &str) -> Command {
clap::Arg::new("INPUT")
.help("Sets the input file to use")
.required(false)
.multiple_occurrences(true),
.action(ArgAction::Append),
)
.arg(
clap::Arg::new("cacert_file")
@ -123,7 +123,6 @@ pub fn app(version: &str) -> Command {
clap::Arg::new("fail_at_end")
.long("fail-at-end")
.help("Fail at end")
.takes_value(false),
)
.arg(
clap::Arg::new("file_root")
@ -142,7 +141,7 @@ pub fn app(version: &str) -> Command {
clap::Arg::new("glob")
.long("glob")
.value_name("GLOB")
.multiple_occurrences(true)
.action(ArgAction::Append)
.number_of_values(1)
.help("Specify input files that match the given blob. Multiple glob flags may be used."),
)
@ -280,7 +279,7 @@ pub fn app(version: &str) -> Command {
clap::Arg::new("variable")
.long("variable")
.value_name("NAME=VALUE")
.multiple_occurrences(true)
.action(ArgAction::Append)
.number_of_values(1)
.help("Define a variable")
.takes_value(true),
@ -301,20 +300,20 @@ pub fn app(version: &str) -> Command {
}
pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
let cacert_file = match matches.value_of("cacert_file") {
let cacert_file = match get_string(&matches, "cacert_file") {
None => None,
Some(filename) => {
if !Path::new(filename).is_file() {
if !Path::new(&filename).is_file() {
let message = format!("File {} does not exist", filename);
return Err(CliError { message });
} else {
Some(filename.to_string())
Some(filename)
}
}
};
let color = output_color(matches.clone());
let compressed = matches.is_present("compressed");
let connect_timeout = match matches.value_of("connect_timeout") {
let compressed = has_flag(&matches, "compressed");
let connect_timeout = match get_string(&matches, "connect_timeout") {
None => ClientOptions::default().connect_timeout,
Some(s) => match s.parse::<u64>() {
Ok(n) => Duration::from_secs(n),
@ -325,19 +324,16 @@ pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
}
},
};
let cookie_input_file = matches
.value_of("cookies_input_file")
.map(|x| x.to_string());
let cookie_output_file = matches
.value_of("cookies_output_file")
.map(|x| x.to_string());
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 cookie_input_file = get_string(&matches, "cookies_input_file");
let cookie_output_file = get_string(&matches, "cookies_output_file");
let fail_fast = !has_flag(&matches, "fail_at_end");
let file_root = get_string(&matches, "file_root");
let follow_location = has_flag(&matches, "follow_location");
let glob_files = match_glob_files(&matches)?;
let report_html = matches.value_of("report_html");
let report_html = get_string(&matches, "report_html");
let html_dir = if let Some(dir) = report_html {
let path = Path::new(dir);
let path = Path::new(&dir);
if !path.exists() {
match std::fs::create_dir(path) {
Err(_) => {
@ -357,14 +353,12 @@ pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
} else {
None
};
let ignore_asserts = matches.is_present("ignore_asserts");
let include = matches.is_present("include");
let insecure = matches.is_present("insecure");
let interactive = matches.is_present("interactive");
let junit_file = matches
.value_of("junit")
.map(|filename| filename.to_string());
let max_redirect = match matches.value_of("max_redirects") {
let ignore_asserts = has_flag(&matches, "ignore_asserts");
let include = has_flag(&matches, "include");
let insecure = has_flag(&matches, "insecure");
let interactive = has_flag(&matches, "interactive");
let junit_file = get_string(&matches, "junit");
let max_redirect = match get_string(&matches, "max_redirects").as_deref() {
None => Some(50),
Some("-1") => None,
Some(s) => match s.parse::<usize>() {
@ -376,21 +370,20 @@ pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
}
},
};
let no_proxy = matches.value_of("proxy").map(|x| x.to_string());
let output = matches
.value_of("output")
.map(|filename| filename.to_string());
let output_type = if matches.is_present("json") {
let no_proxy = get_string(&matches, "proxy");
let output = get_string(&matches, "output");
let test = has_flag(&matches, "test");
let output_type = if has_flag(&matches, "json") {
OutputType::Json
} else if matches.is_present("no_output") || matches.is_present("test") {
} else if has_flag(&matches, "no_output") || test {
OutputType::NoOutput
} else {
OutputType::ResponseBody
};
let progress = matches.is_present("progress") || matches.is_present("test");
let proxy = matches.value_of("proxy").map(|x| x.to_string());
let summary = matches.is_present("summary") || matches.is_present("test");
let timeout = match matches.value_of("max_time") {
let progress = has_flag(&matches, "progress") || test;
let proxy = get_string(&matches, "proxy");
let summary = has_flag(&matches, "summary") || test;
let timeout = match get_string(&matches, "max_time") {
None => ClientOptions::default().timeout,
Some(s) => match s.parse::<u64>() {
Ok(n) => Duration::from_secs(n),
@ -402,10 +395,10 @@ pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
},
};
let to_entry = to_entry(matches.clone())?;
let user = matches.value_of("user").map(|x| x.to_string());
let user_agent = matches.value_of("user_agent").map(|x| x.to_string());
let user = get_string(&matches, "user");
let user_agent = get_string(&matches, "user_agent");
let variables = variables(matches.clone())?;
let verbose = matches.is_present("verbose") || matches.is_present("interactive");
let verbose = has_flag(&matches, "verbose") || has_flag(&matches, "interactive");
Ok(CliOptions {
cacert_file,
@ -441,9 +434,9 @@ pub fn parse_options(matches: ArgMatches) -> Result<CliOptions, CliError> {
}
pub fn output_color(matches: ArgMatches) -> bool {
if matches.is_present("color") {
if has_flag(&matches, "color") {
true
} else if matches.is_present("no_color") {
} else if has_flag(&matches, "no_color") {
false
} else {
atty::is(Stream::Stdout)
@ -451,7 +444,7 @@ pub fn output_color(matches: ArgMatches) -> bool {
}
fn to_entry(matches: ArgMatches) -> Result<Option<usize>, CliError> {
match matches.value_of("to_entry") {
match get_string(&matches, "to_entry") {
Some(value) => match value.parse() {
Ok(v) => Ok(Some(v)),
Err(_) => Err(CliError {
@ -474,8 +467,8 @@ fn variables(matches: ArgMatches) -> Result<HashMap<String, Value>, CliError> {
}
}
if let Some(filename) = matches.value_of("variables_file") {
let path = std::path::Path::new(filename);
if let Some(filename) = get_string(&matches, "variables_file") {
let path = Path::new(&filename);
if !path.exists() {
return Err(CliError {
message: format!("Properties file {} does not exist", path.display()),
@ -502,10 +495,9 @@ fn variables(matches: ArgMatches) -> Result<HashMap<String, Value>, CliError> {
}
}
if matches.is_present("variable") {
let input: Vec<_> = matches.values_of("variable").unwrap().collect();
if let Some(input) = get_strings(&matches, "variable") {
for s in input {
let (name, value) = cli::parse_variable(s)?;
let (name, value) = cli::parse_variable(&s)?;
variables.insert(name.to_string(), value);
}
}
@ -521,10 +513,9 @@ fn variables(matches: ArgMatches) -> Result<HashMap<String, Value>, CliError> {
///
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();
if let Some(exprs) = get_strings(matches, "glob") {
for expr in exprs {
let paths = match glob::glob(expr) {
let paths = match glob::glob(&expr) {
Ok(paths) => paths,
Err(_) => {
return Err(CliError {
@ -553,3 +544,17 @@ fn match_glob_files(matches: &ArgMatches) -> Result<Vec<String>, CliError> {
}
Ok(filenames)
}
fn get_string(matches: &ArgMatches, name: &str) -> Option<String> {
matches.get_one::<String>(name).map(|x| x.to_string())
}
pub fn get_strings(matches: &ArgMatches, name: &str) -> Option<Vec<String>> {
matches
.get_many::<String>(name)
.map(|v| v.map(|x| x.to_string()).collect())
}
pub fn has_flag(matches: &ArgMatches, name: &str) -> bool {
matches.contains_id(name)
}

View File

@ -257,14 +257,14 @@ fn main() {
let matches = app.clone().get_matches();
init_colored();
let verbose = matches.is_present("verbose") || matches.is_present("interactive");
let verbose = cli::has_flag(&matches, "verbose") || cli::has_flag(&matches, "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(cli::parse_options(matches.clone()), &log_error_message);
let mut filenames = vec![];
if let Some(values) = matches.values_of("INPUT") {
if let Some(values) = cli::get_strings(&matches, "INPUT") {
for value in values {
filenames.push(value.to_string());
}

View File

@ -16,7 +16,7 @@ strict = []
[dependencies]
atty = "0.2.14"
base64 = "0.13.0"
clap = { version = "3.1.18", features = ["cargo"] }
clap = { version = "3.2.4", features = ["cargo"] }
colored = "2.0.0"
hurl_core = { version = "1.7.0-snapshot", path = "../hurl_core" }
regex = "1.5.6"

View File

@ -24,6 +24,8 @@ pub use self::logger::{
mod fs;
mod logger;
mod options;
pub use self::options::{get_string, get_strings, has_flag};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CliError {

View File

@ -0,0 +1,33 @@
/*
* Hurl (https://hurl.dev)
* Copyright (C) 2022 Orange
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
use clap::ArgMatches;
pub fn get_string(matches: &ArgMatches, name: &str) -> Option<String> {
matches.get_one::<String>(name).map(|x| x.to_string())
}
pub fn get_strings(matches: &ArgMatches, name: &str) -> Option<Vec<String>> {
matches
.get_many::<String>(name)
.map(|v| v.map(|x| x.to_string()).collect())
}
pub fn has_flag(matches: &ArgMatches, name: &str) -> bool {
matches.contains_id(name)
}

View File

@ -40,7 +40,6 @@ pub fn init_colored() {
fn main() {
let app = clap::Command::new("hurlfmt")
// .author(clap::crate_authors!())
.version(clap::crate_version!())
.disable_colored_help(true)
.about("Format hurl FILE")
@ -69,6 +68,7 @@ fn main() {
.long("format")
.conflicts_with("check")
.value_name("FORMAT")
.default_value("text")
.help("Specify output format: text (default), json or html"),
)
.arg(
@ -106,14 +106,16 @@ fn main() {
init_colored();
// Additional checks
if matches.is_present("standalone") && matches.value_of("format") != Some("html") {
if cli::has_flag(&matches, "standalone")
&& cli::get_string(&matches, "format") != Some("html".to_string())
{
eprintln!("use --standalone option only with html output");
std::process::exit(1);
process::exit(1);
}
let output_color = if matches.is_present("color") {
let output_color = if cli::has_flag(&matches, "color") {
true
} else if matches.is_present("no_color") || matches.is_present("in_place") {
} else if cli::has_flag(&matches, "no_color") || cli::has_flag(&matches, "in_place") {
false
} else {
atty::is(Stream::Stdout)
@ -121,9 +123,8 @@ fn main() {
let log_error_message = cli::make_logger_error_message(output_color);
let filename = match matches.value_of("INPUT") {
None => "-",
Some("-") => "-",
let filename = match cli::get_string(&matches, "INPUT") {
None => "-".to_string(),
Some(v) => v,
};
@ -132,23 +133,23 @@ fn main() {
panic!("panic during printing help");
}
println!();
std::process::exit(1);
} else if filename != "-" && !Path::new(filename).exists() {
process::exit(1);
} else if filename != "-" && !Path::new(&filename).exists() {
eprintln!("Input file {} does not exit!", filename);
std::process::exit(1);
process::exit(1);
};
if matches.is_present("in_place") {
if cli::has_flag(&matches, "in_place") {
if filename == "-" {
log_error_message(
true,
"You can not use --in-place with standard input stream!",
);
std::process::exit(1);
process::exit(1);
};
if matches.value_of("format").unwrap_or("text") != "text" {
if cli::get_string(&matches, "format") != Some("text".to_string()) {
log_error_message(true, "You can use --in-place only text format!");
std::process::exit(1);
process::exit(1);
};
}
@ -159,18 +160,18 @@ fn main() {
false,
format!("Input stream can not be read - {}", e).as_str(),
);
std::process::exit(2);
process::exit(2);
}
contents
} else {
match cli::read_to_string(filename) {
match cli::read_to_string(&filename) {
Ok(s) => s,
Err(e) => {
log_error_message(
false,
format!("Input stream can not be read - {}", e.message).as_str(),
);
std::process::exit(2);
process::exit(2);
}
}
};
@ -187,10 +188,10 @@ fn main() {
Some(filename.to_string())
};
let output_file = if matches.is_present("in_place") {
let output_file = if cli::has_flag(&matches, "in_place") {
Some(filename)
} else {
matches.value_of("output")
cli::get_string(&matches, "output")
};
let log_parser_error =
@ -202,15 +203,15 @@ fn main() {
process::exit(2);
}
Ok(hurl_file) => {
if matches.is_present("check") {
if cli::has_flag(&matches, "check") {
for e in hurl_file.errors() {
log_linter_error(&e, true);
}
std::process::exit(1);
process::exit(1);
} else {
let output = match matches.value_of("format").unwrap_or("text") {
let output = match cli::get_string(&matches, "format").unwrap().as_str() {
"text" => {
let hurl_file = if matches.is_present("no_format") {
let hurl_file = if cli::has_flag(&matches, "no_format") {
hurl_file
} else {
hurl_file.lint()
@ -219,16 +220,16 @@ fn main() {
}
"json" => format::format_json(hurl_file),
"html" => {
let standalone = matches.is_present("standalone");
let standalone = cli::has_flag(&matches, "standalone");
hurl_core::format::format_html(hurl_file, standalone)
}
"ast" => format!("{:#?}", hurl_file),
_ => {
eprintln!("Invalid output option - expecting text, html or json");
std::process::exit(1);
process::exit(1);
}
};
write_output(output.into_bytes(), output_file);
write_output(output.into_bytes(), output_file.as_deref());
}
}
}