예제 #1
0
 def __init__(self,
              source_filename: str,
              project_root_dir: str,
              target_rst_filename: str,
              method: AutodocMethod = AutodocMethod.BEST,
              python_package_root_dir: str = None,
              source_rst_title_style_python: bool = True,
              pygments_language_override: Dict[str, str] = None) -> None:
     """
     Args:
         source_filename: source file (e.g. Python, C++, XML file) to
             document
         project_root_dir: root directory of the whole project
         target_rst_filename: filenamd of an RST file to write that will
             document the source file
         method: instance of :class:`AutodocMethod`; for example, should we
             ask Sphinx's ``autodoc`` to read docstrings and build us a
             pretty page, or just include the contents with syntax
             highlighting?
         python_package_root_dir: if your Python modules live in a directory
             other than ``project_root_dir``, specify it here
         source_rst_title_style_python: if ``True`` and the file is a Python
             file and ``method == AutodocMethod.AUTOMODULE``, the heading
             used will be in the style of a Python module, ``x.y.z``.
             Otherwise, it will be a path (``x/y/z``).
         pygments_language_override: if specified, a dictionary mapping
             file extensions to Pygments languages (for example: a ``.pro``
             file will be autodetected as Prolog, but you might want to
             map that to ``none`` for Qt project files).
     """
     self.source_filename = abspath(expanduser(source_filename))
     self.project_root_dir = abspath(expanduser(project_root_dir))
     self.target_rst_filename = abspath(expanduser(target_rst_filename))
     self.method = method
     self.source_rst_title_style_python = source_rst_title_style_python
     self.python_package_root_dir = (
         abspath(expanduser(python_package_root_dir))
         if python_package_root_dir else self.project_root_dir
     )
     self.pygments_language_override = pygments_language_override or {}  # type: Dict[str, str]  # noqa
     assert isfile(self.source_filename), (
         f"Not a file: source_filename={self.source_filename!r}")
     assert isdir(self.project_root_dir), (
         f"Not a directory: project_root_dir={self.project_root_dir!r}")
     assert relative_filename_within_dir(
         filename=self.source_filename,
         directory=self.project_root_dir
     ), (
         f"Source file {self.source_filename!r} is not within "
         f"project directory {self.project_root_dir!r}"
     )
     assert relative_filename_within_dir(
         filename=self.python_package_root_dir,
         directory=self.project_root_dir
     ), (
         f"Python root {self.python_package_root_dir!r} is not within "
         f"project directory {self.project_root_dir!r}"
     )
     assert isinstance(method, AutodocMethod)
예제 #2
0
    def specific_file_rst_filename(self, source_filename: str) -> str:
        """
        Gets the RST filename corresponding to a source filename.
        See the help for the constructor for more details.

        Args:
            source_filename: source filename within current project

        Returns:
            RST filename

        Note in particular: the way we structure the directories means that we
        won't get clashes between files with idential names in two different
        directories. However, we must also incorporate the original source
        filename, in particular for C++ where ``thing.h`` and ``thing.cpp``
        must not generate the same RST filename. So we just add ``.rst``.
        """
        highest_code_to_target = relative_filename_within_dir(
            source_filename, self.highest_code_dir)
        bname = basename(source_filename)
        result = join(self.autodoc_rst_root_dir,
                      dirname(highest_code_to_target),
                      bname + EXT_RST)
        log.debug("Source {!r} -> RST {!r}", source_filename, result)
        return result
