diff --git a/README.md b/README.md
index 5ffda1d27af..636d3901778 100644
--- a/README.md
+++ b/README.md
@@ -1229,6 +1229,7 @@ will follow a redirection only for the second entry.
| --continue-on-error
| Continue executing requests to the end of the Hurl file even when an assert error occurs.
By default, Hurl exits after an assert error in the HTTP response.
Note that this option does not affect the behavior with multiple input Hurl files.
All the input files are executed independently. The result of one file does not affect the execution of the other Hurl files.
This is a cli-only option.
|
| -b, --cookie <FILE>
| Read cookies from FILE (using the Netscape cookie file format).
Combined with [`-c, --cookie-jar`](#cookie-jar), you can simulate a cookie storage between successive Hurl runs.
This is a cli-only option.
|
| -c, --cookie-jar <FILE>
| Write cookies to FILE after running the session (only for one session).
The file will be written using the Netscape cookie file format.
Combined with [`-b, --cookie`](#cookie), you can simulate a cookie storage between successive Hurl runs.
This is a cli-only option.
|
+| --curl <FILE>
| Export each request to a list of curl commands.
This is a cli-only option.
|
| --delay <MILLISECONDS>
| Sets delay before each request. The delay is not applied to requests that have been retried because of [`--retry`](#retry). See [`--retry-interval`](#retry-interval) to space retried requests.
You can specify time units in the delay expression. Set Hurl to use a delay of 2 seconds with `--delay 2s` or set it to 500 milliseconds with `--delay 500ms`. No spaces allowed.
|
| --error-format <FORMAT>
| Control the format of error message (short by default or long)
This is a cli-only option.
|
| --file-root <DIR>
| Set root directory to import files in Hurl. This is used for files in multipart form data, request body and response output.
When it is not explicitly defined, files are relative to the Hurl file's directory.
This is a cli-only option.
|
diff --git a/completions/_hurl b/completions/_hurl
index 93fd19a33fa..d98c6661336 100644
--- a/completions/_hurl
+++ b/completions/_hurl
@@ -26,6 +26,7 @@ _hurl() {
'--continue-on-error[Continue executing requests even if an error occurs]' \
'(-b --cookie)'{-b,--cookie}'[Read cookies from FILE]: :_files' \
'(-c --cookie-jar)'{-c,--cookie-jar}'[Write cookies to FILE after running the session (only for one session)]: :_files' \
+ '--curl[Export each request to a list of curl commands]: :_files' \
'--delay[Sets delay before each request]: :' \
'--error-format[Control the format of error messages]: :' \
'--fail-at-end[Fail at end]' \
diff --git a/completions/_hurl.ps1 b/completions/_hurl.ps1
index 1fc5a5598c1..73e75f35a54 100644
--- a/completions/_hurl.ps1
+++ b/completions/_hurl.ps1
@@ -31,6 +31,7 @@ Register-ArgumentCompleter -Native -CommandName 'hurl' -ScriptBlock {
[CompletionResult]::new('--continue-on-error', 'continue-on-error', [CompletionResultType]::ParameterName, 'Continue executing requests even if an error occurs')
[CompletionResult]::new('--cookie', 'cookie', [CompletionResultType]::ParameterName, 'Read cookies from FILE')
[CompletionResult]::new('--cookie-jar', 'cookie-jar', [CompletionResultType]::ParameterName, 'Write cookies to FILE after running the session (only for one session)')
+ [CompletionResult]::new('--curl', 'curl', [CompletionResultType]::ParameterName, 'Export each request to a list of curl commands')
[CompletionResult]::new('--delay', 'delay', [CompletionResultType]::ParameterName, 'Sets delay before each request')
[CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'Control the format of error messages')
[CompletionResult]::new('--fail-at-end', 'fail-at-end', [CompletionResultType]::ParameterName, 'Fail at end')
diff --git a/completions/hurl.bash b/completions/hurl.bash
index 1624e2de481..14352ab33fa 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 --from-entry --glob --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --jobs --json --limit-rate --max-filesize --max-redirs --max-time --netrc --netrc-file --netrc-optional --no-color --no-output --noproxy --output --parallel --path-as-is --proxy --repeat --report-html --report-json --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 --curl --delay --error-format --fail-at-end --file-root --location --location-trusted --from-entry --glob --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --jobs --json --limit-rate --max-filesize --max-redirs --max-time --netrc --netrc-file --netrc-optional --no-color --no-output --noproxy --output --parallel --path-as-is --proxy --repeat --report-html --report-json --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 b01087832c5..5498ef234bd 100644
--- a/completions/hurl.fish
+++ b/completions/hurl.fish
@@ -9,6 +9,7 @@ complete -c hurl -l connect-to -d 'For a request to the given HOST1:PORT1 pair,
complete -c hurl -l continue-on-error -d 'Continue executing requests even if an error occurs'
complete -c hurl -l cookie -d 'Read cookies from FILE'
complete -c hurl -l cookie-jar -d 'Write cookies to FILE after running the session (only for one session)'
+complete -c hurl -l curl -d 'Export each request to a list of curl commands'
complete -c hurl -l delay -d 'Sets delay before each request'
complete -c hurl -l error-format -d 'Control the format of error messages'
complete -c hurl -l fail-at-end -d 'Fail at end'
diff --git a/docs/manual.md b/docs/manual.md
index 4c53600fba3..fdbaf2d8c88 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -159,6 +159,7 @@ will follow a redirection only for the second entry.
| --continue-on-error
| Continue executing requests to the end of the Hurl file even when an assert error occurs.
By default, Hurl exits after an assert error in the HTTP response.
Note that this option does not affect the behavior with multiple input Hurl files.
All the input files are executed independently. The result of one file does not affect the execution of the other Hurl files.
This is a cli-only option.
|
| -b, --cookie <FILE>
| Read cookies from FILE (using the Netscape cookie file format).
Combined with [`-c, --cookie-jar`](#cookie-jar), you can simulate a cookie storage between successive Hurl runs.
This is a cli-only option.
|
| -c, --cookie-jar <FILE>
| Write cookies to FILE after running the session (only for one session).
The file will be written using the Netscape cookie file format.
Combined with [`-b, --cookie`](#cookie), you can simulate a cookie storage between successive Hurl runs.
This is a cli-only option.
|
+| --curl <FILE>
| Export each request to a list of curl commands.
This is a cli-only option.
|
| --delay <MILLISECONDS>
| Sets delay before each request. The delay is not applied to requests that have been retried because of [`--retry`](#retry). See [`--retry-interval`](#retry-interval) to space retried requests.
You can specify time units in the delay expression. Set Hurl to use a delay of 2 seconds with `--delay 2s` or set it to 500 milliseconds with `--delay 500ms`. No spaces allowed.
|
| --error-format <FORMAT>
| Control the format of error message (short by default or long)
This is a cli-only option.
|
| --file-root <DIR>
| Set root directory to import files in Hurl. This is used for files in multipart form data, request body and response output.
When it is not explicitly defined, files are relative to the Hurl file's directory.
This is a cli-only option.
|
diff --git a/docs/manual/hurl.1 b/docs/manual/hurl.1
index 71c071d54a6..1f477c1e5d0 100644
--- a/docs/manual/hurl.1
+++ b/docs/manual/hurl.1
@@ -1,4 +1,4 @@
-.TH hurl 1 "28 Oct 2024" "hurl 6.0.0-SNAPSHOT" " Hurl Manual"
+.TH hurl 1 "07 Nov 2024" "hurl 6.0.0-SNAPSHOT" " Hurl Manual"
.SH NAME
hurl - run and test HTTP requests.
@@ -197,6 +197,12 @@ Combined with \fI-b, --cookie\fP, you can simulate a cookie storage between succ
This is a cli-only option.
+.IP "--curl "
+
+Export each request to a list of curl commands.
+
+This is a cli-only option.
+
.IP "--delay "
Sets delay before each request. The delay is not applied to requests that have been retried because of \fI--retry\fP. See \fI--retry-interval\fP to space retried requests.
diff --git a/docs/manual/hurl.md b/docs/manual/hurl.md
index e7c30166c07..ba64a71186f 100644
--- a/docs/manual/hurl.md
+++ b/docs/manual/hurl.md
@@ -216,6 +216,12 @@ Combined with [`-b, --cookie`](#cookie), you can simulate a cookie storage betwe
This is a cli-only option.
+### --curl {#curl}
+
+Export each request to a list of curl commands.
+
+This is a cli-only option.
+
### --delay {#delay}
Sets delay before each request. The delay is not applied to requests that have been retried because of [`--retry`](#retry). See [`--retry-interval`](#retry-interval) to space retried requests.
diff --git a/docs/manual/hurlfmt.1 b/docs/manual/hurlfmt.1
index d5ab4964dbb..6546c7888ca 100644
--- a/docs/manual/hurlfmt.1
+++ b/docs/manual/hurlfmt.1
@@ -1,4 +1,4 @@
-.TH hurl 1 "28 Oct 2024" "hurl 6.0.0-SNAPSHOT" " Hurl Manual"
+.TH hurl 1 "07 Nov 2024" "hurl 6.0.0-SNAPSHOT" " Hurl Manual"
.SH NAME
hurlfmt - format Hurl files
diff --git a/docs/spec/options/hurl/curl.option b/docs/spec/options/hurl/curl.option
new file mode 100644
index 00000000000..5c0d742872a
--- /dev/null
+++ b/docs/spec/options/hurl/curl.option
@@ -0,0 +1,8 @@
+name: curl
+long: curl
+value: FILE
+help: Export each request to a list of curl commands
+help_heading: Output options
+cli_only: true
+---
+Export each request to a list of curl commands.
diff --git a/integration/hurl/tests_ok/assert_body.ps1 b/integration/hurl/tests_ok/assert_body.ps1
index 870aa196728..7bd0a22d024 100644
--- a/integration/hurl/tests_ok/assert_body.ps1
+++ b/integration/hurl/tests_ok/assert_body.ps1
@@ -1,3 +1,4 @@
Set-StrictMode -Version latest
$ErrorActionPreference = 'Stop'
+
hurl --verbose tests_ok/assert_body.hurl
diff --git a/integration/hurl/tests_ok/assert_body.sh b/integration/hurl/tests_ok/assert_body.sh
index bc1003f6590..fca8fe60bea 100755
--- a/integration/hurl/tests_ok/assert_body.sh
+++ b/integration/hurl/tests_ok/assert_body.sh
@@ -1,3 +1,4 @@
#!/bin/bash
set -Eeuo pipefail
+
hurl --verbose tests_ok/assert_body.hurl
diff --git a/integration/hurl/tests_ok/assert_body_curl.out b/integration/hurl/tests_ok/assert_body_curl.out
new file mode 100644
index 00000000000..07db44f15e9
--- /dev/null
+++ b/integration/hurl/tests_ok/assert_body_curl.out
@@ -0,0 +1,4 @@
+curl 'http://localhost:8000/assert-body'
+curl 'http://localhost:8000/assert-body'
+curl 'http://localhost:8000/assert-body-with-crlf'
+curl 'http://localhost:8000/assert-body'
diff --git a/integration/hurl/tests_ok/assert_body_curl.ps1 b/integration/hurl/tests_ok/assert_body_curl.ps1
new file mode 100644
index 00000000000..644e773d08a
--- /dev/null
+++ b/integration/hurl/tests_ok/assert_body_curl.ps1
@@ -0,0 +1,6 @@
+Set-StrictMode -Version latest
+$ErrorActionPreference = 'Stop'
+
+hurl --curl build/assert_body.curl --no-output tests_ok/assert_body.hurl
+
+Write-Host (Get-Content build/assert_body.curl -Raw) -NoNewLine
diff --git a/integration/hurl/tests_ok/assert_body_curl.sh b/integration/hurl/tests_ok/assert_body_curl.sh
new file mode 100755
index 00000000000..6bfc0665e25
--- /dev/null
+++ b/integration/hurl/tests_ok/assert_body_curl.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -Eeuo pipefail
+
+hurl --curl build/assert_body.curl --no-output tests_ok/assert_body.hurl
+
+cat build/assert_body.curl
diff --git a/integration/hurl/tests_ok/help.out.pattern b/integration/hurl/tests_ok/help.out.pattern
index bf8b43545cc..c4ed4732740 100644
--- a/integration/hurl/tests_ok/help.out.pattern
+++ b/integration/hurl/tests_ok/help.out.pattern
@@ -72,6 +72,7 @@ HTTP options:
Output options:
--color Colorize output
+ --curl Export each request to a list of curl commands
--error-format Control the format of error messages [default: short] [possible
values: short, long]
-i, --include Include the HTTP headers in the output
diff --git a/integration/hurl/tests_ok/multilines.ps1 b/integration/hurl/tests_ok/multilines.ps1
index 4ef108cec47..d704a28f894 100644
--- a/integration/hurl/tests_ok/multilines.ps1
+++ b/integration/hurl/tests_ok/multilines.ps1
@@ -1,3 +1,4 @@
Set-StrictMode -Version latest
$ErrorActionPreference = 'Stop'
-hurl tests_ok/multilines.hurl --verbose
+
+hurl --verbose tests_ok/multilines.hurl
diff --git a/integration/hurl/tests_ok/multilines.sh b/integration/hurl/tests_ok/multilines.sh
index 11dc716a52e..844bc8128d4 100755
--- a/integration/hurl/tests_ok/multilines.sh
+++ b/integration/hurl/tests_ok/multilines.sh
@@ -1,3 +1,4 @@
#!/bin/bash
set -Eeuo pipefail
-hurl tests_ok/multilines.hurl --verbose
+
+hurl --verbose tests_ok/multilines.hurl
diff --git a/integration/hurl/tests_ok/multilines_curl.out b/integration/hurl/tests_ok/multilines_curl.out
new file mode 100644
index 00000000000..7076bee81ca
--- /dev/null
+++ b/integration/hurl/tests_ok/multilines_curl.out
@@ -0,0 +1,4 @@
+curl --header 'Content-Type:' --data $'line1\nline2\nline3\n' 'http://localhost:8000/multilines/plain-text'
+curl --header 'Content-Type: application/json' --data $'{\n "foo": "bar"\n "baz": 123456\n}\n' 'http://localhost:8000/multilines/json'
+curl --header 'Content-Type: application/xml' --data $'\n\n \n Gambardella, Matthew\n XML Developer\'s Guide\n Computer\n 44.95\n 2000-10-01\n An in-depth look at creating applications\n with XML.\n \n\n' 'http://localhost:8000/multilines/xml'
+curl --header 'Content-Type: application/json' --data '{"query":"{\n hero {\n name\n # Queries can have comments!\n friends {\n name\n }\n }\n}"}' 'http://localhost:8000/multilines/graphql'
diff --git a/integration/hurl/tests_ok/multilines_curl.ps1 b/integration/hurl/tests_ok/multilines_curl.ps1
new file mode 100644
index 00000000000..0c014bb8024
--- /dev/null
+++ b/integration/hurl/tests_ok/multilines_curl.ps1
@@ -0,0 +1,6 @@
+Set-StrictMode -Version latest
+$ErrorActionPreference = 'Stop'
+
+hurl --verbose --no-output --curl build/multilines.curl tests_ok/multilines.hurl
+
+Write-Host (Get-Content build/multilines.curl -Raw) -NoNewLine
diff --git a/integration/hurl/tests_ok/multilines_curl.sh b/integration/hurl/tests_ok/multilines_curl.sh
new file mode 100755
index 00000000000..56f37a5c503
--- /dev/null
+++ b/integration/hurl/tests_ok/multilines_curl.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -Eeuo pipefail
+
+hurl --verbose --no-output --curl build/multilines.curl tests_ok/multilines.hurl
+
+cat build/multilines.curl
diff --git a/packages/hurl/README.md b/packages/hurl/README.md
index 9dc116a6747..9d7d16a65a9 100644
--- a/packages/hurl/README.md
+++ b/packages/hurl/README.md
@@ -1229,6 +1229,7 @@ will follow a redirection only for the second entry.
| --continue-on-error
| Continue executing requests to the end of the Hurl file even when an assert error occurs.
By default, Hurl exits after an assert error in the HTTP response.
Note that this option does not affect the behavior with multiple input Hurl files.
All the input files are executed independently. The result of one file does not affect the execution of the other Hurl files.
This is a cli-only option.
|
| -b, --cookie <FILE>
| Read cookies from FILE (using the Netscape cookie file format).
Combined with [`-c, --cookie-jar`](#cookie-jar), you can simulate a cookie storage between successive Hurl runs.
This is a cli-only option.
|
| -c, --cookie-jar <FILE>
| Write cookies to FILE after running the session (only for one session).
The file will be written using the Netscape cookie file format.
Combined with [`-b, --cookie`](#cookie), you can simulate a cookie storage between successive Hurl runs.
This is a cli-only option.
|
+| --curl <FILE>
| Export each request to a list of curl commands.
This is a cli-only option.
|
| --delay <MILLISECONDS>
| Sets delay before each request. The delay is not applied to requests that have been retried because of [`--retry`](#retry). See [`--retry-interval`](#retry-interval) to space retried requests.
You can specify time units in the delay expression. Set Hurl to use a delay of 2 seconds with `--delay 2s` or set it to 500 milliseconds with `--delay 500ms`. No spaces allowed.
|
| --error-format <FORMAT>
| Control the format of error message (short by default or long)
This is a cli-only option.
|
| --file-root <DIR>
| Set root directory to import files in Hurl. This is used for files in multipart form data, request body and response output.
When it is not explicitly defined, files are relative to the Hurl file's directory.
This is a cli-only option.
|
diff --git a/packages/hurl/src/cli/options/commands.rs b/packages/hurl/src/cli/options/commands.rs
index c5c563333c4..642430e2900 100644
--- a/packages/hurl/src/cli/options/commands.rs
+++ b/packages/hurl/src/cli/options/commands.rs
@@ -128,6 +128,15 @@ pub fn cookies_output_file() -> clap::Arg {
.num_args(1)
}
+pub fn curl() -> clap::Arg {
+ clap::Arg::new("curl")
+ .long("curl")
+ .value_name("FILE")
+ .help("Export each request to a list of curl commands")
+ .help_heading("Output options")
+ .num_args(1)
+}
+
pub fn delay() -> clap::Arg {
clap::Arg::new("delay")
.long("delay")
diff --git a/packages/hurl/src/cli/options/matches.rs b/packages/hurl/src/cli/options/matches.rs
index 6133928f486..80d70dc1073 100644
--- a/packages/hurl/src/cli/options/matches.rs
+++ b/packages/hurl/src/cli/options/matches.rs
@@ -126,6 +126,10 @@ pub fn cookie_output_file(arg_matches: &ArgMatches) -> Option {
get::(arg_matches, "cookies_output_file").map(PathBuf::from)
}
+pub fn curl_file(arg_matches: &ArgMatches) -> Option {
+ get::(arg_matches, "curl").map(PathBuf::from)
+}
+
pub fn delay(arg_matches: &ArgMatches) -> Result {
let s = get::(arg_matches, "delay").unwrap_or_default();
get_duration(&s, DurationUnit::MilliSecond)
diff --git a/packages/hurl/src/cli/options/mod.rs b/packages/hurl/src/cli/options/mod.rs
index 218e78a20b4..25440d01a0e 100644
--- a/packages/hurl/src/cli/options/mod.rs
+++ b/packages/hurl/src/cli/options/mod.rs
@@ -54,6 +54,7 @@ pub struct CliOptions {
pub continue_on_error: bool,
pub cookie_input_file: Option,
pub cookie_output_file: Option,
+ pub curl_file: Option,
pub delay: Duration,
pub error_format: ErrorFormat,
pub file_root: Option,
@@ -180,6 +181,7 @@ pub fn parse() -> Result {
.arg(commands::continue_on_error())
.arg(commands::cookies_input_file())
.arg(commands::cookies_output_file())
+ .arg(commands::curl())
.arg(commands::delay())
.arg(commands::error_format())
.arg(commands::fail_at_end())
@@ -269,6 +271,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result Result Result<(), CliError> {
+ if let Some(file) = &opts.curl_file {
+ create_curl_export(runs, file)?;
+ }
if let Some(file) = &opts.junit_file {
logger.debug(&format!("Writing JUnit report to {}", file.display()));
create_junit_report(runs, file)?;
@@ -161,7 +164,14 @@ fn export_results(
Ok(())
}
-/// Create a JUnit report for this run.
+/// Creates an export of all curl commands for this run.
+fn create_curl_export(runs: &[HurlRun], filename: &Path) -> Result<(), CliError> {
+ let results = runs.iter().map(|r| &r.hurl_result).collect::>();
+ curl::write_curl(&results, filename)?;
+ Ok(())
+}
+
+/// Creates a JUnit report for this run.
fn create_junit_report(runs: &[HurlRun], filename: &Path) -> Result<(), CliError> {
let testcases = runs
.iter()
@@ -171,7 +181,7 @@ fn create_junit_report(runs: &[HurlRun], filename: &Path) -> Result<(), CliError
Ok(())
}
-/// Create a TAP report for this run.
+/// Creates a TAP report for this run.
fn create_tap_report(runs: &[HurlRun], filename: &Path) -> Result<(), CliError> {
let testcases = runs
.iter()
@@ -181,7 +191,7 @@ fn create_tap_report(runs: &[HurlRun], filename: &Path) -> Result<(), CliError>
Ok(())
}
-/// Create an HTML report for this run.
+/// Creates an HTML report for this run.
fn create_html_report(runs: &[HurlRun], dir_path: &Path) -> Result<(), CliError> {
// We ensure that the containing folder exists.
let store_path = dir_path.join("store");
@@ -198,7 +208,7 @@ fn create_html_report(runs: &[HurlRun], dir_path: &Path) -> Result<(), CliError>
Ok(())
}
-/// Create an JSON report for this run.
+/// Creates an JSON report for this run.
fn create_json_report(runs: &[HurlRun], dir_path: &Path) -> Result<(), CliError> {
// We ensure that the containing folder exists.
let store_path = dir_path.join("store");
diff --git a/packages/hurl/src/report/curl.rs b/packages/hurl/src/report/curl.rs
new file mode 100644
index 00000000000..f3100e2c9a6
--- /dev/null
+++ b/packages/hurl/src/report/curl.rs
@@ -0,0 +1,49 @@
+/*
+ * Hurl (https://hurl.dev)
+ * Copyright (C) 2024 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 crate::report::ReportError;
+use crate::runner::HurlResult;
+use std::fs::OpenOptions;
+use std::io::Write;
+use std::path::Path;
+
+/// Creates a curl export from a list of `hurl_results`.
+pub fn write_curl(hurl_results: &[&HurlResult], filename: &Path) -> Result<(), ReportError> {
+ // We ensure that parent folder is created.
+ if let Some(parent) = filename.parent() {
+ match std::fs::create_dir_all(parent) {
+ Ok(_) => {}
+ Err(err) => return Err(ReportError::from_error(err, filename, "Issue curl export")),
+ }
+ }
+ let mut file = OpenOptions::new()
+ .create(true)
+ .truncate(true)
+ .write(true)
+ .append(false)
+ .open(filename)?;
+ let mut cmds = hurl_results
+ .iter()
+ .flat_map(|h| &h.entries)
+ .map(|e| e.curl_cmd.to_string())
+ .collect::>()
+ .join("\n");
+ cmds.push('\n');
+ file.write_all(cmds.as_bytes())?;
+
+ Ok(())
+}
diff --git a/packages/hurl/src/report/mod.rs b/packages/hurl/src/report/mod.rs
index 7d70f8ab7e0..d1b2d1f224a 100644
--- a/packages/hurl/src/report/mod.rs
+++ b/packages/hurl/src/report/mod.rs
@@ -19,9 +19,11 @@
//! Various reports for Hurl runs (JUnit, HTML etc...) A report aggregates multiple runs into
//! a single unit.
+pub mod curl;
mod error;
pub mod html;
pub mod json;
pub mod junit;
pub mod tap;
+
pub use error::ReportError;