Example #1
0
    def test_yosys_script(self):
        TEST_NAME = "test_compat"
        TEST_BUILD_DIR = os.path.join("build", self.TEST_CASE_NAME, TEST_NAME)
        TEST_FILES = ["test_compat/test_compat.rst", "code/verilog/adder.v"]
        TEST_JINJA_DICT = {
            "hdl_diagrams_path":
            "'{}'".format(HDL_DIAGRAMS_PATH),
            "master_doc":
            "'test_compat'",
            "custom_variables":
            """
extensions = [
    'sphinxcontrib_verilog_diagrams',
]"""
        }

        self.prepare_test(TEST_NAME, TEST_BUILD_DIR, TEST_FILES,
                          **TEST_JINJA_DICT)

        # Run the Sphinx
        sphinx_dirs = get_sphinx_dirs(TEST_BUILD_DIR)
        with docutils_namespace():
            app = Sphinx(buildername="html",
                         warningiserror=True,
                         **sphinx_dirs)
            app.build(force_all=True)
Example #2
0
    def test_yosys_path(self):
        TEST_NAME = "test_yosys_path"
        TEST_BUILD_DIR = os.path.join("build", self.TEST_CASE_NAME, TEST_NAME)
        TEST_FILES = [
            "test_yosys_type/test_yosys_path.rst", "code/verilog/adder.v"
        ]

        yosys_path = shutil.which("yosys")

        TEST_JINJA_DICT = {
            "hdl_diagrams_path": "'{}'".format(HDL_DIAGRAMS_PATH),
            "master_doc": "'test_yosys_path'",
            "custom_variables": "hdl_diagram_yosys = '{}'".format(yosys_path)
        }

        self.prepare_test(TEST_NAME, TEST_BUILD_DIR, TEST_FILES,
                          **TEST_JINJA_DICT)

        # Run the Sphinx
        sphinx_dirs = get_sphinx_dirs(TEST_BUILD_DIR)
        with docutils_namespace():
            app = Sphinx(buildername="html",
                         warningiserror=True,
                         **sphinx_dirs)
            app.build(force_all=True)
Example #3
0
    def test_netlistsvg_diagram(self):
        TEST_NAME = "test_skins"
        TEST_BUILD_DIR = os.path.join("build", self.TEST_CASE_NAME, TEST_NAME)
        TEST_FILES = [
            "test_skins/test_skins.rst", "test_skins/skin-purple.svg",
            "test_skins/skin-yellow.svg", "code/verilog/adder.v"
        ]
        TEST_JINJA_DICT = {
            "hdl_diagrams_path":
            "'{}'".format(HDL_DIAGRAMS_PATH),
            "master_doc":
            "'test_skins'",
            "custom_variables":
            "hdl_diagram_skin = os.path.realpath('skin-purple.svg')"
        }

        self.prepare_test(TEST_NAME, TEST_BUILD_DIR, TEST_FILES,
                          **TEST_JINJA_DICT)

        # Run the Sphinx
        sphinx_dirs = get_sphinx_dirs(TEST_BUILD_DIR)
        with docutils_namespace():
            app = Sphinx(buildername="html",
                         warningiserror=True,
                         **sphinx_dirs)
            app.build(force_all=True)
Example #4
0
def build_sphinx(src_dir, output_dir, files=None, config={}):
    doctrees_dir = join(output_dir, '.doctrees')

    filenames = []
    force_all = True

    default_config = {
        'extensions': ['sphinxcontrib.restbuilder'],
        'master_doc': 'index',
    }
    default_config.update(config)
    config = default_config

    if files:
        force_all = False
        filenames = [join(src_dir, file + '.rst') for file in files]
        config['master_doc'] = files[0]

    with docutils_namespace():
        app = Sphinx(
            src_dir,
            None,
            output_dir,
            doctrees_dir,
            'rst',
            confoverrides=config,
            verbosity=0,
        )

        app.build(force_all=force_all, filenames=filenames)
Example #5
0
def render_sphinx_project(name,
                          project_dir,
                          template_cfg=None,
                          stylesheet=None):
    project_path = TEST_DIR / project_dir
    out_path = OUTPUT_DIR / name
    confoverrides = {}
    if template_cfg:
        confoverrides['rinoh_template'] = str(TEST_DIR / template_cfg)
    if stylesheet:
        confoverrides['rinoh_stylesheet'] = str(TEST_DIR / stylesheet)
    with docutils_namespace():
        sphinx = Sphinx(srcdir=str(project_path),
                        confdir=str(project_path),
                        outdir=str(out_path / 'rinoh'),
                        doctreedir=str(out_path / 'doctrees'),
                        buildername='rinoh',
                        confoverrides=confoverrides)
        sphinx.build()
    out_filename = '{}.pdf'.format(name)
    with in_directory(out_path):
        if not diff_pdf(TEST_DIR / 'reference' / out_filename,
                        out_path / 'rinoh' / out_filename):
            pytest.fail(
                'The generated PDF is different from the reference '
                'PDF.\nGenerated files can be found in {}'.format(out_path))
Example #6
0
def sphinx_app(tmpdir_factory, req_mpl, req_pil):
    temp_dir = (tmpdir_factory.getbasetemp() / 'root').strpath
    src_dir = op.join(op.dirname(__file__), 'tinybuild')

    def ignore(src, names):
        return ('_build', 'gen_modules', 'auto_examples')

    shutil.copytree(src_dir, temp_dir, ignore=ignore)
    # For testing iteration, you can get similar behavior just doing `make`
    # inside the tinybuild directory
    src_dir = temp_dir
    conf_dir = temp_dir
    out_dir = op.join(temp_dir, '_build', 'html')
    toctrees_dir = op.join(temp_dir, '_build', 'toctrees')
    # Avoid warnings about re-registration, see:
    # https://github.com/sphinx-doc/sphinx/issues/5038
    with docutils_namespace():
        app = Sphinx(src_dir,
                     conf_dir,
                     out_dir,
                     toctrees_dir,
                     buildername='html',
                     status=StringIO(),
                     warning=StringIO())
        # need to build within the context manager
        # for automodule and backrefs to work
        app.build(False, [])
    return app
Example #7
0
def sphinx_env(app_env: SphinxAppEnv):
    """This context enters the standard sphinx contexts,
    then registers the roles, directives and nodes saved in the app_env.

    The standard sphinx contexts:

    - Patch docutils.languages.get_language(), to suppress reporter warnings
    - Temporarily sets `os.environ['DOCUTILSCONFIG']` to the sphinx confdir
    - Saves copies of roles._roles and directives._directives & resets them on exit
    - Un-registers additional nodes (set via `register_node`) on exit
      (by deleting `GenericNodeVisitor` visit/depart methods)
    - Patches roles.roles and directives.directives functions to also look in domains
    """
    with patch_docutils(
            app_env.app.confdir), docutils_namespace(), sphinx_domains(
                app_env.app.env):
        from docutils.parsers.rst import directives, roles
        from sphinx.util.docutils import register_node

        if app_env.roles:
            roles._roles.update(app_env.roles)
        if app_env.directives:
            directives._directives.update(app_env.directives)
        for node in app_env.additional_nodes:
            register_node(node)
        # TODO how to make `unregister_node` thread safe

        yield
Example #8
0
def sphinx_app(tmpdir_factory):
    temp_dir = (tmpdir_factory.getbasetemp() / "root").strpath
    src_dir = op.join(op.dirname(__file__), "tinybuild")

    def ignore(src, names):
        return ("_build", "generated")

    shutil.copytree(src_dir, temp_dir, ignore=ignore)
    # For testing iteration, you can get similar behavior just doing `make`
    # inside the tinybuild directory
    src_dir = temp_dir
    conf_dir = temp_dir
    out_dir = op.join(temp_dir, "_build", "html")
    toctrees_dir = op.join(temp_dir, "_build", "toctrees")
    # Set behavior across different Sphinx versions
    kwargs = dict()
    if LooseVersion(sphinx.__version__) >= LooseVersion("1.8"):
        kwargs.update(warningiserror=True, keep_going=True)
    # Avoid warnings about re-registration, see:
    # https://github.com/sphinx-doc/sphinx/issues/5038
    with docutils_namespace():
        app = Sphinx(
            src_dir, conf_dir, out_dir, toctrees_dir, buildername="html", **kwargs
        )
        # need to build within the context manager
        # for automodule and backrefs to work
        app.build(False, [])
    return app
