From 0931c3251095789cb49b83ba71a6fca37d963c50 Mon Sep 17 00:00:00 2001 From: jcamiel Date: Fri, 15 Mar 2024 16:45:52 +0100 Subject: [PATCH] Add experimental parallel flag. --- bin/spec/options/generate_man.py | 7 +++--- bin/spec/options/generate_source.py | 7 +++--- bin/spec/options/option.py | 26 +++++++++++++++++++---- completions/_hurl | 1 + completions/_hurl.ps1 | 1 + completions/hurl.bash | 2 +- completions/hurl.fish | 1 + docs/spec/options/hurl/parallel.option | 9 ++++++++ packages/hurl/src/cli/options/commands.rs | 8 +++++++ packages/hurl/src/cli/options/matches.rs | 4 ++++ packages/hurl/src/cli/options/mod.rs | 6 +++++- 11 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 docs/spec/options/hurl/parallel.option diff --git a/bin/spec/options/generate_man.py b/bin/spec/options/generate_man.py index 72bbecce8..f5ef8311e 100755 --- a/bin/spec/options/generate_man.py +++ b/bin/spec/options/generate_man.py @@ -5,20 +5,19 @@ from option import Option """ Generate options for man """ -from typing import * import sys -def generate_man(options: List[Option]): +def generate_man(options: list[Option]) -> str: s = "" for option in options: - if not option.deprecated: + if not option.deprecated and not option.experimental: s += generate_man_option(option) s += "\n\n" return s -def generate_man_option(option: Option): +def generate_man_option(option: Option) -> str: s = "###" if option.short: s += " -%s," % option.short diff --git a/bin/spec/options/generate_source.py b/bin/spec/options/generate_source.py index 13deec343..ce8d27057 100755 --- a/bin/spec/options/generate_source.py +++ b/bin/spec/options/generate_source.py @@ -25,7 +25,6 @@ COPYRIGHT = """/* * limitations under the License. * */""" -from typing import * import os import sys @@ -33,7 +32,7 @@ import sys SCRIPT_FILE = __file__[len(os.getcwd()) + 1 :] -def generate_source(options: List[Option]): +def generate_source(options: list[Option]) -> str: s = COPYRIGHT s += "\n" + "// Generated by " + SCRIPT_FILE + " - Do not modify" # s += "\nuse clap::{value_parser, ArgAction};" @@ -51,7 +50,7 @@ def generate_source(options: List[Option]): return s -def generate_source_option(option: Option): +def generate_source_option(option: Option) -> str: s = f"pub fn {option.name}() -> clap::Arg {{" s += f'\n clap::Arg::new("{option.name}")' s += f'\n .long("{option.long}")' @@ -75,7 +74,7 @@ def generate_source_option(option: Option): s += f"\n .action(clap::ArgAction::SetTrue)" if option.append: s += f"\n .action(clap::ArgAction::Append)" - if option.deprecated: + if option.deprecated or option.experimental: s += f"\n .hide(true)" s += "\n}" return s diff --git a/bin/spec/options/option.py b/bin/spec/options/option.py index 57f6ab6ec..b7f24d3fc 100644 --- a/bin/spec/options/option.py +++ b/bin/spec/options/option.py @@ -16,6 +16,7 @@ class Option: append, cli_only, deprecated, + experimental, description, ): self.name = name @@ -29,6 +30,7 @@ class Option: self.append = append self.cli_only = cli_only self.deprecated = deprecated + self.experimental = experimental self.description = description def __eq__(self, other): @@ -45,6 +47,7 @@ class Option: and self.conflict == other.conflict and self.append == other.append and self.deprecated == other.deprecated + and self.experimental == other.experimental and self.description == other.description and self.cli_only == other.cli_only ) @@ -70,6 +73,8 @@ class Option: s += "\ncli_only: true" if self.deprecated: s += "\ndeprecated: true" + if self.experimental: + s += "\nexperimental: true" s += "\n---" s += "\n" + self.description return s @@ -86,13 +91,15 @@ class Option: self.help, self.conflict, self.append, - self.description, self.cli_only, + self.deprecated, + self.experimental, + self.description, ) ) @staticmethod - def parse(s): + def parse(s) -> "Option": name = None long = None short = None @@ -105,6 +112,7 @@ class Option: cli_only = False deprecated = False description = "" + experimental = False in_description = False for line in s.split("\n"): @@ -149,6 +157,15 @@ class Option: raise Exception( "Expected true or false for deprecated attribute" ) + elif key == "experimental": + if v == "true": + experimental = True + elif v == "false": + experimental = False + else: + raise Exception( + "Expected true or false for experimental attribute" + ) else: raise Exception("Invalid attribute " + key) @@ -170,11 +187,12 @@ class Option: append, cli_only, deprecated, + experimental, description.strip(), ) @staticmethod - def parse_file(filename): + def parse_file(filename: str) -> "Option": import sys # sys.stderr.write("Parsing " + filename + "\n") @@ -182,7 +200,7 @@ class Option: return Option.parse(s) -def parse_key_value(s) -> tuple[str, str]: +def parse_key_value(s: str) -> tuple[str, str]: if ":" not in s: raise Exception("Expecting key value") index = s.index(":") diff --git a/completions/_hurl b/completions/_hurl index 539846b31..936b7b78d 100644 --- a/completions/_hurl +++ b/completions/_hurl @@ -53,6 +53,7 @@ _hurl() { '--no-output[Suppress output. By default, Hurl outputs the body of the last response]' \ '--noproxy[List of hosts which do not use proxy]: :' \ '(-o --output)'{-o,--output}'[Write to FILE instead of stdout]: :_files' \ + '--parallel[(Experimental) Run files in parallel]' \ '--path-as-is[Tell Hurl to not handle sequences of /../ or /./ in the given URL path]' \ '(-x --proxy)'{-x,--proxy}'[Use proxy on given PROTOCOL/HOST/PORT]: :' \ '--report-html[Generate HTML report to DIR]: :' \ diff --git a/completions/_hurl.ps1 b/completions/_hurl.ps1 index c6bccb0e8..baeccdef4 100644 --- a/completions/_hurl.ps1 +++ b/completions/_hurl.ps1 @@ -58,6 +58,7 @@ Register-ArgumentCompleter -Native -CommandName 'hurl' -ScriptBlock { [CompletionResult]::new('--no-output', 'no-output', [CompletionResultType]::ParameterName, 'Suppress output. By default, Hurl outputs the body of the last response') [CompletionResult]::new('--noproxy', 'noproxy', [CompletionResultType]::ParameterName, 'List of hosts which do not use proxy') [CompletionResult]::new('--output', 'output', [CompletionResultType]::ParameterName, 'Write to FILE instead of stdout') + [CompletionResult]::new('--parallel', 'parallel', [CompletionResultType]::ParameterName, '(Experimental) Run files in parallel') [CompletionResult]::new('--path-as-is', 'path-as-is', [CompletionResultType]::ParameterName, 'Tell Hurl to not handle sequences of /../ or /./ in the given URL path') [CompletionResult]::new('--proxy', 'proxy', [CompletionResultType]::ParameterName, 'Use proxy on given PROTOCOL/HOST/PORT') [CompletionResult]::new('--report-html', 'report-html', [CompletionResultType]::ParameterName, 'Generate HTML report to DIR') diff --git a/completions/hurl.bash b/completions/hurl.bash index 1dac932a1..f12872711 100644 --- a/completions/hurl.bash +++ b/completions/hurl.bash @@ -5,7 +5,7 @@ _hurl() _init_completion || return if [[ $cur == -* ]]; then - COMPREPLY=($(compgen -W '--aws-sigv4 --cacert --cert --key --color --compressed --connect-timeout --connect-to --continue-on-error --cookie --cookie-jar --delay --error-format --fail-at-end --file-root --location --location-trusted --glob --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --json --max-redirs --max-time --netrc --netrc-file --netrc-optional --no-color --no-output --noproxy --output --path-as-is --proxy --report-html --report-junit --report-tap --resolve --retry --retry-interval --ssl-no-revoke --test --to-entry --unix-socket --user --user-agent --variable --variables-file --verbose --very-verbose --help --version' -- "$cur")) + COMPREPLY=($(compgen -W '--aws-sigv4 --cacert --cert --key --color --compressed --connect-timeout --connect-to --continue-on-error --cookie --cookie-jar --delay --error-format --fail-at-end --file-root --location --location-trusted --glob --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --json --max-redirs --max-time --netrc --netrc-file --netrc-optional --no-color --no-output --noproxy --output --parallel --path-as-is --proxy --report-html --report-junit --report-tap --resolve --retry --retry-interval --ssl-no-revoke --test --to-entry --unix-socket --user --user-agent --variable --variables-file --verbose --very-verbose --help --version' -- "$cur")) return fi diff --git a/completions/hurl.fish b/completions/hurl.fish index 8f3093e1b..fbbb272ab 100644 --- a/completions/hurl.fish +++ b/completions/hurl.fish @@ -36,6 +36,7 @@ complete -c hurl -l no-color -d 'Do not colorize output' complete -c hurl -l no-output -d 'Suppress output. By default, Hurl outputs the body of the last response' complete -c hurl -l noproxy -d 'List of hosts which do not use proxy' complete -c hurl -l output -d 'Write to FILE instead of stdout' +complete -c hurl -l parallel -d '(Experimental) Run files in parallel' complete -c hurl -l path-as-is -d 'Tell Hurl to not handle sequences of /../ or /./ in the given URL path' complete -c hurl -l proxy -d 'Use proxy on given PROTOCOL/HOST/PORT' complete -c hurl -l report-html -d 'Generate HTML report to DIR' diff --git a/docs/spec/options/hurl/parallel.option b/docs/spec/options/hurl/parallel.option new file mode 100644 index 000000000..7efc49b25 --- /dev/null +++ b/docs/spec/options/hurl/parallel.option @@ -0,0 +1,9 @@ +name: parallel +long: parallel +help: (Experimental) Run files in parallel +cli_only: true +experimental: true +--- +(Experimental) Run files in parallel. + +Each Hurl file is executed in its own worker thread, without sharing anything with the other workers. The default run mode is sequential. diff --git a/packages/hurl/src/cli/options/commands.rs b/packages/hurl/src/cli/options/commands.rs index 10feb5ad1..5b8ecf750 100644 --- a/packages/hurl/src/cli/options/commands.rs +++ b/packages/hurl/src/cli/options/commands.rs @@ -344,6 +344,14 @@ pub fn output() -> clap::Arg { .num_args(1) } +pub fn parallel() -> clap::Arg { + clap::Arg::new("parallel") + .long("parallel") + .help("(Experimental) Run files in parallel") + .action(clap::ArgAction::SetTrue) + .hide(true) +} + pub fn path_as_is() -> clap::Arg { clap::Arg::new("path_as_is") .long("path-as-is") diff --git a/packages/hurl/src/cli/options/matches.rs b/packages/hurl/src/cli/options/matches.rs index 814215dc7..224f53e9b 100644 --- a/packages/hurl/src/cli/options/matches.rs +++ b/packages/hurl/src/cli/options/matches.rs @@ -286,6 +286,10 @@ pub fn output_type(arg_matches: &ArgMatches) -> OutputType { } } +pub fn parallel(arg_matches: &ArgMatches) -> bool { + has_flag(arg_matches, "parallel") +} + pub fn path_as_is(arg_matches: &ArgMatches) -> bool { has_flag(arg_matches, "path_as_is") } diff --git a/packages/hurl/src/cli/options/mod.rs b/packages/hurl/src/cli/options/mod.rs index beecea905..9113f7529 100644 --- a/packages/hurl/src/cli/options/mod.rs +++ b/packages/hurl/src/cli/options/mod.rs @@ -72,6 +72,7 @@ pub struct CliOptions { pub no_proxy: Option, pub output: Option, pub output_type: OutputType, + pub parallel: bool, pub path_as_is: bool, pub progress_bar: bool, pub proxy: Option, @@ -195,6 +196,7 @@ pub fn parse() -> Result { .arg(commands::no_output()) .arg(commands::noproxy()) .arg(commands::output()) + .arg(commands::parallel()) .arg(commands::path_as_is()) .arg(commands::proxy()) .arg(commands::report_html()) @@ -262,8 +264,9 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result Result