获取诗歌脚本端点

Get Poetry script endpoints

Poetry 有一个很好的方法 运行 你的 Python 入口点使用 poetry run <entrypoint>。使用 Python 或 Bash 从 pyproject.toml 以编程方式获取 <entrypoints> 列表的最佳方法是什么?

例如,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 这很容易,因为您可以使用 tomlpyproject.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/^([^ ]+) .*$//p' poetry.toml
tool
other_tool
all_the_tools

其中:

  • -En - 启用 Extended 正则表达式支持并禁止打印模式 space (n)
  • 1,/\[tool.poetry.scripts\]/d - 删除范围从第 1 行到包含字符串 [tool.poetry.scripts\]
  • 的行中的所有内容
  • /^$/,$d - 删除从第一个空行 (^$) 到文件末尾 ($)
  • 范围内的所有内容
  • s/^([^ ]+) .*$)//p - 将第一个捕获组定义为行的开始,但不包括第一个 space (([^ ]+)),然后打印第一个捕获组 (/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          # 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 }' poetry.toml
tool
other_tool
all_the_tools


从这里开始,有几种方法可以将此数据加载到 bash 数组结构中;一个想法使用 mapfile:

# load sed output into array endpoints[]

$ mapfile -t endpoints < <(sed -En '1,/\[tool.poetry.scripts\]/d;/^$/,$d;s/^([^ ]+) .*$//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