fab-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fab-user] More Complex Objects in Fabric Variables


From: Paul Baumgart
Subject: [Fab-user] More Complex Objects in Fabric Variables
Date: Sat, 21 Mar 2009 02:29:51 -0700

Hi,

I just recently came across Fabric, and I think it's a really useful
tool. I was wondering, though, what the best way is to store, for
example, a list in a Fabric variable.

My use case is as follows:
I'm creating an Apache virtual host file, and I want to store a list
of ServerAliases, and then create the file containing these
ServerAliases dynamically. There are anywhere from 0-5 ServerAliases
depending on the site, so I want to avoid creating separate variables
for each "slot". The problem with using a list though, is that, as I
understand it, it's not possible to do anything with a Fabric variable
besides cast it to a string, so, for example,
let(directives="'ServerAlias ' + '\\\\nServerAlias '.join(aliases) +
'\\\\n'") doesn't work.

As a work-around I added the following functionality:
http://github.com/paulbaumgart/fabric/blob/e36611d6be5a45b2dbd0771f6698c3c74d81f711/fabric.py#L844
. Here's the docstring I wrote for it:
"""
Optionally, you can pass eval=True, and all string values will be interpreted
as lines of Python code, evaluated over all Fabric variables that have been
previously set. String interpolation will not be performed if eval=True.
Be sure to escape backslashes.

Important note: do not reference variables set in the same let command. There
is no guarantee the variables will be evaluated in the order given.

Given the following fabfile:
def print_y():
require('y')
local('echo "$(y)"');

You can do this:
$ fab let:x='1',eval=True let:y='x+1',eval=True print_y
Fabric v. 0.1.1.
Running let...
Running let...
Running print_y...
[localhost] run: echo "2"
2
Done.

But /not/ this:
$ fab let:x='1',y='x+1',eval=True print_y > /dev/null
NameError: name 'x' is not defined
Make sure the variable exists and that you are not referencing a
variable defined elsewhere in the same let command.

As you can see, it tries to warn you, but there would have been no error
message if x had been set previously; it would just have the unexpected
behavior of using the previous value of x.
"""

But this feels a bit kludgy, especially because the evaluation order
is not guaranteed for multiple expressions in one let statement.

Can anyone suggest a better way to do this? Did I overlook existing
functionality that accomplishes the same thing?

Best,
Paul




reply via email to

[Prev in Thread] Current Thread [Next in Thread]