使用Makefile安装python的requirements.txt,仅在requirements.txt更改时执行。

4
如何只有当 requirements.txt 文件被更改时才运行目标 make install?
我不想每次执行 make install 时都更新软件包。
我找到了一些解决方法,比如创建一个假文件 _requirements.txt.pyc,但这是丑陋和不干净的。它会拒绝第二次安装 pip 要求,因为 requirements.txt 没有更改。
$ make install-pip-requirements 
make: Nothing to be done for 'install-pip-requirements'.

但我的目标是做:
# first time,
$ make install # create virtual environment, install requirements

# second time
$ make install # detected and skipping creating virtual env,
               # detect that requirements.txt have no changes 
               # and skipping installing again all python packages
make: Nothing to be done for 'install'.

Python包的样子如下:
.
├── Makefile
├── README.rst
├── lambda_handler.py
└── requirements.txt

我正在使用文件 Makefile,用于一些 Python 自动化。
/opt/virtual_env:
    # create virtual env if folder not exists
    python -m venv /opt/virtual_env

virtual: /opt/virtual_env

# if requirements.txt is modified than execute pip install
_requirements.txt.pyc: requirements.txt
    /opt/virtual_env/bin/pip install -r --upgrade requirements.txt
    echo > _requirements.txt.pyc

requirements: SOME MAGIG OR SOME make flags        
    pip install -r requirements.txt

install-pip-requirements: _requirements.txt.pyc

install: virtual requirements

我相信一定有更好的方法来做这件事;)

你能详细解释一下你的Python包是什么样子吗?你使用任何类型的Python项目模板吗?为什么要用sudo运行make命令? - ovanes
更新了@ovanes,添加了文件夹树,并删除了sudo,因为它与问题无关(假设我是root)。 - Andrei.Danciuc
2个回答

4

@Andrei.Danciuc,make 只需要比较两个文件;您可以使用运行pip install生成的任何输出文件。

例如,我通常使用 “vendored” 文件夹,因此我可以将路径别名为“vendored” 文件夹而不是使用虚拟文件。

# Only run install if requirements.txt is newer than vendored folder
vendored-folder := vendored
.PHONY: install
install: $(vendored-folder)

$(vendored-folder): requirements.txt
    rm -rf $(vendored-folder)
    pip install -r requirements.txt -t $(vendored-folder)

如果您不使用供应商文件夹,下面的代码应该适用于虚拟环境和全局设置。
# Only run install if requirements.txt is newer than SITE_PACKAGES location
.PHONY: install
SITE_PACKAGES := $(shell pip show pip | grep '^Location' | cut -f2 -d':')
install: $(SITE_PACKAGES)

$(SITE_PACKAGES): requirements.txt
    pip install -r requirements.txt

3

目前不确定它是否能回答您的问题。更好的方法是使用一个完全成熟的Python PIP项目模板。

我们使用 cookiecutter 创建一个特定的pip包,使用 cookiecutter template

它有一个Makefile,不会不断重新安装所有依赖项,并且它利用 Python tox,可以自动在不同的python环境中运行项目测试。您仍然可以在dev虚拟环境中开发,但只有在添加新包时才更新它,其他所有内容都由tox处理。

但是,到目前为止,您所展示的是试图从头开始编写Python构建的方式,这已经通过多个项目模板完成。如果您真的想了解那里正在发生什么,可以分析 这些模板


作为后续:由于您希望它能与makefile一起使用,我建议从pip命令中删除--upgrade标志。我怀疑您的要求不包括项目需要的版本。我们有过这样的经历,不将版本放在那里可能会严重破坏事情。因此,我们的requirements.txt看起来像:
configure==0.5
falcon==0.3.0
futures==3.0.5
gevent==1.1.1
greenlet==0.4.9
gunicorn==19.4.5
hiredis==0.2.0
python-mimeparse==1.5.2
PyYAML==3.11
redis==2.10.5
six==1.10.0
eventlet==0.18.4

如果不使用--upgrade参数,使用要求时pip仅验证virtualenv中存在的内容。满足所需版本的所有内容都将被跳过(无需下载)。您还可以在要求中引用git版本,例如:

-e git+http://some-url-here/path-to/repository.git@branch-name-OR-commit-id#egg=package-name-how-to-appear-in-pip-freeze

我不知道为什么,但我仍然认为一定有更好的方法 https://youtu.be/wf-BqAjZb8M?t=1390。我期望一个makefile解决方案 :( - Andrei.Danciuc
@Andrei.Danciuc: 好的,我提供了第二个选择,通过将版本控制引入到requirements.txt中。 - ovanes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接