""" Silique (https://www.silique.fr) Copyright (C) 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 json import loads from .config import OutPuts from .i18n import _ from .utils import calc_path class Changelog: # pylint: disable=no-member,too-few-public-methods """Build changelog""" def gen_doc_changelog(self): """Return changelog""" with Path(self.previous_json_file).open() as outfh: previous_doc = loads(outfh.read()) self.load() self._added_variables = [] self._modified_variables = [] self._removed_variables = [] self.parser(previous_doc, self.informations) return self.display() def parser(self, previous_families, new_families): def add(new): self.formater.variable_to_string(new, self._added_variables) def remove(previous): self._removed_variables.append(previous) done = [] for element in list(previous_families) + list(new_families): if element in done: continue done.append(element) previous = previous_families.get(element) new = new_families.get(element) if not previous: if new["type"] == "variable": add(new) else: self.parser({}, new["children"]) elif not new: if previous["type"] == "variable": if "identifiers" in previous: for identifiers in previous["identifiers"]: remove(calc_path(previous["path"], self.formater, identifiers)) else: remove(calc_path(previous["path"], self.formater)) else: self.parser(previous["children"], {}) elif previous["type"] != new["type"]: if previous["type"] == "variable": if "identifiers" in previous: for identifiers in previous["identifiers"]: remove(calc_path(previous["path"], self.formater, identifiers)) else: remove(calc_path(previous["path"], self.formater)) self.parser({}, new["children"]) else: add(new) self.parser(previous["children"], {}) elif previous["type"] != "variable": self.parser(previous["children"], new["children"]) else: modified_attributes = {} for prop in set(previous) | set(new): prop_previous = previous.get(prop, []) prop_new = new.get(prop, []) if prop_previous != prop_new: name = None if ( isinstance(prop_previous, dict) and "values" in prop_previous ): name = prop_previous["name"] local_prop_previous = prop_previous = prop_previous[ "values" ] if not isinstance(prop_previous, list): if prop == "default": local_prop_previous = [prop_previous] else: local_prop_previous = prop_previous = [ prop_previous ] else: local_prop_previous = prop_previous if isinstance(prop_new, dict) and "values" in prop_new: name = prop_new["name"] prop_new = prop_new["values"] if not isinstance(prop_new, list): prop_new = [prop_new] if isinstance(prop_new, list): prop_new = prop_new.copy() else: prop_new = [prop_new] if isinstance(prop_previous, list): prop_previous = [ p for p in prop_previous if p not in prop_new ] elif prop_previous in prop_new: prop_new.remove(prop_previous) prop_previous = [] prop_new = [p for p in prop_new if p not in local_prop_previous] if prop_previous not in [None, []] or prop_new not in [ None, [], ]: modified_attributes[prop] = (name, prop_previous, prop_new) if not modified_attributes: continue self.formater.variable_to_string( new, self._modified_variables, modified_attributes ) def display(self) -> str: msg = "" if self._added_variables: if len(self._added_variables) == 1: title = _("New variable") else: title = _("New variables") msg += self.formater.run( [ self.formater.title(title, self.level), self.formater.table(self._added_variables), ], self.level, dico_is_already_treated=True, ) if self._modified_variables: if len(self._modified_variables) == 1: title = _("Modified variable") else: title = _("Modified variables") msg += self.formater.run( [ self.formater.title(title, self.level), self.formater.table(self._modified_variables), ], self.level, dico_is_already_treated=True, ) if self._removed_variables: if len(self._removed_variables) == 1: title = _("Deleted variable") else: title = _("Deleted variables") msg += self.formater.run( [ self.formater.title(title, self.level), self.formater.list(self._removed_variables), ], self.level, dico_is_already_treated=True, ) return msg