From 57d2b9361952953956a0c558e8e453bf1cfac20b Mon Sep 17 00:00:00 2001 From: Stanislav Pankevich Date: Sun, 5 Oct 2025 00:27:41 +0200 Subject: [PATCH] feat(project_config): add a new option for reading configuration from a Python file instead of TOML Configuring StrictDoc with a Python file provides more flexibility when a user has to: - Create custom generators - Remove the existing generators - Customize requirement and document tree validations - Customize project statistics When the Python config feature becomes stable, the TOML config will be deprecated and removed from StrictDoc after some time. --- .link_health.yml | 1 + strictdoc.toml | 78 ------- strictdoc/cli/main.py | 6 - strictdoc/core/project_config.py | 220 ++++++++++-------- strictdoc/helpers/module.py | 17 ++ strictdoc_config.py | 73 ++++++ tests/end2end/__init__.py | 2 +- .../export_questionnaires.py | 4 +- tests/unit/conftest.py | 5 +- tests/unit/helpers/document_builder.py | 5 +- .../test_junit_xml_reader_ctest.py | 9 +- .../strictdoc/core/test_project_config.py | 37 +-- .../transforms/test_update_requirement.py | 13 +- .../rst/directives/test_raw_html_role.py | 3 +- .../rst/test_rst_to_html_fragment_writer.py | 13 +- .../server/01_hello_world/test_case.py | 5 +- .../02_export_document_to_reqif/test_case.py | 5 +- .../test_case.py | 5 +- .../test_case.py | 5 +- .../test_case.py | 5 +- .../server/10_redirect_to_uid/test_case.py | 5 +- .../server/20_feature_diff/test_case.py | 2 - tools/confluence_html_table_import.py | 3 +- tools/ecss/import_ecss_earm_excel.py | 3 +- 24 files changed, 249 insertions(+), 275 deletions(-) delete mode 100644 strictdoc.toml create mode 100644 strictdoc/helpers/module.py create mode 100644 strictdoc_config.py diff --git a/.link_health.yml b/.link_health.yml index 5f6908922..ded694cbe 100644 --- a/.link_health.yml +++ b/.link_health.yml @@ -32,3 +32,4 @@ exceptions: - url: https://github.com/tree-sitter/tree-sitter/blob/master/LICENSE - url: https://github.com/doorstop-dev/doorstop/blob/804153c67c7c5466ee94e9553118cc3df03a56f9/reqs/REQ001.yml - url: https://github.com/tiangolo/fastapi/blob/master/LICENSE + - url: https://github.com/strictdoc-project/strictdoc/blob/main/about/2025_ESA_SW_Product_Assurance_Workshop.pdf diff --git a/strictdoc.toml b/strictdoc.toml deleted file mode 100644 index fd8f0ffcf..000000000 --- a/strictdoc.toml +++ /dev/null @@ -1,78 +0,0 @@ -[project] -title = "StrictDoc Documentation" - -html_assets_strictdoc_dir = "assets" -cache_dir = "./output/_cache" - -section_behavior = "[[SECTION]]" - -features = [ - # Stable features. - "TABLE_SCREEN", - "TRACEABILITY_SCREEN", - "DEEP_TRACEABILITY_SCREEN", - "SEARCH", - - # Stable features but not used by StrictDoc. - # "MATHJAX" - - # Experimental features. - "PROJECT_STATISTICS_SCREEN", - "TREE_MAP_SCREEN", - - # "REQIF", - # "STANDALONE_DOCUMENT_SCREEN", - "TRACEABILITY_MATRIX_SCREEN", - "REQUIREMENT_TO_SOURCE_TRACEABILITY", - "SOURCE_FILE_LANGUAGE_PARSERS", - "HTML2PDF", - "DIFF", - "NESTOR", -] - -include_doc_paths = [ - "docs/**", - "docs_extra/**", - "reports/**", -] - -exclude_doc_paths = [ - "docs/sphinx/**", - "build/**", - "tests/**", -] - -include_source_paths = [ - "strictdoc/**.py", - "strictdoc/**.js", - "strictdoc/**.jinja.rst", - "tests/integration/**itest", - "tests/unit/**.py", - "tests/unit_server/**.py", - "tests/end2end/**.py", - "tasks.py", - "pyproject.toml", -] - -exclude_source_paths = [ - # StrictDoc (almost never) uses __init__ files. - # The used files will be whitelisted include_source_paths. - "**__init__.py", - "**.test.py", - "build/**", - "output/**", - "tests/unit/*.py", - "tests/unit/helpers/*.py", - "tests/integration/**ignored.itest", - "tests/end2end/*.py", - "tests/end2end/helpers/*.py", -] - -test_report_root_dict = [ - { "reports/tests_integration.lit.junit.xml" = "tests/integration" }, - { "reports/tests_integration_html2pdf.lit.junit.xml" = "tests/integration" }, -] - -html2pdf_strict = true - -statistics_generator = "docs.sdoc_project_statistics.SDocStatisticsGenerator" diff --git a/strictdoc/cli/main.py b/strictdoc/cli/main.py index 47e4e60a7..ce1688037 100644 --- a/strictdoc/cli/main.py +++ b/strictdoc/cli/main.py @@ -62,7 +62,6 @@ def _main(parallelizer: Parallelizer, parser: SDocArgsParser) -> None: raise exception_ project_config = ProjectConfigLoader.load_from_path_or_get_default( path_to_config=export_config.get_path_to_config(), - environment=environment, ) project_config.integrate_export_config(export_config) @@ -86,7 +85,6 @@ def _main(parallelizer: Parallelizer, parser: SDocArgsParser) -> None: raise exception_ project_config = ProjectConfigLoader.load_from_path_or_get_default( path_to_config=server_config.get_path_to_config(), - environment=environment, ) run_strictdoc_server( server_config=server_config, project_config=project_config @@ -95,7 +93,6 @@ def _main(parallelizer: Parallelizer, parser: SDocArgsParser) -> None: elif parser.is_import_command_reqif: project_config = ProjectConfigLoader.load_from_path_or_get_default( path_to_config=os.getcwd(), - environment=environment, ) import_reqif_config: ImportReqIFCommandConfig = ( parser.get_import_config_reqif(environment.path_to_strictdoc) @@ -106,7 +103,6 @@ def _main(parallelizer: Parallelizer, parser: SDocArgsParser) -> None: elif parser.is_import_command_excel: project_config = ProjectConfigLoader.load_from_path_or_get_default( path_to_config=os.getcwd(), - environment=environment, ) import_excel_config: ImportExcelCommandConfig = ( parser.get_import_config_excel(environment.path_to_strictdoc) @@ -125,7 +121,6 @@ def _main(parallelizer: Parallelizer, parser: SDocArgsParser) -> None: project_config = ProjectConfigLoader.load_from_path_or_get_default( path_to_config=manage_config.get_path_to_config(), - environment=environment, ) # FIXME: This must be improved. project_config.input_paths = [manage_config.input_path] @@ -153,7 +148,6 @@ def _main(parallelizer: Parallelizer, parser: SDocArgsParser) -> None: diff_config: DiffCommandConfig = parser.get_diff_config() project_config = ProjectConfigLoader.load_from_path_or_get_default( path_to_config=os.getcwd(), - environment=environment, ) DiffCommand.execute( project_config=project_config, diff_config=diff_config diff --git a/strictdoc/core/project_config.py b/strictdoc/core/project_config.py index ddc5190cc..9717c63c6 100644 --- a/strictdoc/core/project_config.py +++ b/strictdoc/core/project_config.py @@ -3,12 +3,13 @@ import re import sys import tempfile +import types from enum import Enum from typing import Any, Dict, List, Optional, Tuple import toml -from strictdoc import __version__ +from strictdoc import __version__, environment from strictdoc.backend.reqif.sdoc_reqif_fields import ReqIFProfile from strictdoc.backend.sdoc.constants import SDocMarkup from strictdoc.cli.cli_arg_parser import ( @@ -20,6 +21,7 @@ from strictdoc.helpers.exception import StrictDocException from strictdoc.helpers.file_modification_time import get_file_modification_time from strictdoc.helpers.md5 import get_md5 +from strictdoc.helpers.module import import_from_path from strictdoc.helpers.net import is_valid_host from strictdoc.helpers.path_filter import validate_mask @@ -64,8 +66,7 @@ def all() -> List[str]: # noqa: A003 return list(map(lambda c: c.value, ProjectFeature)) -@auto_described -class ProjectConfig: +class ProjectConfigDefault: DEFAULT_PROJECT_TITLE = "Untitled Project" DEFAULT_DIR_FOR_SDOC_ASSETS = "_static" DEFAULT_DIR_FOR_SDOC_CACHE = "output/_cache" @@ -82,43 +83,50 @@ class ProjectConfig: DEFAULT_BUNDLE_DOCUMENT_COMMIT_DATE = "@GIT_COMMIT_DATETIME" DEFAULT_SECTION_BEHAVIOR = "[SECTION]" + +@auto_described +class ProjectConfig: def __init__( self, - environment: SDocRuntimeEnvironment, - project_title: str, - dir_for_sdoc_assets: str, - dir_for_sdoc_cache: str, - project_features: List[str], - server_host: str, - server_port: int, - include_doc_paths: List[str], - exclude_doc_paths: List[str], - source_root_path: Optional[str], - include_source_paths: List[str], - exclude_source_paths: List[str], - test_report_root_dict: Dict[str, str], - source_nodes: List[Dict[str, str]], - html2pdf_strict: bool, - html2pdf_template: Optional[str], - bundle_document_version: Optional[str], - bundle_document_date: Optional[str], + project_title: str = ProjectConfigDefault.DEFAULT_PROJECT_TITLE, + dir_for_sdoc_assets: str = ProjectConfigDefault.DEFAULT_DIR_FOR_SDOC_ASSETS, + dir_for_sdoc_cache: str = ProjectConfigDefault.DEFAULT_DIR_FOR_SDOC_CACHE, + project_features: Optional[List[str]] = None, + server_host: str = ProjectConfigDefault.DEFAULT_SERVER_HOST, + server_port: int = ProjectConfigDefault.DEFAULT_SERVER_PORT, + include_doc_paths: Optional[List[str]] = None, + exclude_doc_paths: Optional[List[str]] = None, + source_root_path: Optional[str] = None, + include_source_paths: Optional[List[str]] = None, + exclude_source_paths: Optional[List[str]] = None, + test_report_root_dict: Optional[Dict[str, str]] = None, + source_nodes: Optional[List[Dict[str, str]]] = None, + html2pdf_strict: bool = False, + html2pdf_template: Optional[str] = None, + bundle_document_version: Optional[ + str + ] = ProjectConfigDefault.DEFAULT_BUNDLE_DOCUMENT_VERSION, + bundle_document_date: Optional[ + str + ] = ProjectConfigDefault.DEFAULT_BUNDLE_DOCUMENT_COMMIT_DATE, traceability_matrix_relation_columns: Optional[ List[Tuple[str, Optional[str]]] - ], - reqif_profile: str, - reqif_multiline_is_xhtml: bool, - reqif_enable_mid: bool, - reqif_import_markup: Optional[str], - config_last_update: Optional[datetime.datetime], - chromedriver: Optional[str], - section_behavior: Optional[str], - statistics_generator: Optional[str], + ] = None, + reqif_profile: str = ReqIFProfile.P01_SDOC, + # FIXME: Change to true by default. + reqif_multiline_is_xhtml: bool = False, + # FIXME: Change to true by default. + reqif_enable_mid: bool = False, + reqif_import_markup: Optional[str] = None, + chromedriver: Optional[str] = None, + # FIXME: The section_behavior field will be removed by the end of 2025-Q4. + section_behavior: Optional[ + str + ] = ProjectConfigDefault.DEFAULT_SECTION_BEHAVIOR, + statistics_generator: Optional[str] = None, + # Reserved for StrictDoc's internal use. + _config_last_update: Optional[datetime.datetime] = None, ) -> None: - assert isinstance(environment, SDocRuntimeEnvironment) - if source_root_path is not None: - assert os.path.isdir(source_root_path), source_root_path - assert os.path.isabs(source_root_path), source_root_path - self.environment: SDocRuntimeEnvironment = environment # Settings obtained from the strictdoc.toml config file. @@ -145,16 +153,37 @@ def __init__( self.dir_for_sdoc_cache: str = dir_for_sdoc_cache - self.project_features: List[str] = project_features + self.project_features: List[str] = ( + project_features + if project_features is not None + else ProjectConfigDefault.DEFAULT_FEATURES + ) self.server_host: str = server_host self.server_port: int = server_port - self.include_doc_paths: List[str] = include_doc_paths - self.exclude_doc_paths: List[str] = exclude_doc_paths + self.include_doc_paths: List[str] = ( + include_doc_paths if include_doc_paths is not None else [] + ) + self.exclude_doc_paths: List[str] = ( + exclude_doc_paths if exclude_doc_paths is not None else [] + ) + + if source_root_path is not None: + assert os.path.isdir(source_root_path), source_root_path + assert os.path.isabs(source_root_path), source_root_path self.source_root_path: Optional[str] = source_root_path - self.include_source_paths: List[str] = include_source_paths - self.exclude_source_paths: List[str] = exclude_source_paths - self.test_report_root_dict: Dict[str, str] = test_report_root_dict - self.source_nodes: List[Dict[str, str]] = source_nodes + + self.include_source_paths: List[str] = ( + include_source_paths if include_source_paths is not None else [] + ) + self.exclude_source_paths: List[str] = ( + exclude_source_paths if exclude_source_paths is not None else [] + ) + self.test_report_root_dict: Dict[str, str] = ( + test_report_root_dict if test_report_root_dict is not None else {} + ) + self.source_nodes: List[Dict[str, str]] = ( + source_nodes if source_nodes is not None else [] + ) # Settings derived from the command-line parameters. @@ -201,48 +230,20 @@ def __init__( self.auto_uid_mode = False self.autouuid_include_sections: bool = False - self.config_last_update: Optional[datetime.datetime] = ( - config_last_update - ) - self.is_running_on_server: bool = False self.view: Optional[str] = None self.chromedriver: Optional[str] = chromedriver self.section_behavior: Optional[str] = section_behavior self.statistics_generator: Optional[str] = statistics_generator - @staticmethod - def default_config(environment: SDocRuntimeEnvironment) -> "ProjectConfig": - assert isinstance(environment, SDocRuntimeEnvironment) - return ProjectConfig( - environment=environment, - project_title=ProjectConfig.DEFAULT_PROJECT_TITLE, - dir_for_sdoc_assets=ProjectConfig.DEFAULT_DIR_FOR_SDOC_ASSETS, - dir_for_sdoc_cache=ProjectConfig.DEFAULT_DIR_FOR_SDOC_CACHE, - project_features=ProjectConfig.DEFAULT_FEATURES, - server_host=ProjectConfig.DEFAULT_SERVER_HOST, - server_port=ProjectConfig.DEFAULT_SERVER_PORT, - include_doc_paths=[], - exclude_doc_paths=[], - source_root_path=None, - include_source_paths=[], - exclude_source_paths=[], - test_report_root_dict={}, - source_nodes=[], - html2pdf_strict=False, - html2pdf_template=None, - bundle_document_version=ProjectConfig.DEFAULT_BUNDLE_DOCUMENT_VERSION, - bundle_document_date=ProjectConfig.DEFAULT_BUNDLE_DOCUMENT_COMMIT_DATE, - traceability_matrix_relation_columns=None, - reqif_profile=ReqIFProfile.P01_SDOC, - reqif_multiline_is_xhtml=False, - reqif_enable_mid=False, - reqif_import_markup=None, - config_last_update=None, - chromedriver=None, - section_behavior=ProjectConfig.DEFAULT_SECTION_BEHAVIOR, - statistics_generator=None, + self.config_last_update: Optional[datetime.datetime] = ( + _config_last_update ) + self.is_running_on_server: bool = False + + @staticmethod + def default_config() -> "ProjectConfig": + return ProjectConfig() # Some server command settings can override the project config settings. def integrate_server_config( @@ -269,7 +270,7 @@ def integrate_server_config( # If a custom cache folder is not specified in the config, adjust the # cache folder to be located in the output folder. if self.dir_for_sdoc_cache.startswith( - ProjectConfig.DEFAULT_DIR_FOR_SDOC_CACHE + ProjectConfigDefault.DEFAULT_DIR_FOR_SDOC_CACHE ): self.dir_for_sdoc_cache = os.path.join( output_dir_, "_cache", __version__ @@ -308,7 +309,7 @@ def integrate_export_config( # If a custom cache folder is not specified in the config, adjust the # cache folder to be located in the output folder. if self.dir_for_sdoc_cache.startswith( - ProjectConfig.DEFAULT_DIR_FOR_SDOC_CACHE + ProjectConfigDefault.DEFAULT_DIR_FOR_SDOC_CACHE ): self.dir_for_sdoc_cache = os.path.join( output_dir, "_cache", __version__ @@ -444,14 +445,24 @@ class ProjectConfigLoader: def load_from_path_or_get_default( *, path_to_config: str, - environment: SDocRuntimeEnvironment, ) -> ProjectConfig: if not os.path.exists(path_to_config): - return ProjectConfig.default_config(environment=environment) + return ProjectConfig.default_config() if os.path.isdir(path_to_config): - path_to_config = os.path.join(path_to_config, "strictdoc.toml") + path_to_config_dir = path_to_config + path_to_config = os.path.join(path_to_config_dir, "strictdoc.toml") + if not os.path.isfile(path_to_config): + path_to_config = os.path.join( + path_to_config_dir, "strictdoc_config.py" + ) + if not os.path.isfile(path_to_config): - return ProjectConfig.default_config(environment=environment) + return ProjectConfig.default_config() + + if path_to_config.endswith("strictdoc_config.py"): + return ProjectConfigLoader.load_from_python( + config_py_path=path_to_config + ) try: config_content = toml.load(path_to_config) @@ -467,19 +478,26 @@ def load_from_path_or_get_default( return ProjectConfigLoader._load_from_dictionary( config_dict=config_content, - environment=environment, config_last_update=config_last_update, path_to_config=path_to_config, ) @staticmethod - def load_from_string( - *, toml_string: str, environment: SDocRuntimeEnvironment - ) -> ProjectConfig: + def load_from_python(*, config_py_path: str) -> ProjectConfig: + module = import_from_path(config_py_path) + create_config_function = module.create_config + assert isinstance(create_config_function, types.FunctionType), type( + create_config_function + ) + project_config = create_config_function() + assert isinstance(project_config, ProjectConfig) + return project_config + + @staticmethod + def load_from_string(*, toml_string: str) -> ProjectConfig: config_dict = toml.loads(toml_string) return ProjectConfigLoader._load_from_dictionary( config_dict=config_dict, - environment=environment, config_last_update=None, path_to_config=None, ) @@ -488,7 +506,6 @@ def load_from_string( def _load_from_dictionary( *, config_dict: Dict[str, Any], - environment: SDocRuntimeEnvironment, config_last_update: Optional[datetime.datetime], path_to_config: Optional[str], ) -> ProjectConfig: @@ -496,12 +513,12 @@ def _load_from_dictionary( assert os.path.isfile(path_to_config), path_to_config path_to_config = os.path.abspath(path_to_config) - project_title = ProjectConfig.DEFAULT_PROJECT_TITLE - dir_for_sdoc_assets = ProjectConfig.DEFAULT_DIR_FOR_SDOC_ASSETS - dir_for_sdoc_cache = ProjectConfig.DEFAULT_DIR_FOR_SDOC_CACHE - project_features = ProjectConfig.DEFAULT_FEATURES - server_host = ProjectConfig.DEFAULT_SERVER_HOST - server_port = ProjectConfig.DEFAULT_SERVER_PORT + project_title = ProjectConfigDefault.DEFAULT_PROJECT_TITLE + dir_for_sdoc_assets = ProjectConfigDefault.DEFAULT_DIR_FOR_SDOC_ASSETS + dir_for_sdoc_cache = ProjectConfigDefault.DEFAULT_DIR_FOR_SDOC_CACHE + project_features = ProjectConfigDefault.DEFAULT_FEATURES + server_host = ProjectConfigDefault.DEFAULT_SERVER_HOST + server_port = ProjectConfigDefault.DEFAULT_SERVER_PORT include_doc_paths: List[str] = [] exclude_doc_paths: List[str] = [] source_root_path = None @@ -511,8 +528,12 @@ def _load_from_dictionary( source_nodes: List[Dict[str, str]] = [] html2pdf_strict: bool = False html2pdf_template: Optional[str] = None - bundle_document_version = ProjectConfig.DEFAULT_BUNDLE_DOCUMENT_VERSION - bundle_document_date = ProjectConfig.DEFAULT_BUNDLE_DOCUMENT_COMMIT_DATE + bundle_document_version = ( + ProjectConfigDefault.DEFAULT_BUNDLE_DOCUMENT_VERSION + ) + bundle_document_date = ( + ProjectConfigDefault.DEFAULT_BUNDLE_DOCUMENT_COMMIT_DATE + ) traceability_matrix_relation_columns: Optional[ List[Tuple[str, Optional[str]]] @@ -523,7 +544,7 @@ def _load_from_dictionary( reqif_import_markup: Optional[str] = None chromedriver: Optional[str] = None - section_behavior: str = ProjectConfig.DEFAULT_SECTION_BEHAVIOR + section_behavior: str = ProjectConfigDefault.DEFAULT_SECTION_BEHAVIOR statistics_generator: Optional[str] = None if "project" in config_dict: @@ -758,7 +779,6 @@ def _load_from_dictionary( ) return ProjectConfig( - environment=environment, project_title=project_title, dir_for_sdoc_assets=dir_for_sdoc_assets, dir_for_sdoc_cache=dir_for_sdoc_cache, @@ -781,8 +801,8 @@ def _load_from_dictionary( reqif_multiline_is_xhtml=reqif_multiline_is_xhtml, reqif_enable_mid=reqif_enable_mid, reqif_import_markup=reqif_import_markup, - config_last_update=config_last_update, chromedriver=chromedriver, section_behavior=section_behavior, statistics_generator=statistics_generator, + _config_last_update=config_last_update, ) diff --git a/strictdoc/helpers/module.py b/strictdoc/helpers/module.py new file mode 100644 index 000000000..d36b7eee4 --- /dev/null +++ b/strictdoc/helpers/module.py @@ -0,0 +1,17 @@ +import importlib.util +import sys +import types +from pathlib import Path +from typing import Union + + +def import_from_path(path: Union[str, Path]) -> types.ModuleType: + path = Path(path) + module_name = path.stem + spec = importlib.util.spec_from_file_location(module_name, path) + if spec is None or spec.loader is None: + raise ImportError(f"Cannot load module from {path}") + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + spec.loader.exec_module(module) + return module diff --git a/strictdoc_config.py b/strictdoc_config.py new file mode 100644 index 000000000..a6124d7b5 --- /dev/null +++ b/strictdoc_config.py @@ -0,0 +1,73 @@ +from strictdoc.core.project_config import ProjectConfig + + +def create_config() -> ProjectConfig: + config = ProjectConfig( + project_title="StrictDoc Documentation", + dir_for_sdoc_assets="assets", + dir_for_sdoc_cache="output/_cache", + project_features=[ + # Stable features. + "TABLE_SCREEN", + "TRACEABILITY_SCREEN", + "DEEP_TRACEABILITY_SCREEN", + "SEARCH", + # Stable features but not used by StrictDoc. + # "MATHJAX" + # Experimental features. + "PROJECT_STATISTICS_SCREEN", + "TREE_MAP_SCREEN", + # "REQIF", + # "STANDALONE_DOCUMENT_SCREEN", + "TRACEABILITY_MATRIX_SCREEN", + "REQUIREMENT_TO_SOURCE_TRACEABILITY", + "SOURCE_FILE_LANGUAGE_PARSERS", + "HTML2PDF", + "DIFF", + "NESTOR", + ], + include_doc_paths=[ + "docs/**", + "docs_extra/**", + "reports/**", + ], + exclude_doc_paths=[ + "docs/sphinx/**", + "build/**", + "tests/**", + ], + include_source_paths=[ + "strictdoc/**.py", + "strictdoc/**.js", + "strictdoc/**.jinja.rst", + "tests/integration/**itest", + "tests/unit/**.py", + "tests/unit_server/**.py", + "tests/end2end/**.py", + "tasks.py", + "pyproject.toml", + ], + exclude_source_paths=[ + # StrictDoc (almost never) uses __init__ files. + # The used files will be whitelisted include_source_paths. + "**__init__.py", + "**.test.py", + "build/**", + "output/**", + "tests/unit/*.py", + "tests/unit/helpers/*.py", + "tests/integration/**ignored.itest", + "tests/end2end/*.py", + "tests/end2end/helpers/*.py", + ], + test_report_root_dict={ + "reports/tests_integration.lit.junit.xml": "tests/integration", + "reports/tests_integration_html2pdf.lit.junit.xml": "tests/integration", + }, + html2pdf_strict=True, + reqif_multiline_is_xhtml=True, + reqif_enable_mid=True, + section_behavior="[[SECTION]]", + statistics_generator="docs.sdoc_project_statistics.SDocStatisticsGenerator", + ) + return config diff --git a/tests/end2end/__init__.py b/tests/end2end/__init__.py index 4e2048858..1df4b49af 100644 --- a/tests/end2end/__init__.py +++ b/tests/end2end/__init__.py @@ -1 +1 @@ -# Dummy comment to trigger CI. +# Dummy comment to trigger CI diff --git a/tests/integration/scripting_examples/questionnaires/02_user_provided_example/export_questionnaires.py b/tests/integration/scripting_examples/questionnaires/02_user_provided_example/export_questionnaires.py index 577f37c94..91c68327c 100644 --- a/tests/integration/scripting_examples/questionnaires/02_user_provided_example/export_questionnaires.py +++ b/tests/integration/scripting_examples/questionnaires/02_user_provided_example/export_questionnaires.py @@ -4,7 +4,6 @@ import xlsxwriter -from strictdoc import environment from strictdoc.backend.excel.export.excel_generator import ExcelGenerator from strictdoc.backend.sdoc.errors.document_tree_error import DocumentTreeError from strictdoc.backend.sdoc.models.document import SDocDocument @@ -125,7 +124,8 @@ def find_doc(self, name): export_config: ExportCommandConfig = parser.get_export_config() project_config = ProjectConfigLoader.load_from_path_or_get_default( - path_to_config=export_config.get_path_to_config(), environment=environment) + path_to_config=export_config.get_path_to_config() + ) project_config.integrate_export_config(export_config) parallelizer = Parallelizer.create(False) diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 1e5d0251f..3a1c8ca7c 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -3,7 +3,6 @@ import pytest -from strictdoc.core.environment import SDocRuntimeEnvironment from strictdoc.core.project_config import ProjectConfig strictdoc_root_path = os.path.abspath(os.path.join(__file__, "../../..")) @@ -15,6 +14,4 @@ @pytest.fixture def default_project_config(): - return ProjectConfig.default_config( - SDocRuntimeEnvironment(strictdoc_root_path) - ) + return ProjectConfig.default_config() diff --git a/tests/unit/helpers/document_builder.py b/tests/unit/helpers/document_builder.py index 9313f8e1e..68d39ed49 100644 --- a/tests/unit/helpers/document_builder.py +++ b/tests/unit/helpers/document_builder.py @@ -2,7 +2,6 @@ import tempfile from typing import Optional -from strictdoc import environment from strictdoc.backend.sdoc.document_reference import DocumentReference from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.models.document_config import DocumentConfig @@ -21,9 +20,7 @@ class DocumentBuilder: def __init__(self, uid="DOC-1"): - self.project_config: ProjectConfig = ProjectConfig.default_config( - environment - ) + self.project_config: ProjectConfig = ProjectConfig.default_config() self.document: SDocDocument = self._create_empty_document( self.project_config, uid ) diff --git a/tests/unit/strictdoc/backend/sdoc_source_code/test_reports/test_junit_xml_reader_ctest.py b/tests/unit/strictdoc/backend/sdoc_source_code/test_reports/test_junit_xml_reader_ctest.py index a94f3263f..a2e570c9d 100644 --- a/tests/unit/strictdoc/backend/sdoc_source_code/test_reports/test_junit_xml_reader_ctest.py +++ b/tests/unit/strictdoc/backend/sdoc_source_code/test_reports/test_junit_xml_reader_ctest.py @@ -7,7 +7,6 @@ import pytest -from strictdoc import environment from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.models.node import SDocNode from strictdoc.backend.sdoc_source_code.test_reports.junit_xml_reader import ( @@ -39,9 +38,7 @@ def test_01_ctest(): """.lstrip() - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() with tempfile.NamedTemporaryFile( mode="w+", delete=True, suffix=".ctest.junit.xml" @@ -69,9 +66,7 @@ def test_01_ctest(): def test__90__error_handling__empty_xml(): source_input = "" - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() with tempfile.NamedTemporaryFile( mode="w+", delete=True, suffix=".ctest.junit.xml" diff --git a/tests/unit/strictdoc/core/test_project_config.py b/tests/unit/strictdoc/core/test_project_config.py index 7f130682d..5f1a8daca 100644 --- a/tests/unit/strictdoc/core/test_project_config.py +++ b/tests/unit/strictdoc/core/test_project_config.py @@ -1,6 +1,5 @@ import pytest -from strictdoc import environment from strictdoc.core.project_config import ( ProjectConfigLoader, ProjectFeature, @@ -14,7 +13,7 @@ def test_01_project_title(): title = "StrictDoc Documentation" """ project_config = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment + toml_string=config_string ) assert project_config.project_title == "StrictDoc Documentation" @@ -30,7 +29,7 @@ def test_02_features(): ] """ project_config = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment + toml_string=config_string ) assert project_config.project_title == "StrictDoc Documentation" assert project_config.project_features == [ @@ -82,9 +81,7 @@ def test_80_validate_include_doc_paths_mask(): """ with pytest.raises(SyntaxError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: SyntaxError = exc_info_.value assert exception.args[0] == ( @@ -104,9 +101,7 @@ def test_81_validate_exclude_doc_paths_mask(): """ with pytest.raises(SyntaxError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: SyntaxError = exc_info_.value assert exception.args[0] == ( @@ -126,9 +121,7 @@ def test_82_validate_include_source_paths_mask(): """ with pytest.raises(SyntaxError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: SyntaxError = exc_info_.value assert exception.args[0] == ( @@ -148,9 +141,7 @@ def test_83_validate_exclude_source_paths_mask(): """ with pytest.raises(SyntaxError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: SyntaxError = exc_info_.value assert exception.args[0] == ( @@ -169,9 +160,7 @@ def test_84_validate_bad_host(): """ with pytest.raises(ValueError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: ValueError = exc_info_.value assert exception.args[0] == ( @@ -189,9 +178,7 @@ def test_85_validate_bad_port(): """ with pytest.raises(ValueError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: ValueError = exc_info_.value assert exception.args[0] == ( @@ -208,9 +195,7 @@ def test_86_validate_non_existing_chrome_driver(): """ with pytest.raises(ValueError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: ValueError = exc_info_.value assert exception.args[0] == ( @@ -227,9 +212,7 @@ def test_87_validate_non_existing_html2pdf_template(): """ with pytest.raises(ValueError) as exc_info_: - _ = ProjectConfigLoader.load_from_string( - toml_string=config_string, environment=environment - ) + _ = ProjectConfigLoader.load_from_string(toml_string=config_string) exception: ValueError = exc_info_.value assert exception.args[0] == ( diff --git a/tests/unit/strictdoc/core/transforms/test_update_requirement.py b/tests/unit/strictdoc/core/transforms/test_update_requirement.py index 22437dd44..0e5ad6154 100644 --- a/tests/unit/strictdoc/core/transforms/test_update_requirement.py +++ b/tests/unit/strictdoc/core/transforms/test_update_requirement.py @@ -1,4 +1,3 @@ -from strictdoc import environment from strictdoc.backend.sdoc.models.grammar_element import ( GrammarElementRelationChild, GrammarElementRelationParent, @@ -69,7 +68,7 @@ def test_01_single_document_add_first_parent_relation_with_no_role(): node_info=UpdateNodeInfo(requirement2), context_document=document_1, traceability_index=traceability_index, - project_config=ProjectConfig.default_config(environment), + project_config=ProjectConfig.default_config(), ) update_command.perform() @@ -137,7 +136,7 @@ def test_02_single_document_add_second_parent_relation_with_role(): node_info=UpdateNodeInfo(requirement2), context_document=document_1, traceability_index=traceability_index, - project_config=ProjectConfig.default_config(environment), + project_config=ProjectConfig.default_config(), ) update_command.perform() assert len(requirement2.relations) == 1 @@ -229,7 +228,7 @@ def test_20_single_document_add_second_child_relation_with_role(): node_info=UpdateNodeInfo(requirement2), context_document=document_1, traceability_index=traceability_index, - project_config=ProjectConfig.default_config(environment), + project_config=ProjectConfig.default_config(), ) update_command.perform() @@ -314,7 +313,7 @@ def test_25_single_document_remove_child_relation(): node_info=UpdateNodeInfo(requirement2), context_document=document_1, traceability_index=traceability_index, - project_config=ProjectConfig.default_config(environment), + project_config=ProjectConfig.default_config(), ) update_command.perform() @@ -370,7 +369,7 @@ def test_26_two_documents_remove_child_relation(): traceability_index: TraceabilityIndex = ( TraceabilityIndexBuilder.create_from_document_tree( document_tree, - project_config=ProjectConfig.default_config(environment), + project_config=ProjectConfig.default_config(), ) ) traceability_index.document_tree = document_tree @@ -395,7 +394,7 @@ def test_26_two_documents_remove_child_relation(): node_info=UpdateNodeInfo(requirement2), context_document=document_1, traceability_index=traceability_index, - project_config=ProjectConfig.default_config(environment), + project_config=ProjectConfig.default_config(), ) update_command.perform() diff --git a/tests/unit/strictdoc/export/rst/directives/test_raw_html_role.py b/tests/unit/strictdoc/export/rst/directives/test_raw_html_role.py index e6a915b14..2422ac349 100644 --- a/tests/unit/strictdoc/export/rst/directives/test_raw_html_role.py +++ b/tests/unit/strictdoc/export/rst/directives/test_raw_html_role.py @@ -1,6 +1,5 @@ import os -from strictdoc import environment from strictdoc.core.project_config import ProjectConfig from strictdoc.export.rst.rst_to_html_fragment_writer import ( RstToHtmlFragmentWriter, @@ -16,7 +15,7 @@ def test_01(): :rawhtml:`LINK`\ """ - project_config = ProjectConfig.default_config(environment=environment) + project_config = ProjectConfig.default_config() html_output = RstToHtmlFragmentWriter( project_config=project_config, context_document=None ).write(rst_input, use_cache=False) diff --git a/tests/unit/strictdoc/export/rst/test_rst_to_html_fragment_writer.py b/tests/unit/strictdoc/export/rst/test_rst_to_html_fragment_writer.py index 371882bec..d1b38a00d 100644 --- a/tests/unit/strictdoc/export/rst/test_rst_to_html_fragment_writer.py +++ b/tests/unit/strictdoc/export/rst/test_rst_to_html_fragment_writer.py @@ -1,6 +1,5 @@ import os -from strictdoc import environment from strictdoc.core.project_config import ProjectConfig from strictdoc.export.rst.rst_to_html_fragment_writer import ( RstToHtmlFragmentWriter, @@ -28,7 +27,7 @@ def test_01(): - Row 2, column 3 """.lstrip() - project_config = ProjectConfig.default_config(environment=environment) + project_config = ProjectConfig.default_config() html_output = RstToHtmlFragmentWriter( context_document=None, project_config=project_config ).write(rst_input) @@ -40,7 +39,7 @@ def test_02(): - First item is a bullet point. """.lstrip() - project_config = ProjectConfig.default_config(environment=environment) + project_config = ProjectConfig.default_config() html_output = RstToHtmlFragmentWriter( context_document=None, project_config=project_config ).write(rst_input) @@ -52,7 +51,7 @@ def test_image_01(): .. image:: _assets/picture.svg """.lstrip() - project_config = ProjectConfig.default_config(environment=environment) + project_config = ProjectConfig.default_config() html_output = RstToHtmlFragmentWriter( context_document=None, project_config=project_config ).write(rst_input) @@ -83,7 +82,7 @@ def test_with_validation_01_tables(): - Row 2, column 3 """.lstrip() - project_config = ProjectConfig.default_config(environment=environment) + project_config = ProjectConfig.default_config() html_output, _ = RstToHtmlFragmentWriter( context_document=None, project_config=project_config ).write_with_validation(rst_input) @@ -98,7 +97,7 @@ def test_with_validation_02_warning_message(): --- """.lstrip() - project_config = ProjectConfig.default_config(environment=environment) + project_config = ProjectConfig.default_config() html_output, error = RstToHtmlFragmentWriter( context_document=None, project_config=project_config ).write_with_validation(rst_input) @@ -120,7 +119,7 @@ def test_with_validation_03_severe_errors(): ---- """.lstrip() - project_config = ProjectConfig.default_config(environment=environment) + project_config = ProjectConfig.default_config() html_output, error = RstToHtmlFragmentWriter( context_document=None, project_config=project_config ).write_with_validation(rst_input) diff --git a/tests/unit_server/strictdoc/server/01_hello_world/test_case.py b/tests/unit_server/strictdoc/server/01_hello_world/test_case.py index a7ed7de32..610463ac6 100644 --- a/tests/unit_server/strictdoc/server/01_hello_world/test_case.py +++ b/tests/unit_server/strictdoc/server/01_hello_world/test_case.py @@ -2,7 +2,6 @@ from fastapi.testclient import TestClient -from strictdoc import environment from strictdoc.cli.cli_arg_parser import ServerCommandConfig from strictdoc.core.project_config import ProjectConfig from strictdoc.server.app import create_app @@ -19,9 +18,7 @@ def test_get_document(): host="127.0.0.1", port=8001, ) - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() project_config.integrate_server_config(server_config) client = TestClient( create_app( diff --git a/tests/unit_server/strictdoc/server/02_export_document_to_reqif/test_case.py b/tests/unit_server/strictdoc/server/02_export_document_to_reqif/test_case.py index c44c06f27..6682cbcc8 100644 --- a/tests/unit_server/strictdoc/server/02_export_document_to_reqif/test_case.py +++ b/tests/unit_server/strictdoc/server/02_export_document_to_reqif/test_case.py @@ -4,7 +4,6 @@ from fastapi.testclient import TestClient -from strictdoc import environment from strictdoc.cli.cli_arg_parser import ServerCommandConfig from strictdoc.core.project_config import ProjectConfig, ProjectFeature from strictdoc.server.app import create_app @@ -24,9 +23,7 @@ def test_export_document_to_reqif(): host="127.0.0.1", port=8001, ) - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() project_config.project_features.append(ProjectFeature.REQIF) project_config.integrate_server_config(server_config) diff --git a/tests/unit_server/strictdoc/server/03_http_404_for_non_existing_resources/test_case.py b/tests/unit_server/strictdoc/server/03_http_404_for_non_existing_resources/test_case.py index fdd8eb693..52c0a3bf7 100644 --- a/tests/unit_server/strictdoc/server/03_http_404_for_non_existing_resources/test_case.py +++ b/tests/unit_server/strictdoc/server/03_http_404_for_non_existing_resources/test_case.py @@ -3,7 +3,6 @@ import pytest from fastapi.testclient import TestClient -from strictdoc import environment from strictdoc.cli.cli_arg_parser import ServerCommandConfig from strictdoc.core.project_config import ProjectConfig from strictdoc.server.app import create_app @@ -21,9 +20,7 @@ def project_config(): host="127.0.0.1", port=8001, ) - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() project_config.integrate_server_config(server_config) return project_config diff --git a/tests/unit_server/strictdoc/server/04_http_412_for_non_activated_features/test_case.py b/tests/unit_server/strictdoc/server/04_http_412_for_non_activated_features/test_case.py index 04a5ce175..e906c701e 100644 --- a/tests/unit_server/strictdoc/server/04_http_412_for_non_activated_features/test_case.py +++ b/tests/unit_server/strictdoc/server/04_http_412_for_non_activated_features/test_case.py @@ -3,7 +3,6 @@ import pytest from fastapi.testclient import TestClient -from strictdoc import environment from strictdoc.cli.cli_arg_parser import ServerCommandConfig from strictdoc.core.project_config import ProjectConfig from strictdoc.server.app import create_app @@ -21,9 +20,7 @@ def project_config(): host="127.0.0.1", port=8001, ) - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() project_config.integrate_server_config(server_config) return project_config diff --git a/tests/unit_server/strictdoc/server/05_http_304_non_modified_for_documents_and_assets/test_case.py b/tests/unit_server/strictdoc/server/05_http_304_non_modified_for_documents_and_assets/test_case.py index 31f2e8bd6..617ad6d1a 100644 --- a/tests/unit_server/strictdoc/server/05_http_304_non_modified_for_documents_and_assets/test_case.py +++ b/tests/unit_server/strictdoc/server/05_http_304_non_modified_for_documents_and_assets/test_case.py @@ -3,7 +3,6 @@ import pytest from fastapi.testclient import TestClient -from strictdoc import environment from strictdoc.cli.cli_arg_parser import ServerCommandConfig from strictdoc.core.project_config import ProjectConfig from strictdoc.server.app import create_app @@ -23,9 +22,7 @@ def project_config(): host="127.0.0.1", port=8001, ) - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() project_config.integrate_server_config(server_config) return project_config diff --git a/tests/unit_server/strictdoc/server/10_redirect_to_uid/test_case.py b/tests/unit_server/strictdoc/server/10_redirect_to_uid/test_case.py index de6d93aac..19eec8078 100644 --- a/tests/unit_server/strictdoc/server/10_redirect_to_uid/test_case.py +++ b/tests/unit_server/strictdoc/server/10_redirect_to_uid/test_case.py @@ -3,7 +3,6 @@ import pytest from fastapi.testclient import TestClient -from strictdoc import environment from strictdoc.cli.cli_arg_parser import ServerCommandConfig from strictdoc.core.project_config import ProjectConfig from strictdoc.server.app import create_app @@ -21,9 +20,7 @@ def project_config(): host="127.0.0.1", port=8001, ) - project_config: ProjectConfig = ProjectConfig.default_config( - environment=environment - ) + project_config: ProjectConfig = ProjectConfig.default_config() project_config.integrate_server_config(server_config) return project_config diff --git a/tests/unit_server/strictdoc/server/20_feature_diff/test_case.py b/tests/unit_server/strictdoc/server/20_feature_diff/test_case.py index d917f369d..997212456 100644 --- a/tests/unit_server/strictdoc/server/20_feature_diff/test_case.py +++ b/tests/unit_server/strictdoc/server/20_feature_diff/test_case.py @@ -3,7 +3,6 @@ import pytest from fastapi.testclient import TestClient -from strictdoc import environment from strictdoc.cli.cli_arg_parser import ServerCommandConfig from strictdoc.core.project_config import ProjectConfig, ProjectConfigLoader from strictdoc.server.app import create_app @@ -24,7 +23,6 @@ def project_config(): ) project_config: ProjectConfig = ProjectConfigLoader.load_from_path_or_get_default( path_to_config=PATH_TO_CONFIG, - environment=environment ) project_config.integrate_server_config(server_config) return project_config diff --git a/tools/confluence_html_table_import.py b/tools/confluence_html_table_import.py index f5d5cb29f..c55536c75 100644 --- a/tools/confluence_html_table_import.py +++ b/tools/confluence_html_table_import.py @@ -16,7 +16,6 @@ from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.writer import SDWriter -from strictdoc.core.environment import SDocRuntimeEnvironment from strictdoc.core.project_config import ProjectConfig @@ -193,7 +192,7 @@ def main(): sdoc = ConfluenceHTMLTableImport.import_from_file(path_to_input_html) print(sdoc) # noqa: T201 - project_config = ProjectConfig.default_config(SDocRuntimeEnvironment(__file__)) + project_config = ProjectConfig.default_config() sdoc_content = SDWriter(project_config).write(sdoc) with open("output.sdoc", "w") as output_file: output_file.write(sdoc_content) diff --git a/tools/ecss/import_ecss_earm_excel.py b/tools/ecss/import_ecss_earm_excel.py index f1482f59c..533dfb780 100644 --- a/tools/ecss/import_ecss_earm_excel.py +++ b/tools/ecss/import_ecss_earm_excel.py @@ -46,7 +46,6 @@ import openpyxl -from strictdoc import environment from strictdoc.backend.sdoc.document_reference import DocumentReference from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.models.document_config import DocumentConfig @@ -231,7 +230,7 @@ def import_from_file(path_to_excel: str, path_to_output_dir: str): ecss_document.section_contents.append(requirement_node) - project_config = ProjectConfig.default_config(environment) + project_config = ProjectConfig.default_config() ecss_output_dir = os.path.join(path_to_output_dir, "ecss") shutil.rmtree(ecss_output_dir, ignore_errors=True)