例如命令:
make install
将等同于
source path/to/virtualenv/bin/activate
pip install -r requirements.txt
这是可能的吗?
make install
将等同于
source path/to/virtualenv/bin/activate
pip install -r requirements.txt
这是可能的吗?
我喜欢使用仅在 requirements.txt
变更时运行的东西:
这假定源文件位于项目根目录下的 project
中,并且测试位于 project/test
下。(您应该更改 project
以匹配您实际的项目名称。)
venv: venv/touchfile
venv/touchfile: requirements.txt
test -d venv || virtualenv venv
. venv/bin/activate; pip install -Ur requirements.txt
touch venv/touchfile
test: venv
. venv/bin/activate; nosetests project/test
clean:
rm -rf venv
find -iname "*.pyc" -delete
make
安装requirements.txt
中的软件包。make test
来运行您的测试(如果您的测试在其他地方,则可以更新此命令)。make clean
以删除所有产生的文件。在Make中,您可以将shell作为命令运行。在此shell中,您可以执行从命令行启动的shell中可以执行的所有操作。例如:
install:
( \
source path/to/virtualenv/bin/activate; \
pip install -r requirements.txt; \
)
注意必须注意分号;
和反斜杠\
。
大括号之间的所有内容将在单个shell实例中执行。
()
符号。对于规则主体中的每一行,make命令已经会为其生成一个新的shell实例。你只需要使用续行符来让make命令将这些行读取并在单个shell实例中执行,而不是像默认情况下在多个shell实例中执行。 - Etan Reisner. path/to/virtualenv/bin/activate; \
希望这能帮助其他遇到类似问题的人 :-) - Frito通常情况下,make
命令会在不同的子 shell 中运行每个配方中的命令。但是,设置 .ONESHELL:
将会在同一个子 shell 中运行所有命令,这样您就可以激活一个虚拟环境并在其中运行命令。
请注意,.ONESHELL:
适用于整个 Makefile,而不仅仅是单个配方。它可能会改变现有命令的行为,详细信息可以在完整文档中查看可能的错误。由于命令仍然在子 shell 中运行,这将不能让您在 Makefile 外部使用虚拟环境。
参考文献: https://www.gnu.org/software/make/manual/html_node/One-Shell.html
示例:
.ONESHELL:
.PHONY: install
install:
source path/to/virtualenv/bin/activate
pip install -r requirements.txt
我用这个很顺利。
install:
source ./path/to/bin/activate; \
pip install -r requirements.txt; \
SHELL := /bin/bash
。根据您使用的shell进行调整。 - Juha Untinensource
,例如. ./path/to/bin/activate
。 - Antonio Barreto这是一种在virtualenv中运行所需内容的替代方法。
BIN=venv/bin/
install:
$(BIN)pip install -r requirements.txt
run:
$(BIN)python main.py
提示:这不会激活虚拟环境,但可以完成任务。希望您觉得它干净有用。
.venv
目录,它将使用该目录,否则默认使用PATH。# Running this: # Actually runs this:
make venv # /usr/bin/python3 -m venv .venv
make deps # .venv/bin/python setup.py develop
make test # .venv/bin/python -m tox
# Running this: # Actually runs this:
make deps # /usr/bin/python3 setup.py develop
make test # /usr/bin/python3 -m tox
在你的Makefile顶部,定义以下变量:
VENV = .venv
VENV_PYTHON = $(VENV_PYTHON)/bin/python
SYSTEM_PYTHON = $(or $(shell which python3), $(shell which python))
# If virtualenv exists, use it. If not, find python using PATH
PYTHON = $(or $(wildcard $(VENV_PYTHON)), $(SYSTEM_PYTHON))
./.venv
,你会得到:VENV = .venv
VENV_PYTHON = .venv/bin/python
SYSTEM_PYTHON = /usr/bin/python3
PYTHON = .venv/bin/python
VENV = .venv
VENV_PYTHON = .venv/bin/python
SYSTEM_PYTHON = /usr/bin/python3
PYTHON = /usr/bin/python3
/usr/bin/python3
可能是其他内容,取决于您的 PATH
。$(PYTHON) -m tox
$(PYTHON) -m pip ...
venv
"的目标,用于创建.venv
目录。$(VENV_PYTHON):
rm -rf $(VENV)
$(SYSTEM_PYTHON) -m venv $(VENV)
venv: $(VENV_PYTHON)
deps
目标用于安装依赖项:deps:
$(PYTHON) setup.py develop
# or whatever you need:
#$(PYTHON) -m pip install -r requirements.txt
这是我的 Makefile:
# Variables
VENV = .venv
VENV_PYTHON = $(VENV)/bin/python
SYSTEM_PYTHON = $(or $(shell which python3), $(shell which python))
PYTHON = $(or $(wildcard $(VENV_PYTHON)), $(SYSTEM_PYTHON))
## Dev/build environment
$(VENV_PYTHON):
rm -rf $(VENV)
$(SYSTEM_PYTHON) -m venv $(VENV)
venv: $(VENV_PYTHON)
deps:
$(PYTHON) -m pip install --upgrade pip
# Dev dependencies
$(PYTHON) -m pip install tox pytest
# Dependencies
$(PYTHON) setup.py develop
.PHONY: venv deps
## Test
test:
$(PYTHON) -m tox
.PHONY: test
## Build source distribution, install
sdist:
$(PYTHON) setup.py sdist
install:
$(SYSTEM_PYTHON) -m pip install .
.PHONY: build install
or
和 通配符
?你在使用什么作为CLI? - Kuzeko$(or val1, val2)
将返回第一个非空值。$(wildcard path)
如果文件存在,则返回路径。我在这个例子中省略了常见的SHELL = /bin/...
,因为它可以与/bin/sh
或/bin/bash
一起使用,这是与Makefile一起使用的常用shell。 - mattalxndr./venv
还是 ./.venv
?命令和注释都涉及到这两个路径,所以我认为有拼写错误... - MestreLion./venv
还是./.venv
?命令和注释都提到了这两个,所以我认为可能有个拼写错误。 - undefinedVENV_PYTHON = $(VENV_PYTHON)/bin/python
这个赋值是无效的。 - Mikaelblomkvistsson根据上面的答案(感谢 @Saurabh 和 @oneself!),我编写了一个可重用的 Makefile,它负责创建虚拟环境并将其更新: https://github.com/sio/Makefile.venv
它通过引用 virtualenv 中的正确可执行文件来工作,而不依赖于“activate”shell脚本。以下是一个示例:
test: venv
$(VENV)/python -m unittest
include Makefile.venv
考虑到Windows与其他操作系统之间的差异,Makefile.venv应该可以在任何提供了Python和make功能的操作系统上正常工作。
# system python interpreter. used only to create virtual environment
PY = python3
VENV = venv
BIN=$(VENV)/bin
# make it work on windows too
ifeq ($(OS), Windows_NT)
BIN=$(VENV)/Scripts
PY=python
endif
all: lint test
$(VENV): requirements.txt requirements-dev.txt setup.py
$(PY) -m venv $(VENV)
$(BIN)/pip install --upgrade -r requirements.txt
$(BIN)/pip install --upgrade -r requirements-dev.txt
$(BIN)/pip install -e .
touch $(VENV)
.PHONY: test
test: $(VENV)
$(BIN)/pytest
.PHONY: lint
lint: $(VENV)
$(BIN)/flake8
.PHONY: release
release: $(VENV)
$(BIN)/python setup.py sdist bdist_wheel upload
clean:
rm -rf $(VENV)
find . -type f -name *.pyc -delete
find . -type d -name __pycache__ -delete
我对此进行了更详细的写作, 但基本上的想法是使用系统的Python创建虚拟环境,对于其他目标,只需在命令前加上$(BIN)
变量,该变量指向venv内部的bin
或Scripts
目录。这相当于activate
函数。
我发现在 $PATH
前面添加并加入 $VIRTUAL_ENV
是最好的方法:
activate
并限制自己使用 ;
链接
python
,它会回退到系统 Python
bash
)和 POSIX 兼容# SYSTEM_PYTHON defaults to Python on the local machine
SYSTEM_PYTHON = $(shell which python)
REPO_ROOT = $(shell pwd)
# Specify with REPO_ROOT so recipes can safely change directories
export VIRTUAL_ENV := ${REPO_ROOT}/venv
# bin = POSIX, Scripts = Windows
export PATH := ${VIRTUAL_ENV}/bin:${VIRTUAL_ENV}/Scripts:${PATH}
对于那些对示例用法感兴趣的人:
# SEE: http://redsymbol.net/articles/unofficial-bash-strict-mode/
SHELL=/bin/bash -euo pipefail
.DEFAULT_GOAL := fresh-install
show-python: ## Show path to python and version.
@echo -n "python location: "
@python -c "import sys; print(sys.executable, end='')"
@echo -n ", version: "
@python -c "import platform; print(platform.python_version())"
show-venv: show-python
show-venv: ## Show output of python -m pip list.
python -m pip list
install: show-python
install: ## Install all dev dependencies into a local virtual environment.
python -m pip install -r requirements-dev.txt --progress-bar off
fresh-install: ## Run a fresh install into a local virtual environment.
-rm -rf venv
$(SYSTEM_PYTHON) -m venv venv
@$(MAKE) install
你也可以使用名为“VIRTUALENVWRAPPER_SCRIPT”的环境变量。像这样:
install:
( \
source $$VIRTUALENVWRAPPER_SCRIPT; \
pip install -r requirements.txt; \
)
venv/bin/activate
。最好使用另一个“跟踪文件”。只需更改所有出现的位置(当然不包括源),例如venv/bin/updated_by_make
。 - Antonio Barretomake
即可执行 makefile 中的第一个目标——在本例中是venv
。由于venv
依赖于venv/touchfile
,因此只要requirements.txt
(其依赖项)发生更改,就会运行该配方。venv/touchfile
只是一个空文件,用于跟踪虚拟环境的修改时间。 - Czaporka