#template #hcl #yaml #yaml-config #json #cli #render-template

bin+lib template-cli

基于 JSON、YAML 或 HCL 配置的模板化 CLI

16 个版本

0.4.1 2024 年 4 月 27 日
0.3.7 2023 年 11 月 4 日
0.3.3 2023 年 7 月 4 日
0.2.0 2023 年 3 月 3 日
0.1.0 2022 年 12 月 11 日

#43模板引擎

Download history 167/week @ 2024-04-25 8/week @ 2024-05-02

1,110 每月下载量

MIT 许可证

60KB
962

模板 crates.io Github 状态

基于 JSON、YAML 或 HCL 配置的 CLI。

灵感来源于 Consul TemplateSprigHandlebarsMustache 以及 KotlinRustGoPython 的标准库。

安装

Cargo

使用

cargo install template-cli

预编译的二进制文件

您可以从 最新版本页面 下载适用于多种架构和操作系统的预编译二进制文件。

Docker

二进制文件以 Docker 镜像 的形式提供。

在下面的使用说明中,将所有 template 的用法替换为 docker run --rm ghcr.io/hiddewie/template

使用方法

template --template ./path/to/template.template --configuration ./path/to/configuration.json

使用 --help 选项显示使用信息

template --help

输出如下

CLI for templating based on JSON, YAML or HCL configuration

Usage: template [OPTIONS] --template <TEMPLATE> --configuration <CONFIGURATION>

Options:
  -t, --template <TEMPLATE>            Absolute or relative path to the template file
  -c, --configuration <CONFIGURATION>  Absolute or relative path to the configuration file. Provide `-` as path to read the configuration input from the standard input stream
  -f, --format <FORMAT>                Specify the format of the configuration input. Useful when the configuration file has a non-standard extension, or when the input is given in the standard input stream [possible values: json, hcl, yaml]
  -h, --help                           Print help information
  -V, --version                        Print version information

输出将渲染到标准输出流。日志消息将输出到标准错误流。可以通过使用 RUST_LOG 环境变量 来控制日志级别。

此工具与其他命令行工具配合良好,遵循 UNIX 哲学,例如

curl -s 'https://dummyjson.com/products' \
  | jq '{ items: .products }' \
  | template --configuration - --template products.template \
  | head -n 5 \
  > product-list.txt

退出代码

  • 0:成功。标准输出包含渲染的模板。
  • 1:无法读取模板文件。
  • 2:未给出所需的 CLI 选项之一。
  • 3:无法读取配置文件。
  • 4:无法解析配置文件。
  • 5:无法解析模板文件。
  • 6:无法渲染模板。
  • 101:恐慌。发生了意外的错误,并且未正确处理。请创建一个问题来报告配置、模板和错误输出。

安全性

此软件

  • 读取配置文件或标准输入
  • 读取模板文件
  • 读取环境以设置日志级别,如果使用了 environment 函数
  • 不写入任何文件
  • 不建立任何网络连接

配置

  • JSON,扩展名 .json,默认解析格式
  • YAML,扩展名 .yml.yaml
  • HCL,扩展名 .hcl

如果配置文件具有不同的扩展名,或者在标准输入流中提供配置时,可以使用 --format 选项配置配置格式。

模板化

有关正式模板语法的详细信息,请参阅 Pest 语法

建议模板文件使用扩展名 .template

渲染配置数据

配置

{
  "value": "Hello",
  "nested": {
    "value": "world"
  }
}

使用模板

{% value %} {% nested.value %}{% does_not_exist %}!

生成输出

Hello world!

YAML 配置文件

value: Hello
nested:
  value: world

或 HCL 配置文件

value = "Hello"
nested {
  value = "world"
}

将生成等效的输出。

注释

注释将被忽略,内容不会作为输出渲染

