Source code for sphinx_reports

# ==================================================================================================================== #
#            _     _                                           _                                                       #
#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
#     |_|                                    |_|                                                                       #
# ==================================================================================================================== #
# Authors:                                                                                                             #
#   Patrick Lehmann                                                                                                    #
#                                                                                                                      #
# License:                                                                                                             #
# ==================================================================================================================== #
# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
#                                                                                                                      #
# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
# you may not use this file except in compliance with the License.                                                     #
# You may obtain a copy of the License at                                                                              #
#                                                                                                                      #
#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
#                                                                                                                      #
# Unless required by applicable law or agreed to in writing, software                                                  #
# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
# See the License for the specific language governing permissions and                                                  #
# limitations under the License.                                                                                       #
#                                                                                                                      #
# SPDX-License-Identifier: Apache-2.0                                                                                  #
# ==================================================================================================================== #
#
"""
**A Sphinx domain providing directives to add reports to the Sphinx-based documentation.**

Supported reports:

* :ref:`DOCCOV`
* :ref:`CODECOV`
* :ref:`UNITTEST`
* :ref:`DEP`

"""
__author__ =    "Patrick Lehmann"
__email__ =     "Paebbels@gmail.com"
__copyright__ = "2023-2024, Patrick Lehmann"
__license__ =   "Apache License, Version 2.0"
__version__ =   "0.6.0"
__keywords__ =  ["Python3", "Sphinx", "Extension", "Report", "doc-string", "interrogate"]

from hashlib              import md5
from pathlib              import Path
from typing               import Any, Tuple, Dict, Optional as Nullable, TypedDict, List, Callable

from docutils             import nodes
from sphinx.addnodes      import pending_xref
from sphinx.application   import Sphinx
from sphinx.builders      import Builder
from sphinx.domains       import Domain
from sphinx.environment   import BuildEnvironment
from pyTooling.Decorators import export

from .                    import static as ResourcePackage
from .Common              import ReadResourceFile


[docs] @export class ReportDomain(Domain): """ A Sphinx extension providing a ``report`` domain to integrate reports and summaries into a Sphinx-based documentation. .. rubric:: New directives: * :rst:dir:`doc-coverage` .. rubric:: New roles: * *None* .. rubric:: New indices: * *None* .. rubric:: Configuration variables All configuration variables in :file:`conf.py` are prefixed with ``report_*``: * ``report_unittest_testsuites`` * ``report_codecov_packages`` * ``report_doccov_packages`` """ name = "report" #: The name of this domain label = "rpt" #: The label of this domain dependencies: List[str] = [ ] #: A list of other extensions this domain depends on. from sphinx_reports.CodeCoverage import CodeCoverage from sphinx_reports.DocCoverage import DocStrCoverage from sphinx_reports.Unittest import UnittestSummary directives = { "code-coverage": CodeCoverage, "dependecy": DocStrCoverage, "doc-coverage": DocStrCoverage, "unittest-summary": UnittestSummary, } #: A dictionary of all directives in this domain. roles = { # "design": DesignRole, } #: A dictionary of all roles in this domain. indices = [ # LibraryIndex, ] #: A list of all indices in this domain. configValues: Dict[str, Tuple[Any, str, Any]] = { **DocStrCoverage.configValues, **CodeCoverage.configValues, **UnittestSummary.configValues, } #: A dictionary of all configuration values used by this domain. (name: (default, rebuilt, type)) initial_data = { "reports": {} } #: A dictionary of all global data fields used by this domain. @property def Reports(self) -> Dict[str, Any]: return self.data["reports"]
[docs] @staticmethod def AddCSSFiles(sphinxApplication: Sphinx) -> None: """ Call back for Sphinx ``builder-inited`` event. This callback will copy the CSS file(s) to the build directory. .. seealso:: Sphinx *builder-inited* event See https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events :param sphinxApplication: The Sphinx application. """ # Create a new static path for this extension staticDirectory = (Path(sphinxApplication.outdir) / "_report_static").resolve() staticDirectory.mkdir(exist_ok=True) sphinxApplication.config.html_static_path.append(str(staticDirectory)) # Read the CSS content from package resources and hash it cssFilename = "sphinx-reports.css" cssContent = ReadResourceFile(ResourcePackage, cssFilename) # Compute md5 hash of CSS file hash = md5(cssContent.encode("utf8")).hexdigest() # Write the CSS file into output directory cssFile = staticDirectory / f"sphinx-reports.{hash}.css" sphinxApplication.add_css_file(cssFile.name) if not cssFile.exists(): # Purge old CSS files for file in staticDirectory.glob("*.css"): file.unlink() # Write CSS content cssFile.write_text(cssContent, encoding="utf8")
[docs] @staticmethod def ReadReports(sphinxApplication: Sphinx) -> None: """ Call back for Sphinx ``builder-inited`` event. This callback will read the configuration variable ``vhdl_designs`` and parse the found VHDL source files. .. seealso:: Sphinx *builder-inited* event See https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events :param sphinxApplication: The Sphinx application. """ print(f"Callback: builder-inited -> ReadReports") print(f"[REPORT] Reading reports ...")
callbacks: Dict[str, List[Callable]] = { "builder-inited": [AddCSSFiles, ReadReports], } #: A dictionary of all `events/callbacks <https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events>`__ used by this domain.
[docs] def resolve_xref( self, env: BuildEnvironment, fromdocname: str, builder: Builder, typ: str, target: str, node: pending_xref, contnode: nodes.Element ) -> Nullable[nodes.Element]: raise NotImplementedError()
class setup_ReturnType(TypedDict): version: str env_version: int parallel_read_safe: bool parallel_write_safe: bool
[docs] @export def setup(sphinxApplication: Sphinx) -> setup_ReturnType: """ Extension setup function registering the ``report`` domain in Sphinx. It will execute these steps: * register domains, directives and roles. * connect events (register callbacks) * register configuration variables for :file:`conf.py` :param sphinxApplication: The Sphinx application. :return: Dictionary containing the extension version and some properties. """ sphinxApplication.add_domain(ReportDomain) # Register callbacks for eventName, callbacks in ReportDomain.callbacks.items(): for callback in callbacks: sphinxApplication.connect(eventName, callback) # Register configuration options supported/needed in Sphinx's 'conf.py' for configName, (configDefault, configRebuilt, configTypes) in ReportDomain.configValues.items(): sphinxApplication.add_config_value(f"{ReportDomain.name}_{configName}", configDefault, configRebuilt, configTypes) return { "version": __version__, # version of the extension "env_version": int(__version__.split(".")[0]), # version of the data structure stored in the environment 'parallel_read_safe': False, # Not yet evaluated, thus false 'parallel_write_safe': True, # Internal data structure is used read-only, thus no problems will occur by parallel writing. }