diff --git a/CHANGES b/CHANGES index 8f4d4de50..22cbc3751 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,9 @@ Release 1.0 (in development) * Added ``html-collect-pages`` event. +* Added ``needs_sphinx`` config value and ``Sphinx.require_sphinx`` + application API function. + * Added single-file HTML builder. * Added ``tab-width`` option to ``literalinclude`` directive. diff --git a/doc/conf.py b/doc/conf.py index afa330681..57556990f 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -2,69 +2,33 @@ # # Sphinx documentation build configuration file -import sys, os, re +import re +import sphinx -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.addons.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.autosummary'] -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. master_doc = 'contents' - +templates_path = ['_templates'] exclude_patterns = ['_build'] -# General substitutions. project = 'Sphinx' copyright = '2007-2010, Georg Brandl' - -# The default replacements for |version| and |release|, also used in various -# other places throughout the built documents. -import sphinx version = sphinx.__released__ release = version -# Show author directives in the output. show_authors = True -# The HTML template theme. html_theme = 'sphinxdoc' - -# A list of ignored prefixes names for module index sorting. modindex_common_prefix = ['sphinx.'] - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -html_last_updated_fmt = '%b %d, %Y' - -# Content template for the index page. html_index = 'index.html' - -# Custom sidebar templates, maps page names to templates. html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']} - -# Additional templates that should be rendered to pages, maps page names to -# templates. html_additional_pages = {'index': 'index.html'} - -# Generate an OpenSearch description with that URL as the base. html_use_opensearch = 'http://sphinx.pocoo.org' -# Output file base name for HTML help builder. htmlhelp_basename = 'Sphinxdoc' -# Epub fields epub_theme = 'epub' epub_basename = 'sphinx' epub_author = 'Georg Brandl' @@ -76,21 +40,13 @@ epub_exclude_files = ['_static/opensearch.xml', '_static/doctools.js', '_static/jquery.js', '_static/searchtools.js', '_static/basic.css', 'search.html'] - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation', 'Georg Brandl', 'manual', 1)] - -# Add our logo to the LaTeX file. latex_logo = '_static/sphinx.png' - -# Additional stuff for the LaTeX preamble. latex_elements = { 'fontpkg': '\\usepackage{palatino}', } -# Put TODOs into the output. todo_include_todos = True diff --git a/doc/config.rst b/doc/config.rst index 3b2336837..01d73c974 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -224,6 +224,13 @@ General configuration .. versionadded:: 1.0 +.. confval:: needs_sphinx + + If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will + compare it with its version and refuse to build if it is too old. + + .. versionadded:: 1.0 + Project information ------------------- diff --git a/doc/ext/appapi.rst b/doc/ext/appapi.rst index 12d004a19..a643a4787 100644 --- a/doc/ext/appapi.rst +++ b/doc/ext/appapi.rst @@ -296,6 +296,14 @@ the following public API: .. versionadded:: 0.5 +.. method:: Sphinx.require_sphinx(version) + + Compare *version* (which must be a ``major.minor`` version string, + e.g. ``'1.1'``) with the version of the running Sphinx, and abort the build + when it is too old. + + .. versionadded:: 1.0 + .. exception:: ExtensionError diff --git a/sphinx/application.py b/sphinx/application.py index 37117692f..58570a149 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -25,7 +25,8 @@ import sphinx from sphinx import package_dir, locale from sphinx.roles import XRefRole from sphinx.config import Config -from sphinx.errors import SphinxError, SphinxWarning, ExtensionError +from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \ + VersionRequirementError from sphinx.domains import ObjType, all_domains from sphinx.domains.std import GenericObject, Target, StandardDomain from sphinx.builders import BUILTIN_BUILDERS @@ -111,6 +112,13 @@ class Sphinx(object): # now that we know all config values, collect them from conf.py self.config.init_values() + # check the Sphinx version if requested + if self.config.needs_sphinx and \ + self.config.needs_sphinx > sphinx.__version__[:3]: + raise VersionRequirementError( + 'This project needs at least Sphinx v%s and therefore cannot ' + 'be built with this version.' % self.config.needs_sphinx) + # set up translation infrastructure self._init_i18n() # set up the build environment @@ -232,9 +240,21 @@ class Sphinx(object): self.warn('extension %r has no setup() function; is it really ' 'a Sphinx extension module?' % extension) else: - mod.setup(self) + try: + mod.setup(self) + except VersionRequirementError, err: + # add the extension name to the version required + raise VersionRequirementError( + 'The %s extension used by this project needs at least ' + 'Sphinx v%s; it therefore cannot be built with this ' + 'version.' % (extension, err)) self._extensions[extension] = mod + def require_sphinx(self, version): + # check the Sphinx version if requested + if version > sphinx.__version__[:3]: + raise VersionRequirementError(version) + def import_object(self, objname, source=None): """Import an object from a 'module.name' string.""" try: diff --git a/sphinx/config.py b/sphinx/config.py index f1aba0eb4..fca33136c 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -61,6 +61,7 @@ class Config(object): rst_epilog = (None, 'env'), trim_doctest_flags = (True, 'env'), default_domain = ('py', 'env'), + needs_sphinx = (None, None), # HTML options html_theme = ('default', 'html'), diff --git a/sphinx/errors.py b/sphinx/errors.py index 6e8c4e1c6..b614d9ab0 100644 --- a/sphinx/errors.py +++ b/sphinx/errors.py @@ -52,6 +52,10 @@ class ThemeError(SphinxError): category = 'Theme error' +class VersionRequirementError(SphinxError): + category = 'Sphinx version error' + + class PycodeError(Exception): def __str__(self): res = self.args[0] diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 5767405ce..f3d26aa4d 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -46,6 +46,9 @@ import sys, os # -- General configuration ----------------------------------------------------- +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [%(extensions)s] diff --git a/tests/test_config.py b/tests/test_config.py index 0ccdd9091..cb4e11056 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -12,8 +12,9 @@ from util import * +import sphinx from sphinx.config import Config -from sphinx.errors import ExtensionError, ConfigError +from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError @with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True', @@ -94,3 +95,8 @@ def test_errors_warnings(dir): warned[0] = True cfg.check_unicode(warn) assert warned[0] + + +def test_needs_sphinx(): + raises(VersionRequirementError, TestApp, + confoverrides={'needs_sphinx': '9.9'})