Commits

Anonymous committed 5518267

Allow the configuration directory to be set differently from the source directory.

Also don't import docutils on importing sphinx.

  • Participants
  • Parent commits 29908c3

Comments (0)

Files changed (9)

File doc/concepts.rst

 Since the reST source files can have different extensions (some people like
 ``.txt``, some like ``.rst`` -- the extension can be configured with
 :confval:`source_suffix`) and different OSes have different path separators,
-Sphinx abstracts them: all "document names" are relative to the
-:term:`documentation root`, the extension is stripped, and path separators are
-converted to slashes.  All values, parameters and suchlike referring to
-"documents" expect such a document name.
+Sphinx abstracts them: all "document names" are relative to the :term:`source
+directory`, the extension is stripped, and path separators are converted to
+slashes.  All values, parameters and suchlike referring to "documents" expect
+such a document name.
 
 
 The TOC tree
    The second line above will link to the ``strings`` document, but will use the
    title "All about strings" instead of the title of the ``strings`` document.
           
-   In the end, all documents under the :term:`documentation root` must occur in
-   some ``toctree`` directive; Sphinx will emit a warning if it finds a file
-   that is not included, because that means that this file will not be reachable
-   through standard navigation.  Use :confval:`unused_documents` to explicitly
-   exclude documents from this check.
+   In the end, all documents in the :term:`source directory` (or subdirectories)
+   must occur in some ``toctree`` directive; Sphinx will emit a warning if it
+   finds a file that is not included, because that means that this file will not
+   be reachable through standard navigation.  Use :confval:`unused_documents` to
+   explicitly exclude documents from this check, and :confval:`exclude_dirs` to
+   exclude whole directories.
 
    The "master document" (selected by :confval:`master_doc`) is the "root" of
    the TOC tree hierarchy.  It can be used as the documentation's main page, or

File doc/config.rst

 .. module:: conf
    :synopsis: Build configuration file.
 
-The :term:`documentation root` must contain a file named :file:`conf.py`.  This
-file (containing Python code) is called the "build configuration file" and
+The :term:`configuration directory` must contain a file named :file:`conf.py`.
+This file (containing Python code) is called the "build configuration file" and
 contains all configuration needed to customize Sphinx input and output behavior.
 
 The configuration file if executed as Python code at build time (using
-:func:`execfile`, and with the current directory set to the documentation root),
-and therefore can execute arbitrarily complex code.  Sphinx then reads simple
-names from the file's namespace as its configuration.
+:func:`execfile`, and with the current directory set to its containing
+directory), and therefore can execute arbitrarily complex code.  Sphinx then
+reads simple names from the file's namespace as its configuration.
 
-Some conventions are important to keep in mind here: Relative paths are always
-used relative to the documentation root, and document names must always be given
-without file name extension.
+Important points to note:
 
-The term "fully-qualified name" refers to a string that names an importable
-Python object inside a module; for example, the FQN ``"sphinx.builder.Builder"``
-means the ``Builder`` class in the ``sphinx.builder`` module.
+* If not otherwise documented, values must be strings, and their default is the
+  empty string.
 
-The contents of the namespace are pickled (so that Sphinx can find out when
-configuration changes), so it may not contain unpickleable values -- delete them
-from the namespace with ``del`` if appropriate.  Modules are removed
-automatically, so you don't need to ``del`` your imports after use.
+* The term "fully-qualified name" refers to a string that names an importable
+  Python object inside a module; for example, the FQN
+  ``"sphinx.builder.Builder"`` means the ``Builder`` class in the
+  ``sphinx.builder`` module.
 
-The configuration values can be separated in several groups.  If not otherwise
-documented, values must be strings, and their default is the empty string.
+* Remember that document names use ``/`` as the path separator and don't contain
+  the file name extension.
+
+* The contents of the config namespace are pickled (so that Sphinx can find out
+  when configuration changes), so it may not contain unpickleable values --
+  delete them from the namespace with ``del`` if appropriate.  Modules are
+  removed automatically, so you don't need to ``del`` your imports after use.
 
 
 General configuration
    extensions coming with Sphinx (named ``sphinx.addons.*``) or custom ones.
 
    Note that you can extend :data:`sys.path` within the conf file if your
-   extensions live in another directory -- but make sure you use absolute
-   paths.  If your extension path is relative to the documentation root, use
-   :func:`os.path.abspath` like so::
+   extensions live in another directory -- but make sure you use absolute paths.
+   If your extension path is relative to the :term:`configuration directory`,
+   use :func:`os.path.abspath` like so::
 
       import sys, os
 
 
       extensions = ['extname']
 