Example #9
0
def gen_pdf(isRebuild=False):
    """make latexpdf """

    if isRebuild:
        clear_all_api()

    srcDir = os.path.join(DIR, "docs")
    confDir = os.path.join(docDir, "source")
    outDir = op.join(docDir, '_build', 'latex')
    toctreesDir = op.join(docDir, '_build', 'toctrees-pdf')
    # Avoid warnings about re-registration, see: https://github.com/sphinx-doc/sphinx/issues/5038
    with docutils_namespace():
        app = Sphinx(srcDir, confDir, outDir, toctreesDir,
                     buildername='latex')  # latex 只有 tex 文件
        # need to build within the context manager for automodule and backrefs to work
        app.build(force_all=isRebuild, filenames=[])

    # 构建 pdf ERROR 不行,有异常,还是手动编译算了
    isBuildPdf = False
    if isBuildPdf:
        cmd = "pdflatex {texFile} -output-directory={pdfDir}".format(
            texFile=os.path.join(outDir, "dataset.tex"), pdfDir=outDir)
        ret = subprocess.run(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             shell=True)
        if ret.returncode != 0:
            print("子程序错误!\n {err}".format(err=ret.stderr.decode("utf-8")))
            code = 1
        else:
            code = 0
        return code
Example #10
0
def sphinx_app(tmpdir_factory):
    if LooseVersion(sphinx.__version__) < LooseVersion('1.8'):
        # Previous versions throw an error trying to pickle the scraper
        pytest.skip('Sphinx 1.8+ required')
    temp_dir = (tmpdir_factory.getbasetemp() / 'root').strpath
    src_dir = op.join(op.dirname(__file__), 'tinybuild')

    def ignore(src, names):
        return ('_build', 'gen_modules', 'auto_examples')

    shutil.copytree(src_dir, temp_dir, ignore=ignore)
    # For testing iteration, you can get similar behavior just doing `make`
    # inside the tinybuild directory
    src_dir = temp_dir
    conf_dir = temp_dir
    out_dir = op.join(temp_dir, '_build', 'html')
    toctrees_dir = op.join(temp_dir, '_build', 'toctrees')
    # Avoid warnings about re-registration, see:
    # https://github.com/sphinx-doc/sphinx/issues/5038
    with docutils_namespace():
        app = Sphinx(src_dir,
                     conf_dir,
                     out_dir,
                     toctrees_dir,
                     buildername='html',
                     status=MixedEncodingStringIO())
        # need to build within the context manager
        # for automodule and backrefs to work
        app.build(False, [])
    return app
Example #11
0
def build_sphinx(src_dir, files=None):
    out_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..',
                           'output')
    shutil.rmtree(out_dir, ignore_errors=True)

    doctrees_dir = os.path.join(out_dir, '.doctrees')

    filenames = []
    force_all = True

    config = {'extensions': ['sphinxcontrib.restbuilder']}

    if files:
        force_all = False
        filenames = [os.path.join(src_dir, file + '.rst') for file in files]
        config['master_doc'] = files[0]

    with docutils_namespace():
        app = Sphinx(
            src_dir,
            None,
            out_dir,
            doctrees_dir,
            'rst',
            confoverrides=config,
            verbosity=0,
        )

        app.build(force_all=force_all, filenames=filenames)
    return out_dir
Example #12
0
    def build(self):
        """Build the documentation. Places the data into the `outdir`
        directory. Use it like this::

            support = WebSupport(srcdir, builddir, search='xapian')
            support.build()

        This will read reStructured text files from `srcdir`. Then it will
        build the pickles and search index, placing them into `builddir`.
        It will also save node data to the database.
        """
        if not self.srcdir:
            raise RuntimeError('No srcdir associated with WebSupport object')

        with docutils_namespace():
            from sphinx.application import Sphinx
            app = Sphinx(self.srcdir,
                         self.srcdir,
                         self.outdir,
                         self.doctreedir,
                         self.buildername,
                         self.confoverrides,
                         status=self.status,
                         warning=self.warning)
            app.builder.set_webinfo(
                self.staticdir,
                self.staticroot,  # type: ignore
                self.search,
                self.storage)

            self.storage.pre_build()
            app.build()
            self.storage.post_build()
def sphinx_app(tmpdir_factory):
    if LooseVersion(sphinx.__version__) < LooseVersion('1.8'):
        # Previous versions throw an error trying to pickle the scraper
        pytest.skip('Sphinx 1.8+ required')
    temp_dir = (tmpdir_factory.getbasetemp() / 'root').strpath
    src_dir = op.join(op.dirname(__file__), 'tinybuild')

    def ignore(src, names):
        return ('_build', 'gen_modules', 'auto_examples')

    shutil.copytree(src_dir, temp_dir, ignore=ignore)
    # For testing iteration, you can get similar behavior just doing `make`
    # inside the tinybuild directory
    src_dir = temp_dir
    conf_dir = temp_dir
    out_dir = op.join(temp_dir, '_build', 'html')
    toctrees_dir = op.join(temp_dir, '_build', 'toctrees')
    # Avoid warnings about re-registration, see:
    # https://github.com/sphinx-doc/sphinx/issues/5038
    with docutils_namespace():
        app = Sphinx(src_dir, conf_dir, out_dir, toctrees_dir,
                     buildername='html', status=MixedEncodingStringIO())
        # need to build within the context manager
        # for automodule and backrefs to work
        app.build(False, [])
    return app
Example #14
0
    def prepareSphinx(src_dir, out_dir, doctree_dir, config=None, relax=False):
        """
        prepare a sphinx application instance

        Return a prepared Sphinx application instance [1] ready for execution.

        [1]: https://github.com/sphinx-doc/sphinx/blob/master/sphinx/application.py
        """
        # Enable coloring of warning and other messages.  Note that this can
        # cause sys.stderr to be mocked which is why we pass the new value
        # explicitly on the call to Sphinx() below.
        if not color_terminal():
            nocolor()

        sts = ConfluenceTestUtil.default_sphinx_status
        conf = dict(config) if config else None
        conf_dir = src_dir if not conf else None
        warnerr = not relax

        with docutils_namespace():
            app = Sphinx(
                src_dir,  # output for document sources
                conf_dir,  # ignore configuration directory
                out_dir,  # output for generated documents
                doctree_dir,  # output for doctree files
                ConfluenceBuilder.name,  # use this extension's builder
                confoverrides=conf,  # load provided configuration (volatile)
                status=sts,  # status output
                warning=sys.stderr,  # warnings output
                warningiserror=warnerr)  # treat warnings as errors

            yield app
Example #15
0
def run_setup(
    setup_func: _setup_func_type
) -> RunSetupOutput:  # , buildername: str = "html"
    """
	Function for running an extension's ``setup()`` function for testing.

	:param setup_func: The ``setup()`` function under test.

	:returns: 5-element namedtuple
	"""

    app = Sphinx()  # buildername

    app.add_domain(PythonDomain)

    try:
        _additional_nodes = copy.copy(docutils.additional_nodes)
        docutils.additional_nodes = set()

        with docutils.docutils_namespace():
            setup_ret = setup_func(app)  # type: ignore
            directives = copy.copy(
                docutils.directives._directives)  # type: ignore
            roles = copy.copy(docutils.roles._roles)  # type: ignore
            additional_nodes = copy.copy(docutils.additional_nodes)
    finally:
        docutils.additional_nodes = _additional_nodes

    return RunSetupOutput(setup_ret, directives, roles, additional_nodes, app)
