Pierre de LESPINAY
Pierre de LESPINAY

Reputation: 46178

Virtualenv - Automate project requirements deployment

I'm using Fabric to automate my deployment routines for my projects.

One of them concerns the virtualenv replication.

Automating the installation of new packages is pretty straight forward with

local $ pip freeze > requirements.txt
remote $ pip install -r requirements.txt

Now if I don't need a package anymore, I can simply

local $ pip uninstall unused_package

But as pip install won't remove the packages not present in the requirements anymore,
How can I automate the remove of packages from the virtualenv not present in the requirements ?

I'd like to have a command like:

remote $ pip flush -r requirements.txt

Upvotes: 0

Views: 536

Answers (3)

Pierre de LESPINAY
Pierre de LESPINAY

Reputation: 46178

I ended up by keeping the install/uninstall jobs separated.

Install:

pip install -r requirements.txt

Uninstall:

pip freeze | grep -v -f requirements.txt - | xargs pip uninstall -y

Upvotes: 0

Greg
Greg

Reputation: 5588

Why not just a diff with sets? It might require using a get operation though if you're operating on a remote box

On remote

from fabric.api import get, run

run("pip freeze > existing_pkgs.txt")
get("/path/to/existing_pkgs.txt")

So now existing_pkgs is on your local machine. Assuming you have a new requirements file...

with open("requirements.txt", "r") as req_file:
    req_pkgs = set(req_file.readlines())

with open("existing_pkgs.txt", "r") as existing_pkgs:
    existing = set(existing_pkgs.readlines())

Do an operation that gives you the differences in sets

uninstall_these = existing.difference_update(req_pkgs)

Then uninstall the pkgs from your remote host

for pkg in uninstall_these:
    run("pip uninstall {}".format(pkg))

Upvotes: 1

initall
initall

Reputation: 2385

Another approach could be - and I know this is not answering your question perfectly - to use the power of the virtualenv you already have:

It is convenient to have known stable package and application environments, let's say identified by revision control tags, to be able to roll back to a known working combination (this is no replacement for testing or a staging environment, though).

So you could simply setup a new virtual environment ("workon your-tag"), populate it again with "pip install -r" and leave the old behind (for some time, e.g. until the new your-tag release is considered stable) and finally remove the old virtual-env('s).

In your fabfile do something like

with cd(stage_dir):
    run("./verify_virtual_env.sh %s" % your-tag)

and the "verify_virtual_env.sh" script updates via pip for the given environment.

Upvotes: 1

Related Questions