Exemplo n.º 1
0
 def __init__(self) -> None:
     self.doctreedir = None
     self.events = None
     self.extensions: Dict[str, Extension] = {}
     self.srcdir = None
     self.config = Config()
     self.project = Project(None, None)
     self.registry = SphinxComponentRegistry()
Exemplo n.º 2
0
        def __init__(self,
                     confoverrides=None,
                     srcdir=None,
                     raise_on_warning=False):
            self.extensions = {}
            self.registry = SphinxComponentRegistry()
            try:
                self.html_themes = {}
            except AttributeError:
                # changed to property in sphinx 4.1
                pass
            self.events = EventManager(self)

            # logging
            self.verbosity = 0
            self._warncount = 0
            self.warningiserror = raise_on_warning
            self._status = StringIO()
            self._warning = StringIO()
            logging.setup(self, self._status, self._warning)

            self.tags = Tags([])
            self.config = Config({}, confoverrides or {})
            self.config.pre_init_values()
            self._init_i18n()
            for extension in builtin_extensions:
                self.registry.load_extension(self, extension)
            # fresh env
            self.doctreedir = ""
            self.srcdir = srcdir
            self.confdir = None
            self.outdir = ""
            self.project = Project(srcdir=srcdir,
                                   source_suffix={".md": "markdown"})
            self.project.docnames = {"mock_docname"}
            self.env = BuildEnvironment()
            self.env.setup(self)
            self.env.temp_data["docname"] = "mock_docname"
            # Ignore type checkers because we disrespect superclass typing here
            self.builder = None  # type: ignore[assignment]

            if not with_builder:
                return

            # this code is only required for more complex parsing with extensions
            for extension in self.config.extensions:
                self.setup_extension(extension)
            buildername = "dummy"
            self.preload_builder(buildername)
            self.config.init_values()
            self.events.emit("config-inited", self.config)

            with tempfile.TemporaryDirectory() as tempdir:
                # creating a builder attempts to make the doctreedir
                self.doctreedir = tempdir
                self.builder = self.create_builder(buildername)
            self.doctreedir = ""
Exemplo n.º 3
0
def test_project_path2doc(app):
    project = Project(app.srcdir, app.config.source_suffix)
    assert project.path2doc('index.rst') == 'index'
    assert project.path2doc('index.foo') is None  # unknown extension
    assert project.path2doc('index.foo.rst') == 'index.foo'
    assert project.path2doc('index') is None
    assert project.path2doc('path/to/index.rst') == 'path/to/index'
    assert project.path2doc(app.srcdir / 'to/index.rst') == 'to/index'
Exemplo n.º 4
0
        def __init__(self,
                     confoverrides=None,
                     srcdir=None,
                     raise_on_warning=False):
            self.extensions = {}
            self.registry = SphinxComponentRegistry()
            self.html_themes = {}
            self.events = EventManager(self)

            # logging
            self.verbosity = 0
            self._warncount = 0
            self.warningiserror = raise_on_warning
            self._status = StringIO()
            self._warning = StringIO()
            log_setup(self, self._status, self._warning)

            self.tags = Tags(None)
            self.config = Config({}, confoverrides or {})
            self.config.pre_init_values()
            self._init_i18n()
            for extension in builtin_extensions:
                self.registry.load_extension(self, extension)
            # fresh env
            self.doctreedir = None
            self.srcdir = srcdir
            self.confdir = None
            self.outdir = None
            self.project = Project(srcdir=srcdir, source_suffix=".md")
            self.project.docnames = ["mock_docname"]
            self.env = BuildEnvironment()
            self.env.setup(self)
            self.env.temp_data["docname"] = "mock_docname"
            self.builder = None

            if not with_builder:
                return

            # this code is only required for more complex parsing with extensions
            for extension in self.config.extensions:
                self.setup_extension(extension)
            buildername = "dummy"
            self.preload_builder(buildername)
            self.config.init_values()
            self.events.emit("config-inited", self.config)

            with tempfile.TemporaryDirectory() as tempdir:
                # creating a builder attempts to make the doctreedir
                self.doctreedir = tempdir
                self.builder = self.create_builder(buildername)
            self.doctreedir = None
Exemplo n.º 5
0
def test_project_doc2path(app):
    source_suffix = OrderedDict([('.rst', 'restructuredtext'),
                                 ('.txt', 'restructuredtext')])

    project = Project(app.srcdir, source_suffix)
    assert project.doc2path('index') == (app.srcdir / 'index.rst')

    # first source_suffix is used for missing file
    assert project.doc2path('foo') == (app.srcdir / 'foo.rst')

    # matched source_suffix is used if exists
    (app.srcdir / 'foo.txt').write_text('')
    assert project.doc2path('foo') == (app.srcdir / 'foo.txt')

    # absolute path
    assert project.doc2path('index', basedir=True) == (app.srcdir / 'index.rst')

    # relative path
    assert project.doc2path('index', basedir=False) == 'index.rst'