예제 #3
0
def warn_if_not_within_docker_dir(param_name: str,
                                  filespec: str,
                                  permit_cfg: bool = False,
                                  permit_venv: bool = False,
                                  permit_tmp: bool = False,
                                  param_contains_not_is: bool = False,
                                  is_env_var: bool = False,
                                  as_file_url: bool = False) -> None:
    """
    If the specified filename isn't within a relevant directory that will be
    used by CRATE when operating within a Docker Compose application, warn
    the user.

    Args:
        param_name:
            Name of the parameter in the CRATE config file.
        filespec:
            Filename (or filename-like thing) to check.
        permit_cfg:
            Permit the file to be in the configuration directory.
        permit_venv:
            Permit the file to be in the virtual environment directory.
        permit_tmp:
            Permit the file to be in the shared temporary space.
        param_contains_not_is:
            The parameter "contains", not "is", the filename.
        is_env_var:
            The parameter is an environment variable.
        as_file_url:
            filespec is a "file://" URL, rather than a filename
    """
    if not filespec:
        return
    if as_file_url:
        filepath = urllib.parse.urlparse(filespec).path
    else:
        filepath = filespec
    param_descriptor = ("Environment variable"
                        if is_env_var else "Config parameter")
    is_phrase = "contains" if param_contains_not_is else "is"
    permitted_dirs = []  # type: List[str]
    if permit_cfg:
        permitted_dirs.append(DockerConstants.CONFIG_DIR)
    if permit_venv:
        permitted_dirs.append(DockerConstants.VENV_DIR)
    if permit_tmp:
        permitted_dirs.append(DockerConstants.TMP_DIR)
    ok = any(relative_filename_within_dir(filepath, d) for d in permitted_dirs)
    if not ok:
        log.warning(
            f"{param_descriptor} {param_name} {is_phrase} {filespec!r}, "
            f"which is not within the permitted Docker directories "
            f"{permitted_dirs!r}")
예제 #4
0
    def __init__(self, full_path: str, top_dir: str,
                 correct_copyright_lines: List[str]) -> None:
        """

        Args:
            full_path:
                full path to source file
            top_dir:
                directory from which we calculate a relative filename to be
                shown
            correct_copyright_lines:
                list of lines (without newlines) representing the copyright
                docstring block, including the transition lines of equals
                symbols
        """
        self.full_path = full_path
        self.advertised_filename = relative_filename_within_dir(
            full_path, top_dir)
        self.correct_copyright_lines = correct_copyright_lines
        self.needs_rewriting = False
        self.source_lines = []  # type: List[str]
        self.dest_lines = []  # type: List[str]
        self._read_source()
        self._create_dest()
