Skip to content

Commit

Permalink
Use task variable name when task name is undefined.
Browse files Browse the repository at this point in the history
In fabric.main.extract_tasks(), the dict mapping names to new-style task
objects now uses the variable name of the object when the object's name
attribute is not defined.  (Technically, when not obj.name or obj.name
== 'undefined').

This change brings the behavior for mapping tasks to names in compliance
with the fabric documentation.
http://docs.fabfile.org/en/1.4.3/usage/tasks.html#new-style-tasks:

    Subclass Task (Task itself is intended to be abstract), define a run
    method, and instantiate your subclass at module level.  Instances’
    name attributes are used as the task name; if omitted the instance’s
    variable name will be used instead.

A test case was added to confirm that the task name equal the variable
name when the task object name attribute is undefined.  This test fails
with the old code and passes with the patched code.
  • Loading branch information
Todd DeLuca authored and bitprophet committed Dec 28, 2012
1 parent 8392da0 commit f8b3abf
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
7 changes: 5 additions & 2 deletions fabric/main.py
Expand Up @@ -210,8 +210,11 @@ def extract_tasks(imported_vars):
name, obj = tup
if is_task_object(obj):
state.env.new_style_tasks = True
# Honor instance.name
new_style_tasks[obj.name] = obj
# Use instance.name if defined
if obj.name and obj.name != 'undefined':
new_style_tasks[obj.name] = obj
else:
new_style_tasks[name] = obj
# Handle aliasing
if obj.aliases is not None:
for alias in obj.aliases:
Expand Down
7 changes: 7 additions & 0 deletions tests/support/classbased_task_fabfile.py
@@ -0,0 +1,7 @@
from fabric import tasks

class ClassBasedTask(tasks.Task):
def run(self, *args, **kwargs):
pass

foo = ClassBasedTask()
12 changes: 12 additions & 0 deletions tests/test_main.py
Expand Up @@ -444,6 +444,18 @@ def test_class_based_tasks_are_found_with_proper_name(self):
eq_(len(funcs), 1)
ok_('foo' in funcs)

def test_class_based_tasks_are_found_with_variable_name(self):
"""
A new-style tasks with undefined name attribute should use the instance
variable name.
"""
module = fabfile('classbased_task_fabfile.py')
from fabric.state import env
with path_prefix(module):
docs, funcs = load_fabfile(module)
eq_(len(funcs), 1)
ok_('foo' in funcs)

def test_recursion_steps_into_nontask_modules(self):
"""
Recursive loading will continue through modules with no tasks
Expand Down

0 comments on commit f8b3abf

Please sign in to comment.