1 个不稳定版本
0.0.1-beta.1 | 2023年4月24日 |
---|
#441 in 命令行界面
3MB
33K SLoC
TomLyre
提供了一种处理配置文件的工具,您可以使用它自由地探索 toml、yaml、json、ron、bson、Lisp S-exp 和 xml,并发现其中的乐趣。
默认情况下,bson 和 xml 功能未启用。
功能
此工具的核心功能仅三个
- 转换 (conv)
- 获取 (get)
- 设置/修改 (set)
其他所有功能都是附加功能,例如设置主题和表格样式。
使用 --帮助
获取详细信息。
tomlyre set
等同于tomlyre set -h
,它输出简明扼要的帮助信息。tomlyre set --help
输出非常详细的信息。- 同样,其他子命令也可以调用
--帮助
。
get --help |
conv --help |
它甚至支持 L10n(本地化)(资源位于 assets/l10n 目录)。遗憾的是,目前存在许多翻译错误。😭
如果您喜欢它,任何人都可以改善翻译。
如果您不知道如何操作,请随时提交问题。
西班牙语(西班牙) | 德语(德国) |
日语 | 阿拉伯语 |
葡萄牙语(巴西) | 法语(法国) |
主题
使用 --theme
参数(可以缩写为 -t
)来指定主题,例如 tomlyre -t "One Dark" conv test.yml -t json
。
子命令
conv
中的-t
指的是--to
,而根命令中的-t
是--theme
。
未指定主题名称时,将列出所有主题。
以下为内置主题,但您也可以手动加载一组主题并指定名称,而不是使用内置主题。
大多数这些主题使用 MIT 许可证,您可以在 assets/theme 目录中找到内置主题和相关许可证文件。
表格样式
使用 --table-style
(可以缩写为 --ts
)来指定表格样式。例如,使用 --table-style markdown
或 --ts md
可以指定表格样式为 markdown。
tomlyre --ts md get Cargo.toml -k profile.fat
profile.fat | 类型 | 值 |
---|---|---|
继承 | 字符串 | 瘦 |
lto | 字符串 | fat |
opt-level | 字符串 | z |
以下为内置表格样式:(非等宽字体可能会引起布局问题。)
style: default
╭─────────┬──────────┬────────────╮
│ Version ┆ Codename ┆ Created │
├─────────┼──────────┼────────────┤
│ 10 ┆ Buster ┆ 2017-06-17 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 11 ┆ Bullseye ┆ 2019-07-16 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 12 ┆ Bookworm ┆ 2021-08-14 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13 ┆ Trixie ┆ 2023 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 14 ┆ Forky ┆ 2025 │
╰─────────┴──────────┴────────────╯
style: nothing
Version Codename Created
10 Buster 2017-06-17
11 Bullseye 2019-07-16
12 Bookworm 2021-08-14
13 Trixie 2023
14 Forky 2025
style: ascii
+---------+----------+------------+
| Version | Codename | Created |
+=================================+
| 10 | Buster | 2017-06-17 |
|---------+----------+------------|
| 11 | Bullseye | 2019-07-16 |
|---------+----------+------------|
| 12 | Bookworm | 2021-08-14 |
|---------+----------+------------|
| 13 | Trixie | 2023 |
|---------+----------+------------|
| 14 | Forky | 2025 |
+---------+----------+------------+
style: ascii-borders
+---------------------------------+
| Version Codename Created |
+=================================+
| 10 Buster 2017-06-17 |
| 11 Bullseye 2019-07-16 |
| 12 Bookworm 2021-08-14 |
| 13 Trixie 2023 |
| 14 Forky 2025 |
+---------------------------------+
style: right-u8-fat
┌─────────┬──────────┬────────────┐
│ Version │ Codename │ Created │
╞═════════╪══════════╪════════════╡
│ 10 │ Buster │ 2017-06-17 │
├─────────┼──────────┼────────────┤
│ 11 │ Bullseye │ 2019-07-16 │
├─────────┼──────────┼────────────┤
│ 12 │ Bookworm │ 2021-08-14 │
├─────────┼──────────┼────────────┤
│ 13 │ Trixie │ 2023 │
├─────────┼──────────┼────────────┤
│ 14 │ Forky │ 2025 │
└─────────┴──────────┴────────────┘
style: right-u8
┌─────────┬──────────┬────────────┐
│ Version │ Codename │ Created │
├─────────┼──────────┼────────────┤
│ 10 │ Buster │ 2017-06-17 │
├─────────┼──────────┼────────────┤
│ 11 │ Bullseye │ 2019-07-16 │
├─────────┼──────────┼────────────┤
│ 12 │ Bookworm │ 2021-08-14 │
├─────────┼──────────┼────────────┤
│ 13 │ Trixie │ 2023 │
├─────────┼──────────┼────────────┤
│ 14 │ Forky │ 2025 │
└─────────┴──────────┴────────────┘
style: right-u8-thin
┌─────────┬──────────┬────────────┐
│ Version ┆ Codename ┆ Created │
├─────────┼──────────┼────────────┤
│ 10 ┆ Buster ┆ 2017-06-17 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 11 ┆ Bullseye ┆ 2019-07-16 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 12 ┆ Bookworm ┆ 2021-08-14 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13 ┆ Trixie ┆ 2023 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 14 ┆ Forky ┆ 2025 │
└─────────┴──────────┴────────────┘
style: u8
┌─────────┬──────────┬────────────┐
│ Version ┆ Codename ┆ Created │
╞═════════╪══════════╪════════════╡
│ 10 ┆ Buster ┆ 2017-06-17 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 11 ┆ Bullseye ┆ 2019-07-16 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 12 ┆ Bookworm ┆ 2021-08-14 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13 ┆ Trixie ┆ 2023 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 14 ┆ Forky ┆ 2025 │
└─────────┴──────────┴────────────┘
style: u8-no-dividers
┌─────────┬──────────┬────────────┐
│ Version ┆ Codename ┆ Created │
╞═════════╪══════════╪════════════╡
│ 10 ┆ Buster ┆ 2017-06-17 │
│ 11 ┆ Bullseye ┆ 2019-07-16 │
│ 12 ┆ Bookworm ┆ 2021-08-14 │
│ 13 ┆ Trixie ┆ 2023 │
│ 14 ┆ Forky ┆ 2025 │
└─────────┴──────────┴────────────┘
style: u8-borders
┌─────────────────────────────────┐
│ Version Codename Created │
╞═════════════════════════════════╡
│ 10 Buster 2017-06-17 │
│ 11 Bullseye 2019-07-16 │
│ 12 Bookworm 2021-08-14 │
│ 13 Trixie 2023 │
│ 14 Forky 2025 │
└─────────────────────────────────┘
style: u8-no-borders
Version ┆ Codename ┆ Created
═════════╪══════════╪════════════
10 ┆ Buster ┆ 2017-06-17
╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌
11 ┆ Bullseye ┆ 2019-07-16
╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌
12 ┆ Bookworm ┆ 2021-08-14
╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌
13 ┆ Trixie ┆ 2023
╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌
14 ┆ Forky ┆ 2025
style: horizontal
---------------------------------
Version Codename Created
=================================
10 Buster 2017-06-17
---------------------------------
11 Bullseye 2019-07-16
---------------------------------
12 Bookworm 2021-08-14
---------------------------------
13 Trixie 2023
---------------------------------
14 Forky 2025
---------------------------------
style: round-u8
╭─────────┬──────────┬────────────╮
│ Version │ Codename │ Created │
├─────────┼──────────┼────────────┤
│ 10 │ Buster │ 2017-06-17 │
├─────────┼──────────┼────────────┤
│ 11 │ Bullseye │ 2019-07-16 │
├─────────┼──────────┼────────────┤
│ 12 │ Bookworm │ 2021-08-14 │
├─────────┼──────────┼────────────┤
│ 13 │ Trixie │ 2023 │
├─────────┼──────────┼────────────┤
│ 14 │ Forky │ 2025 │
╰─────────┴──────────┴────────────╯
style: round-u8-fat
╭─────────┬──────────┬────────────╮
│ Version ┆ Codename ┆ Created │
╞═════════╪══════════╪════════════╡
│ 10 ┆ Buster ┆ 2017-06-17 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 11 ┆ Bullseye ┆ 2019-07-16 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 12 ┆ Bookworm ┆ 2021-08-14 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13 ┆ Trixie ┆ 2023 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 14 ┆ Forky ┆ 2025 │
╰─────────┴──────────┴────────────╯
style: markdown
| Version | Codename | Created |
|---------|----------|------------|
| 10 | Buster | 2017-06-17 |
| 11 | Bullseye | 2019-07-16 |
| 12 | Bookworm | 2021-08-14 |
| 13 | Trixie | 2023 |
| 14 | Forky | 2025 |
conv
警告:如果两个配置之间的数据类型不完全兼容,数据类型将在转换后更改。
例如,ron 有一个 char
类型,表示一个字符。
以 hello, 世界
为例。这是一个字符串。'h' 是 char,"h" 是字符串。 "世界" 是字符串,'世' 是 char。
但是,json 1.0
和 toml 1.0
都没有 char
类型。
hello.ron
{
"s": '世',
"j": '界',
}
tomlyre c hello.ron -t json
json
{
"j": "界",
"s": "世"
}
因此,将 char
从 ron
转换为 json 1.0
将得到一个字符串。
例如,目前许多配置格式支持两个特殊浮点数: NaN 和 inf,但 json 1.0
不支持它们。
在 json 1.0
中,它们都将变为 null
。
f64-map.toml
[double-float-map]
not-a-num = nan
infinity = inf
tomlyre conv f64-map.toml -t ./f.yaml --save
f.yaml
double-float-map:
infinity: .inf
not-a-num: .nan
tomlyre conv f.yaml -t ron --sv
f.ron
{
"double-float-map": {
"infinity": inf,
"not-a-num": NaN,
},
}
tomlyre conv f.ron -t sexp
sexp 指的是 Lisp S-Expressions。
(("double-float-map" ("infinity" . inf) ("not-a-num" . NaN)))
tomlyre conv f.ron -t json
{
"double-float-map": {
"infinity": null,
"not-a-num": null
}
}
tomlyre conv f.ron -t json5
{ "double-float-map": { infinity: Infinity, "not-a-num": NaN } }
问题:JSON类型具有,而其他格式没有的数据类型是什么?
答案:null
例如,toml 1.0
和 ron
不支持 null
值。如果您将包含 null
的 json 1.0
配置转换为 toml
,toml
将直接报告错误,而 ron
将将其转换为空元组 ()
,这通常被称为 单元 类型。
注意:ron 使用
Option<T>
类型,其值为Some(T)
或None
,而不是null
。
此外,不同的配置格式之间存在许多差异,我们并没有列出所有。
获取和设置
当您使用 set
子命令指定一个键但未指定值时,它等同于更详细的 set
版本。
例如,我们使用以下命令从 stdin 读取和解析数据
-
后的get
表示源是 stdin 而不是特定文件
curl -sL https://raw.githubusercontent.com/2moe/tomlyre/main/Cargo.toml | tomlyre get - -k profile.thin.strip
当使用 get
时,stdout 将输出 true
。
但是当我们把 get
改为 set
,它将输出
true
key: ["profile", "thin", "strip"]
type: boolean
value:
true
问题:输出更多信息更好吗?
答案:不一定!
这主要取决于我们的预期用途。
当我们需要用脚本来获取特定值时,只需要有效信息。额外信息不仅无用,还可能干扰数据检索。
相反,当我们需要手动修改数据时,有具体信息通常更好。
设置
我们可以使用 --help
与 set
子命令来获取详细信息。
基本用法是:set [source file] -k [keys separated by "."] [options for specifying data type] [value(s) for the specified data type (may be empty or multiple)]
例如,set test.toml --key package.edition --str 2024
。
注意
只有当src
的格式为toml
时,才会保留注释,否则不会。其他格式在修改之前将首先转换为toml
,并且转换后的文件将不会保留注释。
以下是它支持的一些数据类型
基本数据类型
选项 | 别名 | 值类型 | 描述 | 示例 |
---|---|---|---|---|
-s | --str | 字符串 | 字符串类型 | -s"1.114.5-beta.1" |
-b | --bool | 布尔型 | 布尔类型 | -btrue |
--f64 | f64 | 双精度浮点数 | 64位浮点数 314e-2 |
|
-n | --num/--int | i64 | 64位有符号整数 | -n2048 |
-a | --arr | Vec<字符串> |
字符串数组 | -a hello-a world |
--num-arr | --na | Vec<i64> |
i64数组 | --na11--na -3 |
--f64-arr | --fa | Vec<f64> |
双精度浮点数数组 | --fa3.14--fa2.71828182 |
--bool-arr | --ba | Vec<布尔型> |
布尔数组 | --ba true --ba false |
-i | --inline-table | Vec<(键,值)> |
内联表 | -i name sd-i os android |
--rm | 删除指定的键及其值 |
此外,还有一些不是“基本”的数据类型,例如“标准表”、“表数组”和DateTime。
标准表与内联表非常相似。如果您不知道该使用哪一个,请使用内联表(-i
)而不是标准表(-m
)。
对于除了toml
之外的格式,请使用-i
创建新表,而不是使用-m
!
假设在hello.toml
中,有一个名为test
的表数组,索引0处的映射有一个名为kk
的键,其值为v
。
[[test]]
kk = "v"
set hello.toml -k test.
test. | 类型 | 值 |
---|---|---|
0.kk | 字符串 | v |
key: ["test"]
type: array of tables
value:
[{ kk = "v" }]
让我们使用-m
或--table
创建一个子表。
set hello.toml --key test.0.a --map hello world --pre
输出
key: ["test", "0", "a"]
type: table
new value: hello = "world"
test.0 | 类型 | 新值 |
---|---|---|
kk | 字符串 | v |
a.hello | 字符串 | world |
[[test]]
kk = "v"
[test.a]
hello = "world"
看起来没有问题。让我们尝试使用内联表。
set hello.toml -k test.0.a -i hello world --pre
输出
[[test]]
kk = "v"
a = { hello = "world" }
对于这个案例,标准表和内联表是相同的。(虽然它们看起来不同,但它们的解析结果相同。)
然而,当键是test.0.x.y.z
并且内部有多个不存在的嵌套子表时,您可以尝试分别使用-m
和-i
。
亲自尝试后,我相信您会明白为什么不要使用-m
。
日志级别
从高到低,详细程度为trace
> debug
> info
> warn
> error
。
trace
是最详细的。
默认级别是info
。
我们可以通过设置环境变量来修改日志级别
env RUST_LOG=debug tomlyre
无关话题
原始设计意图
问题:这个工具的原始设计意图是什么?
答案:原始意图是允许每个人都能以简单优雅的方式在CLI中查询和修改配置文件。
大约一年或两年前,我在另一个项目的文档中提到
- 该项目随后将使用
toml
格式进行配置。- 并介绍了一些具体细节
- 例如使用
get
子命令来检索 - 使用
set
来修改
- 例如使用
- 并介绍了一些具体细节
在设计时,我在是否使用toml、yaml、ron或更进一步直接使用数据库之间犹豫。
起初,我已经编写了同时支持toml和yaml的代码。
这涉及到解析优先级的问题。
当以下文件同时存在时,程序应该先解析哪一个?
- cfg.toml
- cfg.Toml
- cfg.yaml
- cfg.yml
- cfg.YAML
- cfg.YML
- cfg.Yaml
此时,需要有一个核心配置来指定用户配置。
所以问题是,核心配置应该是什么格式?
我们可以使用环境变量来指定核心配置的格式。
这样看起来似乎并不困难!
注意:不同的格式有不同的规范,而与不同格式的兼容性需要了解它们之间的差异。
如果您想支持更多格式,这将变得有些繁琐。
有些事情本身并不难,但处理起来需要大量的时间和努力。
最后,我将它分离成了单独的小工具。
这样,每个人都可以通过这个小工具间接支持多种格式。(我们看到的是yaml,但实际上修改的是toml文件)
yaml
问:为什么支持多种配置格式?很多人说
yaml
更易读。我们难道只能支持yaml吗?
虽然我愿意坚定地回答“不”,但实际上这取决于您和您的用户的需求。
YAML支持的特性比TOML和JSON更高级,例如引用、包含和标签。
- 锚点和别名:允许在同一个文档中重复使用相同的数据结构或节点。
- 引用:允许从YAML文档中的其他节点引用值。
- 自定义标签:允许定义自定义标签以更好地控制YAML数据类型的解析。
- 包含:允许将多个YAML文件合并到一个文件中,提高代码复用性。
如果您需要这些功能,那么使用YAML是一个很好的选择。
如果您不需要这些功能,选择YAML是否值得呢?
这个问题值得讨论。
支持方:特性越多越好。我可能不会使用它们,但您不能没有它们。
反对方:太多的特性会增加复杂性和困惑。
除了平衡可读性和功能性之外,还应考虑普通用户的感受。
如果配置文件包含复杂嵌套的结构,而您的用户没有“高级”编辑器,那么yaml的缩进功能可能很容易导致错误。
如果您的用户可能在早期的Windows上使用notepad
编写配置,那么TOML是否比yaml更好?
早期是指2022年之前在Windows 10上,当时
notepad.exe
只有基本功能。
Windows工具不断进化,也许有一天notepad也会拥有像语法高亮、显示空白字符和代码补全这样的高级功能。因此,我将它限制在“早期”。
以Windows为例可能不合适,因为有很多编辑器软件。
即使你在街上找到一个孩子,他也能轻松地帮助你安装编辑器软件。
所以,我们将问题转化为:“嗨,我的环境是RISC-V架构,uClibc Linux,没有包管理器。你能帮我在你的电脑上设置一个交叉编译环境吗?然后编译一个超轻量级的编辑器,它需要语法高亮和可以突出显示空白字符。”
嗯,不要让那个孩子太难了。
依赖项
~15–26MB
~361K SLoC