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: Jeff Forcier
Subject: Re: [Fab-user] More Complex Objects in Fabric Variables
Date: Sat, 21 Mar 2009 15:11:37 -0400

On Sat, Mar 21, 2009 at 2:53 PM, Paul Baumgart <address@hidden> wrote:
> 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?

Reference config.myvar! This is why I'm confused, you're focusing on
let(), which may still be around as a vestigal method, but is not how
you're intended to interface with the ENV as of 0.1.0 -- it's from the
old let()/set() setup which was in 0.0.9 and earlier.

Instead, you should probably be doing config.myvar = foo, and then
e.g. print config.myvar[0] -- and that ought to be 100% Pythonic and
not do any sort of casting to string (unless you're using the lazy
string eval, which is only one way of gettng data out of the ENV.)

Let me update your example:


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

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

def show_first_datum():
   #local('echo $(data[0])') <-- This is not possible right now, but
might be a legitimate feature request :)
   config.first_datum=data[0]
   local('echo $(first_datum)')


The result:


Fabric v. 0.1.0.
Running data1...
Running show_first_datum...
[localhost] run: echo 1
1
Done.


As noted in the example, a potential side-issue here, interpreting
Python statements such as indexing within the lazily-interpreted
string, is not currently supported. I personally am not sure it's
worth using eval() to have that added, either (it's easy enough to use
normal string interpolation there and do the indexing outside the
string), but I'll let Christian weigh in before I make any sort of
judgement :)


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

Yup, but I'm not sure you've read the most recent docs -- they outline
how to use the 'config' object :)


I hope this clears things up some, let me know if I'm still missing something

-Jeff

>
> 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]