diff --git a/CHANGELOG.md b/CHANGELOG.md index cedbc6e3..a88e198b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ All notable changes to MiniJinja are documented here. - Reversing bytes and convergint them implicitly to strings will now work more consistently. #619 - Added type hints for the Python binding and relaxed maturin constraint. #590 +- `minijinja-cli` now allows the template name to be set to an empty + string when `--template` is used, to allow suppliying a data file. #624 ## 2.4.0 diff --git a/minijinja-cli/src/cli.rs b/minijinja-cli/src/cli.rs index c4825ace..c24e74fa 100644 --- a/minijinja-cli/src/cli.rs +++ b/minijinja-cli/src/cli.rs @@ -409,12 +409,13 @@ pub fn execute() -> Result { .map(|x| x.as_str()), ) { (None, Some(STDIN_STDOUT)) => (Cow::Borrowed(STDIN_STDOUT), None), + (None, Some("")) => bail!("Empty template names are only valid with --template."), (None, Some(rel_name)) => ( Cow::Owned(cwd.join(rel_name).to_string_lossy().to_string()), None, ), - (Some(source), Some(STDIN_STDOUT)) => (Cow::Borrowed(""), Some(source.clone())), - _ => unreachable!(), + (Some(source), None | Some("")) => (Cow::Borrowed(""), Some(source.clone())), + _ => bail!("When --template is used, a template cannot be passed as argument (only an empty argument is allowed)."), }; let mut output = Output::new(matches.get_one::("output").unwrap())?; diff --git a/minijinja-cli/src/command.rs b/minijinja-cli/src/command.rs index 585c5bb5..1a9c6f01 100644 --- a/minijinja-cli/src/command.rs +++ b/minijinja-cli/src/command.rs @@ -3,6 +3,7 @@ /// application and by build.rs to generate shell completions. use std::path::PathBuf; +use clap::builder::ArgPredicate; use clap::{arg, command, value_parser, ArgAction, Command}; const ADVANCED: &str = "Advanced"; @@ -324,9 +325,12 @@ pub(super) fn make_command() -> Command { This is the path to the input template in MiniJinja/Jinja2 syntax. \ If not provided this defaults to '-' which means the template is \ loaded from stdin. When the format is set to 'auto' which is the \ - default, the extension of the filename is used to detect the format.") + default, the extension of the filename is used to detect the format.\n\n\ + \ + This argument can be set to an empty string when --template is provided \ + to allow a data file to be supplied.") .default_value("-") - .conflicts_with("template"), + .default_value_if("template", ArgPredicate::IsPresent, None), arg!(data_file: [DATA_FILE] "Path to the data file") .long_help("\ Path to the data file in the given format.\n\n\ diff --git a/minijinja-cli/tests/test_basic.rs b/minijinja-cli/tests/test_basic.rs index 4ddc654a..48c97646 100644 --- a/minijinja-cli/tests/test_basic.rs +++ b/minijinja-cli/tests/test_basic.rs @@ -656,6 +656,63 @@ fn test_template_string() { "###); } +#[test] +#[allow(clippy::suspicious_command_arg_space)] +fn test_empty_template_name_with_string_template() { + let input = file_with_contents_and_ext(r#"{"name": "Peter"}"#, ".json"); + assert_cmd_snapshot!( + cli() + .arg("-tHello {{ name }}") + .arg("") + .arg(input.path()) + .arg("--no-newline"), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + Hello Peter + ----- stderr ----- + "###); +} + +#[test] +#[allow(clippy::suspicious_command_arg_space)] +fn test_template_name_with_string_template_fails() { + let input = file_with_contents_and_ext(r#"{"name": "Peter"}"#, ".json"); + assert_cmd_snapshot!( + cli() + .arg("-tHello {{ name }}") + .arg("invalid.tmpl") + .arg(input.path()) + .arg("--no-newline"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + error: When --template is used, a template cannot be passed as argument (only an empty argument is allowed). + "###); +} + +#[test] +fn test_empty_template_name_errors() { + let input = file_with_contents_and_ext(r#"{"name": "Peter"}"#, ".json"); + assert_cmd_snapshot!( + cli() + .arg("") + .arg(input.path()) + .arg("--no-newline"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + error: Empty template names are only valid with --template. + "###); +} + #[test] fn test_print_config_fully_loaded() { assert_cmd_snapshot!(