Sphinx プロジェクト横断的構成を考える

created at 2019-08-10 11:59+0900

複数のプロジェクトで同じカスタムレイアウトを適用したりプロジェクト間でリンク貼ったり、各プロジェクトが互いにちょこちょこ関連している場合、どんなディレクトリ構成にするのが良いだろうか。いくつか試してみた。

Sphinx ディレクトリ構成その1

Sphinxをいじり始めた時は、sphinx-quickstart コマンド実行時に --sep オプションをつけて次のようなディレクトリ構成にしていた。

ディレクトリ構成

  • {プロジェクト}/build/html

  • {プロジェクト}/build/doctrees

  • {プロジェクト}/source

.
├── conoha    # プロジェクトディレクトリ
│        ├── Makefile
│        ├── build
│        │   ├── doctrees
│        │   └── html
│        │       ├── genindex.html
│        │       ├── index.html
│        │       ├── objects.inv
│        │       ├── search.html
│        │       └── searchindex.js
│        └── source
│            ├── 00_setup.rst
│            ├── 01_maintenance.rst
│            ├── _static
│            ├── _templates
│            ├── conf.py
│            └── index.rst
└── sphinx            # プロジェクトディレクトリ
          ├── Makefile
          ├── build
          │   ├── doctrees
          │   └── html
          │       ├── genindex.html
          │       ├── index.html
          │       ├── objects.inv
          │       ├── search.html
          │       └── searchindex.js
          └── source
              ├── 00_setup.rst
              ├── 01_create_conf.py_t.rst
              ├── _static
              ├── _templates
              ├── conf.py
              └── index.rst

intersphinx設定

拡張機能intersphinxを有効にしている場合 :any:`conoha:install-ubuntu` みたいな感じでrstファイルに記述すると、 そのプロジェクトのそのラベル .. _install-ubuntu: へのリンクが生成される。

conohaプロジェクトのconf.py (conoha/source/conf.py)。sphinxプロジェクトへリンクを貼りたいので次のように設定する。

intersphinx_mapping = {
    'sphinx':('../../../sphinx/build/html', '../../sphinx/build/html/objects.inv'),
  # '識別子':(
  #    'conohaプロジェクトのHTMLルートから見たsphinxプロジェクトのHTMLルートへのパス',
  #    'conohaプロジェクトのsourceディレクトリから見たsphinxプロジェクトのinvファイルへのパス'
  # ),
}

sphinxプロジェクトのconf.py (sphinx/source/conf.py)。conohaプロジェクトへリンクを貼りたいので次のように設定する。

intersphinx_mapping = {
    'conoha':('../../../conoha/build/html', '../../conoha/build/html/objects.inv'),
  # '識別子':(
  #    'sphinxプロジェクトのHTMLルートから見たconohaプロジェクトのHTMLルートへのパス',
  #    'sphinxプロジェクトのsourceディレクトリから見たconohaプロジェクトのinvファイルへのパス'
  # ),
}

問題点

  • conohaプロジェクト→sphinxプロジェクトの順番でビルドすると、conohaプロジェクトをビルドする時点ではsphinxプロジェクトのインベントリファイル(objects.inv)は作成されていないので、そんなインベントリは見つからないよの旨警告が表示される。

    • 最初にビルドするプロジェクトは2度ビルドしなくてはいけない。(これはしゃーない)

  • Webサーバーにデプロイした場合、ターゲットへのパスがローカル開発環境(MacBook Pro)におけるパスと異なる。

    • sphinx-buildコマンドの -Dオプションでconf.py設定を上書きできるが、-Dオプションで指定できるのは数値、文字列、リスト、ディクショナリ型であり、タプル型は指定できない。よってconf.pyファイルを書き分ける必要がある。

Sphinx ディレクトリ構成その2

環境ごとのconf.pyファイルを作成した場合、パス指定の記述とか面倒の少ないのはどのようなやり方だろうか。 build, source, confそれぞれのディレクトリ配下に環境ごとのディレクトリを作り、その下にプロジェクトごとのディレクトリを作ったらどうだろうか、と思ってやってみた。

ディレクトリ構成

_conf_tmpl

プロジェクト生成時に使うconf.py_t置き場

_themes

オリジナルテーマ置き場

conf/{環境}/{プロジェクト}

HTMLビルド時に使うconf.py置き場

build/{環境}/{プロジェクト}

ビルドディレクトリ(HTML出力場所)

build/doctrees/{プロジェクト}