Example #16
0
def build_main(args_parser):
    """
    build mainline

    The mainline for the 'build' action.

    Args:
        args_parser: the argument parser to use for argument processing

    Returns:
        the exit code
    """

    args_parser.add_argument('-D', action='append', default=[], dest='define')
    args_parser.add_argument('--output-dir', '-o')

    known_args = sys.argv[1:]
    args, unknown_args = args_parser.parse_known_args(known_args)
    if unknown_args:
        logger.warn('unknown arguments: {}'.format(' '.join(unknown_args)))

    defines = {}
    for val in args.define:
        try:
            key, val = val.split('=', 1)
            defines[key] = val
        except ValueError:
            logger.error('invalid define provided in command line')
            return 1

    work_dir = args.work_dir if args.work_dir else os.getcwd()
    if args.output_dir:
        output_dir = args.output_dir
    else:
        output_dir = os.path.join(work_dir, '_build', 'confluence')
    doctrees_dir = os.path.join(output_dir, '.doctrees')
    builder = args.action if args.action else DEFAULT_BUILDER

    verbosity = 0
    if args.verbose:
        try:
            verbosity = int(args.verbose)
        except ValueError:
            pass

    # run sphinx engine
    with docutils_namespace():
        app = Sphinx(
            work_dir,  # document sources
            work_dir,  # directory with configuration
            output_dir,  # output for generated documents
            doctrees_dir,  # output for doctree files
            builder,  # builder to execute
            confoverrides=defines,  # configuration overload
            freshenv=True,  # fresh environment
            verbosity=verbosity)  # verbosity
        app.build(force_all=True)

    return 0
 def create_sphinx_app(self):
     # Avoid warnings about re-registration, see:
     # https://github.com/sphinx-doc/sphinx/issues/5038
     with docutils_namespace():
         app = Sphinx(self.srcdir, self.confdir, self.outdir,
                      self.doctreedir, self.buildername, **self.kwargs)
     sphinx_compatibility._app = app
     return app
 def create_sphinx_app(self):
     # Avoid warnings about re-registration, see:
     # https://github.com/sphinx-doc/sphinx/issues/5038
     with docutils_namespace():
         app = Sphinx(self.srcdir, self.confdir, self.outdir,
                      self.doctreedir, self.buildername, **self.kwargs)
     sphinx_compatibility._app = app
     return app
Example #19
0
    def run(self) -> None:
        warnings.warn('setup.py build_sphinx is deprecated.',
                      RemovedInSphinx70Warning,
                      stacklevel=2)

        if not color_terminal():
            nocolor()
        if not self.verbose:  # type: ignore
            status_stream = StringIO()
        else:
            status_stream = sys.stdout  # type: ignore
        confoverrides: Dict[str, Any] = {}
        if self.project:
            confoverrides['project'] = self.project
        if self.version:
            confoverrides['version'] = self.version
        if self.release:
            confoverrides['release'] = self.release
        if self.today:
            confoverrides['today'] = self.today
        if self.copyright:
            confoverrides['copyright'] = self.copyright
        if self.nitpicky:
            confoverrides['nitpicky'] = self.nitpicky

        for builder, builder_target_dir in self.builder_target_dirs:
            app = None

            try:
                confdir = self.config_dir or self.source_dir
                with patch_docutils(confdir), docutils_namespace():
                    app = Sphinx(self.source_dir,
                                 self.config_dir,
                                 builder_target_dir,
                                 self.doctree_dir,
                                 builder,
                                 confoverrides,
                                 status_stream,
                                 freshenv=self.fresh_env,
                                 warningiserror=self.warning_is_error,
                                 verbosity=self.verbosity,
                                 keep_going=self.keep_going)
                    app.build(force_all=self.all_files)
                    if app.statuscode:
                        raise DistutilsExecError('caused by %s builder.' %
                                                 app.builder.name)
            except Exception as exc:
                handle_exception(app, self, exc, sys.stderr)
                if not self.pdb:
                    raise SystemExit(1) from exc

            if not self.link_index:
                continue

            src = app.config.root_doc + app.builder.out_suffix  # type: ignore
            dst = app.builder.get_outfilename('index')  # type: ignore
            os.symlink(src, dst)
Example #20
0
def render_sphinx(content):
    with tempfile.TemporaryDirectory() as tmp_dir:
        src_path = pathlib.Path(tmp_dir, "src/contents.rst")
        src_path.parent.mkdir()
        with src_path.open("w") as src:
            src.write(content)

        build_path = pathlib.Path(tmp_dir, "build/contents.fjson")

        source_dir = str(src_path.parent)
        doctree_dir = os.path.join(source_dir, ".doctrees")
        confoverrides = {
            "extensions": ["zuul_sphinx"],
            "master_doc": "contents"
        }
        status_log = io.StringIO()

        # NOTE (fschmidt): This part needs to be in sync with the used version
        # of Sphinx. Current version is:
        # https://github.com/sphinx-doc/sphinx/blob/v1.8.1/sphinx/cmd/build.py#L299
        with patch_docutils(source_dir), docutils_namespace():
            # Remove the color from the Sphinx' console output. Otherwise
            # the lines cannot be parsed properly as some \n are not set properly.
            nocolor()
            app = Sphinx(
                srcdir=source_dir,
                confdir=None,
                outdir=str(build_path.parent),
                doctreedir=doctree_dir,
                buildername="json",
                confoverrides=confoverrides,
                status=status_log,
                warning=sys.stderr,
            )

            # Add the mocked SupportedOS directive to get the os information
            # without rendering it into the resulting HTML page
            app.add_directive("supported_os", SupportedOS)

            # Start the Sphinx build
            app.build(force_all=True, filenames=[])

            if app.statuscode:
                raise SphinxBuildError

        # Extract the platforms from the logger output
        platforms = []
        status_log.seek(0)
        for line in status_log.readlines():
            prefix, _, platform = line.partition(":")
            if prefix == SUPPORTED_OS_LOG_PREFIX:
                platforms.append(platform.strip().lower())

        with build_path.open() as build:
            html_parts = json.load(build)

    return {"html": html_parts["body"], "platforms": platforms}
Example #21
0
def runsphinx(_outdir, _srcdir, text, builder, confoverrides):
    f = open(os.path.join(_srcdir, 'index.rst'), 'w')
    try:
        f.write(text)
    finally:
        f.close()
    with docutils_namespace():
        app = Sphinx(_srcdir, _fixturedir, _outdir, _outdir, builder,
                     confoverrides)
        app.build()
Example #22
0
def prepareSphinx(src_dir,
                  out_dir,
                  doctree_dir,
                  config=None,
                  extra_config=None,
                  builder=None,
                  relax=False):
    """
    prepare a sphinx application instance

    Return a prepared Sphinx application instance [1] ready for execution.

    [1]: https://github.com/sphinx-doc/sphinx/blob/master/sphinx/application.py
    """
    # Enable coloring of warning and other messages.  Note that this can
    # cause sys.stderr to be mocked which is why we pass the new value
    # explicitly on the call to Sphinx() below.
    if not color_terminal():
        nocolor()

    conf = dict(config) if config else {}
    if extra_config:
        conf.update(extra_config)
    conf_dir = src_dir if config is None else None
    warnerr = not relax

    sts = None
    if 'SPHINX_STATUS' in os.environ:
        sts = sys.stdout

    verbosity = 0
    if 'SPHINX_VERBOSITY' in os.environ:
        try:
            verbosity = int(os.environ['SPHINX_VERBOSITY'])
        except ValueError:
            pass

    # default to using this extension's builder
    if not builder:
        builder = 'confluence'

    with docutils_namespace():
        app = Sphinx(
            src_dir,  # output for document sources
            conf_dir,  # configuration directory
            out_dir,  # output for generated documents
            doctree_dir,  # output for doctree files
            builder,  # builder to execute
            confoverrides=conf,  # load provided configuration (volatile)
            status=sts,  # status output
            warning=sys.stderr,  # warnings output
            warningiserror=warnerr,  # treat warnings as errors
            verbosity=verbosity)  # verbosity

        yield app
Example #23
0
def test_sphinx_build(buildername: str, tmp_path: pathlib.Path) -> None:
    """Test :meth:`sphinx.application.Sphinx.build`."""
    doctreedir = tmp_path / "doctrees"
    with docutils_namespace():
        app = Sphinx("docs",
                     "docs",
                     tmp_path,
                     doctreedir,
                     buildername=buildername,
                     warningiserror=True)
        app.build(force_all=True)
