关于python:如何运行用pybuilder构建的脚本? 有没有`pyb run`?

How to run the script built with pybuilder? Is there `pyb run`?

请原谅我可能琐碎的问题,但是:我如何运行pybuilder发布的脚本?

我正在尝试遵循官方的Pybuilder教程。

我已经完成了这些步骤并成功生成了一个项目

  • 运行单元测试
  • 计算覆盖范围
  • 生成setup.py
  • 生成.tar.gz,可以由pip install使用。

这一切都很好,但我仍然看不到实际的可运行工件是什么?

target目录中包含的所有内容似乎与src目录中的内容或其他报表和可安装的归档文件大致相同。

在"添加可运行脚本"部分结尾处的教程本身得出结论"脚本已被拾取"。好的,它已被拿起,现在我该怎么运行它?教程在任何时候都没有证明我们可以实际打印字符串"Hello,World!"在屏幕上,尽管整个玩具项目都是关于这样做的事实。

MCVE

下面是一个Bash脚本,它使用Python源文件和构建脚本生成以下目录树:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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

生成示例项目的完整脚本(免责声明:按原样提供,修改文件和目录,执行风险自负):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/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的目录中使用):

1
2
3
4
5
6
7
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

这确实成功地运行了脚本及其依赖于用户定义的包,并打印:

1
Hello, world! 42 * 42 - 42 = 1722

但整个过程似乎相当复杂。相比之下,在SBT的类似情况下,我只会发行单曲

1
run

来自SBT-shell的命令 - 这就是为什么上面的七步食谱对我来说似乎有些怀疑。

是否有像pyb runpyb exec插件那样的东西,但我不需要我设置所有这些环境并安装任何东西?我正在寻找的是SBT中的sbt run或Maven中的mvn exec:java的类比,它将构建所有内容,设置所有类路径,然后使用main方法运行类,而不会留下任何痕迹项目目录。

由于源代码和目标输出之间基本没有区别,我可能错过了一些如何运行脚本的明显方法。如果根本不需要PyBuilder本身,那也没关系:我想要的只是以某种方式在终端中打印Hello, world! 42 * 42 - 42 = 1722 -string。


显然以下工作流程:

  • pyb发布
  • pip install .tar.gz
  • runMyScript.py
  • 卸载

这正是PyBuilder的创建者在本次演讲中提出的。

请注意,链接的视频来自2014年。如果有人可以提出更精简的最近提供的解决方案,我当然会接受。