Tinkerer の動き方

このブログは Tinkererで生成している。 Tinkererが動くための最初の流れをメモしておく。

TinkererとSphinxの関係

SphinxというreST形式から他の形式に変換するツールが存在する。 TinkererSphinxを使ってブログを生成する。 TinkererSphinxを呼ぶだけで実装は Sphinx拡張 + コマンドラインフロントエンドとなっている。

Tinkerer独自の処理はSphinx拡張で定義されていて tinker -sコマンドで生成した設定ファイルに最初から使う様に指定されている。

ちなみに Sphinx のマークアップは沢山ある。 Shinxの公式ドキュメントからユーザードキュメントに辿り着ける。

設定ファイル

Sphinxはソースディレクトリ(Sphinxが処理する対象のトップレベルディレクトリ)に含まれる conf.pyを設定ファイルとして使う。extensionsに設定されている拡張が利用される。

1
extensions = ['tinkerer.ext.blog', 'tinkerer.ext.disqus']

上のはDisqus拡張も使う様に追加している。 モジュールtinkerer.ext.blogの挙動の説明は先にSphinx拡張の説明が必要なので別の機会に書く。

Sphinxが動くまで

コマンドtinker -bSphinxを呼ぶまでを追う。 Sphinxが呼ばれるまでに解決される事が2つある。

  1. コマンドtinkerの実行関数の特定
  2. tinkerのサブコマンド の識別

コマンド tinker の実行関数の特定

コマンドの実行コードの解決にはpkg_resources/load_entry_point が使われていた。 実際に vim $(which tinker)したら以下の様に書かれていた。

1
2
3
4
5
# ...
from pkg_resources import load_entry_point
sys.exit(
  load_entry_point('Tinkerer==1.2.1', 'tinkerer')
)

上記は以下2つの事をしている。

  1. sys.exit はコマンドの実行ステータスを受け取り SystemExit を送出する。要するに明示的に終了している
  2. easy_installのサブモジュールpkg_resourcesload_entry_point でpkg情報とコマンド名からコマンドのエントリポイントを取得し実行する

load_entry_pointで呼ばれる関数はPKGNAME-Ver-pyVer.egg-info/entry_points.txtファイルに記述されいる。 自分の環境では以下となっている。

1
2
3
4
5
$ cat Tinkerer-1.2.1-py2.7.egg-info/entry_points.txt
...

[console_scripts]
tinker = tinkerer.cmdline:main

なのでコマンドtinkererはlib内のtinkerer.cmdline:mainを呼ぶ。 pkg_resourcesが呼び出し可能オブジェクトを生成する部分は追っていない。

tinkerのサブコマンド の識別

tinker本体はディスパッチャで引数解析にargparseパッケージが使われている

ref. http://docs.python.jp/2/library/argparse.html

ビルド(-b)では tinkerer.cmdline:build が呼ばれる。 その中でフラグ類が設定されSphinxが呼ばれる。

comments powered by Disqus