0032 — Sphinx Multiversion
Sphinx Multiversion
Если вы работаете с системой документирования Sphinx, то, наверное, рано или поздно столкнётесь с проблемой поддержки документации для нескольких версий продукта.
Для решения этой проблемы существует несколько расширений Sphinx:
- Уже 4 года не получает обновлений.
- 17 звёзд на GitHub.
- Уже 4 года не получает обновлений.
- 116 звёзд на GitHub.
- Уже 3 года не получает обновлений.
- 126 звёзд на GitHub.
Во время поиска подходящего решения для своего проекта, я делал выбор из 2-х последних. В итоге остановился на sphinx-multiversion
как более актуальном. Также в его пользу сыграло то, что описано решение некоторых типовых проблем, например, с темой оформления ReadTheDocs.
В этой статье рассказывается как установить и настроить расширение sphinx-multiversion
, а также дан обзор некоторым его возможностям.
Установка
Установите пакет Python
sphinx-multiversion
:pip3 install sphinx-miltiversion
В каталоге
source/_templates/
создайте файлversions.html
, содержащий шаблон для отображения списка версий в боковой панели навигации:{% if versions %} <h3>{{ _('Versions') }}</h3> <ul> {%- for item in versions %} <li><a href="{{ item.url }}">{{ item.name }}</a></li> {%- endfor %} </ul> {% endif %}
Если используется тема ReadTheDocs, шаблон должен иметь такой вид:
{%- if current_version %} <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions"> <span class="rst-current-version" data-toggle="rst-current-version"> <span class="fa fa-book"> Other Versions</span> v: {{ current_version.name }} <span class="fa fa-caret-down"></span> </span> <div class="rst-other-versions"> {%- if versions.tags %} <dl> <dt>Tags</dt> {%- for item in versions.tags %} <dd><a href="{{ item.url }}">{{ item.name }}</a></dd> {%- endfor %} </dl> {%- endif %} {%- if versions.branches %} <dl> <dt>Branches</dt> {%- for item in versions.branches %} <dd><a href="{{ item.url }}">{{ item.name }}</a></dd> {%- endfor %} </dl> {%- endif %} </div> </div> {%- endif %}
Другие шаблоны можно посмотреть на странице проекта.
Сделайте правки в конфигурационном файле
source/conf.py
:Добавьте в список
extensions
модульsphinx_multiversion
:extensions = [ 'sphinx_multiversion', ]
Добавьте в список
templates_path
каталог_templates
:templates_path = [ '_templates', ]
Чтобы использовать созданный ранее шаблон на всех страницах проекта, добавьте в словарь
html_sidebars
строки:html_sidebars = { '**': [ 'versions.html', ], }
Добавьте файлы проекта в индекс и зафиксируйте изменения:
git add . && git commit -m "<message>"
где
<message>
— сообщение коммита.Этот шаг обязателен, так как для управления версиями документации расширение
sphinx-multiversion
использует возможности Git.
Сборка
Для сборки документации следует использовать команду:
sphinx-multiversion \
-c <PATH> \
-C \
-D <setting>=<value> \
<sourcedir> \
<targetdir>
Здесь:
-c
— путь к каталогу с файломconf.py
. По умолчанию используется значение, указанное в параметре<sourcedir>
.-C
— указание не использовать настройки из файлаconf.py
.-D
— указание настроек в формате<settings>=<value>
. Позволяет переопределить значения параметров из файлаconf.py
, либо вовсе избежать его использования, если ключ используется совместно с ключом-C
.<sourcedir>
— путь к каталогу с исходными файлами проекта.<targetdir>
— путь к каталогу, в котором следует разместить результаты сборки.
В самом простом случае команду можно сократить до такой:
sphinx-multiversion source/ build/
В каталоге build/
в этом случае будут созданы подкаталоги с версиями документации.
Сборка ветки master
Допустим, в проекте сейчас есть только ветка master
. Даже с ней проект можно собрать. Зафиксируйте изменения и соберите проект. В каталоге build/
будет создан подкаталог master/
, в котором будет размещена версия проекта для ветки master
.
Чтобы проверить результаты сборки:
Запустите локальный хостинг, например:
python3 -m http.server -d build/ -b 127.0.0.1 8080
Откройте в браузере ссылку http://127.0.0.1:8080/master/.
Убедитесь, что в панели навигации слева отображается блок Versions, который сейчас содержит всего одну запись — ссылку на версию master.
Версионирование проекта
Есть несколько подходов к версионированию, но я считаю самым удобным использование тегов Git. В этом случае история коммитов выглядит так:
Возможно, нам никогда не придётся вносить изменения в версию 1, и пока нет смысла заводить отдельную ветку. Но если вдруг такая необходимость появится, можно сделать так:
Переключиться на нужный тег:
git checkout v1
Git переместит указатель HEAD на коммит с привязанным к нему тегом.
Создать новую ветку:
git checkout -b v1
Это предотвратит ситуацию с «detached HEAD».
Сделать правки и зафиксировать изменения.
Удалить старый тег:
git tag -d v1
Воссоздать тег на текущем коммите, в новой ветке:
git tag v1
История коммитов примет вид:
Настройка
По умолчанию расширение собирает версии проекта, перебирая все имеющиеся теги и ветки. С учётом вышесказанного имеет смысл ограничить доступные версии только тегами. Для этого в source/conf.py
следует добавить строки:
smv_tag_whitelist= r'^.*$'
smv_branch_whitelist = r'^(?!master).*$'
smv_released_pattern = r'^tags/.*$' # только теги
Другие возможные варианты описаны в документации проекта.