Discussion:
[Fab-user] Dynamically Create Task?
Chris Spencer
2015-10-22 15:19:26 UTC
Permalink
Is it possible to dynamically define a Fabric task?

Currently, in order to make `fab` show the task mymodule.mytask, I need to
define the function `mytask` inside `mymodule`. As I use Fabric more, I'm
finding this gets very tedious, because different modules often define
similar functions, so I end up writing duplicate code. I'm trying to
refactor my code to be more object-oriented, and would like to register
class methods as tasks, but I can't find a reliable way to do this.

How can I tell Fabric to expose an arbitrary callable with a specific name,
regardless of which package or module it resides in?
Carlos García
2015-10-22 17:08:16 UTC
Permalink
Hi Chris

I developed exactly that some time ago, but I need time to clean the code
prior to release it.

If you want to try yourself, what I did was to create a template class (an
abstract class) with some general methods, as configure(), deploy(),
restart(), that are invoked as tasks. Your modules should be child classes
of this template class, overwritting the methods. The fabfile should have
the tasks deploy(), configure() and so on.

This is how it looks in fabfile:

def deploy(module_name = None, class_name = None):
""" Deploy a template """
role = task_helper(module_name, class_name)
if role:
role.deploy()



Now, what you need is a function that returns an instance of your selected
class (in the function above, task_helper()). You should use importlib to
importing your modules dinamically. As an example, you can use this:

def task_helper(module_name, class_name):
m = importlib.import_module(module_name)

if hasattr(m, class_name):
cls = getattr(m, class_name)
if inspect.isclass(cls):
return cls()


To use it from the CLI:

fab deploy:module_name,class_name



The hard part comes when you have dozens of modules and you need to
remember every module and class name. We resolved this using introspection
and integrating that with the autocomplete bash feature.

Hope it helps!
Post by Chris Spencer
Is it possible to dynamically define a Fabric task?
Currently, in order to make `fab` show the task mymodule.mytask, I need to
define the function `mytask` inside `mymodule`. As I use Fabric more, I'm
finding this gets very tedious, because different modules often define
similar functions, so I end up writing duplicate code. I'm trying to
refactor my code to be more object-oriented, and would like to register
class methods as tasks, but I can't find a reliable way to do this.
How can I tell Fabric to expose an arbitrary callable with a specific
name, regardless of which package or module it resides in?
_______________________________________________
Fab-user mailing list
https://lists.nongnu.org/mailman/listinfo/fab-user
--

Loading...