More than 1 year has passed since last update.


はじめに

以前の投稿で、1コマンドでsphinx-apidocとsphinxを両方実行する方法について記載しました。しかしながら、この方法はsphinx自体ではなく、setuptoolsの挙動を変更する方法であったため、setuptoolsを噛まさず直接sphinxを実行するRead the Docsなどのサービスとうまく連携できないという問題がありました。本投稿では、sphinx側の実行に直接sphinx-apidocを組みこむ方法について記載します。


手順

ディレクトリ構造などは前回の投稿に準拠します。

まず、Sphinxの実行にsphinx-apidocを組み込みます。


doc/source/conf.py

import sphinx.apidoc

root_dir = os.path.abspath('../..')

try:
# This succeeds = the project is already installed.
# This directive avoids Readthedocs to fail
import my_project
except ImportError:
sys.path.insert(0, root_dir)
import my_project

# ...
# Rest of the conf.py
# ...

def run_apidoc(_):
script_dir = os.path.dirname(os.path.realpath(__file__))
src_dir = os.path.join(script_dir, root_dir)
out_dir = os.path.join(script_dir, "modules")
sphinx.apidoc.main(
['', '-f', '-H', project, '-A', author,
'-V', version, '-R', release, '-T', '-M',
'-o', out_dir, src_dir])

def setup(app):
app.connect('builder-inited', run_apidoc)


ポイントは2つあります:

1. import my_project をこころみ、失敗したらプロジェクトのrootにパスを通して再度インポートを試みます。Read the Docsは一度ライブラリをビルドして、ローカルの環境にインストールしてからドキュメントをビルドするからです1

2.setup コマンドを定義することで、Sphinx実行時にsphinx-apidocの実行をhookします。

前回の投稿のようにsetup.pyにsphinx-apidocを組み込んでしまっている場合には元の状態に戻します。その上で下記のようにsetup.pyまわりを修正します。


setup.py


cmdclass = {}

# こうしないとライブラリを利用者としてインストールするためだけにSphinxが必要になる
try:
from sphinx.setup_command import BuildDoc
cmdclass['build_sphinx'] = BuildDoc
except ImportError:
pass

# ...
# Rest of the setup.py
# ...

setup(
...
cmdclass=cmdclass
)



setup.cfg

[build_sphinx]

source-dir = doc/source
build-dir = doc/build
all_files = 1

最後にRead the Docs側を設定します。

rtd_settings.png

以上の手順をふむことで python setup.py build_sphinx で開発環境でドキュメンテーションのビルドができ、かつRead the Docsからも同じようにビルドできる環境が出来上がります。





  1. これはRead the Docsのオプションであり、初期設定の挙動ではありません。しかし、setuptools側で依存ライブラリを定義してあるのであれば、別途Read the Docs用に requirements.txt を作ったりするよりスマートだと思います。