doctree出力場所

source/{プロジェクト}

rstファイル置き場

  • sphinx-quickstart はconf.pyを置きたいディレクトリで実行する(conf/dev_html/{project})

  • sphinx-build はこれらのディレクトリが配置してあるルートディレクトリ(次のツリーでカレントの場所)で実行する

.
├── Pipfile
├── Pipfile.lock
├── _conf_tmpl
│   ├── bootstrap_theme
│   │   └── conf.py_t
│   └── r2theme
│       └── conf.py_t
├── _themes
│   └── r2theme
│       ├── layout.html
│       ├── static
│       │   ├── ie6.css
│       │   ├── r2.css_t
│       │   └── tw.css
│       └── theme.conf
├── build
│   ├── dev_html
│   │   ├── conoha
│   │   └── sphinx
│   ├── doctrees
│   │   ├── conoha
│   │   └── sphinx
│   └── prod_html
├── conf
│   ├── dev_html
│   │   ├── conoha
│   │   │   ├── _build
│   │   │   ├── _static
│   │   │   ├── _templates
│   │   │   └── conf.py
│   │   └── sphinx
│   │       ├── _build
│   │       ├── _static
│   │       ├── _templates
│   │       └── conf.py
│   └── prod_html
├── fonts
│   ├── ipaexg.ttf
│   └── ipaexm.ttf
└── source
    ├── conoha
    │   ├── 00_setup.rst
    │   ├── 01_maintenance.rst
    │   └── index.rst
    ├── readinglist
    │   ├── IBM_Watson.rst
    │   └── fontUtils.rst
    └── sphinx
        ├── 00_setup.rst
        ├── 01_create_conf.py_t.rst
        ├── 02_sphinx_project.rst
        ├── 99_memo.txt
        └── index.rst

実行例

プロジェクト"conoha"

# create project conoha
cd ~/Documents/XDOCS/conf/dev_html/conoha && ls -la && pwd
sphinx-quickstart -q -p conoha -a 'r-square.net' -v 2019 -r '2019-alpha-0.1' -l ja -t '../../../_conf_tmpl/r2theme' \
    --no-makefile --no-batchfile --ext-autodoc --ext-intersphinx --ext-todo --ext-ifconfig \
    --extensions='sphinxcontrib.blockdiag,sphinxcontrib.seqdiag,sphinxcontrib.actdiag,sphinxcontrib.nwdiag' \
    --extensions='sphinx.ext.graphviz,sphinxcontrib.plantuml'

ls -la ../../../source/conoha/
mv index.rst ../../../source/conoha/
cd ~/Documents/XDOCS/source/conoha && ls -la && pwd
# index.rstごにょごにょ編集。その他ソースファイル作成したり編集したり。conf.pyもいろいろ設定しよう。

# build html conoha
cd ~/Documents/XDOCS && ls -la && pwd
sphinx-build -b html -E -d build/doctrees/conoha -c conf/dev_html/conoha source/conoha build/dev_html/conoha

プロジェクト"sphinx"

# create project sphinx
cd ~/Documents/XDOCS/conf/dev_html/sphinx && ls -la && pwd
sphinx-quickstart -q -p sphinx -a 'r-square.net' -v 2019 -r '2019-alpha-0.1' -l ja -t '../../../_conf_tmpl/r2theme' \
    --no-makefile --no-batchfile --ext-autodoc --ext-intersphinx --ext-todo --ext-ifconfig \
    --extensions='sphinxcontrib.blockdiag,sphinxcontrib.seqdiag,sphinxcontrib.actdiag,sphinxcontrib.nwdiag' \
    --extensions='sphinx.ext.graphviz,sphinxcontrib.plantuml'

ls -la ../../../source/sphinx/
mv index.rst ../../../source/sphinx/
cd ~/Documents/XDOCS/source/sphinx && ls -la && pwd
# index.rstごにょごにょ編集。その他ソースファイル作成したり編集したり。conf.pyもいろいろ設定しよう。

# build html sphinx
cd ~/Documents/XDOCS && ls -la && pwd
sphinx-build -b html -E -d build/doctrees/sphinx -c conf/dev_html/sphinx source/sphinx build/dev_html/sphinx

問題点

  • プロジェクトのためのディレクトリがあっちこっちにあるのはやっぱりキモい。(じゃあ何故やった?)

  • build/htmlディレクトリ配下の構成がリモート環境(Webサーバ)のHTMLドキュメントルートと同じになっていれば、conf.pyファイル分けなくても良さげ。(早く気づけや)