Exemplo n.º 6
0
def test_project_discover(rootdir):
    project = Project(rootdir / 'test-root', {})

    docnames = {
        'autodoc', 'bom', 'extapi', 'extensions', 'footnote', 'images',
        'includes', 'index', 'lists', 'markup', 'math', 'objects',
        'subdir/excluded', 'subdir/images', 'subdir/includes'
    }
    subdir_docnames = {'subdir/excluded', 'subdir/images', 'subdir/includes'}

    # basic case
    project.source_suffix = ['.txt']
    assert project.discover() == docnames

    # exclude_paths option
    assert project.discover(['subdir/*']) == docnames - subdir_docnames

    # exclude_patterns
    assert project.discover(['.txt', 'subdir/*']) == docnames - subdir_docnames

    # multiple source_suffixes
    project.source_suffix = ['.txt', '.foo']
    assert project.discover() == docnames | {'otherext'}

    # complicated source_suffix
    project.source_suffix = ['.foo.png']
    assert project.discover() == {'img'}

    # templates_path
    project.source_suffix = ['.html']
    assert project.discover() == {
        '_templates/layout', '_templates/customsb', '_templates/contentssb'
    }

    assert project.discover(['_templates']) == set()
Exemplo n.º 7
0
    def __init__(self,
                 srcdir,
                 confdir,
                 outdir,
                 doctreedir,
                 buildername,
                 confoverrides=None,
                 status=sys.stdout,
                 warning=sys.stderr,
                 freshenv=False,
                 warningiserror=False,
                 tags=None,
                 verbosity=0,
                 parallel=0,
                 keep_going=False):
        # type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None  # NOQA
        self.phase = BuildPhase.INITIALIZATION
        self.verbosity = verbosity
        self.extensions = {}  # type: Dict[str, Extension]
        self.builder = None  # type: Builder
        self.env = None  # type: BuildEnvironment
        self.project = None  # type: Project
        self.registry = SphinxComponentRegistry()
        self.html_themes = {}  # type: Dict[str, str]

        # validate provided directories
        self.srcdir = abspath(srcdir)
        self.outdir = abspath(outdir)
        self.doctreedir = abspath(doctreedir)
        self.confdir = confdir
        if self.confdir:  # confdir is optional
            self.confdir = abspath(self.confdir)
            if not path.isfile(path.join(self.confdir, 'conf.py')):
                raise ApplicationError(
                    __("config directory doesn't contain a "
                       "conf.py file (%s)") % confdir)

        if not path.isdir(self.srcdir):
            raise ApplicationError(
                __('Cannot find source directory (%s)') % self.srcdir)

        if self.srcdir == self.outdir:
            raise ApplicationError(
                __('Source directory and destination '
                   'directory cannot be identical'))

        self.parallel = parallel

        if status is None:
            self._status = StringIO()  # type: IO
            self.quiet = True
        else:
            self._status = status
            self.quiet = False

        if warning is None:
            self._warning = StringIO()  # type: IO
        else:
            self._warning = warning
        self._warncount = 0
        self.keep_going = warningiserror and keep_going
        if self.keep_going:
            self.warningiserror = False
        else:
            self.warningiserror = warningiserror
        logging.setup(self, self._status, self._warning)

        self.events = EventManager(self)

        # keep last few messages for traceback
        # This will be filled by sphinx.util.logging.LastMessagesWriter
        self.messagelog = deque(maxlen=10)  # type: deque

        # say hello to the world
        logger.info(bold(
            __('Running Sphinx v%s') % sphinx.__display_version__))

        # notice for parallel build on macOS and py38+
        if sys.version_info > (
                3, 8) and platform.system() == 'Darwin' and parallel > 1:
            logger.info(
                bold(
                    __("For security reason, parallel mode is disabled on macOS and "
                       "python3.8 and above.  For more details, please read "
                       "https://github.com/sphinx-doc/sphinx/issues/6803")))

        # status code for command-line application
        self.statuscode = 0

        # read config
        self.tags = Tags(tags)
        if self.confdir is None:
            self.config = Config({}, confoverrides or {})
        else:
            self.config = Config.read(self.confdir, confoverrides or {},
                                      self.tags)

        # initialize some limited config variables before initialize i18n and loading
        # extensions
        self.config.pre_init_values()

        # set up translation infrastructure
        self._init_i18n()

        # check the Sphinx version if requested
        if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__:
            raise VersionRequirementError(
                __('This project needs at least Sphinx v%s and therefore cannot '
                   'be built with this version.') % self.config.needs_sphinx)

        # set confdir to srcdir if -C given (!= no confdir); a few pieces
        # of code expect a confdir to be set
        if self.confdir is None:
            self.confdir = self.srcdir

        # load all built-in extension modules
        for extension in builtin_extensions:
            self.setup_extension(extension)

        # load all user-given extension modules
        for extension in self.config.extensions:
            self.setup_extension(extension)

        # preload builder module (before init config values)
        self.preload_builder(buildername)

        if not path.isdir(outdir):
            with progress_message(__('making output directory')):
                ensuredir(outdir)

        # the config file itself can be an extension
        if self.config.setup:
            prefix = __('while setting up extension %s:') % "conf.py"
            with prefixed_warnings(prefix):
                if callable(self.config.setup):
                    self.config.setup(self)
                else:
                    raise ConfigError(
                        __("'setup' as currently defined in conf.py isn't a Python callable. "
                           "Please modify its definition to make it a callable function. "
                           "This is needed for conf.py to behave as a Sphinx extension."
                           ))

        # now that we know all config values, collect them from conf.py
        self.config.init_values()
        self.events.emit('config-inited', self.config)

        # create the project
        self.project = Project(self.srcdir, self.config.source_suffix)
        # create the builder
        self.builder = self.create_builder(buildername)
        # set up the build environment
        self._init_env(freshenv)
        # set up the builder
        self._init_builder()