Provide a better error message if the master document is not included in the project documents (#12011)

This commit is contained in:
Lingyu Hu 2024-07-13 19:22:39 -07:00 committed by GitHub
parent e04b0d4bec
commit f0d8e2ef5e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 7 deletions

View File

@ -4,6 +4,7 @@ from __future__ import annotations
import codecs
import pickle
import re
import time
from os import path
from typing import TYPE_CHECKING, Any, Literal, final
@ -21,7 +22,7 @@ from sphinx.util.console import bold
from sphinx.util.display import progress_message, status_iterator
from sphinx.util.docutils import sphinx_domains
from sphinx.util.i18n import CatalogInfo, CatalogRepository, docname_to_domain
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
from sphinx.util.osutil import SEP, canon_path, ensuredir, relative_uri, relpath
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, parallel_available
# side effect: registers roles and directives
@ -423,9 +424,40 @@ class Builder:
else:
self._read_serial(docnames)
if self.config.root_doc not in self.env.all_docs:
raise SphinxError('root file %s not found' %
self.env.doc2path(self.config.root_doc))
if self.config.master_doc not in self.env.all_docs:
from sphinx.project import EXCLUDE_PATHS
from sphinx.util.matching import _translate_pattern
master_doc_path = self.env.doc2path(self.config.master_doc)
master_doc_canon = canon_path(master_doc_path)
for pat in EXCLUDE_PATHS:
if not re.match(_translate_pattern(pat), master_doc_canon):
continue
msg = __('Sphinx is unable to load the master document (%s) '
'because it matches a built-in exclude pattern %r. '
'Please move your master document to a different location.')
raise SphinxError(msg % (master_doc_path, pat))
for pat in self.config.exclude_patterns:
if not re.match(_translate_pattern(pat), master_doc_canon):
continue
msg = __('Sphinx is unable to load the master document (%s) '
'because it matches an exclude pattern specified '
'in conf.py, %r. '
'Please remove this pattern from conf.py.')
raise SphinxError(msg % (master_doc_path, pat))
if set(self.config.include_patterns) != {'**'} and not any(
re.match(_translate_pattern(pat), master_doc_canon)
for pat in self.config.include_patterns
):
msg = __('Sphinx is unable to load the master document (%s) '
'because it is not included in the custom include_patterns = %r. '
'Ensure that a pattern in include_patterns matches the '
'master document.')
raise SphinxError(msg % (master_doc_path, self.config.include_patterns))
msg = __('Sphinx is unable to load the master document (%s). '
'The master document must be within the source directory '
'or a subdirectory of it.')
raise SphinxError(msg % master_doc_path)
for retval in self.events.emit('env-updated', self.env):
if retval is not None:

View File

@ -416,11 +416,12 @@ class Config:
except ValueError as exc:
logger.warning("%s", exc)
else:
self.__dict__[name] = value
self.__setattr__(name, value)
return value
# then check values from 'conf.py'
if name in self._raw_config:
self.__dict__[name] = value = self._raw_config[name]
value = self._raw_config[name]
self.__setattr__(name, value)
return value
# finally, fall back to the default value
default = self._options[name].default

View File

@ -34,7 +34,7 @@ def test_config_status(make_app, app_params):
assert app3.env.config_status == CONFIG_CHANGED
app3.build()
shutil.move(fname[:-4] + 'x.rst', fname)
assert "[config changed ('root_doc')] 1 added" in app3._status.getvalue()
assert "[config changed ('master_doc')] 1 added" in app3._status.getvalue()
# incremental build (extension changed)
app4 = make_app(*args, confoverrides={'extensions': ['sphinx.ext.autodoc']}, **kwargs)