Question

I recently asked for explanations about a Fabric script behavior I couldn't understand. Now that I understand how Fabric works, I am still struggling to find a solution to my problem :-)

Basically, I wanted to nest a cd() call, a prefix() call (that would load some stuff from the current path) and another cd() call to finally run() a comment.

The best example that comes to my mind is the following:

with cd('/my/virtualenv/dir/'):
  with prefix('source bin/activate'):
    with cd('/my/project/dir/'):
      run('pip install -r requirements.txt')
      run('./run_something')

This would not work because cd('/my/project/dir') would take precedecence over cd('/my/virtualenv/dir'), which would be completely overridden from the context.

The only solution I can see is to concatenate the first 3 lines inside a unique prefix(), separated by &&s but it really seems hackish to me:

with prefix('cd /my/virtualenv/dir/ && source bin/activate && cd /my/project/dir/'):
  run('pip install -r requirements.txt')
  run('./run_something')

Is there another/more elegant way to do that? By "more elegant", I mean a solution that would use Fabric methods instead of my hack.

Of course, for this specific example, I could use virtualenvwrapper, but then it becomes too specific and does not work for other similar cases not based upon virtualenv.

Était-ce utile?

La solution

I've gotten the following to work on my own machine:

with cd("~/somedir"), prefix("source ~/.virtualenvs/venv/bin/activate"):
    with cd("anotherdir"):
        run("ls")

The real question I have is, once you activate the virtualenv, why do you need to cd into another directory? This should work just fine for your purposes if you just want to install something using pip

with cd('/my/virtualenv/dir/'), prefix('source bin/activate'):
   run('pip install something')

I got the with cd("dir"), prefix("stuff") idea from the fabric docs btw

EDIT:

As an update to my answer: Why not just use two absolute paths?

with cd("/abs/path/to/my/file"), prefix("source /abs/path/to/my/venv/bin/activate"):
    run("pip install something")
    run("./somefile.py")

Fabric will execute a command similar to what you were trying to input:

Executed: /bin/bash -l -c "cd /abs/path/to/my/file && source ~/abs/path/to/my/venv/bin/activate && pip install something"

Then it will run

./somefile.py
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top