Example #24
0
    def run(self):
        # type: () -> None
        if not color_terminal():
            nocolor()
        if not self.verbose:  # type: ignore
            status_stream = StringIO()
        else:
            status_stream = sys.stdout  # type: ignore
        confoverrides = {}
        if self.project:
            confoverrides['project'] = self.project
        if self.version:
            confoverrides['version'] = self.version
        if self.release:
            confoverrides['release'] = self.release
        if self.today:
            confoverrides['today'] = self.today
        if self.copyright:
            confoverrides['copyright'] = self.copyright

        for builder, builder_target_dir in self.builder_target_dirs:
            app = None

            try:
                confdir = self.config_dir or self.source_dir
                with patch_docutils(confdir), docutils_namespace():
                    app = Sphinx(self.source_dir,
                                 self.config_dir,
                                 builder_target_dir,
                                 self.doctree_dir,
                                 builder,
                                 confoverrides,
                                 status_stream,
                                 freshenv=self.fresh_env,
                                 warningiserror=self.warning_is_error)
                    app.build(force_all=self.all_files)
                    if app.statuscode:
                        raise DistutilsExecError('caused by %s builder.' %
                                                 app.builder.name)
            except Exception as exc:
                handle_exception(app, self, exc, sys.stderr)
                if not self.pdb:
                    raise SystemExit(1)

            if not self.link_index:
                continue

            src = app.config.master_doc + app.builder.out_suffix  # type: ignore
            dst = app.builder.get_outfilename('index')  # type: ignore
            os.symlink(src, dst)
Example #25
0
def create_sphinx_app(tmp_path, all_docs=('index', ), **confoverrides):
    with docutils_namespace():
        confdir = tmp_path / 'confdir'
        confdir.mkdir()
        conf_py = confdir / 'conf.py'
        conf_py.touch()
        app = Sphinx(srcdir=str(tmp_path),
                     confdir=str(confdir),
                     outdir=str(tmp_path / 'output'),
                     doctreedir=str(tmp_path / 'doctrees'),
                     buildername='rinoh',
                     confoverrides=confoverrides)
        app.env.all_docs.update({doc: 0 for doc in all_docs})
    return app
Example #26
0
def test(test_name):
    rst_path = RST_PATH / (test_name + '.rst')
    test_output_dir = OUTPUT_DIR / test_name
    if test_name.startswith('sphinx_'):
        with docutils_namespace():
            out_dir = str(test_output_dir)
            Sphinx(srcdir=str(RST_PATH),
                   confdir=None,
                   outdir=out_dir,
                   doctreedir=out_dir,
                   buildername='dummy',
                   status=None)
            render_rst_file(rst_path, test_name, RST_PATH)
    else:
        render_rst_file(rst_path, test_name, RST_PATH)
Example #27
0
    def run(self):
        # type: () -> None
        if not color_terminal():
            nocolor()
        if not self.verbose:  # type: ignore
            status_stream = StringIO()
        else:
            status_stream = sys.stdout  # type: ignore
        confoverrides = {}  # type: Dict[str, Any]
        if self.project:
            confoverrides['project'] = self.project
        if self.version:
            confoverrides['version'] = self.version
        if self.release:
            confoverrides['release'] = self.release
        if self.today:
            confoverrides['today'] = self.today
        if self.copyright:
            confoverrides['copyright'] = self.copyright
        if self.nitpicky:
            confoverrides['nitpicky'] = self.nitpicky

        for builder, builder_target_dir in self.builder_target_dirs:
            app = None

            try:
                confdir = self.config_dir or self.source_dir
                with patch_docutils(confdir), docutils_namespace():
                    app = Sphinx(self.source_dir, self.config_dir,
                                 builder_target_dir, self.doctree_dir,
                                 builder, confoverrides, status_stream,
                                 freshenv=self.fresh_env,
                                 warningiserror=self.warning_is_error)
                    app.build(force_all=self.all_files)
                    if app.statuscode:
                        raise DistutilsExecError(
                            'caused by %s builder.' % app.builder.name)
            except Exception as exc:
                handle_exception(app, self, exc, sys.stderr)
                if not self.pdb:
                    raise SystemExit(1)

            if not self.link_index:
                continue

            src = app.config.master_doc + app.builder.out_suffix  # type: ignore
            dst = app.builder.get_outfilename('index')  # type: ignore
            os.symlink(src, dst)
Example #28
0
def test_junit(sphinx_app, tmpdir):
    out_dir = sphinx_app.outdir
    junit_file = op.join(out_dir, 'sphinx-gallery', 'junit-results.xml')
    assert op.isfile(junit_file)
    with codecs.open(junit_file, 'r', 'utf-8') as fid:
        contents = fid.read()
    assert contents.startswith('<?xml')
    assert 'errors="0" failures="0"' in contents
    assert 'tests="5"' in contents
    assert 'local_module' not in contents  # it's not actually run as an ex
    assert 'expected example failure' in contents
    assert '<failure message' not in contents
    src_dir = sphinx_app.srcdir
    new_src_dir = op.join(str(tmpdir), 'src')
    shutil.copytree(src_dir, new_src_dir)
    del src_dir
    new_out_dir = op.join(new_src_dir, '_build', 'html')
    new_toctree_dir = op.join(new_src_dir, '_build', 'toctrees')
    passing_fname = op.join(new_src_dir, 'examples',
                            'plot_numpy_matplotlib.py')
    failing_fname = op.join(new_src_dir, 'examples',
                            'plot_future_imports_broken.py')
    shutil.move(passing_fname, passing_fname + '.temp')
    shutil.move(failing_fname, passing_fname)
    shutil.move(passing_fname + '.temp', failing_fname)
    with docutils_namespace():
        app = Sphinx(new_src_dir,
                     new_src_dir,
                     new_out_dir,
                     new_toctree_dir,
                     buildername='html',
                     status=MixedEncodingStringIO())
        # need to build within the context manager
        # for automodule and backrefs to work
        with pytest.raises(ValueError, match='Here is a summary of the '):
            app.build(False, [])
    junit_file = op.join(new_out_dir, 'sphinx-gallery', 'junit-results.xml')
    assert op.isfile(junit_file)
    with codecs.open(junit_file, 'r', 'utf-8') as fid:
        contents = fid.read()
    assert 'errors="0" failures="2"' in contents
    assert 'tests="2"' in contents  # this time we only ran the two stale files
    if LooseVersion(sys.version) >= LooseVersion('3'):
        assert '<failure message="RuntimeError: Forcing' in contents
    else:
        assert '<failure message="SyntaxError: invalid' in contents
    assert 'Passed even though it was marked to fail' in contents
Example #29
0
def test_register_node():
    class custom_node(nodes.Element):
        pass

    with docutils_namespace():
        register_node(custom_node)

        # check registered
        assert hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
        assert hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
        assert hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
        assert hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')

    # check unregistered outside namespace
    assert not hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
    assert not hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
    assert not hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
    assert not hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')
Example #30
0
    def run(self):
        if not color_terminal():
            nocolor()
        if not self.verbose:
            status_stream = StringIO()
        else:
            status_stream = sys.stdout
        confoverrides = {}
        if self.project:
            confoverrides["project"] = self.project
        if self.version:
            confoverrides["version"] = self.version
        if self.release:
            confoverrides["release"] = self.release
        if self.today:
            confoverrides["today"] = self.today
        if self.copyright:
            confoverrides["copyright"] = self.copyright

        try:
            with docutils_namespace():
                app = Sphinx(
                    self.source_dir,
                    self.config_dir,
                    self.builder_target_dir,
                    self.doctree_dir,
                    self.builder,
                    confoverrides,
                    status_stream,
                    freshenv=self.fresh_env,
                    warningiserror=self.warning_is_error,
                )
                app.build(force_all=self.all_files)
                if app.statuscode:
                    raise DistutilsExecError("caused by %s builder." % app.builder.name)
        except Exception as exc:
            handle_exception(app, self, exc, sys.stderr)
            if not self.pdb:
                raise SystemExit(1)

        if self.link_index:
            src = app.config.master_doc + app.builder.out_suffix
            dst = app.builder.get_outfilename("index")
            os.symlink(src, dst)
