Получить конечные точки сценария поэзии

#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. Это действительно отличный и хорошо объясненный ответ, спасибо!