예제 #5
0
    def __init__(self,
                 index_filename: str,
                 project_root_dir: str,
                 autodoc_rst_root_dir: str,
                 highest_code_dir: str,
                 python_package_root_dir: str = None,
                 source_filenames_or_globs: Union[str, Iterable[str]] = None,
                 index_heading_underline_char: str = "-",
                 source_rst_heading_underline_char: str = "~",
                 title: str = DEFAULT_INDEX_TITLE,
                 introductory_rst: str = "",
                 recursive: bool = True,
                 skip_globs: List[str] = None,
                 toctree_maxdepth: int = 1,
                 method: AutodocMethod = AutodocMethod.BEST,
                 rst_prefix: str = "",
                 rst_suffix: str = "",
                 source_rst_title_style_python: bool = True,
                 pygments_language_override: Dict[str, str] = None) -> None:
        """
        Args:
            index_filename:
                filename of the index ``.RST`` (ReStructured Text) file to
                create

            project_root_dir:
                top-level directory for the whole project

            autodoc_rst_root_dir:
                directory within which all automatically generated ``.RST``
                files (each to document a specific source file) will be placed.
                A directory hierarchy within this directory will be created,
                reflecting the structure of the code relative to
                ``highest_code_dir`` (q.v.).

            highest_code_dir:
                the "lowest" directory such that all code is found within it;
                the directory structure within ``autodoc_rst_root_dir`` is to
                ``.RST`` files what the directory structure is of the source
                files, relative to ``highest_code_dir``.

            python_package_root_dir:
                if your Python modules live in a directory other than
                ``project_root_dir``, specify it here

            source_filenames_or_globs:
                optional string, or list of strings, each describing a file or
                glob-style file specification; these are the source filenames
                to create automatic RST` for. If you don't specify them here,
                you can use :func:`add_source_files`. To add sub-indexes, use
                :func:`add_index` and :func:`add_indexes`.

            index_heading_underline_char:
                the character used to underline the title in the index file

            source_rst_heading_underline_char:
                the character used to underline the heading in each of the
                source files

            title:
                title for the index

            introductory_rst:
                extra RST for the index, which goes between the title and the
                table of contents

            recursive:
                use :func:`glob.glob` in recursive mode?

            skip_globs:
                list of file names or file specifications to skip; e.g.
                ``['__init__.py']``

            toctree_maxdepth:
                ``maxdepth`` parameter for the ``toctree`` command generated in
                the index file

            method:
                see :class:`FileToAutodocument`

            rst_prefix:
                optional RST content (e.g. copyright comment) to put early on
                in each of the RST files

            rst_suffix:
                optional RST content to put late on in each of the RST files

            source_rst_title_style_python:
                make the individual RST files use titles in the style of Python
                modules, ``x.y.z``, rather than path style (``x/y/z``); path
                style will be used for non-Python files in any case.

            pygments_language_override:
                if specified, a dictionary mapping file extensions to Pygments
                languages (for example: a ``.pro`` file will be autodetected as
                Prolog, but you might want to map that to ``none`` for Qt
                project files).

        """
        assert index_filename
        assert project_root_dir
        assert autodoc_rst_root_dir
        assert isinstance(toctree_maxdepth, int)
        assert isinstance(method, AutodocMethod)

        self.index_filename = abspath(expanduser(index_filename))
        self.title = title
        self.introductory_rst = introductory_rst
        self.project_root_dir = abspath(expanduser(project_root_dir))
        self.autodoc_rst_root_dir = abspath(expanduser(autodoc_rst_root_dir))
        self.highest_code_dir = abspath(expanduser(highest_code_dir))
        self.python_package_root_dir = (
            abspath(expanduser(python_package_root_dir))
            if python_package_root_dir else self.project_root_dir
        )
        self.index_heading_underline_char = index_heading_underline_char
        self.source_rst_heading_underline_char = source_rst_heading_underline_char  # noqa
        self.recursive = recursive
        self.skip_globs = skip_globs if skip_globs is not None else DEFAULT_SKIP_GLOBS  # noqa
        self.toctree_maxdepth = toctree_maxdepth
        self.method = method
        self.rst_prefix = rst_prefix
        self.rst_suffix = rst_suffix
        self.source_rst_title_style_python = source_rst_title_style_python
        self.pygments_language_override = pygments_language_override or {}  # type: Dict[str, str]  # noqa

        assert isdir(self.project_root_dir), (
            f"Not a directory: project_root_dir={self.project_root_dir!r}")
        assert relative_filename_within_dir(
            filename=self.index_filename,
            directory=self.project_root_dir
        ), (
            f"Index file {self.index_filename!r} is not within "
            f"project directory {self.project_root_dir!r}"
        )
        assert relative_filename_within_dir(
            filename=self.highest_code_dir,
            directory=self.project_root_dir
        ), (
            f"Highest code directory {self.highest_code_dir!r} is not within "
            f"project directory {self.project_root_dir!r}"
        )
        assert relative_filename_within_dir(
            filename=self.autodoc_rst_root_dir,
            directory=self.project_root_dir
        ), (
            f"Autodoc RST root directory {self.autodoc_rst_root_dir!r} is not "
            f"within project directory {self.project_root_dir!r}"
        )
        assert isinstance(method, AutodocMethod)
        assert isinstance(recursive, bool)

        self.files_to_index = []  # type: List[Union[FileToAutodocument, AutodocIndex]]  # noqa
        if source_filenames_or_globs:
            self.add_source_files(source_filenames_or_globs)