用于优雅任务的Fabric docstring

时间:2014-05-04 21:18:30

标签: python fabric

我通过子类化Task定义了许多结构任务(如下所述:http://docs.fabfile.org/en/latest/usage/tasks.html#task-subclasses)。我希望有一个docstring来描述每个任务子类将在fab -l上显示的内容,就像使用@task装饰器定义任务一样。我尝试将文档字符串放在许多地方(classdef run之后),但它没有用。

对于定义为fab -l的子类的任务,是否可以有Task个可见描述?

例如,这是我的fabfile的一部分:

class BaseConfig(Task):
    def run(self):
        env.env = self.name
        env.user = 'serafeim'
        env.role = self.name
        puts("Using {0} configuration with user {1} at {2}".format(env.env, env.user, env.roledefs[env.env]))

class UatConfig(BaseConfig):
    """
    UAT settings
    """
    name = "uat"
uat_cfg_instance = UatConfig()


class ProdConfig(BaseConfig):
    """
    Prod settings
    """
    name = "prod"
prod_cfg_instance = ProdConfig()

当我运行fab -l时,我只看到

uat
dev

没有任何关于这些内容的描述。

3 个答案:

答案 0 :(得分:2)

使用Fabric==1.8.3

您的代码添加了导入并管理任务的文档字符串: fabfile.py

from fabric.api import *
from fabric.tasks import Task

class BaseConfig(Task):
    """BaseConfig task docstring"""
    def run(self):
        """BaseConfig task docstring for `run` method"""
        env.env = self.name
        env.user = 'serafeim'
        env.role = self.name
        puts("Using {0} configuration with user {1} at {2}".format(env.env, env.user, env.roledefs[env.env]))

class UatConfig(BaseConfig):
    """
    UAT settings
    """
    name = "uat"
uat_cfg_instance = UatConfig()


class ProdConfig(BaseConfig):
    """
    Prod settings

    talking a bit more about our classy concept, not yet diving into `run` details
    """
    name = "prod"
    def run(self):
        """ProdConfig run docstring

        on multiple lines
        we are now in prod"""
        super(ProdConfig, self).run()

prod_cfg_instance = ProdConfig()

列出可用任务

$ fab -l
Available commands:

    prod  Prod settings
    uat   UAT settings

在这里我们看到,使用派生自Task的类的docstring - 但只是第一行。

显示uat的详细文档字符串 - 来自超类

的docstring

uat的详细说明说明了您所描述的问题:

$ fab -d uat
Displaying detailed information for task 'uat':

    BaseConfig task docstring for `run` method
    Arguments: self

由于uat未重新定义run方法,因此使用了父run方法,这适用于为任务详细信息显示docstring。

显示来自run方法

的prod-docstring的详细docstring

对于prod,我们重新定义了run方法,这使我们有机会修改任务的文档字符串:

$ fab -d prod
Displaying detailed information for task 'prod':

    ProdConfig run docstring

            on multiple lines
            we are now in prod
    Arguments: self

结论

  • 简要列表(通过$ fab -l)显示了类docstring的第一行
  • 详细列表(通过$ fab -d <taskname>)显示了使用过的run方法
  • 的文档字符串
  • 如果要更改任务详细文档字符串,则必须在继承的类中定义run方法并在那里指定docstring。不要忘记从超类中调用run(如果相关)。

答案 1 :(得分:1)

为了在调用fab -d时显示子类的docstring,以下内容适用于Fabric 1.13.1:

 class BaseConfig(Task):
        def run(self):
            env.env = self.name
            env.user = 'serafeim'
            env.role = self.name
            puts("Using {0} configuration with user {1} at {2}".format(env.env, env.user, env.roledefs[env.env]))

        def __details__(self):
            return self.__doc__

瞧:

$ fab -d provision.prod
Displaying detailed information for task 'provision.prod':

    Prod settings

$ fab -d provision.uat
Displaying detailed information for task 'provision.uat':

    UAT settings

答案 2 :(得分:0)

如果要对Task类和run()方法使用相同的docstring,请使用以下方法:

from fabric.api import *
from fabric.tasks import Task


class BaseConfig(Task):
    def __init__(self, *args, **kwargs):
        super(BaseConfig, self).__init__(*args, **kwargs)
        # Update docstring of run() so `fab -d <task>` will show the same
        # docstring of the class
        if self.__doc__:
            # http://stackoverflow.com/a/4835557/2293304
            self.run.__func__.__doc__ = self.__doc__


class FooConfig(BaseConfig):
    """
    Foo docstring

    This is the foo description.
    """
    name = 'foo'

    def run(self):
        # This method will automatically use the docstring of the class
        puts('This run foo...')


foo_instance = FooConfig()