diff --git a/doc/Doc-License.rst b/doc/Doc-License.rst index c2595bde..ca0c2560 100644 --- a/doc/Doc-License.rst +++ b/doc/Doc-License.rst @@ -17,7 +17,7 @@ licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. -.. rubric:: Using Creative Commons Public Licenses +.. topic:: Using Creative Commons Public Licenses Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of diff --git a/sphinx_reports/CodeCoverage.py b/sphinx_reports/CodeCoverage.py index c47f3c4c..5ec6daca 100644 --- a/sphinx_reports/CodeCoverage.py +++ b/sphinx_reports/CodeCoverage.py @@ -271,7 +271,11 @@ def _CheckOptions(self) -> None: self._noBranchCoverage = "no-branch-coverage" in self.options - packageConfiguration = self._packageConfigurations[self._packageID] + try: + packageConfiguration = self._packageConfigurations[self._packageID] + except KeyError as ex: + raise ReportExtensionError(f"No configuration for '{self._packageID}'") from ex + self._packageName = packageConfiguration["name"] self._jsonReport = packageConfiguration["json_report"] self._failBelow = packageConfiguration["fail_below"] @@ -372,11 +376,11 @@ def _CreatePages(self) -> None: def handlePackage(package: PackageCoverage) -> None: for pack in package._packages.values(): if handlePackage(pack): - return True + return for module in package._modules.values(): if handleModule(module): - return True + return def handleModule(module: ModuleCoverage) -> None: doc = new_document("dummy") @@ -392,12 +396,18 @@ def handleModule(module: ModuleCoverage) -> None: self.env.titles[docname] = title self.env.longtitles[docname] = title - return True + return handlePackage(self._coverage) def run(self) -> List[nodes.Node]: - self._CheckOptions() + container = nodes.container() + + try: + self._CheckOptions() + except ReportExtensionError as ex: + message = f"Caught {ex.__class__.__name__} when checking options for directive '{self.directiveName}'." + return self._internalError(container, __name__, message, ex) # Assemble a list of Python source files analyzer = Analyzer(self._packageName, self._jsonReport) @@ -406,7 +416,6 @@ def run(self) -> List[nodes.Node]: self._CreatePages() - container = nodes.container() container += self._GenerateCoverageTable() docName = self.env.docname @@ -481,7 +490,11 @@ def _CheckOptions(self) -> None: self._style = self._ParseLegendStyle("style", LegendStyle.horizontal_table) - packageConfiguration = self._packageConfigurations[self._packageID] + try: + packageConfiguration = self._packageConfigurations[self._packageID] + except KeyError as ex: + raise ReportExtensionError(f"No configuration for '{self._packageID}'") from ex + self._levels = packageConfiguration["levels"] def _CreateHorizontalLegendTable(self, identifier: str, classes: List[str]) -> nodes.table: @@ -534,9 +547,14 @@ def _CreateVerticalLegendTable(self, identifier: str, classes: List[str]) -> nod return table def run(self) -> List[nodes.Node]: - self._CheckOptions() - container = nodes.container() + + try: + self._CheckOptions() + except ReportExtensionError as ex: + message = f"Caught {ex.__class__.__name__} when checking options for directive '{self.directiveName}'." + return self._internalError(container, __name__, message, ex) + if LegendStyle.Table in self._style: if LegendStyle.Horizontal in self._style: container += self._CreateHorizontalLegendTable(identifier=f"{self._packageID}-legend", classes=["report-codecov-legend"]) @@ -578,12 +596,22 @@ def _CheckOptions(self) -> None: self._moduleName = self._ParseStringOption("module") - packageConfiguration = self._packageConfigurations[self._packageID] + try: + packageConfiguration = self._packageConfigurations[self._packageID] + except KeyError as ex: + raise ReportExtensionError(f"No configuration for '{self._packageID}'") from ex + self._packageName = packageConfiguration["name"] self._jsonReport = packageConfiguration["json_report"] def run(self) -> List[nodes.Node]: - self._CheckOptions() + container = nodes.container() + + try: + self._CheckOptions() + except ReportExtensionError as ex: + message = f"Caught {ex.__class__.__name__} when checking options for directive '{self.directiveName}'." + return self._internalError(container, __name__, message, ex) # Assemble a list of Python source files analyzer = Analyzer(self._packageName, self._jsonReport) @@ -591,9 +619,14 @@ def run(self) -> List[nodes.Node]: sourceFile = "../../sphinx_reports/__init__.py" - container = nodes.container() container += nodes.paragraph(text=f"Code coverage of {self._moduleName}") + # lexer = get_lexer_by_name("python", tabsize=2) + # tokens = lex(code, lexer) + + # htmlFormatter = HtmlFormatter(linenos=True, cssclass="source") + # highlight() + location = self.state_machine.get_source_and_line(self.lineno) rel_filename, filename = self.env.relfn2path(sourceFile) self.env.note_dependency(rel_filename) diff --git a/sphinx_reports/DocCoverage.py b/sphinx_reports/DocCoverage.py index f0b79df6..882b9ddb 100644 --- a/sphinx_reports/DocCoverage.py +++ b/sphinx_reports/DocCoverage.py @@ -330,7 +330,13 @@ def renderlevel(tableBody: nodes.tbody, packageCoverage: PackageCoverage, level: @export class DocStrCoverage(DocCoverage): def run(self) -> List[nodes.Node]: - self._CheckOptions() + container = nodes.container() + + try: + self._CheckOptions() + except ReportExtensionError as ex: + message = f"Caught {ex.__class__.__name__} when checking options for directive '{self.directiveName}'." + return self._internalError(container, __name__, message, ex) # Assemble a list of Python source files docStrCov = DocStrCovAnalyzer(self._packageName, self._directory) @@ -339,7 +345,6 @@ def run(self) -> List[nodes.Node]: # self._coverage.CalculateCoverage() self._coverage.Aggregate() - container = nodes.container() container += self._GenerateCoverageTable() return [container] @@ -414,9 +419,14 @@ def _CreateVerticalLegendTable(self, identifier: str, classes: List[str]) -> nod return table def run(self) -> List[nodes.Node]: - self._CheckOptions() - container = nodes.container() + + try: + self._CheckOptions() + except ReportExtensionError as ex: + message = f"Caught {ex.__class__.__name__} when checking options for directive '{self.directiveName}'." + return self._internalError(container, __name__, message, ex) + if LegendStyle.Table in self._style: if LegendStyle.Horizontal in self._style: container += self._CreateHorizontalLegendTable(identifier=f"{self._packageID}-legend", classes=["report-doccov-legend"]) diff --git a/sphinx_reports/Sphinx.py b/sphinx_reports/Sphinx.py index eb81d9a1..2505f096 100644 --- a/sphinx_reports/Sphinx.py +++ b/sphinx_reports/Sphinx.py @@ -37,6 +37,7 @@ from docutils import nodes from sphinx.directives import ObjectDescription from pyTooling.Decorators import export +from sphinx.util.logging import getLogger from sphinx_reports.Common import ReportExtensionError, LegendStyle @@ -174,3 +175,11 @@ def _CreateTableHeader(self, columns: List[Tuple[str, Nullable[List[Tuple[str, i tableHeader += tableRow return table, tableGroup + + def _internalError(self, container: nodes.container, location: str, message: str, exception: Exception) -> List[nodes.Node]: + logger = getLogger(location) + logger.error(f"{message}\n {exception}") + + container += nodes.paragraph(text=message) + + return [container] diff --git a/sphinx_reports/Unittest.py b/sphinx_reports/Unittest.py index d295603c..283bcf55 100644 --- a/sphinx_reports/Unittest.py +++ b/sphinx_reports/Unittest.py @@ -42,7 +42,6 @@ from pyEDAA.Reports.Unittesting.JUnit import Testsuite, TestsuiteSummary, Testcase, Document from sphinx.application import Sphinx from sphinx.config import Config -from sphinx.util.logging import getLogger from sphinx_reports.Common import ReportExtensionError from sphinx_reports.Sphinx import strip, BaseDirective @@ -245,33 +244,35 @@ def renderTestcase(tableBody: nodes.tbody, testcase: Testcase, level: int) -> No return table def run(self) -> List[nodes.Node]: - self._CheckOptions() + container = nodes.container() + + try: + self._CheckOptions() + except ReportExtensionError as ex: + message = f"Caught {ex.__class__.__name__} when checking options for directive '{self.directiveName}'." + return self._internalError(container, __name__, message, ex) # Assemble a list of Python source files try: - doc = Document(self._xmlReport, parse=True) + doc = Document(self._xmlReport, analyzeAndConvert=True) except Exception as ex: - logger = getLogger(__name__) - logger.error(f"Caught {ex.__class__.__name__} when reading and parsing '{self._xmlReport}'.\n {ex}") - return [] + message = f"Caught {ex.__class__.__name__} when reading and parsing '{self._xmlReport}'." + return self._internalError(container, __name__, message, ex) doc.Aggregate() try: self._testsuite = doc.ToTestsuiteSummary() except Exception as ex: - logger = getLogger(__name__) - logger.error(f"Caught {ex.__class__.__name__} when converting to a TestsuiteSummary for JUnit document '{self._xmlReport}'.\n {ex}") - return [] + message = f"Caught {ex.__class__.__name__} when converting to a TestsuiteSummary for JUnit document '{self._xmlReport}'." + return self._internalError(container, __name__, message, ex) self._testsuite.Aggregate() try: - container = nodes.container() container += self._GenerateTestSummaryTable() except Exception as ex: - logger = getLogger(__name__) - logger.error(f"Caught {ex.__class__.__name__} when generating the document structure for JUnit document '{self._xmlReport}'.\n {ex}") - return [] + message = f"Caught {ex.__class__.__name__} when generating the document structure for JUnit document '{self._xmlReport}'." + return self._internalError(container, __name__, message, ex) return [container] diff --git a/sphinx_reports/__init__.py b/sphinx_reports/__init__.py index bea99b9f..6ad2ff87 100644 --- a/sphinx_reports/__init__.py +++ b/sphinx_reports/__init__.py @@ -59,6 +59,9 @@ from sphinx.environment import BuildEnvironment from pyTooling.Decorators import export from pyTooling.Common import readResourceFile +from sphinx.util.logging import getLogger + +from sphinx_reports.Common import ReportExtensionError from sphinx_reports import static as ResourcePackage @@ -173,9 +176,18 @@ def CheckConfigurationVariables(sphinxApplication: Sphinx, config: Config) -> No from sphinx_reports.DocCoverage import DocCoverageBase from sphinx_reports.Unittest import UnittestSummary - CodeCoverageBase.CheckConfiguration(sphinxApplication, config) - DocCoverageBase.CheckConfiguration(sphinxApplication, config) - UnittestSummary.CheckConfiguration(sphinxApplication, config) + checkConfigurations = ( + CodeCoverageBase.CheckConfiguration, + DocCoverageBase.CheckConfiguration, + UnittestSummary.CheckConfiguration, + ) + + for checkConfiguration in checkConfigurations: + try: + checkConfiguration(sphinxApplication, config) + except ReportExtensionError as ex: + logger = getLogger(__name__) + logger.error(f"Caught {ex.__class__.__name__} when checking configuration variables.\n {ex}") @staticmethod def AddCSSFiles(sphinxApplication: Sphinx) -> None: