问题描述
Poetry 有一种使用 poetry run <entrypoint>
运行 Python 入口点的好方法。使用 Python 或 Bash 以编程方式从 <entrypoints>
中获取 pyproject.toml
列表的最佳方法是什么?
例如,pyproject.toml
:
[tool.poetry]
name = "random-tool"
version = "1.0"
[tool.poetry.scripts]
tool = "tool.function:main"
other_tool = "other_tool.function:main"
all_the_tools = "other_tool.function:all"
输出为:
entrypoint = [ "tool","other_tool","all_the_tools" ]
解决方法
使用 python 这很容易,因为您可以使用 toml 将 pyproject.toml
文件解析为字典:
import toml
pyproject = toml.load("pyproject.toml")
print(pyproject["tool"]["poetry"]["scripts"].keys())
,
OP 在评论中表示希望将端点收集到一个可以在以后迭代的结构中。
对于这个答案,我将专注于一个 bash/array
想法......
第一个问题是从 pyproject.toml
文件中解析所需的数据;我的示例文件:
$ cat poetry.toml
[tool.poetry]
name = "random-tool"
version = "1.0"
[tool.poetry.scripts]
tool = "tool.function:main"
other_tool = "other_tool.function:main"
all_the_tools = "other_tool.function:all"
[tool.poetry.other_stuff] # add some gibberish to demonstrate extracting data from middle of file
a = "a"
b = "b"
c = "c"
解析所需数据的一个sed
想法:
$ sed -En '1,/\[tool.poetry.scripts\]/d;/^$/,$d;s/^([^ ]+) .*$/\1/p' poetry.toml
tool
other_tool
all_the_tools
地点:
-
-En
- 启用E
扩展的正则表达式支持并禁止打印模式空间 (n
) -
1,/\[tool.poetry.scripts\]/d
- 删除从第 1 行到包含字符串[tool.poetry.scripts\]
的行范围内的所有内容 -
/^$/,$d
- 删除从第一个空行 (^$
) 到文件末尾 ($
) 范围内的所有内容 -
s/^([^ ]+) .*$)/\1/p
- 将第一个捕获组定义为行首,但不包括第一个空格 (([^ ]+)
),然后打印第一个捕获组 (\1/p
)
使用 awk
的一个想法:
$ awk '
/\[tool.poetry.scripts\]/ { extract=1 # set "extract" flag
next # go to next record
}
# when "extract" flag = 1:
extract { if ( NF == 0) # if no fields (ie,blank line) then
exit # exit processing
print $1 # else print first field
}
' poetry.toml
tool
other_tool
all_the_tools
或者作为单线:
$ awk '/\[tool.poetry.scripts\]/ { extract=1 ; next } extract { if ( NF == 0) { exit } ; print $1}' poetry.toml
tool
other_tool
all_the_tools
从这里有几种方法可以将这些数据加载到 bash
数组结构中;使用 mapfile
的一个想法:
# load sed output into array endpoints[]
$ mapfile -t endpoints < <(sed -En '1,$d;s/^([^ ]+) .*$/\1/p' poetry.toml)
# display contents of the endpoints[] array
$ typeset -p endpoints
declare -a endpoints=([0]="tool" [1]="other_tool" [2]="all_the_tools")
此时数据已经加载到endpoints[]
数组中,可以在以后迭代,例如:
for i in "${!endpoints[@]}"
do
echo "endpoints[${i}] = ${endpoints[${i}]}"
done
产生:
endpoints[0] = tool
endpoints[1] = other_tool
endpoints[2] = all_the_tools