""" Silique (https://www.silique.fr) Copyright (C) 2024-2025 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . """ from pathlib import Path from rougail.utils import load_modules from .i18n import _ ROUGAIL_VARIABLE_TYPE = ( "https://rougail.readthedocs.io/en/latest/variable.html#variables-types" ) OUTPUTS = None TABULARS = None def get_outputs_or_tabulars(type_) -> None: """Load all outputs or tabulars""" module_name = f"rougail.output_doc.{type_}" outputs = {} names = [] for path in (Path(__file__).parent / type_).iterdir(): name = path.name if not name.endswith(".py") or name.endswith("__.py"): continue module = load_modules(module_name + "." + name[:-3], str(path)) if type_ == "output": if "Formatter" not in dir(module): continue obj_class = module.Formatter elif type_ == "tabular": if "Tabular" not in dir(module): continue obj_class = module.Tabular level = obj_class.level if level in outputs: raise ImportError( _('duplicated level rougail-output-doc for {0} "{1}": {2} and {3}').format( type_, level, obj_class.name, outputs[level].name ) ) if obj_class.name in names: raise ImportError( _('duplicated name "{0}" in rougail-output-doc').format( obj_class.name ) ) names.append(obj_class.name) outputs[level] = obj_class return {outputs[level].name: outputs[level] for level in sorted(outputs)} class OutPuts: # pylint: disable=R0903 """Transformations applied on a object instance""" def __init__( self, ) -> None: global OUTPUTS if OUTPUTS is None: OUTPUTS = get_outputs_or_tabulars("output") def get(self) -> dict: """Get all outputs""" return OUTPUTS class Tabulars: # pylint: disable=R0903 """Transformations applied on a object instance""" def __init__( self, ) -> None: global TABULARS if TABULARS is None: TABULARS = get_outputs_or_tabulars("tabular") def get(self) -> dict: """Get all tabulars""" return TABULARS def get_rougail_config( *, backward_compatibility=True, # pylint: disable=unused-argument ) -> dict: """Get documentation for output_doc modules""" outputs = list(OutPuts().get()) output_format_default = outputs[0] tabulars = list(Tabulars().get()) tabular_default = tabulars[0] rougail_options = f""" cli: read_write: redefine: true exists: true default: jinja: |- {{{{ __.step.output is not propertyerror and "doc" in __.step.output }}}} description: {_('is true if doc is activate')} doc: description: {_('Generate documentation from structural files')} help: {_('The structural files contain all the information related to the variables. This output generates the documentation for all or some of these variables.')} disabled: jinja: |- {{{{ step.output is propertyerror or step.output != 'doc' }}}} return_type: boolean description: {_('if doc is not set in "step.output"')} output_format: description: {_('The output format of the generated documentation')} alternative_name: do default: { output_format_default } choices: """ for output in outputs: rougail_options += f" - {output}\n" rougail_options += f""" tabular_template: description: {_('Generate document with this tabular model')} help: {_("The variables are documented with a tabular view. A template selection allows you to choose the content of each column.")} alternative_name: dm default: { tabular_default } disabled: jinja: |- {{{{ _.output_format == 'json' }}}} return_type: boolean description: > {_('"_.output_format" in json is not compatible with this variable')} choices: """ for tabular in tabulars: rougail_options += f" - {tabular}\n" rougail_options += f""" contents: description: {_('Generated content')} help: {_('You can generate three type of document. All variables ("variables"), an example file in YAML format ("example") or change log ("changelog").')} alternative_name: dc choices: - variables - example - changelog default: - variables hidden: jinja: |- {{{{ _.output_format == 'json' }}}} return_type: boolean description: > {_('"_.output_format" in json is not compatible with changelog or example "_.contents"')} title_level: description: {_('Starting title level')} alternative_name: dt default: 1 default_values: description: {_('Modify values to document all variables')} help: {_('To document leadership or dynamic family variables, it is sometimes necessary to generate values, which can change the values in the configuration. Be careful if you reuse this configuration.')} default: true true_color: description: {_('Display documentation in console always with true color terminal')} default: false disabled: variable: _.output_format when_not: console root: description: {_('Document the child variables of the family')} help: {_('By default, all accessible variables are included in the documentation. It is possible to define the family from which the documentation should be generated.')} alternative_name: dr mandatory: false other_root_filenames: description: {_("The variables in this family are documented in another file")} help: {_("If you separate the variables into different files, the links between the variables will break. Therefore, you must define different filenames for the files containing these variables.")} type: leadership disabled: variable: _.root when: null root_path: description: {_("This file contains child variables of the family")} mandatory: false filename: description: {_("Name of the file")} type: unix_filename params: allow_relative: true types: - file tabulars: description: {_('Variables and changelog documentation')} disabled: jinja: |- {{{{ step.output is propertyerror or "doc" not in step.output or _.output_format == "json" or ("variables" not in _.contents and "changelog" not in _.contents) }}}} return_type: boolean description: {_('if "_.output_format" is json or "_.contents" hasn\'t variables or changelog')} without_family: description: {_('Do not add families in documentation')} default: false alternative_name: df with_commandline: description: {_('Add command line informations in documentation')} alternative_name: dw default: false with_environment: description: {_('Add environment variable informations in documentation')} alternative_name: de default: false environment_prefix: description: {_("Environment variables prefix name")} alternative_name: dv default: ROUGAIL validators: - jinja: |- {{{{ (_.environment_prefix | upper) != _.environment_prefix }}}} return_type: boolean description: {_("should only use uppercase characters")} disabled: jinja: |- {{{{ ___.main_namespace is not defined or ___.main_namespace == none or _.with_environment is false }}}} return_type: boolean description: {_('if "main_namespace" is not set or "_.with_environment" is false')} changelog: description: {_('Changelog documentation')} disabled: jinja: |- {{{{ step.output is propertyerror or "doc" not in step.output or _.output_format == "json" or "changelog" not in _.contents }}}} return_type: boolean description: {_('if changelog in not in "_.contents"')} previous_json_file: description: {_('Previous description file in JSON format')} help: {_('To generate the changelog, you need to compare the old list of variables (in json format) with the current variables.')} alternative_name: dp examples: description: {_('Examples configuration')} disabled: jinja: |- {{{{ step.output is propertyerror or "doc" not in step.output or "example" not in _.contents }}}} return_type: boolean description: {_('if example is not in "_.contents"')} comment: description: {_('Add description of variables and families when generate examples')} alternative_name: dx default: false comment_column: description: {_('Comment in examples starts at column')} default: 30 disabled: variable: _.comment when: false """ return { "name": "doc", "process": "output", "options": rougail_options, "allow_user_data": False, "level": 50, } __all__ = ("OutPuts", "get_rougail_config")