-   That way, you can load an extension called ``extname`` from the documentation
-   root's subdirectory ``sphinxext``.
+   That way, you can load an extension called ``extname`` from the subdirectory
+   ``sphinxext``.
 
    The configuration file itself can be an extension; for that, you only need to
    provide a :func:`setup` function in it.
 .. confval:: templates_path
 
    A list of paths that contain extra templates (or templates that overwrite
-   builtin templates).
+   builtin templates).  Relative paths are taken as relative to the
+   configuration directory.
 
 .. confval:: template_bridge
 
 .. confval:: html_static_path
 
    A list of paths that contain custom static files (such as style sheets or
-   script files).  They are copied to the output directory after the builtin
-   static files, so a file named :file:`default.css` will overwrite the builtin
+   script files).  Relative paths are taken as relative to the configuration
+   directory.  They are copied to the output directory after the builtin static
+   files, so a file named :file:`default.css` will overwrite the builtin
    :file:`default.css`.
 
 .. confval:: html_last_updated_fmt
 .. confval:: latex_logo
 
    If given, this must be the name of an image file (relative to the
-   documentation root) that is the logo of the docs.  It is placed at the top of
-   the title page.  Default: ``None``.
+   configuration directory) that is the logo of the docs.  It is placed at the
+   top of the title page.  Default: ``None``.
 
 .. confval:: latex_appendices
 

File doc/glossary.rst

 
       See :ref:`builders` for an overview over Sphinx' built-in builders.
 
+   configuration directory
+      The directory containing :file:`conf.py`.  By default, this is the same as
+      the :term:`source directory`, but can be set differently with the **-c**
+      command-line option.
+
    description unit
       The basic building block of Sphinx documentation.  Every "description
       directive" (e.g. :dir:`function` or :dir:`describe`) creates such a unit;
       and most units can be cross-referenced to.
 
-   documentation root
-      The directory which contains the documentation's :file:`conf.py` file and
-      is therefore seen as one Sphinx project.
-
    environment
       A structure where information about all documents under the root is saved,
       and used for cross-referencing.  The environment is pickled after the
       parsing stage, so that successive runs only need to read and parse new and
       changed documents.
+
+   source directory
+      The directory which, including its subdirectories, contains all source
+      files for one Sphinx project.

File doc/intro.rst

 .. _Pygments: http://pygments.org
 
 
-Setting up a documentation root
--------------------------------
+Setting up the documentation sources
+------------------------------------
 
-The root directory of a documentation collection is called the
-:dfn:`documentation root`.  There's nothing special about it; it just needs to
-contain the Sphinx configuration file, :file:`conf.py`.
+The root directory of a documentation collection is called the :dfn:`source
+directory`.  Normally, this directory also contains the Sphinx configuration
+file :file:`conf.py`, but that file can also live in another directory, the
+:dfn:`configuration directory`.
+
+.. versionadded:: 0.2.1
+   Support for a different configuration directory.
 
 Sphinx comes with a script called :program:`sphinx-quickstart` that sets up a
-documentation root and creates a default :file:`conf.py` from a few questions
-it asks you.  Just run ::
+source directory and creates a default :file:`conf.py` from a few questions it
+asks you.  Just run ::
 
    $ sphinx-quickstart
 
 
      $ sphinx-build -b latex sourcedir builddir
 
-where *sourcedir* is the :term:`documentation root`, and *builddir* is the
+where *sourcedir* is the :term:`source directory`, and *builddir* is the
 directory in which you want to place the built documentation (it must be an
 existing directory).  The :option:`-b` option selects a builder; in this example
 Sphinx will build LaTeX files.
    the build directory; with this option you can select a different cache
    directory (the doctrees can be shared between all builders).
 
+**-c** *path*
+   Don't look for the :file:`conf.py` in the source directory, but use the given
+   configuration directory instead.  Note that various other files and paths
+   given by configuration values are expected to be relative to the
+   configuration directory, so they will have to be present at this location
+   too.
+
+   .. versionadded:: 0.2.1
+
 **-D** *setting=value*
    Override a configuration value set in the :file:`conf.py` file.  (The value
    must be a string value.)

File doc/markup/para.rst

 
       .. glossary::
 
-         documentation root
-            The directory which contains the documentation's :file:`conf.py` file and
-            is therefore seen as one Sphinx project.
-
          environment
             A structure where information about all documents under the root is saved,
             and used for cross-referencing.  The environment is pickled after the
             parsing stage, so that successive runs only need to read and parse new and
             changed documents.
 
+         source directory
+            The directory which, including its subdirectories, contains all source
+            files for one Sphinx project.
 
 
 Grammar production displays

File sphinx/__init__.py

 from os import path
 from cStringIO import StringIO
 
-from docutils.utils import SystemMessage
-
 from sphinx.util import format_exception_cut_frames, save_traceback
-from sphinx.application import Sphinx
 from sphinx.util.console import darkred, nocolor
 
 __revision__ = '$Revision$'
          -a        -- write all files; default is to only write new and changed files
          -E        -- don't use a saved environment, always read all files
          -d <path> -- path for the cached environment and doctree files
