我有以下YAML:
paths:
patha: /path/to/root/a
pathb: /path/to/root/b
pathc: /path/to/root/c
我如何“正常化”它,通过从三个路径中删除/path/到/root/,并将其作为自己的设置,类似于:
paths:
root: /path/to/root/
patha: *root* + a
pathb: *root* + b
pathc: *root* + c
显然这是无效的,我瞎编的。真正的语法是什么?这能做到吗?
我用Python编写了自己的库来扩展从目录中加载的变量,其层次结构如下:
/root
|
+- /proj1
|
+- config.yaml
|
+- /proj2
|
+- config.yaml
|
... and so on ...
这里的关键区别是,扩展必须在所有配置完成后才应用。Yaml文件被加载,其中来自下一个文件的变量可以覆盖来自前一个文件的变量,所以伪代码应该是这样的:
env = YamlEnv()
env.load('/root/proj1/config.yaml')
env.load('/root/proj1/proj2/config.yaml')
...
env.expand()
作为一个附加选项,xonsh脚本可以将结果变量导出到环境变量中(请参阅yaml_update_global_vars函数)。
脚本:
https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/cmdoplib/cmdoplib.yaml.xsh
https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.yaml.py
优点:
简单,不支持递归和嵌套变量
可以将未定义的变量替换为占位符(${MYUNDEFINEDVAR} -> *$/{MYUNDEFINEDVAR})
可以从环境变量(${env:MYVAR}
${env:MYVAR:path}可以替换所有的\\ to / in路径变量
缺点:
不支持嵌套变量,因此不能展开嵌套字典中的值(例如${MYSCOPE. xml)。MYVAR}未实现)
不检测展开递归,包括递归后的占位符放
是的,使用自定义标签。Python中的示例,使用!join标记连接数组中的字符串:
import yaml
## define custom tag handler
def join(loader, node):
seq = loader.construct_sequence(node)
return ''.join([str(i) for i in seq])
## register the tag handler
yaml.add_constructor('!join', join)
## using your sample data
yaml.load("""
paths:
root: &BASE /path/to/root/
patha: !join [*BASE, a]
pathb: !join [*BASE, b]
pathc: !join [*BASE, c]
""")
结果是:
{
'paths': {
'patha': '/path/to/root/a',
'pathb': '/path/to/root/b',
'pathc': '/path/to/root/c',
'root': '/path/to/root/'
}
}
join的参数数组可以包含任意数量的任何数据类型的元素,只要它们可以转换为字符串,因此!join [*a, "/", *b, "/", *c]就是您所期望的那样。