clickで–versionオプションを実装する

以前使った Python の click モジュールだけど、コマンドやオプションを定義すると自動で --help オプションを作ってくれる。例えばこんなスクリプトがあったとすると:

# encoding: utf-8

import click

@click.command()
@click.option('--times', '-t', type=int, default=1, help='Repeat.')
@click.option('--morning', '-m', is_flag=True, help='In morning.')
@click.argument('name', default='World')
def main(times, morning, name):
    if morning:
        greeting = 'Good morning'
    else:
        greeting = 'Hello'
    for i in range(times):
        print '{greeting}, {name}!'.format(greeting=greeting, name=name)

if __name__ == '__main__':
    main()

こんな感じでヘルプメッセージを生成してくれる。

takatoh@nightschool $ python hello.py --help
Usage: hello.py [OPTIONS] [NAME]

Options:
  -t, --times INTEGER  Repeat.
  -m, --morning        In morning.
  --help               Show this message and exit.

だけど、--version オプションまでは作ってくれない。まあ、当たり前だ。
で、どうするかというと @click.version_option デコレータを使う。

# encoding: utf-8

import click

script_version = '0.1.0'

@click.command()
@click.option('--times', '-t', type=int, default=1, help='Repeat.')
@click.option('--morning', '-m', is_flag=True, help='In morning.')
@click.version_option(version=script_version)
@click.argument('name', default='World')
def main(times, morning, name):
    if morning:
        greeting = 'Good morning'
    else:
        greeting = 'Hello'
    for i in range(times):
        print '{greeting}, {name}!'.format(greeting=greeting, name=name)

if __name__ == '__main__':
    main()

これで --version オプションが使えるようになる。

takatoh@nightschool $ python hello_version.py --version
hello_version.py, version 0.1.0

ちょっと表示が冗長なので、もう少しシンプルにしてみる。デコレータの引数でメッセージのフォーマットを渡してやる。

# encoding: utf-8

import click

script_version = '0.1.0'

@click.command()
@click.option('--times', '-t', type=int, default=1, help='Repeat.')
@click.option('--morning', '-m', is_flag=True, help='In morning.')
@click.version_option(version=script_version, message='%(prog)s v%(version)s')
@click.argument('name', default='World')
def main(times, morning, name):
    if morning:
        greeting = 'Good morning'
    else:
        greeting = 'Hello'
    for i in range(times):
        print '{greeting}, {name}!'.format(greeting=greeting, name=name)

if __name__ == '__main__':
    main()
takatoh@nightschool $ python hello_version2.py --version
hello_version2.py v0.1.0

ちょっとだけシンプルになった。

参考ページ:
 cf. API – click