From 5a9a454631ff9e68cf1827ba1a9582a993dca8db Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 17 Jan 2010 18:24:35 +0100 Subject: [PATCH] Added ``needs_sphinx`` config value and ``Sphinx.require_sphinx`` application API function. --- CHANGES | 3 +++ doc/config.rst | 7 +++++++ doc/ext/appapi.rst | 8 ++++++++ sphinx/application.py | 24 ++++++++++++++++++++++-- sphinx/config.py | 1 + sphinx/errors.py | 4 ++++ sphinx/quickstart.py | 3 +++ tests/test_config.py | 8 +++++++- 8 files changed, 55 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 9cdc624aa..9d7dcd9b4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ Release 1.0 (in development) ============================ +* 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/config.rst b/doc/config.rst index e4693d848..92542f8ce 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 88bbe4853..7652f97c7 100644 --- a/doc/ext/appapi.rst +++ b/doc/ext/appapi.rst @@ -269,6 +269,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 baa67b2ac..f21aa60d7 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -22,7 +22,8 @@ from docutils.parsers.rst import directives, roles import sphinx from sphinx.roles import xfileref_role, innernodetypes from sphinx.config import Config -from sphinx.errors import SphinxError, SphinxWarning, ExtensionError +from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \ + VersionRequirementError from sphinx.builders import BUILTIN_BUILDERS from sphinx.directives import GenericDesc, Target, additional_xref_types from sphinx.environment import SphinxStandaloneReader @@ -104,6 +105,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) + if buildername is None: print >>status, 'No builder selected, using default: html' buildername = 'html' @@ -173,9 +181,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 566132b57..a77957777 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -60,6 +60,7 @@ class Config(object): modindex_common_prefix = ([], 'html'), rst_epilog = (None, 'env'), trim_doctest_flags = (True, 'env'), + needs_sphinx = (None, None), # HTML options html_theme = ('default', 'html'), diff --git a/sphinx/errors.py b/sphinx/errors.py index 4e62b1af1..4738f0cce 100644 --- a/sphinx/errors.py +++ b/sphinx/errors.py @@ -50,3 +50,7 @@ class ConfigError(SphinxError): class ThemeError(SphinxError): category = 'Theme error' + + +class VersionRequirementError(SphinxError): + category = 'Sphinx version error' diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 269170535..4e5b72e7d 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 5193bebe4..0d18bf7f0 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'})