Sphinx ディレクトリ構成その3

sphinx-quickstart 実行時に --sepオプションをつけない。sphinx-build 実行時にビルドディレクトリとしてプロジェクト外のディレクトリを指定する。

sphinxプロジェクト作成・実行例

新たに"top"と言う名称のプロジェクトを作成する。

cd ~/Documents/XDOCS/source/top && ls -la && pwd
ls -la ../../_conf_tmpl/r2theme
sphinx-quickstart -q -p top -a 'r-square.net' -v 2019 -r '2019-alpha-0.1' -l ja -t '../../_conf_tmpl/r2theme' \
       --no-makefile --no-batchfile --ext-autodoc --ext-intersphinx --ext-todo --ext-ifconfig \
       --extensions='sphinxcontrib.blockdiag,sphinxcontrib.seqdiag,sphinxcontrib.actdiag,sphinxcontrib.nwdiag' \
       --extensions='sphinx.ext.graphviz,sphinxcontrib.plantuml'

ディレクトリ構成

.
├── Pipfile
├── Pipfile.lock
├── _conf_tmpl
├── _themes
├── build       # html出力先
├── fonts
│   ├── ipaexg.ttf
│   └── ipaexm.ttf
└── source
    ├── conoha
    ├── readinglist
    ├── sphinx
    └── top
        ├── _build    # ここにはdoctreesだけ置く
        ├── _static
        ├── _templates
        ├── conf.py
        └── index.rst

sphinxビルド実行例

プロジェクト"sphinx"

cd ~/Documents/XDOCS/source/sphinx/ && ls -la && pwd
sphinx-build -b html -E -d _build/doctrees ./ ../../build/html/sphinx

プロジェクト"conoha"

cd ~/Documents/XDOCS/source/conoha/ && ls -la && pwd
sphinx-build -b html -E -d _build/doctrees ./ ../../build/html/conoha

プロジェクト"top"

cd ~/Documents/XDOCS/source/top/ && ls -la && pwd
sphinx-build -b html -E -d _build/doctrees ./ ../../build/html/top

ディレクトリ構成

既出のソース類は一部省略

.
├── Pipfile
├── Pipfile.lock
├── _conf_tmpl
│   ├── bootstrap_theme
│   └── r2theme
│       └── conf.py_t
├── _themes
│   └── r2theme
├── build
│   └── html
│       ├── conoha
│       │   ├── _sources
│       │   ├── _static
│       │   ├── index.html
│       │   └── objects.inv
│       ├── sphinx
│       │   ├── _sources
│       │   ├── _static
│       │   ├── index.html
│       │   └── objects.inv
│       └── top
│           ├── _sources
│           ├── _static
│           ├── index.html
│           └── objects.inv
├── fonts
│   ├── ipaexg.ttf
│   └── ipaexm.ttf
└── source
    ├── conoha
    │   ├── _build
    │   │   └── doctrees
    │   ├── _static
    │   ├── _templates
    │   ├── conf.py
    │   └── index.rst
    ├── readinglist
    ├── sphinx
    │   ├── _build
    │   │   └── doctrees
    │   ├── _static
    │   ├── _templates
    │   ├── conf.py
    │   └── index.rst
    └── top
        ├── _build
        │   └── doctrees
        │       ├── environment.pickle
        │       └── index.doctree
        ├── _static
        │   └── tw.css
        ├── _templates
        │   └── layout.html
        ├── conf.py
        └── index.rst

まとまらないまとめ

迷走しまくってとりとめのない記事になってしまった。とにかくいろいろやってみた感想。

  • conf.pyの設定項目には、conf.py(のあるディレクトリ)からの相対パスだのソースディレクトリからの相対パスだのいろいろあってめんどくさい。

  • 一つのソースに対してconf.pyを複数作ってしまうとややこしい。

  • sphinx-build の '-D ' オプションでconf.pyの設定値を書き込めるので、ビルドスクリプトを作って環境ごとの差異を吸収するのが良さげ。

  • でもsphinx-build の '-D ' オプションで指定できるのは、文字列・リスト・辞書型なので、設定値がタプルの場合や辞書のリストの場合はconf.pyにガチ書きするしかない。

  • デフォルトで作られるディレクトリ構成に捉われないで、いろいろやってみると光明が見えるかもしれない。

  • 公式のベストプラクティスってあるのかな?