给 Arch 打一个包 – Python 模块篇

这是一篇简化的教程,如果你有一个喜爱的 Python 模块不在 Arch 仓库里,AUR 里也没有,可以尝试读下去。

准备

对 Python 模块来说,一般仅仅一个 PKGBUILD 文件就足以完成所有的事情。现在你可以打开你最喜欢的文本编辑器,把下面这一个简单的 PKGBUILD 模板复制进去:

因为距离 Python 2 的废弃时间(2020年)还早,Arch 仓库中的 Python 模块包通常同时提供 Python 2/3 模块。上面例子里的 Python 软件包名叫 whatever,这也同样是它在 PyPI 中的名字。如果原来的包名中包含大写字母,在制作软件包时需要改成小写。

名字和源代码位置

现在你可以开始修改了。首先替换名字,一个简单的方法是首先找到你要处理的软件包的仓库,然后全局查找替换 GitHub URL 和软件包名(如果不在 GitHub 上,就稍微找一下吧)。

注:PyPI 的下载地址一般格式为:

注意把中间的“喵”换成包名的首字母。

依赖、介绍、授权

现在可以打开代码中的 setup.py 了。如果你看到了 install_requires=,那恭喜你,基本可以参照这个文件的内容(或者它打开的文件)来找到依赖列表。对每一个依赖,先检查一下是否在 Arch 仓库或 AUR 中(大部分都在),如果在的话,更新一下上面的 makedepends 列表和下方 python 2/3 对应的 package_*() 函数中的 depends 列表,加入这些依赖。接下来,在附近你可以找到模块介绍和授权,分别填入 pkgdesc 和 license 即可。

如果你看到的是一个只有包括 pbr=True 的很短的 setup.py 文件,说明这个项目使用了 pbr。这时候你需要打开 requirements.txt 查找依赖,并把 python{,2}-pbr 加入 makedepends。模块介绍和授权则会在同目录的 setup.cfg 文件中。

测试

下面是一个比较麻烦的步骤:确定测试如何运行。当然如果你对你的包已经信心满满根本不想跑测试,可以直接去掉 check() 和 checkdepends() (咳咳)然后完工。

一般来说项目自己跑着的持续集成会把测试工具定义在 .travis.yml 或者 tox.ini 这样的文件里,可以在这些地方找到一些线索。一般来说,如果测试使用的是 pytest/py.test 这样的命令,说明测试工具是 pytest,上面的模板已经是这个工具的用法了。模板里定义的 pytest-runner 是一个可以用来解决 PYTHONPATH、2to3、以及依赖等问题的 pytest 运行工具。

如果你看到了 nosetests,说明测试工具是 nose。把上面模板中的 pytest-runner 替换成 nose,并把下面的 setup.py pytest 替换为 setup.py nosetests 一般可以解决问题。

如果你看到的是普通的 setup.py test,则可以去掉 checkdepends,直接修改 check() 为一样的语句。

还有一些其他情况,可以试试在官方仓库里找找我对类似情况的处理进行参考 🙂

最后把定义在 setup.py 中 tests_requires 里,或者 tox.ini、.travis.yml 中的依赖加入 checkdepends 列表,大功告成!

现在你可以运行 makepkg 进行打包尝试了。如果上面的步骤都正确完成了,这里应该可以顺利完成(flag)。

疑难解答

  • 有些项目的测试需要 X 环境,而我的服务器上不一定启动了 X。

在 checkdepends 中加入 xorg-server-xvfb,然后在 check() 中两个运行测试的语句前面加上 xvfb-run 即可。

  • 打包过程中因为 UnicodeDecodeError 挂掉了。

在不同的条件下,这个问题的原因可能是多种多样的,但解决方法通常比较一致:在出问题的语句前面加上 LC_CTYPE=en_US.UTF-8。

  • pbr 提示无法找到版本。

在 prepare() 里加上:export PBR_VERSION=$pkgver

  • setuptools_scm 提示无法找到版本。

在 prepare() 里加上:export SETUPTOOLS_SCM_PRETEND_VERSION=$pkgver

  • 测试中用到了 entry_point 功能,因此在未安装的情况下测试软件会失败。

这种情况确实需要更多的 hack,我常用的一个简单方法是安装到临时目录,然后修改 PYTHONPATH:

  • 我实在调不过测试了,但我确定这个包没问题;或者上游已经知道这个问题了,确定不是因为我打包方面的问题引起。

把这个测试跳过吧!(咳咳)

Leave a Reply

Your email address will not be published.