从卸载的 wheel 生成 requirements.txt

Generate requirements.txt from uninstalled wheel

我正在尝试从本地未安装的 wheel 生成需求列表。简单地将作为 packages 参数输入的列表获取到 setup.pysetuptools.setup 调用中将是最佳的。如果安装了轮子,pip freeze 将生成的输出也可以工作。


更多上下文

我想构建一个将在 CI 链中使用的 docker 图像。为了减少管道时间,它应该预先加载所有运行时依赖项。但是在构建镜像的时候,python包还没有构建,链外构建包只是为了得到一个requirements.txt,很麻烦而且容易出错。

我尝试过的事情

将其写入 Dockerfile:

python -c $'\
import setuptools\n\
setuptools.setup = lambda *args, **kwargs: None\n\
exec(compile(open("setup.py").read(), "setup.py", "exec"))\n\
for requirement in requirements: print(requirement)\n' > python_packages.txt
# `requirements` is the name of variable that holds the package list 

这不是很好,因为 docker 在其构建上下文中做了一些奇怪的事情。 setup.py 中有任何访问本地文件的代码(例如,从 VERSION 文件中获取当前版本号)会破坏此 hack。

修复 docker-build 上下文以便这段代码可以工作将解决我的问题,但我更喜欢一个不隐式依赖于 setup.py 中的内容的正确解决方案。

使用pip/pipreqs/pipenv/pipdeptree:

所有这些工具都在本地环境之上工作,无法处理未安装的轮子。 This answer 使用 pip 非常接近,但 1) 仅当包在 pyPI 上载时才有效(我的目标包不是)和 2) 进行大量的 dry-build 以获取包列表.

我的项目 johnnydep 恰好具有从 未安装的 wheel 文件生成依赖项的功能。

pip install johnnydep
johnnydep your-wheel-file.whl --output-format=pinned

演示:

$ johnnydep johnnydep-0.5-py2.py3-none-any.whl --output-format pinned
johnnydep==0.5
anytree==2.4.3
cachetools==2.1.0
colorama==0.3.9
oyaml==0.7
packaging==18.0
pip==18.0
pkginfo==1.4.2
pytoml==0.1.19
setuptools==40.4.3
structlog==18.2.0
tabulate==0.8.2
wheel==0.32.1
wimpy==0.4
six==1.11.0
pyyaml==3.13
pyparsing==2.2.2