2008-07-29 09:51:58 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
"""
|
|
|
|
|
sphinx.setup_command
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Setuptools/distutils commands to assist the building of sphinx
|
|
|
|
|
documentation.
|
|
|
|
|
|
|
|
|
|
:author: Sebastian Wiesner
|
|
|
|
|
:contact: basti.wiesner@gmx.net
|
2010-01-01 14:09:13 +01:00
|
|
|
:copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
|
2009-01-03 12:15:19 +01:00
|
|
|
:license: BSD, see LICENSE for details.
|
2008-07-29 09:51:58 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
from StringIO import StringIO
|
|
|
|
|
from distutils.cmd import Command
|
|
|
|
|
|
|
|
|
|
from sphinx.application import Sphinx
|
2009-05-10 21:06:34 +02:00
|
|
|
from sphinx.util.console import darkred, nocolor, color_terminal
|
2008-07-29 09:51:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class BuildDoc(Command):
|
2009-09-10 16:25:48 +02:00
|
|
|
"""Distutils command to build Sphinx documentation.
|
2010-02-19 10:28:32 +01:00
|
|
|
|
|
|
|
|
The Sphinx build can then be triggered from distutils, and some Sphinx
|
|
|
|
|
options can be set in ``setup.py`` or ``setup.cfg`` instead of Sphinx own
|
|
|
|
|
configuration file.
|
|
|
|
|
|
2009-09-10 16:25:48 +02:00
|
|
|
For instance, from `setup.py`::
|
2010-02-19 10:28:32 +01:00
|
|
|
|
|
|
|
|
# this is only necessary when not using setuptools/distribute
|
|
|
|
|
from sphinx.setup_command import BuildDoc
|
|
|
|
|
cmdclass = {'build_sphinx': BuildDoc}
|
|
|
|
|
|
|
|
|
|
name = 'My project'
|
|
|
|
|
version = 1.2
|
|
|
|
|
release = 1.2.0
|
|
|
|
|
setup(
|
|
|
|
|
name=name,
|
|
|
|
|
author='Bernard Montgomery',
|
|
|
|
|
version=release,
|
|
|
|
|
cmdclass={'build_sphinx': BuildDoc},
|
|
|
|
|
# these are optional and override conf.py settings
|
|
|
|
|
command_options={
|
|
|
|
|
'build_sphinx': {
|
|
|
|
|
'project': ('setup.py', name),
|
|
|
|
|
'version': ('setup.py', version),
|
|
|
|
|
'release': ('setup.py', release)}},
|
|
|
|
|
)
|
|
|
|
|
|
2009-09-10 16:25:48 +02:00
|
|
|
Or add this section in ``setup.cfg``::
|
2010-02-19 10:28:32 +01:00
|
|
|
|
|
|
|
|
[build_sphinx]
|
|
|
|
|
project = 'My project'
|
|
|
|
|
version = 1.2
|
|
|
|
|
release = 1.2.0
|
2009-09-10 16:25:48 +02:00
|
|
|
"""
|
2008-07-29 09:51:58 +00:00
|
|
|
|
|
|
|
|
description = 'Build Sphinx documentation'
|
|
|
|
|
user_options = [
|
|
|
|
|
('fresh-env', 'E', 'discard saved environment'),
|
|
|
|
|
('all-files', 'a', 'build all files'),
|
|
|
|
|
('source-dir=', 's', 'Source directory'),
|
|
|
|
|
('build-dir=', None, 'Build directory'),
|
2010-04-29 18:01:58 -04:00
|
|
|
('config-dir=', 'c', 'Location of the configuration directory'),
|
2008-07-29 09:51:58 +00:00
|
|
|
('builder=', 'b', 'The builder to use. Defaults to "html"'),
|
2010-02-19 10:28:32 +01:00
|
|
|
('project=', None, 'The documented project\'s name'),
|
2009-08-31 16:32:14 +02:00
|
|
|
('version=', None, 'The short X.Y version'),
|
|
|
|
|
('release=', None, 'The full version, including alpha/beta/rc tags'),
|
2010-02-19 10:28:32 +01:00
|
|
|
('today=', None, 'How to format the current date, used as the '
|
|
|
|
|
'replacement for |today|'),
|
2010-04-29 21:08:58 -04:00
|
|
|
('link-index', 'i', 'Link index.html to the master doc'),
|
2010-02-19 10:28:32 +01:00
|
|
|
]
|
2010-04-29 21:08:58 -04:00
|
|
|
boolean_options = ['fresh-env', 'all-files', 'link-index']
|
2008-07-29 09:51:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
|
self.fresh_env = self.all_files = False
|
|
|
|
|
self.source_dir = self.build_dir = None
|
|
|
|
|
self.builder = 'html'
|
2009-08-31 16:32:14 +02:00
|
|
|
self.version = ''
|
|
|
|
|
self.release = ''
|
|
|
|
|
self.today = ''
|
2010-04-29 18:01:58 -04:00
|
|
|
self.config_dir = None
|
2010-04-29 21:08:58 -04:00
|
|
|
self.link_index = False
|
2008-07-29 09:51:58 +00:00
|
|
|
|
2010-02-07 23:40:40 +01:00
|
|
|
def _guess_source_dir(self):
|
2010-04-29 18:53:15 -04:00
|
|
|
for guess in ('doc', 'docs'):
|
2010-02-07 23:40:40 +01:00
|
|
|
if not os.path.isdir(guess):
|
|
|
|
|
continue
|
|
|
|
|
for root, dirnames, filenames in os.walk(guess):
|
|
|
|
|
if 'conf.py' in filenames:
|
|
|
|
|
return root
|
2010-04-29 18:53:15 -04:00
|
|
|
return None
|
2010-02-07 23:40:40 +01:00
|
|
|
|
2008-07-29 09:51:58 +00:00
|
|
|
def finalize_options(self):
|
|
|
|
|
if self.source_dir is None:
|
2010-02-07 23:40:40 +01:00
|
|
|
self.source_dir = self._guess_source_dir()
|
|
|
|
|
self.announce('Using source directory %s' % self.source_dir)
|
2008-07-29 09:51:58 +00:00
|
|
|
self.ensure_dirname('source_dir')
|
2010-04-29 18:53:15 -04:00
|
|
|
if self.source_dir is None:
|
|
|
|
|
self.source_dir = os.curdir
|
2008-07-29 09:51:58 +00:00
|
|
|
self.source_dir = os.path.abspath(self.source_dir)
|
2010-04-29 18:01:58 -04:00
|
|
|
if self.config_dir is None:
|
|
|
|
|
self.config_dir = self.source_dir
|
2008-07-29 09:51:58 +00:00
|
|
|
|
|
|
|
|
if self.build_dir is None:
|
|
|
|
|
build = self.get_finalized_command('build')
|
|
|
|
|
self.build_dir = os.path.join(build.build_base, 'sphinx')
|
|
|
|
|
self.mkpath(self.build_dir)
|
|
|
|
|
self.ensure_dirname('build_dir')
|
|
|
|
|
self.doctree_dir = os.path.join(self.build_dir, 'doctrees')
|
|
|
|
|
self.mkpath(self.doctree_dir)
|
|
|
|
|
self.builder_target_dir = os.path.join(self.build_dir, self.builder)
|
|
|
|
|
self.mkpath(self.builder_target_dir)
|
|
|
|
|
|
|
|
|
|
def run(self):
|
2009-05-10 21:06:34 +02:00
|
|
|
if not color_terminal():
|
2008-07-29 09:51:58 +00:00
|
|
|
# Windows' poor cmd box doesn't understand ANSI sequences
|
|
|
|
|
nocolor()
|
|
|
|
|
if not self.verbose:
|
|
|
|
|
status_stream = StringIO()
|
|
|
|
|
else:
|
|
|
|
|
status_stream = sys.stdout
|
2009-08-31 16:32:14 +02:00
|
|
|
confoverrides = {}
|
|
|
|
|
if self.version:
|
|
|
|
|
confoverrides['version'] = self.version
|
|
|
|
|
if self.release:
|
|
|
|
|
confoverrides['release'] = self.release
|
|
|
|
|
if self.today:
|
|
|
|
|
confoverrides['today'] = self.today
|
2010-04-29 18:01:58 -04:00
|
|
|
app = Sphinx(self.source_dir, self.config_dir,
|
2008-07-29 09:51:58 +00:00
|
|
|
self.builder_target_dir, self.doctree_dir,
|
2009-08-31 16:32:14 +02:00
|
|
|
self.builder, confoverrides, status_stream,
|
2008-07-29 09:51:58 +00:00
|
|
|
freshenv=self.fresh_env)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
if self.all_files:
|
|
|
|
|
app.builder.build_all()
|
|
|
|
|
else:
|
|
|
|
|
app.builder.build_update()
|
|
|
|
|
except Exception, err:
|
2008-08-30 13:29:17 +00:00
|
|
|
from docutils.utils import SystemMessage
|
2008-07-29 09:51:58 +00:00
|
|
|
if isinstance(err, SystemMessage):
|
2010-08-17 05:15:14 +02:00
|
|
|
print >>sys.stderr, darkred('reST markup error:')
|
2009-01-10 21:23:39 +01:00
|
|
|
print >>sys.stderr, err.args[0].encode('ascii',
|
|
|
|
|
'backslashreplace')
|
2008-07-29 09:51:58 +00:00
|
|
|
else:
|
|
|
|
|
raise
|
2010-04-29 21:08:58 -04:00
|
|
|
|
|
|
|
|
if self.link_index:
|
|
|
|
|
src = app.config.master_doc + app.builder.out_suffix
|
|
|
|
|
dst = app.builder.get_outfilename('index')
|
|
|
|
|
os.symlink(src, dst)
|