我正在尝试从本地未安装的车轮生成需求列表。仅将作为packages
参数输入的列表添加到setup.py
的setuptools.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