From 0279d89367cd239b34f16de7c039527e77132d67 Mon Sep 17 00:00:00 2001 From: drewcassidy Date: Fri, 16 Apr 2021 21:43:10 -0700 Subject: [PATCH] Use regex for parsing --- pyproject.toml | 21 +++--------- setup.cfg | 29 +++++++++++++++++ ya_changelog/__init__.py | 0 yaclog/__init__.py | 11 +++++++ {ya_changelog => yaclog}/changelog.py | 47 +++++++++++++-------------- 5 files changed, 68 insertions(+), 40 deletions(-) create mode 100644 setup.cfg delete mode 100644 ya_changelog/__init__.py create mode 100644 yaclog/__init__.py rename {ya_changelog => yaclog}/changelog.py (70%) diff --git a/pyproject.toml b/pyproject.toml index dc0aa7f..94eacd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,20 +1,9 @@ -[project] -name = "ya-changelog" -description = "Yet another changelog CLI tool." -authors = ["Andrew Cassidy"] -license = "AGPL" -readme = "README.md" -python = "^3.8" -homepage = "https://github.com/drewcassidy/yet-another-changelog" -repository = "https://github.com/drewcassidy/yet-another-changelog" - -keywords = ["changelog", "commandline"] - -dependencies = ["Click", "GitPython"] - [build-system] requires = [ "setuptools >= 35.0.2", - "setuptools_scm >= 2.0.0" + "setuptools_scm[toml] >= 3.4", + "wheel" ] -build-backend = "setuptools.build_meta" \ No newline at end of file +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..0329a80 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,29 @@ +[metadata] +# until setuptools supports PEP621, this will have to do +name = yaclog +description = Yet another changelog CLI tool. +author = Andrew Cassidy +license = AGPLv3 +license_file = LICENSE.md +long_description = file: README.md +long_description_content_type = text/markdown +url = https://github.com/drewcassidy/yet-another-changelog + +keywords = changelog, commandline, markdown +classifiers = + Development Status :: 3 - Alpha + Intended Audience :: Developers + License :: OSI Approved :: GNU Affero General Public License v3 + Operating System :: OS Independent + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Topic :: Text Processing :: Markup :: Markdown + Topic :: Software Development :: Version Control :: Git + Topic :: Utilities + +[options] +install_requires = Click; GitPython +python_requires >= 3.8 +packages = find: diff --git a/ya_changelog/__init__.py b/ya_changelog/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/yaclog/__init__.py b/yaclog/__init__.py new file mode 100644 index 0000000..cac66ac --- /dev/null +++ b/yaclog/__init__.py @@ -0,0 +1,11 @@ +import os +from yaclog.changelog import Changelog + + +def read(path: os.PathLike): + """ + Create a new Changelog object from the given path + :param path: a path to a markdown changelog file + :return: a parsed Changelog object + """ + return Changelog(path) diff --git a/ya_changelog/changelog.py b/yaclog/changelog.py similarity index 70% rename from ya_changelog/changelog.py rename to yaclog/changelog.py index 2c5ecbd..1f095b9 100644 --- a/ya_changelog/changelog.py +++ b/yaclog/changelog.py @@ -62,44 +62,43 @@ class Changelog: if line.isspace(): # skip empty lines pass - elif line.startswith('## '): - # line is a version header + elif match := re.fullmatch( + r'^##\s+(?P\S*)(?:\s+-\s+(?P\S+))?\s*?(?P.*?)\s*#*$', line): + # this is a version header in the form '## Name (- date) (tags*) (#*)' version = VersionEntry() section = '' - split = line.removeprefix('##').strip().split() - version.name, version.link, version.link_id = _strip_link(split[0]) - - if len(split) > 1: - if split[1] == '-': - split.remove('-') + version.name, version.link, version.link_id = _strip_link(match['name']) + if match['date']: try: - version.date = datetime.date.fromisoformat(split[1].strip(string.punctuation)) + version.date = datetime.date.fromisoformat(match['date'].strip(string.punctuation)) except ValueError: version.date = None - version.tags = [s.strip(brackets) for s in split[2:]] + if match['extra']: + version.tags = [s.strip('[]') for s in re.findall(r'\[.*?]', match['extra'])] + self.versions.append(version) - elif line.startswith('### '): - # line is a version section header - section = line.removeprefix('###').strip().title() + elif match := re.fullmatch(r'###\s+(\S*?)(\s+#*)?', line): + # this is a version section header in the form '### Name' or '### Name ###' + section = match[1].title() if section not in version.sections.keys(): version.sections[section] = [] + elif match := re.fullmatch(r'\[(\S*)]:\s*(\S*)\n', line): + # this is a link definition in the form '[id]: link', so add it to the link table + self.links[match[1].lower()] = match[2] + + elif line[0] in bullets or last_line.isspace(): + # bullet point or new paragraph + # bullet points are preserved since some people like to use '+', '-' or '*' for different things + version.sections[section].append(line.strip()) + else: - # line is an entry - if match := re.fullmatch(r'\[(.*)]:\s*(.*)\n', line): - # this is a link, so a it to the link table - self.links[match[1].lower()] = match[2] - elif line[0] in bullets or last_line.isspace(): - # bullet point or new paragraph - # bullet points are preserved since some people like to use '+', '-' or '*' for different things - version.sections[section].append(line.strip()) - else: - # not a bullet point, and no whitespace on last line, so append to the last entry - version.sections[section][-1] += '\n' + line.strip() + # not a bullet point, and no whitespace on last line, so append to the last entry + version.sections[section][-1] += '\n' + line.strip() last_line = line line = fp.readline()