fabricの環境設定とコマンドの実行の定義の区別が分かりにくい
注釈を付けるデコレータを定義すれば良いんじゃないかと思った。
とりあえずしたいこと
- fabfileの中で「環境設定」、「操作」を一目で分かるようにする
- あと、環境設定だけをリストで取り出せるとか便利
なんか注釈を付けるデコレータを定義すれば良いんじゃないかと思った。
こんな感じで書いてみた。
# -*- coding:utf-8 import collections as c class AnnotateDecorator(object): """fabric用の関数に注釈をつけるためのデコレータを生成するオブジェクト """ functions = c.defaultdict(list) #デコレータが付与された関数を格納 decorators = {} #生成されたデコレータを格納 @classmethod def generate(cls, status): """statusに渡された引数の注釈を付けるデコレータを返す。 """ def generated(function): #生成されるデコレータ function.__status__ = status if not function in cls.functions[status]: cls.functions[status].append(function) return lambda *args, **kw : function(*args, **kw) cls.decorators[status] = generated return generated @classmethod def anotate(cls, status): """ 作ったデコレータを返す。無ければ作成 """ if not status in decoratos: return cls.generate(status) else: return cls.decorators[status] @classmethod def list(cls, status): """[maybe]:注釈をもとにフィルタリングした結果をリストで返す """ if status in cls.functions: return cls.functions[status] fab_operation = AnnotateDecorator.generate("operation") fab_environment = AnnotateDecorator.generate("environment") fab_aggregate = AnnotateDecorator.generate("aggregate") @fab_aggregate def operation_list(): for f in AnnotateDecorator.list("operation"): print(f.__name__) @fab_aggregate def environment_list(): for f in AnnotateDecorator.list("environment"): print(f.__name__) ### from fabric.api import run, local, env, sudo env.user = "anonymous" @fab_operation def hello_function(): print("hello %s" % env.user) @fab_operation def hello(): local("echo hello %s" % env.user) @fab_environment def foo(): env.environment = "foo" env.user = "foo" @fab_environment def bar(): env.environment = "bar" env.user = "bar"
利用例
結構便利な気がする。
#fab [environment] <operation> $ fab hello [localhost] local: echo hello anonymous hello anonymous Done. $ fab foo hello [localhost] local: echo hello foo hello foo Done. $ fab bar hello [localhost] local: echo hello bar hello bar Done. $ fab foo hello_function hello foo Done. $ fab environment_list foo bar Done.