This is rendered {# comment #} 
{# {% for item in array %}
This is not a loop
{% end %} #}
This is rendered

文字

Null: {% null %}
Boolean: {% true %} and {% false %}
Integer: {% 0 %}, {% -0 %}, {% -100 %} and {% 100 %}
Floating point: {% .0 %}, {% 0. %}, {% -1.0 %}, {% 10.47e1 %} and {% -1.47e-10 %}
String: {% "" %} and {% "value" %}
Array: {% [] %}, {% [1] %} and {% ["", null, expression, [], {}, ] %}
Dictionary: {% {} %}, {% {a:1} %} and {% {item: expression, " space ": "spacy", "array": [], } %}

流程控制

使用 if / unlesselifelse 进行测试表达式

{% if some_expression %}
  Rendered when the expression is truthy
{% elif else_if_expression %}
  Rendered when the above is not true and the expression is truthy
{% else %}
  Rendered when the above are not truthy
{% end %}

{% unless expression %}
  Rendered when the expression is falsy
{% end %}

使用 forelse 在数组上循环

{% for item in array_value %}
  Rendered content for each item
  reference a property in iteration array: {% item.property %}
  0-based index: {% loop.index0 %}
  1-based index: {% loop.index1 %}
  true if this is the first iteration: {% loop.first %}
  true if this is the last iteration: {% loop.last %}
  the number of iterations in the loop: {% loop.size %}
  alternate items in an array, treating it as circular: {% loop.index0 | alternate(["one", "two", "three"]) %}
{% else %}
  Rendered when the array did not contain any values
{% end %}

注意,在 for 循环内部,loop 变量提供了有关循环迭代的详细信息。

上下文变量

使用 with 在块内设置变量

{% with a = 1 %}
  Value is {% a %}
{% end %}

函数

通过使用管道 | 运算符在模板中应用函数

{% value | function1 | function2 | function3 %}

某些函数需要一个或多个参数,可以通过括号传递

{% value | function(argument1, argument2) %}

通用函数

  • default(value):如果参数是虚假的,则返回默认值。
  • coalesce(value):如果参数是 null,则返回默认值。
  • toString:将值转换为字符串。
  • empty:判断值是否为“非真”,即null00.0-0.0""" "[]{}
  • toJsontoPrettyJson:将值格式化为JSON,可以是紧凑格式或多行缩进格式。

字符串函数

  • length:字符串的长度。
  • upperCase:将字符串转换为大写。
  • lowerCase:将字符串转换为小写。
  • kebabCase:将字符串转换为中划线命名法:lowercase-words-joined-with-dashes
  • snakeCase:将字符串转换为蛇形命名法:lowercase_words_joined_with_underscores
  • camelCase:将字符串转换为驼峰命名法:capitalizedWordsWithoutSpaces
  • pascalCase:将字符串转换为帕斯卡命名法:CapitalizedWordsWithoutSpaces
  • capitalize:将字符串的第一个字符转换为大写。
  • capitalizeWords:将每个单词的第一个字符转换为大写。
  • environment:读取环境变量。
  • reverse:字符串的逆序。
  • split(splitter):根据splitter在每个出现处分割字符串。
  • lines:将字符串分割成一个由行组成的数组。首尾空白将被删除。
  • parseBoolean:解析布尔值。
  • parseInteger:解析整数。
  • parseDecimal:解析十进制数。
  • parseNumber:解析整数或十进制数。
  • substring(from)substring(from, to):从字符串中创建子字符串。from是包含的,to是不包含的。
  • take(n):从字符串中取前n个字符。
  • drop(n):从字符串中删除前n个字符。
  • fromJson:从JSON中解析值。
  • abbreviate:确保值不超过n个字符。如果更长,值将被缩短至n-1个字符,并后缀
  • trimLefttrimRighttrim:从字符串的左侧、右侧或两侧删除空白。
  • matches(regex):检查字符串是否匹配正则表达式。
  • replace(search, replacement):用替换字符串替换搜索字符串。
  • regexReplace(search, replacement):用替换内容替换正则表达式匹配到的内容。替换内容可以包含 $0(整个匹配),$1$2 等,用于匹配的分组,以及 $name 用于匹配命名的分组。
  • contains(substring):字符串是否包含子字符串。
  • startsWith(start)endsWith(end):字符串是否以给定的值开始或结束。

数组函数

  • length:数组的长度。
  • reverse:数组的反向顺序。
  • take(n):从数组中取前 n 项。
  • drop(n):从数组中移除前 n 项。
  • first:数组中的第一项,如果存在的话。
  • last:数组中的最后一项,如果存在的话。
  • index(n):数组中的第 n 项,如果存在的话。
  • contains(value):数组是否包含指定的值。
  • unique:从数组中删除所有重复项。
  • all:如果所有参数都是真值,则为真,表示逻辑与(∧)。
  • any:如果任何参数都是真值,则为真,表示逻辑或(∨)。
  • none:如果所有参数都是假值,则为真。
  • some:如果任何参数是假值,则为真。
  • chunked(items, overlap):将数组分割成数组的数组,每个子数组最多包含 items 项,与上一个块重叠 overlap 项。

字典函数

  • length:字典的大小。
  • containsKey(key):字典是否包含指定的键。
  • containsValue(value):字典是否包含指定的值。
  • keys:字典的键。
  • values:字典的值。
  • invert:值变为键,键变为值。值只能是字符串。不保留重复值。

布尔函数

  • negate:布尔值的否定,表示逻辑非(¬)。

日期/时间函数

  • parseFormatDateTime(parse, format):解析日期/时间,并按给定格式格式化。如果输入是字符串 now,则将其解析为当前时刻。否则,解析和格式化遵循 strftime 规范。

调试

可以使用 debug 语句来记录表达式及其计算结果,而不会将内容输出到模板输出中。

Template content...
{% debug some_value %}
... more template content

日志输出

[2023-03-05T11:18:56Z INFO  template_cli::evaluate] Debug expression: some_value = {"b":"c"}

可以使用 assert 函数来断言表达式的预期值。如果断言失败,模板渲染将因给定的断言消息而失败,并退出程序并记录错误代码。

{% true | assert(true, "This is fine") %}
{% false | assert(true, "This is not OK") %}

模板将退出并带有错误代码,并记录输出

[2023-03-19T16:02:48Z ERROR template] ERROR: Could not render template: Assertion failed: Expected value 'true' but found 'false': This is not OK

开发

构建

cargo build

测试

cargo test

发布

访问发布工作流程

点击 运行工作流程 按钮,并输入以下信息

  • 分支: master
  • 版本: 即将发布的下一个版本,例如 1.2.3

依赖项

~14MB
~252K SLoC