我正在尝试从本地未安装的车轮生成需求列表。仅将作为packages参数输入的列表添加到setup.pysetuptools.setup -call中将是最佳选择。如果安装了轮子,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文件中获取当前版本号)便可以破解此黑客行为。

修复docker-build上下文以使此代码有效将解决我的问题,但我更喜欢一个适当的解决方案,该解决方案不隐式依赖setup.py中的内容。

使用pip / pipreqs / pipenv / pipdeptree :

所有这些工具都可以在本地环境上运行,并且无法处理未安装的车轮。 This answer使用pip非常接近,但是1)仅在将软件包上传到pyPI时才有效(我的目标软件包不是),以及2)进行大量构建以获取软件包列表。

最佳答案

我的项目 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

07-24 09:52
查看更多