#python #python-3.x #bash #python-poetry #toml
Вопрос:
В поэзии есть хороший способ запуска ваших входных точек Python с помощью poetry run <entrypoint>
. Каков был бы лучший способ программно получить список <entrypoints>
из pyproject.toml
с помощью Python или Bash?
Например, в 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" ]
Комментарии:
1. не могли бы вы обновить вопрос, чтобы предоставить более подробную информацию о желаемом результате? вы хотите напечатать буквальную строку
entrypoint = [ ... ]
? хотите ли вы присвоить переменной литеральную строку[ ... ]
entrypoint
(и если да, то говорим ли мы о переменной python или переменной bash)? вы хотите присвоить 3-кратные строки в качестве отдельных значений массиву с именемentrypoint[]
?2. @markp-fuso Я полагаю, что я говорю о наличии переменной bash/python, которую я могу перебирать позже, помогает ли это прояснить?
Ответ №1:
С python это довольно просто, потому что вы можете использовать toml для разбора pyproject.toml
файла в словарь:
import toml
pyproject = toml.load("pyproject.toml")
print(pyproject["tool"]["poetry"]["scripts"].keys())
Ответ №2:
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,/[tool.poetry.scripts]/d;/^$/,$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
Комментарии:
1. Это действительно отличный и хорошо объясненный ответ, спасибо!