def test_junit(sphinx_app, tmpdir):
    out_dir = sphinx_app.outdir
    junit_file = op.join(out_dir, 'sphinx-gallery', 'junit-results.xml')
    assert op.isfile(junit_file)
    with codecs.open(junit_file, 'r', 'utf-8') as fid:
        contents = fid.read()
    assert contents.startswith('<?xml')
    assert 'errors="0" failures="0"' in contents
    assert 'tests="5"' in contents
    assert 'local_module' not in contents  # it's not actually run as an ex
    assert 'expected example failure' in contents
    assert '<failure message' not in contents
    src_dir = sphinx_app.srcdir
    new_src_dir = op.join(str(tmpdir), 'src')
    shutil.copytree(src_dir, new_src_dir)
    del src_dir
    new_out_dir = op.join(new_src_dir, '_build', 'html')
    new_toctree_dir = op.join(new_src_dir, '_build', 'toctrees')
    passing_fname = op.join(new_src_dir, 'examples',
                            'plot_numpy_matplotlib.py')
    failing_fname = op.join(new_src_dir, 'examples',
                            'plot_future_imports_broken.py')
    shutil.move(passing_fname, passing_fname + '.temp')
    shutil.move(failing_fname, passing_fname)
    shutil.move(passing_fname + '.temp', failing_fname)
    with docutils_namespace():
        app = Sphinx(new_src_dir, new_src_dir, new_out_dir,
                     new_toctree_dir,
                     buildername='html', status=MixedEncodingStringIO())
        # need to build within the context manager
        # for automodule and backrefs to work
        with pytest.raises(ValueError, match='Here is a summary of the '):
            app.build(False, [])
    junit_file = op.join(new_out_dir, 'sphinx-gallery', 'junit-results.xml')
    assert op.isfile(junit_file)
    with codecs.open(junit_file, 'r', 'utf-8') as fid:
        contents = fid.read()
    assert 'errors="0" failures="2"' in contents
    assert 'tests="2"' in contents  # this time we only ran the two stale files
    if LooseVersion(sys.version) >= LooseVersion('3'):
        assert '<failure message="RuntimeError: Forcing' in contents
    else:
        assert '<failure message="SyntaxError: invalid' in contents
    assert 'Passed even though it was marked to fail' in contents
Example #32
0
def gen_html(isRebuild=False):
    """ make html """

    if isRebuild:
        clear_all_api()

    srcDir = os.path.join(DIR, "docs")  # Directory containing source
    confDir = os.path.join(docDir,
                           "source")  # Directory containing ``conf.py``
    outDir = op.join(docDir, '_build',
                     'html')  # Directory for storing build documents.
    toctreesDir = op.join(docDir, '_build',
                          'toctrees')  # Directory for storing pickled doctrees
    # Avoid warnings about re-registration, see: https://github.com/sphinx-doc/sphinx/issues/5038
    with docutils_namespace():
        app = Sphinx(srcDir, confDir, outDir, toctreesDir, buildername='html')
        # need to build within the context manager for automodule and backrefs to work
        app.build(force_all=isRebuild, filenames=[])
    return app
Example #33
0
    def test_yosys_script(self):
        TEST_NAME = "test_rtlil"
        TEST_BUILD_DIR = os.path.join("build", self.TEST_CASE_NAME, TEST_NAME)
        TEST_FILES = [
            "test_rtlil/test_rtlil.rst",
            "code/rtlil/counter.il"
        ]
        TEST_JINJA_DICT = {
            "hdl_diagrams_path": "'{}'".format(HDL_DIAGRAMS_PATH),
            "master_doc": "'test_rtlil'",
            "custom_variables": "''"
        }

        self.prepare_test(TEST_NAME, TEST_BUILD_DIR, TEST_FILES, **TEST_JINJA_DICT)

        # Run the Sphinx
        sphinx_dirs = get_sphinx_dirs(TEST_BUILD_DIR)
        with docutils_namespace():
            app = Sphinx(buildername="html", warningiserror=True, **sphinx_dirs)
            app.build(force_all=True)
Example #34
0
def render_sphinx_rst_file(rst_path, out_filename, reference_path,
                           test_output_dir):
    with docutils_namespace():
        out_dir = str(test_output_dir)
        app = Sphinx(srcdir=str(rst_path.parent),
                     confdir=None,
                     outdir=out_dir,
                     doctreedir=out_dir,
                     buildername='dummy',
                     status=None)
        with open(rst_path) as rst_file:
            contents = rst_file.read()
        sphinx_doctree = sphinx_parse(app, contents)
    doctree = from_doctree(sphinx_doctree)
    docinfo = sphinx_doctree.settings.env.metadata['index']
    return _render_rst(rst_path,
                       doctree,
                       out_filename,
                       reference_path,
                       warnings=docinfo.get('warnings', '').splitlines())
Example #35
0
    def _build_documentation(self, builder, out_dir, doctree_dir, config=None):
        conf = dict(config) if config else {}
        conf['master_doc'] = 'index'  # force index for legacy sphinx
        conf['html_theme'] = 'sphinx_alice_theme'
        conf['html_theme_path'] = self.root_dir
        if 'extensions' not in conf:
            conf['extensions'] = []
        conf['extensions'].append('sphinx.ext.autodoc')

        with docutils_namespace():
            app = Sphinx(
                self.doc_dir,  # documentation to process
                None,  # default configuration
                out_dir,  # output for generated documents
                doctree_dir,  # output for doctree files
                builder,  # builder to execute
                confoverrides=conf,  # load provided configuration (volatile)
                warning=sys.stderr,  # warnings output
                warningiserror=True)  # treat warnings as errors

            app.build(force_all=True)
Example #36
0
def sphinx_app(tmpdir_factory):
    temp_dir = (tmpdir_factory.getbasetemp() / 'root').strpath
    src_dir = op.join(op.dirname(__file__), 'tinybuild')

    def ignore(src, names):
        return ('_build', 'gen_modules', 'auto_examples')

    shutil.copytree(src_dir, temp_dir, ignore=ignore)
    # For testing iteration, you can get similar behavior just doing `make`
    # inside the tinybuild directory
    src_dir = temp_dir
    conf_dir = temp_dir
    out_dir = op.join(temp_dir, '_build', 'html')
    toctrees_dir = op.join(temp_dir, '_build', 'toctrees')
    # Avoid warnings about re-registration, see:
    # https://github.com/sphinx-doc/sphinx/issues/5038
    with docutils_namespace():
        app = Sphinx(src_dir, conf_dir, out_dir, toctrees_dir,
                     buildername='html')
        # need to build within the context manager
        # for automodule and backrefs to work
        app.build(False, [])
    return app
Example #37
0
def build_main(argv=sys.argv[1:]):
    # type: (List[str]) -> int
    """Sphinx build "main" command-line entry."""

    parser = get_parser()
    args = parser.parse_args(argv)

    if args.noconfig:
        args.confdir = None
    elif not args.confdir:
        args.confdir = args.sourcedir

    if not args.doctreedir:
        args.doctreedir = os.path.join(args.outputdir, '.doctrees')

    # handle remaining filename arguments
    filenames = args.filenames
    missing_files = []
    for filename in filenames:
        if not os.path.isfile(filename):
            missing_files.append(filename)
    if missing_files:
        parser.error(__('cannot find files %r') % missing_files)

    if args.force_all and filenames:
        parser.error(__('cannot combine -a option and filenames'))

    if args.color == 'no' or (args.color == 'auto' and not color_terminal()):
        nocolor()

    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr

    if args.quiet:
        status = None

    if args.really_quiet:
        status = warning = None

    if warning and args.warnfile:
        try:
            warnfp = open(args.warnfile, 'w')
        except Exception as exc:
            parser.error(__('cannot open warning file %r: %s') % (
                args.warnfile, exc))
        warning = Tee(warning, warnfp)  # type: ignore
        error = warning

    confoverrides = {}
    for val in args.define:
        try:
            key, val = val.split('=', 1)
        except ValueError:
            parser.error(__('-D option argument must be in the form name=value'))
        confoverrides[key] = val

    for val in args.htmldefine:
        try:
            key, val = val.split('=')
        except ValueError:
            parser.error(__('-A option argument must be in the form name=value'))
        try:
            val = int(val)
        except ValueError:
            pass
        confoverrides['html_context.%s' % key] = val

    if args.nitpicky:
        confoverrides['nitpicky'] = True

    app = None
    try:
        confdir = args.confdir or args.sourcedir
        with patch_docutils(confdir), docutils_namespace():
            app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
                         args.doctreedir, args.builder, confoverrides, status,
                         warning, args.freshenv, args.warningiserror,
                         args.tags, args.verbosity, args.jobs, args.keep_going)
            app.build(args.force_all, filenames)
            return app.statuscode
    except (Exception, KeyboardInterrupt) as exc:
        handle_exception(app, args, exc, error)
        return 2
