rougail-output-doc/src/rougail/output_doc/changelog.py

174 lines
7.1 KiB
Python

"""
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 <http://www.gnu.org/licenses/>.
"""
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