fab-user
[Top][All Lists]
Advanced

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

Re: [Fab-user] More Complex Objects in Fabric Variables


From: Paul Baumgart
Subject: Re: [Fab-user] More Complex Objects in Fabric Variables
Date: Sat, 21 Mar 2009 11:53:45 -0700

Hi Jeff,

I understand it's possible to /assign/ non-strings to Fabric
variables, but how do you get them back out as anything other than
strings?

Example of what I mean:

def data1():
    let(data=[1,2,3])

def data2():
    let(data=[4,5,6])

def show_first_datum():
    local('echo $(data[0])')
    let(first_datum=data[0])
    local('echo $(first_datum)')

$ fab data1 show_first_datum
Fabric v. 0.1.1.
Running data1...
Running show_first_datum...
[localhost] run: echo $(data[0])
/bin/sh: data[0]: not found

Traceback (most recent call last):
  File "build/bdist.linux-i686/egg/fabric.py", line 1530, in main
  File "build/bdist.linux-i686/egg/fabric.py", line 1439, in _execute_command
  File "build/bdist.linux-i686/egg/fabric.py", line 1482, in _execute_at_target
  File "fabfile", line 9, in show_first_datum
    let(first_datum=data[0])
NameError: global name 'data' is not defined


(PS: I am using the latest code from the repository, specifically a
fork I made on GitHub to play with 2 days ago.)

Paul

On Sat, Mar 21, 2009 at 6:06 AM, Jeff Forcier <address@hidden> wrote:
> Hi Paul,
>
> I'm not sure where you got the impression that Fabric's let/set
> functionality only works with strings! It should have always worked
> with any Python variable whatsoever. The backend of let/set (which is,
> in 0.1.0, just setting/getting attributes of a 'config' object -- may
> want to upgrade if you can :)) is just a Python dict, nothing special.
>
> If you can clarify how that first let() statement you posted "doesn't
> work", perhaps we can figure out what went wrong.
>
> Best,
> Jeff
>
> On Sat, Mar 21, 2009 at 5:29 AM, Paul Baumgart <address@hidden> wrote:
>> 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
>>
>>
>> _______________________________________________
>> Fab-user mailing list
>> address@hidden
>> http://lists.nongnu.org/mailman/listinfo/fab-user
>>
>




reply via email to

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