PasteScript
PasteScriptは以下の2つの機能を提供するコマンドラインツール.今回話題とするのはpaster create
の方.
- 指定したテンプレート(自作可能)を元に、プロジェクトの雛形を作成する(
paster create
) -
PasteDeployにより設定されたWSGIアプリケーション(WSGIサーバ、関連ミドルウェアの設定含む)を起動する(
paster serve
)
長らくPython3に対応していないのがネックだったが、先月リリースしたPasteScript 2.0によりついにPython3がサポートされた。
paster create
コマンド
以下は、同梱されているbasic_package
テンプレートを指定した例である。basic_package
テンプレートはsetup.pyを含んだPythonパッケージプロジェクトを生成する。
$ paster create -t basic_package test
Selected and implied templates:
PasteScript#basic_package A basic setuptools-enabled package
Variables:
egg: test
package: test
project: test
Enter version (Version (like 0.1)) ['']: 0.1
Enter description (One-line description of the package) ['']: test
Enter long_description (Multi-line description (in reST)) ['']: test
Enter keywords (Space-separated keywords/tags) ['']: python
Enter author (Author name) ['']: FGtatsuro
Enter author_email (Author email) ['']:
Enter url (URL of homepage) ['']:
Enter license_name (License name) ['']:
Enter zip_safe (True/False: if the package can be distributed as a .zip file) [False]:
Creating template basic_package
Creating directory ./test
Recursing into +package+
Creating ./test/test/
Copying __init__.py to ./test/test/__init__.py
Recursing into __pycache__
Creating ./test/test/__pycache__/
Copying setup.cfg to ./test/setup.cfg
Copying setup.py_tmpl to ./test/setup.py
Running /Users/tatsuro/.homesick/repos/dotfiles/home/.virtualenvs/flask-boilerplate/bin/python setup.py egg_info
# setup.pyを含むPythonパッケージプロジェクト
$ ls test
setup.cfg setup.py test test.egg-info
指定するテンプレートは自作できる。
詳細については説明しない(ドキュメント参照)がおおまかな流れは以下の通り。
- テンプレートを定義するPythonパッケージプロジェクトを作成する。
-
paste.script.templates.Template
クラスを継承したクラス(以下、カスタムテンプレート)を作成する。 - 1のプロジェクトの
setup.py
のエントリポイントから、2で定義したクラスを指定する。
デフォルトで提供されるテンプレートエンジン
雛形生成時に与える引数により、指定したテンプレートのファイル名や内容をカスタマイズできる。
# 対話式に与えた引数が反映されている(ex. version, description)
$ cat test/setup.py
from setuptools import setup, find_packages
import sys, os
version = '0.1'
setup(name='test',
version=version,
description="test",
long_description="""\
test""",
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
keywords='python',
author='FGtatsuro',
...
)
この際、内容の書き変えにテンプレートエンジンが用いられる。使用するテンプレートエンジンはドキュメントを見ると以下の通り。
- カスタムテンプレートの
use_cheetah
属性がTrueの場合、Cheetahが使用される。 - それ以外の場合、string.Templateが使用される。
他のテンプレートエンジンを使用する
この2つのどちらかでも悪くはないが、自分の使い慣れているテンプレートエンジンを使ってカスタムテンプレートを作成したいという要求もあるだろう。
個人的には多少使い慣れているJinja2が使いたかった。
カスタムテンプレートのtemplate_renderer
属性に一定の条件を満たすstaticメソッドを紐付けることで上記の要望が実現できる。以下はテンプレートエンジンにJinja2
を使用した例である。
# https://github.com/FGtatsuro/flask-boilerplate/blob/master/flask_boilerplate/templates.py
class Boilerplate(Template):
_template_dir = 'templates'
summary = 'A boilerplate for Flask project'
required_templates = []
vars = [
var('app_name', 'Flask application name', default=NoDefault),
var('description', 'One-line description of the package'),
var('author', 'Author name'),
var('author_email', 'Author email'),
]
@staticmethod
def template_renderer(body, context, filename=None):
return Jinja2Template(body).render(context)
...
staticメソッドが満たさなければいけない条件は下記の通り。
- 書き換え対象文字列を第一引数に、書き換えに使用される変数の辞書を第二引数に、置き変え対象のファイル名を第三引数に取る。なおファイル名が必要ないならば、ファイル名のデフォルトは
None
でかまわない。 - 書き換え後の文字列をreturnする。テンプレートエンジンを使って文字列を書き換えてreturnするだけでOKのケースがほとんどだろう。
今回の例はJinja2
だが、上記の条件を満たすことができる、ようは与えられた3つの引数から書き換え後の文字列を生成できるテンプレートエンジンであれば同様に使用できる。
他のエンジンは未確認のため断言できないが、大多数のテンプレートエンジンは大丈夫ではないか。