Как запустить скрипт, созданный с помощью pybuilder? Есть ли "Pyb Run"?
Простите мне, возможно, тривиальный вопрос, но: как мне запустить скрипт, опубликованный pybuilder?
Я пытаюсь следовать официальному учебнику по Pybuilder.
Я прошел через шаги и успешно создал проект, который
- запускает юнит-тесты
- вычисляет покрытие
- генерирует
setup.py
- генерирует
.tar.gz
которые могут быть использованыpip install
,
Это все очень хорошо, но я все еще не понимаю, что такое настоящий работающий артефакт?
Все, что содержится в target
каталог выглядит более или менее точно так же, как содержание в src
каталог + дополнительные отчеты и устанавливаемые архивы.
Сам учебник в конце раздела "Добавление исполняемого скрипта" делает вывод, что "скрипт был поднят". Хорошо, это было подобрано, теперь, как мне запустить его? Учебник ни в коем случае не демонстрирует, что мы на самом деле можем напечатать строку "Hello, World!" на экране, несмотря на то, что весь игрушечный проект посвящен именно этому.
MCVE
Ниже представлен скрипт Bash, который генерирует следующее дерево каталогов с исходными файлами Python и сценарием сборки:
projectRoot
├── build.py
└── src
└── main
├── python
│ └── pkgRoot
│ ├── __init__.py
│ ├── pkgA
│ │ ├── __init__.py
│ │ └── modA.py
│ └── pkgB
│ ├── __init__.py
│ └── modB.py
└── scripts
└── entryPointScript.py
7 directories, 7 files
================================================================================
projectRoot/build.py
--------------------------------------------------------------------------------
from pybuilder.core import use_plugin
use_plugin("python.core")
use_plugin("python.distutils")
default_task = "publish"
================================================================================
projectRoot/src/main/scripts/entryPointScript.py
--------------------------------------------------------------------------------
#!/usr/bin/env python
from pkgRoot.pkgB.modB import b
if __name__ == "__main__":
print(f"Hello, world! 42 * 42 - 42 = {b(42)}")
================================================================================
projectRoot/src/main/python/pkgRoot/pkgA/modA.py
--------------------------------------------------------------------------------
def a(n):
"""Computes square of a number."""
return n * n
================================================================================
projectRoot/src/main/python/pkgRoot/pkgB/modB.py
--------------------------------------------------------------------------------
from pkgRoot.pkgA.modA import a
def b(n):
"""Evaluates a boring quadratic polynomial."""
return a(n) - n
Полный сценарий, который генерирует пример проекта (Отказ от ответственности: предоставляется как есть, изменяет файлы и каталоги, выполняется на свой страх и риск):
#!/bin/bash
# Creates a very simple hello-world like project
# that can be build with PyBuilder, and describes
# the result.
# Uses BASH heredocs and `cut -d'|' -f2-` to strip
# margin from indented code.
# strict mode
set -eu
# set up directory tree for packages and scripts
ROOTPKG_PATH="projectRoot/src/main/python/pkgRoot"
SCRIPTS_PATH="projectRoot/src/main/scripts"
mkdir -p "$ROOTPKG_PATH/pkgA"
mkdir -p "$ROOTPKG_PATH/pkgB"
mkdir -p "$SCRIPTS_PATH"
# Touch bunch of `__init__.py` files
touch "$ROOTPKG_PATH/__init__.py"
touch "$ROOTPKG_PATH/pkgA/__init__.py"
touch "$ROOTPKG_PATH/pkgB/__init__.py"
# Create module `modA` in package `pkgA`
cut -d'|' -f2- <<__HEREDOC > "$ROOTPKG_PATH/pkgA/modA.py"
|def a(n):
| """Computes square of a number."""
| return n * n
|
__HEREDOC
# Create module `modB` in package `pkgB`
cut -d'|' -f2- <<__HEREDOC > "$ROOTPKG_PATH/pkgB/modB.py"
|from pkgRoot.pkgA.modA import a
|
|def b(n):
| """Evaluates a boring quadratic polynomial."""
| return a(n) - n
|
__HEREDOC
# Create a hello-world script in `scripts`:
cut -d'|' -f2- <<__HEREDOC > "$SCRIPTS_PATH/entryPointScript.py"
|#!/usr/bin/env python
|
|from pkgRoot.pkgB.modB import b
|
|if __name__ == "__main__":
| print(f"Hello, world! 42 * 42 - 42 = {b(42)}")
|
__HEREDOC
# Create a simple `build.py` build script for PyBuilder
cut -d'|' -f2- <<__HEREDOC > "projectRoot/build.py"
|from pybuilder.core import use_plugin
|
|use_plugin("python.core")
|use_plugin("python.distutils")
|
|default_task = "publish"
|
__HEREDOC
#################################################
# Directory tree construction finished, only #
# debug output below this box. #
#################################################
# show the layout of the generater result
tree "projectRoot"
# walk through each python file, show path and content
find "projectRoot" -name "*.py" -print0 | \
while IFS= read -r -d $'\0' pathToFile
do
if [ -s "$pathToFile" ]
then
printf "=%.0s" {1..80} # thick horizontal line
echo ""
echo "$pathToFile"
printf -- "-%.0s" {1..80}
echo ""
cat "$pathToFile"
fi
done
Простейший способ, с помощью которого я нашел запуск только что созданного проекта, заключался в следующем (используется из каталога, который содержит projectRoot
):
virtualenv env
source env/bin/activate
cd projectRoot
pyb
cd target/dist/projectRoot-1.0.dev0/dist/
pip install projectRoot-1.0.dev0.tar.gz
entryPointScript.py
Это действительно успешно запускает сценарий со всеми его зависимостями от пользовательских пакетов и печатает:
Hello, world! 42 * 42 - 42 = 1722
но вся процедура кажется довольно сложной. Для сравнения, в аналогичной ситуации в SBT я бы просто выпустил
run
команда из SBT-оболочки - вот почему приведенный выше семиступенчатый рецепт кажется мне немного подозрительным.
Есть ли что-то вроде pyb run
или же pyb exec
плагин, который делает то же самое, но не требует от меня, чтобы я настроил все эти среды и установить что-нибудь? То, что я ищу, это аналог sbt run
в SBT или mvn exec:java
в Maven, который будет строить все, настроить все пути к классам, а затем запустить класс с main
метод, не оставляя никаких следов за пределами каталога проекта.
Поскольку по сути нет никакой разницы между исходным кодом и выводом цели, я, вероятно, упускаю какой-то очевидный способ запуска сценария. Если PyBuilder
сама для этого вообще не нужна, тоже нормально: все, что я хочу - это как-то получить Hello, world! 42 * 42 - 42 = 1722
-строка напечатана в терминале.
1 ответ
Видимо следующий рабочий процесс:
- Pyb Publish
- pip install.tar.gz
- runMyScript.py
- деинсталляция
это именно то, что предлагает создатель PyBuilder в этом докладе.
Обратите внимание, что связанное видео относится к 2014 году. Если кто-то может предложить более упорядоченное недавно предоставленное решение, я, конечно, приму это.
Создать задачу в build.py
@task
def run(project):
path.append("src/main/python")
from test_pack import test_app
test_app.main()
Пытаться:
pyb run