diff --git a/src/pycalver/__main__.py b/src/pycalver/__main__.py index b25a0af..e393458 100644 --- a/src/pycalver/__main__.py +++ b/src/pycalver/__main__.py @@ -71,9 +71,9 @@ def incr(old_version: str, verbose: int = 0, release: str = None) -> None: """Increment a version number for demo purposes.""" _init_logging(verbose=max(_VERBOSE, verbose)) - if release and release not in parse.VALID_RELESE_VALUES: + if release and release not in parse.VALID_RELEASE_VALUES: log.error(f"Invalid argument --release={release}") - log.error(f"Valid arguments are: {', '.join(parse.VALID_RELESE_VALUES)}") + log.error(f"Valid arguments are: {', '.join(parse.VALID_RELEASE_VALUES)}") sys.exit(1) new_version = version.incr(old_version, release=release) @@ -91,7 +91,7 @@ def _update_cfg_from_vcs(cfg: config.Config, fetch: bool) -> config.Config: log.info(f"fetching tags from remote") _vcs.fetch() - version_tags = [tag for tag in _vcs.ls_tags() if parse.PYCALVER_RE.match(tag)] + version_tags = [tag for tag in _vcs.ls_tags() if version.PYCALVER_RE.match(tag)] if version_tags: version_tags.sort(reverse=True) log.debug(f"found {len(version_tags)} tags: {version_tags[:2]}") @@ -109,8 +109,10 @@ def _update_cfg_from_vcs(cfg: config.Config, fetch: bool) -> config.Config: @cli.command() -@click.option('-v', '--verbose' , count=True , help="Control log level. -vv for debug level.") -@click.option('-f', "--fetch/--no-fetch", is_flag=True, default=True, help="Sync tags from remote origin.") +@click.option('-v', '--verbose', count=True, help="Control log level. -vv for debug level.") +@click.option( + '-f', "--fetch/--no-fetch", is_flag=True, default=True, help="Sync tags from remote origin." +) def show(verbose: int = 0, fetch: bool = True) -> None: """Show current version.""" _init_logging(verbose=max(_VERBOSE, verbose)) @@ -232,9 +234,9 @@ def bump( verbose = max(_VERBOSE, verbose) _init_logging(verbose) - if release and release not in parse.VALID_RELESE_VALUES: + if release and release not in parse.VALID_RELEASE_VALUES: log.error(f"Invalid argument --release={release}") - log.error(f"Valid arguments are: {', '.join(parse.VALID_RELESE_VALUES)}") + log.error(f"Valid arguments are: {', '.join(parse.VALID_RELEASE_VALUES)}") sys.exit(1) ctx: config.ProjectContext = config.init_project_ctx(project_path=".") diff --git a/src/pycalver/config.py b/src/pycalver/config.py index 9548c47..6abfc96 100644 --- a/src/pycalver/config.py +++ b/src/pycalver/config.py @@ -15,7 +15,6 @@ import datetime as dt import logging -from .parse import PYCALVER_RE from . import version log = logging.getLogger("pycalver.config") @@ -179,7 +178,7 @@ def _parse_config(raw_cfg: RawConfig) -> Config: version_str = raw_cfg['current_version'] version_str = raw_cfg['current_version'] = version_str.strip("'\" ") - if PYCALVER_RE.match(version_str) is None: + if version.PYCALVER_RE.match(version_str) is None: raise ValueError(f"Invalid current_version = {version_str}") pep440_version = version.pycalver_to_pep440(version_str) diff --git a/src/pycalver/parse.py b/src/pycalver/parse.py index da666ff..a683516 100644 --- a/src/pycalver/parse.py +++ b/src/pycalver/parse.py @@ -3,63 +3,18 @@ # # Copyright (c) 2018 Manuel Barkhau (@mbarkhau) - MIT License # SPDX-License-Identifier: MIT -"""Parse PyCalVer strings. - ->>> version_info = PYCALVER_RE.match("v201712.0123-alpha").groupdict() ->>> assert version_info == { -... "version" : "v201712.0123-alpha", -... "calver" : "v201712", -... "year" : "2017", -... "month" : "12", -... "build" : ".0123", -... "release" : "-alpha", -... } ->>> ->>> version_info = PYCALVER_RE.match("v201712.0033").groupdict() ->>> assert version_info == { -... "version" : "v201712.0033", -... "calver" : "v201712", -... "year" : "2017", -... "month" : "12", -... "build" : ".0033", -... "release" : None, -... } -""" +"""Parse PyCalVer strings from files.""" import re import logging import typing as typ -from . import version - log = logging.getLogger("pycalver.parse") -VALID_RELESE_VALUES = ("alpha", "beta", "dev", "rc", "post") +VALID_RELEASE_VALUES = ("alpha", "beta", "dev", "rc", "post") -# https://regex101.com/r/fnj60p/10 -PYCALVER_PATTERN = r""" -\b -(?P - (?P - v # "v" version prefix - (?P\d{4}) - (?P\d{2}) - ) - (?P - \. # "." build nr prefix - \d{4,} - ) - (?P - \- # "-" release prefix - (?:alpha|beta|dev|rc|post) - )? -)(?:\s|$) -""" - -PYCALVER_RE: typ.Pattern[str] = re.compile(PYCALVER_PATTERN, flags=re.VERBOSE) - PATTERN_ESCAPES = [ ("\u005c", "\u005c\u005c"), ("-" , "\u005c-"), @@ -86,41 +41,6 @@ RE_PATTERN_PARTS = { } -class VersionInfo(typ.NamedTuple): - """Container for parsed version string.""" - - version : str - pep440_version: str - calver : str - year : str - month : str - build : str - release : typ.Optional[str] - - -def parse_version_info(version_str: str) -> VersionInfo: - """Parse a PyCalVer string. - - >>> vnfo = parse_version_info("v201712.0033-beta") - >>> assert vnfo == VersionInfo( - ... version="v201712.0033-beta", - ... pep440_version="201712.33b0", - ... calver="v201712", - ... year="2017", - ... month="12", - ... build=".0033", - ... release="-beta", - ... ) - """ - match = PYCALVER_RE.match(version_str) - if match is None: - raise ValueError(f"Invalid PyCalVer string: {version_str}") - - kwargs = match.groupdict() - kwargs['pep440_version'] = version.pycalver_to_pep440(kwargs['version']) - return VersionInfo(**kwargs) - - class PatternMatch(typ.NamedTuple): """Container to mark a version string in a file.""" diff --git a/src/pycalver/rewrite.py b/src/pycalver/rewrite.py index 1e5b5bc..21790f0 100644 --- a/src/pycalver/rewrite.py +++ b/src/pycalver/rewrite.py @@ -12,6 +12,7 @@ import typing as typ from . import parse from . import config +from . import version log = logging.getLogger("pycalver.rewrite") @@ -47,7 +48,7 @@ def rewrite_lines( >>> new_lines = rewrite_lines(patterns, "v201811.0123-beta", old_lines) >>> assert new_lines == ['__version__ = "v201811.0123-beta"'] """ - new_version_nfo = parse.parse_version_info(new_version) + new_version_nfo = version.parse_version_info(new_version) new_version_fmt_kwargs = new_version_nfo._asdict() new_lines = old_lines.copy() diff --git a/src/pycalver/version.py b/src/pycalver/version.py index 24de239..08e0b78 100644 --- a/src/pycalver/version.py +++ b/src/pycalver/version.py @@ -3,19 +3,98 @@ # # Copyright (c) 2018 Manuel Barkhau (@mbarkhau) - MIT License # SPDX-License-Identifier: MIT -"""Functions related to version string manipulation.""" +"""Functions related to version string manipulation. +>>> version_info = PYCALVER_RE.match("v201712.0123-alpha").groupdict() +>>> assert version_info == { +... "version" : "v201712.0123-alpha", +... "calver" : "v201712", +... "year" : "2017", +... "month" : "12", +... "build" : ".0123", +... "release" : "-alpha", +... } +>>> +>>> version_info = PYCALVER_RE.match("v201712.0033").groupdict() +>>> assert version_info == { +... "version" : "v201712.0033", +... "calver" : "v201712", +... "year" : "2017", +... "month" : "12", +... "build" : ".0033", +... "release" : None, +... } +""" + +import re import logging import pkg_resources import typing as typ import datetime as dt from . import lex_id -from . import parse log = logging.getLogger("pycalver.version") +# https://regex101.com/r/fnj60p/10 +PYCALVER_PATTERN = r""" +\b +(?P + (?P + v # "v" version prefix + (?P\d{4}) + (?P\d{2}) + ) + (?P + \. # "." build nr prefix + \d{4,} + ) + (?P + \- # "-" release prefix + (?:alpha|beta|dev|rc|post) + )? +)(?:\s|$) +""" + +PYCALVER_RE: typ.Pattern[str] = re.compile(PYCALVER_PATTERN, flags=re.VERBOSE) + + +class VersionInfo(typ.NamedTuple): + """Container for parsed version string.""" + + version : str + pep440_version: str + calver : str + year : str + month : str + build : str + release : typ.Optional[str] + + +def parse_version_info(version_str: str) -> VersionInfo: + """Parse a PyCalVer string. + + >>> vnfo = parse_version_info("v201712.0033-beta") + >>> assert vnfo == VersionInfo( + ... version="v201712.0033-beta", + ... pep440_version="201712.33b0", + ... calver="v201712", + ... year="2017", + ... month="12", + ... build=".0033", + ... release="-beta", + ... ) + """ + match = PYCALVER_RE.match(version_str) + if match is None: + raise ValueError(f"Invalid PyCalVer string: {version_str}") + + kwargs = match.groupdict() + kwargs['pep440_version'] = pycalver_to_pep440(kwargs['version']) + return VersionInfo(**kwargs) + + def current_calver() -> str: """Generate calver version string based on current date. @@ -30,7 +109,7 @@ def incr(old_version: str, *, release: str = None) -> str: Old_version is assumed to be a valid calver string, already validated in pycalver.config.parse. """ - old_ver = parse.parse_version_info(old_version) + old_ver = parse_version_info(old_version) new_calver = current_calver() diff --git a/test/test_parse.py b/test/test_parse.py index 89efcfa..067978a 100644 --- a/test/test_parse.py +++ b/test/test_parse.py @@ -2,34 +2,6 @@ import re from pycalver import parse -def test_readme_pycalver1(): - version_str = "v201712.0001-alpha" - version_info = parse.PYCALVER_RE.match(version_str).groupdict() - - assert version_info == { - 'version': "v201712.0001-alpha", - 'calver' : "v201712", - 'year' : "2017", - 'month' : "12", - 'build' : ".0001", - 'release': "-alpha", - } - - -def test_readme_pycalver2(): - version_str = "v201712.0033" - version_info = parse.PYCALVER_RE.match(version_str).groupdict() - - assert version_info == { - 'version': "v201712.0033", - 'calver' : "v201712", - 'year' : "2017", - 'month' : "12", - 'build' : ".0033", - 'release': None, - } - - def test_re_pattern_parts(): part_re_by_name = { part_name: re.compile(part_re_str) @@ -73,30 +45,6 @@ def test_re_pattern_parts(): assert result_val == expected, (part_name, line) -def test_parse_version_info(): - version_str = "v201712.0001-alpha" - version_nfo = parse.parse_version_info(version_str) - - assert version_nfo.pep440_version == "201712.1a0" - assert version_nfo.version == "v201712.0001-alpha" - assert version_nfo.calver == "v201712" - assert version_nfo.year == "2017" - assert version_nfo.month == "12" - assert version_nfo.build == ".0001" - assert version_nfo.release == "-alpha" - - version_str = "v201712.0001" - version_nfo = parse.parse_version_info(version_str) - - assert version_nfo.pep440_version == "201712.1" - assert version_nfo.version == "v201712.0001" - assert version_nfo.calver == "v201712" - assert version_nfo.year == "2017" - assert version_nfo.month == "12" - assert version_nfo.build == ".0001" - assert version_nfo.release is None - - SETUP_PY_FIXTURE = """ # setup.py import setuptools @@ -167,27 +115,3 @@ def test_badge_parse_patterns(): assert matches[0].match == "badge/CalVer-v201809.0002--beta-blue.svg" assert matches[1].match == ":alt: CalVer v201809.0002-beta" - - -def test_parse_error_empty(): - try: - parse.parse_version_info("") - assert False - except ValueError as err: - pass - - -def test_parse_error_noprefix(): - try: - parse.parse_version_info("201809.0002") - assert False - except ValueError as err: - pass - - -def test_parse_error_nopadding(): - try: - parse.parse_version_info("v201809.2b0") - assert False - except ValueError as err: - pass diff --git a/test/test_version.py b/test/test_version.py index fda6f1a..7c30c9f 100644 --- a/test/test_version.py +++ b/test/test_version.py @@ -52,3 +52,79 @@ def test_bump_random(monkeypatch): ) assert cur_version < new_version cur_version = new_version + + +def test_parse_version_info(): + version_str = "v201712.0001-alpha" + version_nfo = version.parse_version_info(version_str) + + assert version_nfo.pep440_version == "201712.1a0" + assert version_nfo.version == "v201712.0001-alpha" + assert version_nfo.calver == "v201712" + assert version_nfo.year == "2017" + assert version_nfo.month == "12" + assert version_nfo.build == ".0001" + assert version_nfo.release == "-alpha" + + version_str = "v201712.0001" + version_nfo = version.parse_version_info(version_str) + + assert version_nfo.pep440_version == "201712.1" + assert version_nfo.version == "v201712.0001" + assert version_nfo.calver == "v201712" + assert version_nfo.year == "2017" + assert version_nfo.month == "12" + assert version_nfo.build == ".0001" + assert version_nfo.release is None + + +def test_readme_pycalver1(): + version_str = "v201712.0001-alpha" + version_info = version.PYCALVER_RE.match(version_str).groupdict() + + assert version_info == { + 'version': "v201712.0001-alpha", + 'calver' : "v201712", + 'year' : "2017", + 'month' : "12", + 'build' : ".0001", + 'release': "-alpha", + } + + +def test_readme_pycalver2(): + version_str = "v201712.0033" + version_info = version.PYCALVER_RE.match(version_str).groupdict() + + assert version_info == { + 'version': "v201712.0033", + 'calver' : "v201712", + 'year' : "2017", + 'month' : "12", + 'build' : ".0033", + 'release': None, + } + + +def test_parse_error_empty(): + try: + version.parse_version_info("") + assert False + except ValueError as err: + pass + + +def test_parse_error_noprefix(): + try: + version.parse_version_info("201809.0002") + assert False + except ValueError as err: + pass + + +def test_parse_error_nopadding(): + try: + version.parse_version_info("v201809.2b0") + assert False + except ValueError as err: + pass