Example #38
0
def main(argv):
    # type: (List[unicode]) -> int
    parser = optparse.OptionParser(USAGE, epilog=EPILOG, formatter=MyFormatter())
    parser.add_option('--version', action='store_true', dest='version',
                      help='show version information and exit')

    group = parser.add_option_group('General options')
    group.add_option('-b', metavar='BUILDER', dest='builder', default='html',
                     help='builder to use; default is html')
    group.add_option('-a', action='store_true', dest='force_all',
                     help='write all files; default is to only write new and '
                     'changed files')
    group.add_option('-E', action='store_true', dest='freshenv',
                     help='don\'t use a saved environment, always read '
                     'all files')
    group.add_option('-d', metavar='PATH', default=None, dest='doctreedir',
                     help='path for the cached environment and doctree files '
                     '(default: outdir/.doctrees)')
    group.add_option('-j', metavar='N', default=1, type='int', dest='jobs',
                     help='build in parallel with N processes where possible')
    # this option never gets through to this point (it is intercepted earlier)
    # group.add_option('-M', metavar='BUILDER', dest='make_mode',
    #                 help='"make" mode -- as used by Makefile, like '
    #                 '"sphinx-build -M html"')

    group = parser.add_option_group('Build configuration options')
    group.add_option('-c', metavar='PATH', dest='confdir',
                     help='path where configuration file (conf.py) is located '
                     '(default: same as sourcedir)')
    group.add_option('-C', action='store_true', dest='noconfig',
                     help='use no config file at all, only -D options')
    group.add_option('-D', metavar='setting=value', action='append',
                     dest='define', default=[],
                     help='override a setting in configuration file')
    group.add_option('-A', metavar='name=value', action='append',
                     dest='htmldefine', default=[],
                     help='pass a value into HTML templates')
    group.add_option('-t', metavar='TAG', action='append',
                     dest='tags', default=[],
                     help='define tag: include "only" blocks with TAG')
    group.add_option('-n', action='store_true', dest='nitpicky',
                     help='nit-picky mode, warn about all missing references')

    group = parser.add_option_group('Console output options')
    group.add_option('-v', action='count', dest='verbosity', default=0,
                     help='increase verbosity (can be repeated)')
    group.add_option('-q', action='store_true', dest='quiet',
                     help='no output on stdout, just warnings on stderr')
    group.add_option('-Q', action='store_true', dest='really_quiet',
                     help='no output at all, not even warnings')
    group.add_option('--color', dest='color',
                     action='store_const', const='yes', default='auto',
                     help='Do emit colored output (default: auto-detect)')
    group.add_option('-N', '--no-color', dest='color',
                     action='store_const', const='no',
                     help='Do not emit colored output (default: auot-detect)')
    group.add_option('-w', metavar='FILE', dest='warnfile',
                     help='write warnings (and errors) to given file')
    group.add_option('-W', action='store_true', dest='warningiserror',
                     help='turn warnings into errors')
    group.add_option('-T', action='store_true', dest='traceback',
                     help='show full traceback on exception')
    group.add_option('-P', action='store_true', dest='pdb',
                     help='run Pdb on exception')

    # parse options
    try:
        opts, args = parser.parse_args(list(argv[1:]))
    except SystemExit as err:
        return err.code

    # handle basic options
    if opts.version:
        print('Sphinx (sphinx-build) %s' % __display_version__)
        return 0

    # get paths (first and second positional argument)
    try:
        srcdir = abspath(args[0])
        confdir = abspath(opts.confdir or srcdir)
        if opts.noconfig:
            confdir = None
        if not path.isdir(srcdir):
            print('Error: Cannot find source directory `%s\'.' % srcdir,
                  file=sys.stderr)
            return 1
        if not opts.noconfig and not path.isfile(path.join(confdir, 'conf.py')):
            print('Error: Config directory doesn\'t contain a conf.py file.',
                  file=sys.stderr)
            return 1
        outdir = abspath(args[1])
        if srcdir == outdir:
            print('Error: source directory and destination directory are same.',
                  file=sys.stderr)
            return 1
    except IndexError:
        parser.print_help()
        return 1
    except UnicodeError:
        print(
            'Error: Multibyte filename not supported on this filesystem '
            'encoding (%r).' % fs_encoding, file=sys.stderr)
        return 1

    # handle remaining filename arguments
    filenames = args[2:]
    errored = False
    for filename in filenames:
        if not path.isfile(filename):
            print('Error: Cannot find file %r.' % filename, file=sys.stderr)
            errored = True
    if errored:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__('locale')  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    if opts.force_all and filenames:
        print('Error: Cannot combine -a option and filenames.', file=sys.stderr)
        return 1

    if opts.color == 'no' or (opts.color == 'auto' and not color_terminal()):
        nocolor()

    doctreedir = abspath(opts.doctreedir or path.join(outdir, '.doctrees'))

    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr

    if opts.quiet:
        status = None
    if opts.really_quiet:
        status = warning = None
    if warning and opts.warnfile:
        try:
            warnfp = open(opts.warnfile, 'w')
        except Exception as exc:
            print('Error: Cannot open warning file %r: %s' %
                  (opts.warnfile, exc), file=sys.stderr)
            sys.exit(1)
        warning = Tee(warning, warnfp)  # type: ignore
        error = warning

    confoverrides = {}
    for val in opts.define:
        try:
            key, val = val.split('=', 1)
        except ValueError:
            print('Error: -D option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        if likely_encoding and isinstance(val, binary_type):
            try:
                val = val.decode(likely_encoding)
            except UnicodeError:
                pass
        confoverrides[key] = val

    for val in opts.htmldefine:
        try:
            key, val = val.split('=')
        except ValueError:
            print('Error: -A option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        try:
            val = int(val)
        except ValueError:
            if likely_encoding and isinstance(val, binary_type):
                try:
                    val = val.decode(likely_encoding)
                except UnicodeError:
                    pass
        confoverrides['html_context.%s' % key] = val

    if opts.nitpicky:
        confoverrides['nitpicky'] = True

    app = None
    try:
        with docutils_namespace():
            app = Sphinx(srcdir, confdir, outdir, doctreedir, opts.builder,
                         confoverrides, status, warning, opts.freshenv,
                         opts.warningiserror, opts.tags, opts.verbosity, opts.jobs)
            app.build(opts.force_all, filenames)
            return app.statuscode
    except (Exception, KeyboardInterrupt) as exc:
        handle_exception(app, opts, exc, error)
        return 1
def test_rebuild(tmpdir_factory, sphinx_app):
    # Make sure that examples that haven't been changed aren't run twice.

    #
    # First run completes in the fixture.
    #
    status = sphinx_app._status.getvalue()
    want = '.*%s added, 0 changed, 0 removed$.*' % (N_RST,)
    assert re.match(want, status, re.MULTILINE | re.DOTALL) is not None
    assert re.match('.*targets for 1 source files that are out of date$.*',
                    status, re.MULTILINE | re.DOTALL) is not None
    want = ('.*executed %d out of %d.*after excluding 0 files.*based on MD5.*'
            % (N_GOOD, N_TOT))
    assert re.match(want, status, re.MULTILINE | re.DOTALL) is not None
    old_src_dir = (tmpdir_factory.getbasetemp() / 'root_old').strpath
    shutil.copytree(sphinx_app.srcdir, old_src_dir)
    generated_modules_0 = sorted(
        op.join(old_src_dir, 'gen_modules', f)
        for f in os.listdir(op.join(old_src_dir, 'gen_modules'))
        if op.isfile(op.join(old_src_dir, 'gen_modules', f)))
    generated_backrefs_0 = sorted(
        op.join(old_src_dir, 'gen_modules', 'backreferences', f)
        for f in os.listdir(op.join(old_src_dir, 'gen_modules',
                                    'backreferences')))
    generated_rst_0 = sorted(
        op.join(old_src_dir, 'auto_examples', f)
        for f in os.listdir(op.join(old_src_dir, 'auto_examples'))
        if f.endswith('.rst'))
    generated_pickle_0 = sorted(
        op.join(old_src_dir, 'auto_examples', f)
        for f in os.listdir(op.join(old_src_dir, 'auto_examples'))
        if f.endswith('.pickle'))
    copied_py_0 = sorted(
        op.join(old_src_dir, 'auto_examples', f)
        for f in os.listdir(op.join(old_src_dir, 'auto_examples'))
        if f.endswith('.py'))
    copied_ipy_0 = sorted(
        op.join(old_src_dir, 'auto_examples', f)
        for f in os.listdir(op.join(old_src_dir, 'auto_examples'))
        if f.endswith('.ipynb'))
    assert len(generated_modules_0) > 0
    assert len(generated_backrefs_0) > 0
    assert len(generated_rst_0) > 0
    assert len(generated_pickle_0) > 0
    assert len(copied_py_0) > 0
    assert len(copied_ipy_0) > 0
    assert len(sphinx_app.config.sphinx_gallery_conf['stale_examples']) == 0
    assert op.isfile(op.join(sphinx_app.outdir, '_images',
                             'sphx_glr_plot_numpy_matplotlib_001.png'))

    #
    # run a second time, no files should be updated
    #

    src_dir = sphinx_app.srcdir
    del sphinx_app  # don't accidentally use it below
    conf_dir = src_dir
    out_dir = op.join(src_dir, '_build', 'html')
    toctrees_dir = op.join(src_dir, '_build', 'toctrees')
    time.sleep(0.1)
    with docutils_namespace():
        new_app = Sphinx(src_dir, conf_dir, out_dir, toctrees_dir,
                         buildername='html', status=MixedEncodingStringIO())
        new_app.build(False, [])
    status = new_app._status.getvalue()
    lines = [line for line in status.split('\n') if '0 removed' in line]
    assert re.match('.*0 added, [2|3|6|7|8] changed, 0 removed$.*',
                    status, re.MULTILINE | re.DOTALL) is not None, lines
    want = ('.*executed 0 out of 1.*after excluding %s files.*based on MD5.*'
            % (N_GOOD,))
    assert re.match(want, status, re.MULTILINE | re.DOTALL) is not None
    n_stale = len(new_app.config.sphinx_gallery_conf['stale_examples'])
    assert n_stale == N_GOOD
    assert op.isfile(op.join(new_app.outdir, '_images',
                             'sphx_glr_plot_numpy_matplotlib_001.png'))

    generated_modules_1 = sorted(
        op.join(new_app.srcdir, 'gen_modules', f)
        for f in os.listdir(op.join(new_app.srcdir, 'gen_modules'))
        if op.isfile(op.join(new_app.srcdir, 'gen_modules', f)))
    generated_backrefs_1 = sorted(
        op.join(new_app.srcdir, 'gen_modules', 'backreferences', f)
        for f in os.listdir(op.join(new_app.srcdir, 'gen_modules',
                                    'backreferences')))
    generated_rst_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.rst'))
    generated_pickle_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.pickle'))
    copied_py_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.py'))
    copied_ipy_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.ipynb'))

    # mtimes for modules
    _assert_mtimes(generated_modules_0, generated_modules_1)

    # mtimes for backrefs (gh-394)
    _assert_mtimes(generated_backrefs_0, generated_backrefs_1)

    # generated RST files
    ignore = (
        # these two should almost always be different, but in case we
        # get extremely unlucky and have identical run times
        # on the one script that gets re-run (because it's a fail)...
        'sg_execution_times.rst',
        'plot_future_imports_broken.rst',
    )
    _assert_mtimes(generated_rst_0, generated_rst_1, ignore=ignore)

    # mtimes for pickles
    _assert_mtimes(generated_pickle_0, generated_pickle_1)

    # mtimes for .py files (gh-395)
    _assert_mtimes(copied_py_0, copied_py_1)

    # mtimes for .ipynb files
    _assert_mtimes(copied_ipy_0, copied_ipy_1)

    #
    # run a third time, changing one file
    #

    time.sleep(0.1)
    fname = op.join(src_dir, 'examples', 'plot_numpy_matplotlib.py')
    with codecs.open(fname, 'r', 'utf-8') as fid:
        lines = fid.readlines()
    with codecs.open(fname, 'w', 'utf-8') as fid:
        for line in lines:
            if line.startswith('FYI this'):
                line = 'A ' + line
            fid.write(line)
    with docutils_namespace():
        new_app = Sphinx(src_dir, conf_dir, out_dir, toctrees_dir,
                         buildername='html', status=MixedEncodingStringIO())
        new_app.build(False, [])
    status = new_app._status.getvalue()
    if LooseVersion(sphinx.__version__) <= LooseVersion('1.6'):
        n = N_RST
    else:
        n = '[2|3]'
    lines = [line for line in status.split('\n') if 'source files tha' in line]
    want = '.*targets for %s source files that are out of date$.*' % n
    assert re.match(want, status, re.MULTILINE | re.DOTALL) is not None, lines
    want = ('.*executed 1 out of 2.*after excluding %s files.*based on MD5.*'
            % (N_GOOD - 1,))
    assert re.match(want, status, re.MULTILINE | re.DOTALL) is not None
    n_stale = len(new_app.config.sphinx_gallery_conf['stale_examples'])
    assert n_stale == N_GOOD - 1
    assert op.isfile(op.join(new_app.outdir, '_images',
                             'sphx_glr_plot_numpy_matplotlib_001.png'))

    generated_modules_1 = sorted(
        op.join(new_app.srcdir, 'gen_modules', f)
        for f in os.listdir(op.join(new_app.srcdir, 'gen_modules'))
        if op.isfile(op.join(new_app.srcdir, 'gen_modules', f)))
    generated_backrefs_1 = sorted(
        op.join(new_app.srcdir, 'gen_modules', 'backreferences', f)
        for f in os.listdir(op.join(new_app.srcdir, 'gen_modules',
                                    'backreferences')))
    generated_rst_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.rst'))
    generated_pickle_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.pickle'))
    copied_py_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.py'))
    copied_ipy_1 = sorted(
        op.join(new_app.srcdir, 'auto_examples', f)
        for f in os.listdir(op.join(new_app.srcdir, 'auto_examples'))
        if f.endswith('.ipynb'))

    # mtimes for modules
    _assert_mtimes(generated_modules_0, generated_modules_1)

    # mtimes for backrefs (gh-394)
    _assert_mtimes(generated_backrefs_0, generated_backrefs_1)

    # generated RST files
    different = (
        # this one should get rewritten as we retried it
        'plot_future_imports_broken.rst',
        'plot_numpy_matplotlib.rst',
    )
    ignore = (
        # this one should almost always be different, but in case we
        # get extremely unlucky and have identical run times
        # on the one script above that changes...
        'sg_execution_times.rst',
    )
    _assert_mtimes(generated_rst_0, generated_rst_1, different, ignore)

    # mtimes for pickles
    _assert_mtimes(generated_pickle_0, generated_pickle_1,
                   different=('plot_numpy_matplotlib.codeobj.pickle'))

    # mtimes for .py files (gh-395)
    _assert_mtimes(copied_py_0, copied_py_1,
                   different=('plot_numpy_matplotlib.py'))

    # mtimes for .ipynb files
    _assert_mtimes(copied_ipy_0, copied_ipy_1,
                   different=('plot_numpy_matplotlib.ipynb'))
 def create_sphinx_app_context(self):
     with docutils_namespace():
         app = Sphinx(self.srcdir, self.confdir, self.outdir,
                      self.doctreedir, self.buildername, **self.kwargs)
         sphinx_compatibility._app = app
         yield app
Example #41
0
def main(argv=sys.argv[1:]):  # type: ignore
    # type: (List[unicode]) -> int

    parser = get_parser()
    # parse options
    try:
        args = parser.parse_args(argv)
    except SystemExit as err:
        return err.code

    # get paths (first and second positional argument)
    try:
        srcdir = abspath(args.sourcedir)
        confdir = abspath(args.confdir or srcdir)
        if args.noconfig:
            confdir = None
        if not path.isdir(srcdir):
            print('Error: Cannot find source directory `%s\'.' % srcdir,
                  file=sys.stderr)
            return 1
        if not args.noconfig and not path.isfile(path.join(confdir, 'conf.py')):
            print('Error: Config directory doesn\'t contain a conf.py file.',
                  file=sys.stderr)
            return 1
        outdir = abspath(args.outputdir)
        if srcdir == outdir:
            print('Error: source directory and destination directory are same.',
                  file=sys.stderr)
            return 1
    except UnicodeError:
        print(
            'Error: Multibyte filename not supported on this filesystem '
            'encoding (%r).' % fs_encoding, file=sys.stderr)
        return 1

    # handle remaining filename arguments
    filenames = args.filenames
    errored = False
    for filename in filenames:
        if not path.isfile(filename):
            print('Error: Cannot find file %r.' % filename, file=sys.stderr)
            errored = True
    if errored:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__('locale')  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    if args.force_all and filenames:
        print('Error: Cannot combine -a option and filenames.', file=sys.stderr)
        return 1

    if args.color == 'no' or (args.color == 'auto' and not color_terminal()):
        nocolor()

    doctreedir = abspath(args.doctreedir or path.join(outdir, '.doctrees'))

    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr

    if args.quiet:
        status = None
    if args.really_quiet:
        status = warning = None
    if warning and args.warnfile:
        try:
            warnfp = open(args.warnfile, 'w')
        except Exception as exc:
            print('Error: Cannot open warning file %r: %s' %
                  (args.warnfile, exc), file=sys.stderr)
            sys.exit(1)
        warning = Tee(warning, warnfp)  # type: ignore
        error = warning

    confoverrides = {}
    for val in args.define:
        try:
            key, val = val.split('=', 1)
        except ValueError:
            print('Error: -D option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        if likely_encoding and isinstance(val, binary_type):
            try:
                val = val.decode(likely_encoding)
            except UnicodeError:
                pass
        confoverrides[key] = val

    for val in args.htmldefine:
        try:
            key, val = val.split('=')
        except ValueError:
            print('Error: -A option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        try:
            val = int(val)
        except ValueError:
            if likely_encoding and isinstance(val, binary_type):
                try:
                    val = val.decode(likely_encoding)
                except UnicodeError:
                    pass
        confoverrides['html_context.%s' % key] = val

    if args.nitpicky:
        confoverrides['nitpicky'] = True

    app = None
    try:
        with patch_docutils(), docutils_namespace():
            app = Sphinx(srcdir, confdir, outdir, doctreedir, args.builder,
                         confoverrides, status, warning, args.freshenv,
                         args.warningiserror, args.tags, args.verbosity, args.jobs)
            app.build(args.force_all, filenames)
            return app.statuscode
    except (Exception, KeyboardInterrupt) as exc:
        handle_exception(app, args, exc, error)
        return 1
Example #42
0
def main(argv):
    if not color_terminal():
        nocolor()

    parser = optparse.OptionParser(USAGE, epilog=EPILOG, formatter=MyFormatter())
    parser.add_option("--version", action="store_true", dest="version", help="show version information and exit")

    group = parser.add_option_group("General options")
    group.add_option("-b", metavar="BUILDER", dest="builder", default="html", help="builder to use; default is html")
    group.add_option(
        "-a",
        action="store_true",
        dest="force_all",
        help="write all files; default is to only write new and " "changed files",
    )
    group.add_option(
        "-E", action="store_true", dest="freshenv", help="don't use a saved environment, always read " "all files"
    )
    group.add_option(
        "-d",
        metavar="PATH",
        default=None,
        dest="doctreedir",
        help="path for the cached environment and doctree files " "(default: outdir/.doctrees)",
    )
    group.add_option(
        "-j", metavar="N", default=1, type="int", dest="jobs", help="build in parallel with N processes where possible"
    )
    # this option never gets through to this point (it is intercepted earlier)
    # group.add_option('-M', metavar='BUILDER', dest='make_mode',
    #                 help='"make" mode -- as used by Makefile, like '
    #                 '"sphinx-build -M html"')

    group = parser.add_option_group("Build configuration options")
    group.add_option(
        "-c",
        metavar="PATH",
        dest="confdir",
        help="path where configuration file (conf.py) is located " "(default: same as sourcedir)",
    )
    group.add_option("-C", action="store_true", dest="noconfig", help="use no config file at all, only -D options")
    group.add_option(
        "-D",
        metavar="setting=value",
        action="append",
        dest="define",
        default=[],
        help="override a setting in configuration file",
    )
    group.add_option(
        "-A",
        metavar="name=value",
        action="append",
        dest="htmldefine",
        default=[],
        help="pass a value into HTML templates",
    )
    group.add_option(
        "-t", metavar="TAG", action="append", dest="tags", default=[], help='define tag: include "only" blocks with TAG'
    )
    group.add_option(
        "-n", action="store_true", dest="nitpicky", help="nit-picky mode, warn about all missing references"
    )

    group = parser.add_option_group("Console output options")
    group.add_option("-v", action="count", dest="verbosity", default=0, help="increase verbosity (can be repeated)")
    group.add_option("-q", action="store_true", dest="quiet", help="no output on stdout, just warnings on stderr")
    group.add_option("-Q", action="store_true", dest="really_quiet", help="no output at all, not even warnings")
    group.add_option("-N", action="store_true", dest="nocolor", help="do not emit colored output")
    group.add_option("-w", metavar="FILE", dest="warnfile", help="write warnings (and errors) to given file")
    group.add_option("-W", action="store_true", dest="warningiserror", help="turn warnings into errors")
    group.add_option("-T", action="store_true", dest="traceback", help="show full traceback on exception")
    group.add_option("-P", action="store_true", dest="pdb", help="run Pdb on exception")

    # parse options
    try:
        opts, args = parser.parse_args(list(argv[1:]))
    except SystemExit as err:
        return err.code

    # handle basic options
    if opts.version:
        print("Sphinx (sphinx-build) %s" % __display_version__)
        return 0

    # get paths (first and second positional argument)
    try:
        srcdir = abspath(args[0])
        confdir = abspath(opts.confdir or srcdir)
        if opts.noconfig:
            confdir = None
        if not path.isdir(srcdir):
            print("Error: Cannot find source directory `%s'." % srcdir, file=sys.stderr)
            return 1
        if not opts.noconfig and not path.isfile(path.join(confdir, "conf.py")):
            print("Error: Config directory doesn't contain a conf.py file.", file=sys.stderr)
            return 1
        outdir = abspath(args[1])
        if srcdir == outdir:
            print("Error: source directory and destination directory are same.", file=sys.stderr)
            return 1
    except IndexError:
        parser.print_help()
        return 1
    except UnicodeError:
        print(
            "Error: Multibyte filename not supported on this filesystem " "encoding (%r)." % fs_encoding,
            file=sys.stderr,
        )
        return 1

    # handle remaining filename arguments
    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print("Error: Cannot find file %r." % filename, file=sys.stderr)
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__("locale")  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    if opts.force_all and filenames:
        print("Error: Cannot combine -a option and filenames.", file=sys.stderr)
        return 1

    if opts.nocolor:
        nocolor()

    doctreedir = abspath(opts.doctreedir or path.join(outdir, ".doctrees"))

    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr

    if opts.quiet:
        status = None
    if opts.really_quiet:
        status = warning = None
    if warning and opts.warnfile:
        try:
            warnfp = open(opts.warnfile, "w")
        except Exception as exc:
            print("Error: Cannot open warning file %r: %s" % (opts.warnfile, exc), file=sys.stderr)
            sys.exit(1)
        warning = Tee(warning, warnfp)
        error = warning

    confoverrides = {}
    for val in opts.define:
        try:
            key, val = val.split("=")
        except ValueError:
            print("Error: -D option argument must be in the form name=value.", file=sys.stderr)
            return 1
        if likely_encoding and isinstance(val, binary_type):
            try:
                val = val.decode(likely_encoding)
            except UnicodeError:
                pass
        confoverrides[key] = val

    for val in opts.htmldefine:
        try:
            key, val = val.split("=")
        except ValueError:
            print("Error: -A option argument must be in the form name=value.", file=sys.stderr)
            return 1
        try:
            val = int(val)
        except ValueError:
            if likely_encoding and isinstance(val, binary_type):
                try:
                    val = val.decode(likely_encoding)
                except UnicodeError:
                    pass
        confoverrides["html_context.%s" % key] = val

    if opts.nitpicky:
        confoverrides["nitpicky"] = True

    app = None
    try:
        with docutils_namespace():
            app = Sphinx(
                srcdir,
                confdir,
                outdir,
                doctreedir,
                opts.builder,
                confoverrides,
                status,
                warning,
                opts.freshenv,
                opts.warningiserror,
                opts.tags,
                opts.verbosity,
                opts.jobs,
            )
            app.build(opts.force_all, filenames)
            return app.statuscode
    except (Exception, KeyboardInterrupt) as exc:
        handle_exception(app, opts, exc, error)
        return 1