I am currently trying to create a makefile that detects, if a Python venv is active and if so, to deactivate it. So far my attempts have not been successful. Therefore my question, is it even possible to deactivate the current shells venv with make and if so, how?
Update: I want to make sure, that devs do not accidentally install poetry directly in their projects venv.
My ideas so far:
install: # Install poetry and dependencies
ifneq (,$(findstring .venv,$(VIRTUAL_ENV)))
@echo $(VIRTUAL_ENV)
@echo "venv active"
# @.$(VIRTUAL_ENV)/bin/activate deactivate
@./scripts/deactivate_venv.sh deactivate_venv
# @exit "Please deactivate venv before running install command"
else
@echo "No venv activated"
@pip install poetry==1.4.0
@poetry install
endif
The bash script linked to make
#!/usr/bin/env bash
deactivate_venv(){
echo $VIRTUAL_ENV
source $VIRTUAL_ENV/bin/activate deactivate
}
"$@"
How to deactivate virtualenv in Makefile?
is it even possible to deactivate the current shells venv with make
I spent some time on this and my conclusion is: it is not possible to deactivate a virtual environment created in the shell calling the make. Here is why:
According to the documentation,
When it is time to execute recipes to update a target, they are executed by invoking a new sub-shell for each line of the recipe
Please note: this implies that setting shell variables and invoking shell commands such as cd that set a context local to each process will not affect the following lines in the recipe.
So this mean that each line you execute in your Makefile is sent to a new shell; since deactivate
is a shell function stored in the caller shell memory, it's not transferred to the shells make will start, making the lines you execute unaware that it exists.
I understand this will not help your (OP) situation, but for future readers, a pattern that could possibly be available to you is something like this:
pyvenvtest:
@doThis; source myvenv/Scripts/activate; doThatInTheVenv;deactivate; doSomethingElseWhitoutTheVenv
So the idea is to activate the venv, do your thing within the context, and deactivate it on the same line. So if you want to actually deactivate it, you'll have to activate it yourself on the same line. But you'll never have access to the outside venv.