diff --git a/.project b/.project index dc36649..33d24c6 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - {{project_name}} + pychangelogfactory diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index 99f26c0..5e838b3 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,3 @@ eclipse.preferences.version=1 +encoding//src/pychangelogfactory/changelogfactory.py=utf-8 encoding/=UTF-8 diff --git a/src/pychangelogfactory/__init__.py b/src/pychangelogfactory/__init__.py index f73964f..80cc636 100644 --- a/src/pychangelogfactory/__init__.py +++ b/src/pychangelogfactory/__init__.py @@ -19,4 +19,4 @@ except PackageNotFoundError: # pragma: no cover warnings.warn("can not read __version__, assuming local test context, setting it to ?.?.?") __version__ = "?.?.?" -from .test_module import test_function +from pychangelogfactory.changelogfactory import ChangeLogFormater diff --git a/src/pychangelogfactory/changelogfactory.py b/src/pychangelogfactory/changelogfactory.py new file mode 100644 index 0000000..61cbf99 --- /dev/null +++ b/src/pychangelogfactory/changelogfactory.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# pychangelogfactory (c) by chacha +# +# pychangelogfactory is licensed under a +# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported License. +# +# You should have received a copy of the license along with this +# work. If not, see . + +"""Phasellus tellus lectus, volutpat eu dapibus ut, suscipit vel augue. + +""" + +from __future__ import annotations + +import re +from abc import ABC + +def ChangeLogFormaterRecordType(Klass:type) -> type: + ChangeLogFormater.ar_Klass.append(Klass) + return Klass + +class ChangeLogFormater(ABC): + ar_Klass:list[ChangeLogFormater] = [] + ar_LinesResult:list[ChangeLogFormater] = [] + prefix:str = '' + title:str = 'Others :' + keywords:list[str] = [] + priority:int = 0 + + def __init__(self,scope:str | None, ChangelogString:str): + self._scope = scope + self._ChangelogString = ChangelogString.strip() + + def RenderLine(self): + return self._ChangelogString.strip() + + @classmethod + def RenderLines(cls) -> str: + changelog_category: str = "" + lines = cls.GetLines() + if len(lines)>0: + changelog_category = f"#### {cls.title}\n" + for line in lines: + changelog_category = changelog_category + f"> {line.RenderLine()}" + if (scope:=line.GetScope()) != "": + changelog_category = changelog_category + f"\t*[{scope}]*" + changelog_category = changelog_category + "\n" + return changelog_category + + def GetScope(self) -> str: + return self._scope if self._scope != None else "" + + @classmethod + def Clear(cls) -> None: + ChangeLogFormater.ar_LinesResult=[] + + @classmethod + def _CheckLine(cls,content:str) -> bool: + regex=re.compile(f"^(?:-\s+)?(?:{cls.prefix})(?:\((.*)\))?(?::)(?:\s*)([^\s].+)") + return regex.match(content) + + @classmethod + def _CheckLine_keywords(cls,content:str) -> bool: + keyword_list = (cls.keywords + list((cls.prefix,))) + for _keyword in keyword_list: + if ( _keyword != "") and re.search(_keyword,content): + return True + return False + + @classmethod + def FactoryProcessLine(cls,RawChangelogLine:str) -> ChangeLogFormater: + + for Klass in sorted(ChangeLogFormater.ar_Klass,key=lambda x: x.priority): + if content:=Klass._CheckLine(RawChangelogLine): + return Klass(content.group(1),content.group(2)) + + for Klass in sorted(ChangeLogFormater.ar_Klass,key=lambda x: x.priority,reverse=True): + if content:=Klass._CheckLine_keywords(RawChangelogLine): + return Klass(None,RawChangelogLine) + + return ChangeLogFormater_others(None,RawChangelogLine) + + @classmethod + def FactoryProcessFullChangelog(cls,RawChangelogMessage:str) -> list[ChangeLogFormater]: + LinesResult=[] + for line in RawChangelogMessage.split('\n'): + if(line.strip()!=""): + LinesResult.append(cls.FactoryProcessLine(line)) + ChangeLogFormater.ar_LinesResult=LinesResult + return LinesResult + + @classmethod + def GetLinesOfType(cls,Klass:type) -> list[ChangeLogFormater]: + return [_ for _ in ChangeLogFormater.ar_LinesResult if type(_)==Klass] + + @classmethod + def GetLines(cls) -> list[ChangeLogFormater]: + return ChangeLogFormater.GetLinesOfType(cls) + + @classmethod + def RenderFullChangelog(cls) -> str: + full_changelog = "" + for Klass in ChangeLogFormater.ar_Klass: + full_changelog = full_changelog + Klass.RenderLines() + return full_changelog + +# creating category classes: '': (priority, ['',...], '
') +for RecordType, Config in { 'breaking': (20, ["break",], ':rotating_light: Breaking changes :rotating_light::'), + 'feat': (20, ["feat","new","create"], 'Features :sparkles::'), + 'fix': (10, ["issue","problem"], 'Fixes :wrench::'), + 'security': (20, ["safe","leak"], 'Security :shield::'), + 'chore': (20, ["task","refactor","build","better"], 'Chore :building_construction::'), + 'perf': (0, ["fast",], 'Performance Enhancements :rocket::'), + 'wip': (0, ["temp",], 'Work in progress changes :construction::'), + 'docs': (0, ["doc",], 'Documentations :book::'), + 'style': (30, ["beautify",], 'Style :art::'), + 'refactor': (0, [], 'Refactorings :recycle::'), + 'ci': (0, [""], 'Continuous Integration :cyclone::'), + 'test': (15, ["unittest","check"], 'Testings :vertical_traffic_light::'), + 'build': (0, ["compile","version"], 'Builds :package:') + }.items(): + name=f"ChangeLogFormater_{RecordType}" + tmp = globals()[name] = type(name, (ChangeLogFormater,),{"prefix": RecordType,"title": Config[2],"keywords":Config[1],"priority":Config[0] }) + ChangeLogFormater.ar_Klass.append(tmp) + +@ChangeLogFormaterRecordType +class ChangeLogFormater_revert(ChangeLogFormater): + prefix:str = 'revert' + title:str = 'Reverts :back::' + keywords:list[str] = ["fallback"] + priority:int = 0 + + def RenderLine(self) -> str: + return "~~"+super().RenderLine()+"~~" + +@ChangeLogFormaterRecordType +class ChangeLogFormater_others(ChangeLogFormater): + prefix:str = 'other' + title:str = 'Others :question::' + keywords:list[str] = [""] + priority:int = -20 \ No newline at end of file diff --git a/src/pychangelogfactory/test_module.py b/src/pychangelogfactory/test_module.py deleted file mode 100644 index e13b8e9..0000000 --- a/src/pychangelogfactory/test_module.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# pychangelogfactory (c) by chacha -# -# pychangelogfactory is licensed under a -# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported License. -# -# You should have received a copy of the license along with this -# work. If not, see . - -"""Phasellus tellus lectus, volutpat eu dapibus ut, suscipit vel augue. - -Tips: - Aliquam non leo vel libero sagittis viverra. Quisque lobortis nunc sit amet augue euismod laoreet. -Note: - Maecenas volutpat porttitor pretium. Aliquam suscipit quis nisi non imperdiet. -Note: - Vivamus et efficitur lorem, eget imperdiet tortor. Integer vel interdum sem. -""" - -from __future__ import annotations -from typing import TYPE_CHECKING - -if TYPE_CHECKING: # Only imports the below statements during type checking - pass - -def test_function(testvar: int) -> int: - """ A test function that return testvar+1 and print "Hello world !" - - Proin eget sapien eget ipsum efficitur mollis nec ac nibh. - - Note: - Morbi id lectus maximus, condimentum nunc eget, porta felis. In tristique velit tortor. - - Args: - testvar: any integer - - Returns: - testvar+1 - """ - print("Hello world !") - return testvar+1 diff --git a/test/test_changelogfactory.py b/test/test_changelogfactory.py new file mode 100644 index 0000000..75de808 --- /dev/null +++ b/test/test_changelogfactory.py @@ -0,0 +1,68 @@ +# pychangelogfactory (c) by chacha +# +# pychangelogfactory is licensed under a +# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported License. +# +# You should have received a copy of the license along with this +# work. If not, see . + +import unittest +from io import StringIO +from contextlib import redirect_stdout,redirect_stderr + +print(__name__) +print(__package__) + +from src import pychangelogfactory + + + +test_commitlog_1=""" +breaking: test1 +feat: test2 +chore: test3 +security: test4 +style:test5 +fix: test6 +wip: test7 +perf: test8 +refactor: test9 +ci: test10 +docs: test11 +test: test12 +build: test13 +- fix: test14 +revert: test15 +toto:un autre cas +fdsfdsfdsfsdfsdff +""" + + + + + +class Testtest_module(unittest.TestCase): + def test_simplegeneration_full(self): + pychangelogfactory.ChangeLogFormater.FactoryProcessFullChangelog(test_commitlog_1) + changelog = pychangelogfactory.ChangeLogFormater.RenderFullChangelog() + print(changelog) + self.assertIn("test1",changelog) + self.assertIn("test2",changelog) + self.assertIn("test3",changelog) + self.assertIn("test4",changelog) + self.assertIn("test5",changelog) + self.assertIn("test6",changelog) + self.assertIn("test7",changelog) + self.assertIn("test8",changelog) + self.assertIn("test9",changelog) + self.assertIn("test10",changelog) + self.assertIn("test11",changelog) + self.assertIn("test12",changelog) + self.assertIn("test13",changelog) + self.assertIn("test14",changelog) + self.assertIn("test15",changelog) + self.assertIn("un autre cas",changelog) + self.assertIn("fdsfdsfdsfsdfsdff",changelog) + + + \ No newline at end of file diff --git a/test/test_test_module.py b/test/test_test_module.py deleted file mode 100644 index 33582d3..0000000 --- a/test/test_test_module.py +++ /dev/null @@ -1,32 +0,0 @@ -# pychangelogfactory (c) by chacha -# -# pychangelogfactory is licensed under a -# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported License. -# -# You should have received a copy of the license along with this -# work. If not, see . - -import unittest -from io import StringIO -from contextlib import redirect_stdout,redirect_stderr - -print(__name__) -print(__package__) - -from src import pychangelogfactory - -class Testtest_module(unittest.TestCase): - def test_version(self): - self.assertNotEqual(pychangelogfactory.__version__,"?.?.?") - - def test_test_module(self): - - with redirect_stdout(StringIO()) as capted_stdout, redirect_stderr(StringIO()) as capted_stderr: - self.assertEqual(pychangelogfactory.test_function(41),42) - - self.assertEqual(len(capted_stderr.getvalue()),0) - self.assertEqual(capted_stdout.getvalue().strip(),"Hello world !") - self.assertEqual(len(capted_stderr.getvalue()),0) - - - \ No newline at end of file