-                      (default outdir/.doctrees)
-         -D <setting=value> -- override a setting in sourcedir/conf.py
+                      (default: outdir/.doctrees)
+         -c <path> -- path where configuration file (conf.py) is located
+                      (default: same as sourcedir)
+         -D <setting=value> -- override a setting in configuration
          -N        -- do not do colored output
          -q        -- no output on stdout, just warnings on stderr
          -P        -- run Pdb on exception
 
 
 def main(argv=sys.argv):
+    # delay-import these to be able to get sphinx.__version__ from setup.py
+    # even without docutils installed
+    from sphinx.application import Sphinx
+    from docutils.utils import SystemMessage
+
     if not sys.stdout.isatty() or sys.platform == 'win32':
         # Windows' poor cmd box doesn't understand ANSI sequences
         nocolor()
 
     try:
-        opts, args = getopt.getopt(argv[1:], 'ab:d:D:NEqP')
-        srcdir = path.abspath(args[0])
+        opts, args = getopt.getopt(argv[1:], 'ab:d:c:D:NEqP')
+        srcdir = confdir = path.abspath(args[0])
         if not path.isdir(srcdir):
             print >>sys.stderr, 'Error: Cannot find source directory.'
             return 1
-        if not path.isfile(path.join(srcdir, 'conf.py')):
+        if not path.isfile(path.join(srcdir, 'conf.py')) and \
+               '-c' not in (opt[0] for opt in opts):
             print >>sys.stderr, 'Error: Source directory doesn\'t contain conf.py file.'
             return 1
         outdir = path.abspath(args[1])
             all_files = True
         elif opt == '-d':
             doctreedir = val
+        elif opt == '-c':
+            confdir = path.abspath(val)
+            if not path.isfile(path.join(confdir, 'conf.py')):
+                print >>sys.stderr, \
+                      'Error: Configuration directory doesn\'t contain conf.py file.'
+                return 1
         elif opt == '-D':
             key, val = val.split('=')
             try:
             use_pdb = True
 
     try:
-        app = Sphinx(srcdir, outdir, doctreedir, buildername,
+        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
                      confoverrides, status, sys.stderr, freshenv)
         if not app.builder:
             return 1

File sphinx/_jinja.py

     def init(self, builder):
         self.templates = {}
         base_templates_path = path.join(path.dirname(__file__), 'templates')
-        ext_templates_path = [path.join(builder.srcdir, dir)
+        ext_templates_path = [path.join(builder.confdir, dir)
                               for dir in builder.config.templates_path]
         self.templates_path = [base_templates_path] + ext_templates_path
         loader = SphinxFileSystemLoader(base_templates_path, ext_templates_path)

File sphinx/application.py

 
 class Sphinx(object):
 
-    def __init__(self, srcdir, outdir, doctreedir, buildername,
+    def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
                  confoverrides, status, warning=sys.stderr, freshenv=False):
         self.next_listener_id = 0
         self._listeners = {}
         self.builder = None
 
         self.srcdir = srcdir
+        self.confdir = confdir
         self.outdir = outdir
         self.doctreedir = doctreedir
 
         self._events = events.copy()
 
         # read config
-        self.config = Config(srcdir, 'conf.py')
+        self.config = Config(confdir, 'conf.py')
         if confoverrides:
             for key, val in confoverrides.items():
                 setattr(self.config, key, val)

File sphinx/builder.py

 
     def __init__(self, app, env=None, freshenv=False):
         self.srcdir = app.srcdir
+        self.confdir = app.confdir
         self.outdir = app.outdir
         self.doctreedir = app.doctreedir
         if not path.isdir(self.doctreedir):
                 self.info(' '+src, nonl=1)
                 shutil.copyfile(path.join(self.srcdir, src),
                                 path.join(self.outdir, '_images', dest))
-            # the logo is handled differently
-            if self.config.html_logo:
-                logobase = path.basename(self.config.html_logo)
-                self.info(' '+logobase, nonl=1)
-                shutil.copyfile(path.join(self.srcdir, self.config.html_logo),
-                                path.join(self.outdir, '_static', logobase))
             self.info()
 
         # copy static files
         self.info(bold('copying static files...'))
         ensuredir(path.join(self.outdir, '_static'))
         staticdirnames = [path.join(path.dirname(__file__), 'static')] + \
-                         [path.join(self.srcdir, spath)
+                         [path.join(self.confdir, spath)
                           for spath in self.config.html_static_path]
         for staticdirname in staticdirnames:
             for filename in os.listdir(staticdirname):
         if self.config.latex_logo:
             logobase = path.basename(self.config.latex_logo)
             self.info(' '+logobase, nonl=1)
-            shutil.copyfile(path.join(self.srcdir, self.config.latex_logo),
+            shutil.copyfile(path.join(self.confdir, self.config.latex_logo),
                             path.join(self.outdir, logobase))
 
         self.info(bold('copying TeX support files...'))