获取 Poetry 脚本端点

问题描述

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 这很容易,因为您可以使用 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/^([^ ]+) .*$/\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