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)
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
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}")
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()
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)