Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add INI support #532

Merged
merged 7 commits into from
Jul 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,10 @@

All notable changes to MiniJinja are documented here.

## 2.0.4

- minijinja-cli now supports `.ini` files. #532

## 2.0.3

- Added new methods to pycompat: `str.endswith`, `str.rfind`,
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions minijinja-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ json5 = ["serde_json5"]
repl = ["rustyline"]
completions = ["clap_complete", "clap_complete_nushell", "clap_complete_fig"]
unicode = ["minijinja/unicode"]
ini = ["configparser"]

[dependencies]
anyhow = "1.0.74"
@@ -53,6 +54,7 @@ toml = { version = "0.7.6", optional = true }
clap_complete = { version = "4", optional = true }
clap_complete_fig = { version = "4", optional = true }
clap_complete_nushell = { version = "4", optional = true }
configparser = { version = "3.1.0", optional = true }

[build-dependencies]
clap = { version = "4.3.21", default-features = false, features = [
34 changes: 34 additions & 0 deletions minijinja-cli/README.md
Original file line number Diff line number Diff line change
@@ -104,6 +104,8 @@ can be set to stdin at once.
the compiled bytecode.
- `-o`, `--output` `<FILENAME>`:
writes the output to a filename rather than stdout.
- `--select` `<SELECTOR>`:
select a path of the input data.
- `--generate-completion` `<SHELL>`:
generate the completions for the given shell.
- `--version`:
@@ -120,6 +122,37 @@ The following formats are supported:
- `toml` (`*.toml`): TOML
- `cbor` (`*.cbor`): CBOR
- `querystring` (`*.qs`): URL encoded query strings
- `ini` (`*.ini`, `*.config`, `*.properties`): text only INI files

For most formats there is a pretty straightforward mapping into the template
context. The only exception to this is currently INI files where sections are
effectively mandatory. If keys are placed in the unnamed section, the second
is renamed to `default`. You can use `--select` to make a section be implied:

```
minijinja-cli template.j2 input.ini --section default
```

Note that not all formats support all input types. For instance querystring
and INI will only support strings for the most part.

## Selecting

By default the input file is fed directly as context. You can however also
select a sub-portion of this file. For instance if you have a TOML file
where all variables are placed in the `values` section you normally need
to reference the values like so:

```jinja
{{ values.key }}
```

If you however invoke minijinja-cli with `--select=values` you can directly
reference the keys:

```jinja
{{ key }}
```

## Examples

@@ -177,6 +210,7 @@ selected when the defaults are turned off:
* `cbor`: enables CBOR support
* `json5`: enables JSON5 support (instead of JSON)
* `querystring`: enables querystring support
* `ini`: enables INI support
* `datetime`: enables the date and time filters and `now()` function
* `completions`: enables the generation of completions
* `unicode`: enables the unicode identifier support
10 changes: 10 additions & 0 deletions minijinja-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -105,6 +105,8 @@ fn load_data(
Some("toml") => "toml",
#[cfg(feature = "cbor")]
Some("cbor") => "cbor",
#[cfg(feature = "ini")]
Some("ini" | "config" | "properties") => "ini",
_ => bail!("cannot auto detect format from extension"),
}
} else {
@@ -128,6 +130,14 @@ fn load_data(
"toml" => toml::from_str(&contents)?,
#[cfg(feature = "cbor")]
"cbor" => ciborium::from_reader(contents.as_bytes())?,
#[cfg(feature = "ini")]
"ini" => {
let mut config = configparser::ini::Ini::new();
config
.read(contents)
.map_err(|msg| anyhow!("could not load ini: {}", msg))?;
Value::from_serialize(config.get_map_ref())
}
_ => unreachable!(),
};

38 changes: 38 additions & 0 deletions minijinja-cli/tests/test_basic.rs
Original file line number Diff line number Diff line change
@@ -232,6 +232,44 @@ fn test_querystring() {
"###);
}

#[test]
#[cfg(feature = "ini")]
fn test_ini() {
let input = file_with_contents_and_ext("[section]\nfoo = bar", ".ini");
let tmpl = file_with_contents(r#"Hello {{ section.foo }}!"#);

assert_cmd_snapshot!(
cli()
.arg(tmpl.path())
.arg(input.path()),
@r###"
success: true
exit_code: 0
----- stdout -----
Hello bar!

----- stderr -----
"###);

let input = file_with_contents_and_ext("foo = bar", ".ini");
let mut tmpl = NamedTempFile::new().unwrap();
tmpl.write_all(br#"Hello {{ foo }}!"#).unwrap();

assert_cmd_snapshot!(
cli()
.arg("--select=default")
.arg(tmpl.path())
.arg(input.path()),
@r###"
success: true
exit_code: 0
----- stdout -----
Hello bar!

----- stderr -----
"###);
}

#[test]
fn test_context_stdin() {
let tmpl = file_with_contents(r#"Hello {{ foo }}!"#);