mirror of
https://github.com/TECHNOFAB11/bumpver.git
synced 2025-12-12 06:20:08 +01:00
add v2 parsing
This commit is contained in:
parent
d4bd8a5931
commit
5940fdbc40
3 changed files with 435 additions and 322 deletions
|
|
@ -3,30 +3,33 @@
|
|||
#
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
# """Compose Regular Expressions from Patterns.
|
||||
"""Compose Regular Expressions from Patterns.
|
||||
|
||||
# >>> pattern = compile_pattern("vYYYY0M.BUILD[-TAG]")
|
||||
# >>> version_info = pattern.regexp.match("v201712.0123-alpha")
|
||||
# >>> assert version_info == {
|
||||
# ... "version": "v201712.0123-alpha",
|
||||
# ... "YYYY" : "2017",
|
||||
# ... "0M" : "12",
|
||||
# ... "BUILD" : "0123",
|
||||
# ... "TAG" : "alpha",
|
||||
# ... }
|
||||
# >>>
|
||||
# >>> version_info = pattern.regexp.match("201712.1234")
|
||||
# >>> assert version_info is None
|
||||
>>> pattern = compile_pattern("vYYYY0M.BUILD[-TAG]")
|
||||
>>> version_info = pattern.regexp.match("v201712.0123-alpha")
|
||||
>>> assert version_info.groupdict() == {
|
||||
... "version": "v201712.0123-alpha",
|
||||
... "year_y" : "2017",
|
||||
... "month" : "12",
|
||||
... "bid" : "0123",
|
||||
... "tag" : "alpha",
|
||||
... }
|
||||
>>>
|
||||
>>> version_info = pattern.regexp.match("201712.1234")
|
||||
>>> assert version_info is None
|
||||
|
||||
# >>> version_info = pattern.regexp.match("v201712.1234")
|
||||
# >>> assert version_info == {
|
||||
# ... "version": "v201712.0123-alpha",
|
||||
# ... "YYYY" : "2017",
|
||||
# ... "0M" : "12",
|
||||
# ... "BUILD" : "0123",
|
||||
# ... "TAG" : None,
|
||||
# ... }
|
||||
# """
|
||||
>>> version_info = pattern.regexp.match("v201713.1234")
|
||||
>>> assert version_info is None
|
||||
|
||||
>>> version_info = pattern.regexp.match("v201712.1234")
|
||||
>>> assert version_info.groupdict() == {
|
||||
... "version": "v201712.1234",
|
||||
... "year_y" : "2017",
|
||||
... "month" : "12",
|
||||
... "bid" : "1234",
|
||||
... "tag" : None,
|
||||
... }
|
||||
"""
|
||||
|
||||
import re
|
||||
import typing as typ
|
||||
|
|
@ -42,43 +45,52 @@ PATTERN_ESCAPES = [
|
|||
("?" , "\u005c?"),
|
||||
("{" , "\u005c{"),
|
||||
("}" , "\u005c}"),
|
||||
("[" , "\u005c["),
|
||||
("]" , "\u005c]"),
|
||||
("(" , "\u005c("),
|
||||
(")" , "\u005c)"),
|
||||
# ("[" , "\u005c["), # [braces] are used for optional parts
|
||||
# ("]" , "\u005c]"),
|
||||
("(", "\u005c("),
|
||||
(")", "\u005c)"),
|
||||
]
|
||||
|
||||
# NOTE (mb 2020-09-17): For patterns with different options, the longer
|
||||
# patterns should be first/left (e.g. for 'MM', `1[0-2]` before `[1-9]`).
|
||||
# This ensures that the longest match is done rather than the shortest.
|
||||
# To have a consistent ordering, we always put the pattern that matches
|
||||
# the larger number first (even if the patterns would otherwise be the
|
||||
# same size).
|
||||
|
||||
PART_PATTERNS = {
|
||||
# Based on calver.org
|
||||
'YYYY': r"[1-9][0-9]{3}",
|
||||
'YY' : r"[1-9][0-9]?",
|
||||
'0Y' : r"[0-9]{2}",
|
||||
'Q' : r"[1-4]",
|
||||
'MM' : r"(?:[1-9]|1[0-2])",
|
||||
'0M' : r"(?:0[1-9]|1[0-2])",
|
||||
'DD' : r"(?:[1-9]|[1-2][0-9]|3[0-1])",
|
||||
'0D' : r"(?:0[1-9]|[1-2][0-9]|3[0-1])",
|
||||
'JJJ' : r"(?:[1-9]|[1-9][0-9]|[1-2][0-9][0-9]|3[0-5][0-9]|36[0-6])",
|
||||
'00J' : r"(?:00[1-9]|0[1-9][0-9]|[1-2][0-9][0-9]|3[0-5][0-9]|36[0-6])",
|
||||
# week numbering parts
|
||||
'WW' : r"(?:[0-9]|[1-4][0-9]|5[0-2])",
|
||||
'0W' : r"(?:[0-4][0-9]|5[0-2])",
|
||||
'UU' : r"(?:[0-9]|[1-4][0-9]|5[0-2])",
|
||||
'0U' : r"(?:[0-4][0-9]|5[0-2])",
|
||||
'VV' : r"(?:[1-9]|[1-4][0-9]|5[0-3])",
|
||||
'0V' : r"(?:0[1-9]|[1-4][0-9]|5[0-3])",
|
||||
'GGGG': r"[1-9][0-9]{3}",
|
||||
'GG' : r"[1-9][0-9]?",
|
||||
'0G' : r"[0-9]{2}",
|
||||
'Q' : r"[1-4]",
|
||||
'MM' : r"(?:1[0-2]|[1-9])",
|
||||
'0M' : r"(?:1[0-2]|0[1-9])",
|
||||
'DD' : r"(?:3[0-1]|[1-2][0-9]|[1-9])",
|
||||
'0D' : r"(?:3[0-1]|[1-2][0-9]|0[1-9])",
|
||||
'JJJ' : r"(?:36[0-6]|3[0-5][0-9]|[1-2][0-9][0-9]|[1-9][0-9]|[1-9])",
|
||||
'00J' : r"(?:36[0-6]|3[0-5][0-9]|[1-2][0-9][0-9]|0[1-9][0-9]|00[1-9])",
|
||||
# week numbering parts
|
||||
'WW': r"(?:5[0-2]|[1-4][0-9]|[0-9])",
|
||||
'0W': r"(?:5[0-2]|[0-4][0-9])",
|
||||
'UU': r"(?:5[0-2]|[1-4][0-9]|[0-9])",
|
||||
'0U': r"(?:5[0-2]|[0-4][0-9])",
|
||||
'VV': r"(?:5[0-3]|[1-4][0-9]|[1-9])",
|
||||
'0V': r"(?:5[0-3]|[1-4][0-9]|0[1-9])",
|
||||
# non calver parts
|
||||
'MAJOR': r"[0-9]+",
|
||||
'MINOR': r"[0-9]+",
|
||||
'PATCH': r"[0-9]+",
|
||||
'MICRO': r"[0-9]+",
|
||||
'BUILD': r"[0-9]+",
|
||||
'TAG' : r"(?:alpha|beta|dev|rc|post|final)",
|
||||
'PYTAG': r"(?:a|b|dev|rc|post)?[0-9]*",
|
||||
'TAG' : r"(?:alpha|beta|dev|pre|rc|post|final)",
|
||||
'PYTAG': r"(?:a|b|dev|rc|post)",
|
||||
'NUM' : r"[0-9]+",
|
||||
}
|
||||
|
||||
|
||||
PATTERN_PART_FIELDS = {
|
||||
'YYYY' : 'year_y',
|
||||
|
|
@ -109,17 +121,118 @@ PATTERN_PART_FIELDS = {
|
|||
'VV' : 'week_v',
|
||||
'0V' : 'week_v',
|
||||
}
|
||||
|
||||
|
||||
FieldValue = typ.Union[str, int]
|
||||
|
||||
|
||||
def _fmt_num(val: FieldValue) -> str:
|
||||
return str(val)
|
||||
|
||||
|
||||
def _fmt_yy(year_y: FieldValue) -> str:
|
||||
return str(int(str(year_y)[-2:]))
|
||||
|
||||
|
||||
def _fmt_0y(year_y: FieldValue) -> str:
|
||||
return "{0:02}".format(int(str(year_y)[-2:]))
|
||||
|
||||
|
||||
def _fmt_gg(year_g: FieldValue) -> str:
|
||||
return str(int(str(year_g)[-2:]))
|
||||
|
||||
|
||||
def _fmt_0g(year_g: FieldValue) -> str:
|
||||
return "{0:02}".format(int(str(year_g)[-2:]))
|
||||
|
||||
|
||||
def _fmt_0m(month: FieldValue) -> str:
|
||||
return "{0:02}".format(int(month))
|
||||
|
||||
|
||||
def _fmt_0d(dom: FieldValue) -> str:
|
||||
return "{0:02}".format(int(dom))
|
||||
|
||||
|
||||
def _fmt_00j(doy: FieldValue) -> str:
|
||||
return "{0:03}".format(int(doy))
|
||||
|
||||
|
||||
def _fmt_0w(week_w: FieldValue) -> str:
|
||||
return "{0:02}".format(int(week_w))
|
||||
|
||||
|
||||
def _fmt_0u(week_u: FieldValue) -> str:
|
||||
return "{0:02}".format(int(week_u))
|
||||
|
||||
|
||||
def _fmt_0v(week_v: FieldValue) -> str:
|
||||
return "{0:02}".format(int(week_v))
|
||||
|
||||
|
||||
PART_FORMATS: typ.Dict[str, typ.Callable[[FieldValue], str]] = {
|
||||
'YYYY' : _fmt_num,
|
||||
'YY' : _fmt_yy,
|
||||
'0Y' : _fmt_0y,
|
||||
'GGGG' : _fmt_num,
|
||||
'GG' : _fmt_gg,
|
||||
'0G' : _fmt_0g,
|
||||
'Q' : _fmt_num,
|
||||
'MM' : _fmt_num,
|
||||
'0M' : _fmt_0m,
|
||||
'DD' : _fmt_num,
|
||||
'0D' : _fmt_0d,
|
||||
'JJJ' : _fmt_num,
|
||||
'00J' : _fmt_00j,
|
||||
'MAJOR': _fmt_num,
|
||||
'MINOR': _fmt_num,
|
||||
'PATCH': _fmt_num,
|
||||
'MICRO': _fmt_num,
|
||||
'BUILD': _fmt_num,
|
||||
'TAG' : _fmt_num,
|
||||
'PYTAG': _fmt_num,
|
||||
'NUM' : _fmt_num,
|
||||
'WW' : _fmt_num,
|
||||
'0W' : _fmt_0w,
|
||||
'UU' : _fmt_num,
|
||||
'0U' : _fmt_0u,
|
||||
'VV' : _fmt_num,
|
||||
'0V' : _fmt_0v,
|
||||
}
|
||||
|
||||
|
||||
def _replace_pattern_parts(pattern: str) -> str:
|
||||
# The pattern is escaped, so that everything besides the format
|
||||
# string variables is treated literally.
|
||||
if "[" in pattern and "]" in pattern:
|
||||
pattern = pattern.replace("[", "(?:")
|
||||
pattern = pattern.replace("]", ")?")
|
||||
|
||||
part_patterns_by_index: typ.Dict[typ.Tuple[int, int], typ.Tuple[int, int, str]] = {}
|
||||
for part_name, part_pattern in PART_PATTERNS.items():
|
||||
named_part_pattern = f"(?P<{part_name}>{part_pattern})"
|
||||
placeholder = "\u005c{" + part_name + "\u005c}"
|
||||
pattern = pattern.replace(placeholder, named_part_pattern)
|
||||
return pattern
|
||||
start_idx = pattern.find(part_name)
|
||||
if start_idx < 0:
|
||||
continue
|
||||
|
||||
field = PATTERN_PART_FIELDS[part_name]
|
||||
named_part_pattern = f"(?P<{field}>{part_pattern})"
|
||||
end_idx = start_idx + len(part_name)
|
||||
sort_key = (-end_idx, -len(part_name))
|
||||
part_patterns_by_index[sort_key] = (start_idx, end_idx, named_part_pattern)
|
||||
|
||||
# NOTE (mb 2020-09-17): The sorting is done so that we process items:
|
||||
# - right before left
|
||||
# - longer before shorter
|
||||
last_start_idx = len(pattern) + 1
|
||||
result_pattern = pattern
|
||||
for _, (start_idx, end_idx, named_part_pattern) in sorted(part_patterns_by_index.items()):
|
||||
if end_idx <= last_start_idx:
|
||||
result_pattern = (
|
||||
result_pattern[:start_idx] + named_part_pattern + result_pattern[end_idx:]
|
||||
)
|
||||
last_start_idx = start_idx
|
||||
|
||||
return "(?P<version>" + result_pattern + ")"
|
||||
|
||||
|
||||
def compile_pattern_str(pattern: str) -> str:
|
||||
|
|
|
|||
|
|
@ -12,9 +12,11 @@ import datetime as dt
|
|||
import lexid
|
||||
import pkg_resources
|
||||
|
||||
# import pycalver.patterns as v1patterns
|
||||
import pycalver2.patterns as v2patterns
|
||||
|
||||
# import pycalver.version as v1version
|
||||
# import pycalver.patterns as v1patterns
|
||||
|
||||
logger = logging.getLogger("pycalver.version")
|
||||
|
||||
|
||||
|
|
@ -34,11 +36,44 @@ ZERO_VALUES = {
|
|||
'major': "0",
|
||||
'minor': "0",
|
||||
'patch': "0",
|
||||
'TAG' : "final",
|
||||
'PYTAG': "",
|
||||
'tag' : "final",
|
||||
'pytag': "",
|
||||
'num' : "0",
|
||||
}
|
||||
|
||||
|
||||
TAG_BY_PEP440_TAG = {
|
||||
'a' : 'alpha',
|
||||
'b' : 'beta',
|
||||
"" : 'final',
|
||||
'rc' : 'rc',
|
||||
'dev' : 'dev',
|
||||
'post': 'post',
|
||||
}
|
||||
|
||||
|
||||
PEP440_TAG_BY_TAG = {
|
||||
'alpha': "a",
|
||||
'beta' : "b",
|
||||
'final': "",
|
||||
'pre' : "rc",
|
||||
'rc' : "rc",
|
||||
'dev' : "dev",
|
||||
'post' : "post",
|
||||
}
|
||||
|
||||
assert set(TAG_BY_PEP440_TAG.keys()) == set(PEP440_TAG_BY_TAG.values())
|
||||
assert set(TAG_BY_PEP440_TAG.values()) < set(PEP440_TAG_BY_TAG.keys())
|
||||
|
||||
# PEP440_TAGS_REVERSE = {
|
||||
# "a" : 'alpha',
|
||||
# "b" : 'beta',
|
||||
# "rc" : 'rc',
|
||||
# "dev" : 'dev',
|
||||
# "post": 'post',
|
||||
# }
|
||||
|
||||
|
||||
class CalendarInfo(typ.NamedTuple):
|
||||
"""Container for calendar components of version strings."""
|
||||
|
||||
|
|
@ -79,27 +114,26 @@ def _quarter_from_month(month: int) -> int:
|
|||
|
||||
|
||||
def cal_info(date: dt.date = None) -> CalendarInfo:
|
||||
# TODO reenable doctest
|
||||
# """Generate calendar components for current date.
|
||||
"""Generate calendar components for current date.
|
||||
|
||||
# >>> from datetime import date
|
||||
>>> import datetime as dt
|
||||
|
||||
# >>> c = cal_info(date(2019, 1, 5))
|
||||
# >>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
# (2019, 1, 1, 5, 5, 0, 0)
|
||||
>>> c = cal_info(dt.date(2019, 1, 5))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.week_w, c.week_u, c.week_v)
|
||||
(2019, 1, 1, 5, 5, 0, 0, 1)
|
||||
|
||||
# >>> c = cal_info(date(2019, 1, 6))
|
||||
# >>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
# (2019, 1, 1, 6, 6, 0, 1)
|
||||
>>> c = cal_info(dt.date(2019, 1, 6))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.week_w, c.week_u, c.week_v)
|
||||
(2019, 1, 1, 6, 6, 0, 1, 1)
|
||||
|
||||
# >>> c = cal_info(date(2019, 1, 7))
|
||||
# >>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
# (2019, 1, 1, 7, 7, 1, 1)
|
||||
>>> c = cal_info(dt.date(2019, 1, 7))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.week_w, c.week_u, c.week_v)
|
||||
(2019, 1, 1, 7, 7, 1, 1, 2)
|
||||
|
||||
# >>> c = cal_info(date(2019, 4, 7))
|
||||
# >>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
# (2019, 2, 4, 7, 97, 13, 14)
|
||||
# """
|
||||
>>> c = cal_info(dt.date(2019, 4, 7))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.week_w, c.week_u, c.week_v)
|
||||
(2019, 2, 4, 7, 97, 13, 14, 14)
|
||||
"""
|
||||
if date is None:
|
||||
date = TODAY
|
||||
|
||||
|
|
@ -118,59 +152,105 @@ def cal_info(date: dt.date = None) -> CalendarInfo:
|
|||
return CalendarInfo(**kwargs)
|
||||
|
||||
|
||||
MaybeInt = typ.Optional[int]
|
||||
|
||||
|
||||
class VersionInfo(typ.NamedTuple):
|
||||
"""Container for parsed version string."""
|
||||
|
||||
year_y : typ.Optional[int]
|
||||
year_g : typ.Optional[int]
|
||||
quarter: typ.Optional[int]
|
||||
month : typ.Optional[int]
|
||||
dom : typ.Optional[int]
|
||||
doy : typ.Optional[int]
|
||||
week_w : typ.Optional[int]
|
||||
week_u : typ.Optional[int]
|
||||
week_v : typ.Optional[int]
|
||||
year_y : MaybeInt
|
||||
year_g : MaybeInt
|
||||
quarter: MaybeInt
|
||||
month : MaybeInt
|
||||
dom : MaybeInt
|
||||
doy : MaybeInt
|
||||
week_w : MaybeInt
|
||||
week_u : MaybeInt
|
||||
week_v : MaybeInt
|
||||
major : int
|
||||
minor : int
|
||||
patch : int
|
||||
bid : str
|
||||
tag : str
|
||||
pytag : str
|
||||
num : MaybeInt
|
||||
|
||||
|
||||
VALID_FIELD_KEYS = set(VersionInfo._fields) | {'version'}
|
||||
|
||||
FieldKey = str
|
||||
MatchGroupKey = str
|
||||
MatchGroupStr = str
|
||||
|
||||
PatternGroups = typ.Dict[MatchGroupKey, MatchGroupStr]
|
||||
FieldValues = typ.Dict[FieldKey , MatchGroupStr]
|
||||
PatternGroups = typ.Dict[FieldKey, MatchGroupStr]
|
||||
FieldValues = typ.Dict[FieldKey, MatchGroupStr]
|
||||
|
||||
|
||||
def _parse_field_values(field_values: FieldValues) -> VersionInfo:
|
||||
def _parse_version_info(field_values: FieldValues) -> VersionInfo:
|
||||
"""Parse normalized VersionInfo from groups of a matched pattern.
|
||||
|
||||
>>> vnfo = _parse_version_info({'year_y': "2018", 'month': "11", 'bid': "0099"})
|
||||
>>> (vnfo.year_y, vnfo.month, vnfo.quarter, vnfo.bid, vnfo.tag)
|
||||
(2018, 11, 4, '0099', 'final')
|
||||
|
||||
>>> vnfo = _parse_version_info({'year_y': "2018", 'doy': "11", 'bid': "099", 'tag': "beta"})
|
||||
>>> (vnfo.year_y, vnfo.month, vnfo.dom, vnfo.doy, vnfo.bid, vnfo.tag)
|
||||
(2018, 1, 11, 11, '099', 'beta')
|
||||
|
||||
>>> vnfo = _parse_version_info({'year_y': "2018", 'month': "6", 'dom': "15"})
|
||||
>>> (vnfo.year_y, vnfo.month, vnfo.dom, vnfo.doy)
|
||||
(2018, 6, 15, 166)
|
||||
|
||||
>>> vnfo = _parse_version_info({'major': "1", 'minor': "23", 'patch': "45"})
|
||||
>>> (vnfo.major, vnfo.minor, vnfo.patch)
|
||||
(1, 23, 45)
|
||||
|
||||
>>> vnfo = _parse_version_info({'major': "1", 'minor': "023", 'patch': "0045"})
|
||||
>>> (vnfo.major, vnfo.minor, vnfo.patch)
|
||||
(1, 23, 45)
|
||||
|
||||
>>> vnfo = _parse_version_info({'year_y': "2021", 'week_w': "02"})
|
||||
>>> (vnfo.year_y, vnfo.week_w)
|
||||
(2021, 2)
|
||||
>>> vnfo = _parse_version_info({'year_y': "2021", 'week_u': "02"})
|
||||
>>> (vnfo.year_y, vnfo.week_u)
|
||||
(2021, 2)
|
||||
>>> vnfo = _parse_version_info({'year_g': "2021", 'week_v': "02"})
|
||||
>>> (vnfo.year_g, vnfo.week_v)
|
||||
(2021, 2)
|
||||
|
||||
>>> vnfo = _parse_version_info({'year_y': "2021", 'month': "01", 'dom': "03"})
|
||||
>>> (vnfo.year_y, vnfo.month, vnfo.dom, vnfo.tag)
|
||||
(2021, 1, 3, 'final')
|
||||
>>> (vnfo.year_y, vnfo.week_w,vnfo.year_y, vnfo.week_u,vnfo.year_g, vnfo.week_v)
|
||||
(2021, 0, 2021, 1, 2020, 53)
|
||||
"""
|
||||
for key in field_values:
|
||||
assert key in VALID_FIELD_KEYS, key
|
||||
|
||||
fvals = field_values
|
||||
tag = fvals.get('tag')
|
||||
if tag is None:
|
||||
tag = "final"
|
||||
tag = fvals.get('tag' , "final")
|
||||
pytag = fvals.get('pytag', "")
|
||||
|
||||
tag = TAG_ALIASES.get(tag, tag)
|
||||
assert tag is not None
|
||||
# TODO (mb 2020-09-06): parts of course
|
||||
pytag = "TODO"
|
||||
if tag and not pytag:
|
||||
pytag = PEP440_TAG_BY_TAG[tag]
|
||||
elif pytag and not tag:
|
||||
tag = TAG_BY_PEP440_TAG[pytag]
|
||||
|
||||
bid = fvals['bid'] if 'bid' in fvals else "1001"
|
||||
|
||||
year_y = int(fvals['year_y']) if 'year_y' in fvals else None
|
||||
year_g = int(fvals['year_g']) if 'year_g' in fvals else None
|
||||
doy = int(fvals['doy' ]) if 'doy' in fvals else None
|
||||
num: MaybeInt = int(fvals['num']) if 'num' in fvals else None
|
||||
|
||||
date: typ.Optional[dt.date] = None
|
||||
|
||||
month: typ.Optional[int] = None
|
||||
dom : typ.Optional[int] = None
|
||||
year_y: MaybeInt = int(fvals['year_y']) if 'year_y' in fvals else None
|
||||
year_g: MaybeInt = int(fvals['year_g']) if 'year_g' in fvals else None
|
||||
|
||||
week_w: typ.Optional[int] = None
|
||||
week_u: typ.Optional[int] = None
|
||||
week_v: typ.Optional[int] = None
|
||||
month: MaybeInt = int(fvals['month']) if 'month' in fvals else None
|
||||
doy : MaybeInt = int(fvals['doy' ]) if 'doy' in fvals else None
|
||||
dom : MaybeInt = int(fvals['dom' ]) if 'dom' in fvals else None
|
||||
|
||||
week_w: MaybeInt = int(fvals['week_w']) if 'week_w' in fvals else None
|
||||
week_u: MaybeInt = int(fvals['week_u']) if 'week_u' in fvals else None
|
||||
week_v: MaybeInt = int(fvals['week_v']) if 'week_v' in fvals else None
|
||||
|
||||
if year_y and doy:
|
||||
date = _date_from_doy(year_y, doy)
|
||||
|
|
@ -180,26 +260,31 @@ def _parse_field_values(field_values: FieldValues) -> VersionInfo:
|
|||
month = int(fvals['month']) if 'month' in fvals else None
|
||||
dom = int(fvals['dom' ]) if 'dom' in fvals else None
|
||||
|
||||
quarter = int(fvals['quarter']) if 'quarter' in fvals else None
|
||||
if quarter is None and month:
|
||||
quarter = _quarter_from_month(month)
|
||||
|
||||
if year_y and month and dom:
|
||||
date = dt.date(year_y, month, dom)
|
||||
|
||||
if date:
|
||||
# derive all fields from other previous values
|
||||
year_y = int(date.strftime("%Y"), base=10)
|
||||
year_g = int(date.strftime("%G"), base=10)
|
||||
month = int(date.strftime("%m"), base=10)
|
||||
dom = int(date.strftime("%d"), base=10)
|
||||
doy = int(date.strftime("%j"), base=10)
|
||||
week_w = int(date.strftime("%W"), base=10)
|
||||
week_u = int(date.strftime("%U"), base=10)
|
||||
week_v = int(date.strftime("%V"), base=10)
|
||||
year_g = int(date.strftime("%G"), base=10)
|
||||
|
||||
quarter = int(fvals['quarter']) if 'quarter' in fvals else None
|
||||
if quarter is None and month:
|
||||
quarter = _quarter_from_month(month)
|
||||
|
||||
major = int(fvals['major']) if 'major' in fvals else 0
|
||||
minor = int(fvals['minor']) if 'minor' in fvals else 0
|
||||
patch = int(fvals['patch']) if 'patch' in fvals else 0
|
||||
|
||||
return VersionInfo(
|
||||
bid = fvals['bid'] if 'bid' in fvals else "1000"
|
||||
|
||||
vnfo = VersionInfo(
|
||||
year_y=year_y,
|
||||
year_g=year_g,
|
||||
quarter=quarter,
|
||||
|
|
@ -215,47 +300,9 @@ def _parse_field_values(field_values: FieldValues) -> VersionInfo:
|
|||
bid=bid,
|
||||
tag=tag,
|
||||
pytag=pytag,
|
||||
num=num,
|
||||
)
|
||||
|
||||
|
||||
def _is_calver(nfo: typ.Union[CalendarInfo, VersionInfo]) -> bool:
|
||||
# TODO reenable doctest
|
||||
# """Check pattern for any calendar based parts.
|
||||
|
||||
# >>> _is_calver(cal_info())
|
||||
# True
|
||||
|
||||
# >>> vnfo = _parse_version_info({'year': "2018", 'month': "11", 'bid': "0018"})
|
||||
# >>> _is_calver(vnfo)
|
||||
# True
|
||||
|
||||
# >>> vnfo = _parse_version_info({'MAJOR': "1", 'MINOR': "023", 'PATCH': "45"})
|
||||
# >>> _is_calver(vnfo)
|
||||
# False
|
||||
# """
|
||||
for field in CalendarInfo._fields:
|
||||
maybe_val: typ.Any = getattr(nfo, field, None)
|
||||
if isinstance(maybe_val, int):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
TAG_ALIASES: typ.Dict[str, str] = {
|
||||
'a' : "alpha",
|
||||
'b' : "beta",
|
||||
'pre': "rc",
|
||||
}
|
||||
|
||||
|
||||
PEP440_TAGS: typ.Dict[str, str] = {
|
||||
'alpha': "a",
|
||||
'beta' : "b",
|
||||
'final': "",
|
||||
'rc' : "rc",
|
||||
'dev' : "dev",
|
||||
'post' : "post",
|
||||
}
|
||||
return vnfo
|
||||
|
||||
|
||||
VersionInfoKW = typ.Dict[str, typ.Union[str, int, None]]
|
||||
|
|
@ -265,65 +312,17 @@ class PatternError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
def _parse_pattern_groups(pattern_groups: PatternGroups) -> FieldValues:
|
||||
for part_name in pattern_groups.keys():
|
||||
is_valid_part_name = (
|
||||
part_name in v2patterns.COMPOSITE_PART_PATTERNS or part_name in PATTERN_PART_FIELDS
|
||||
)
|
||||
if not is_valid_part_name:
|
||||
err_msg = f"Invalid part '{part_name}'"
|
||||
raise PatternError(err_msg)
|
||||
|
||||
field_value_items = [
|
||||
(field_name, pattern_groups[part_name])
|
||||
for part_name, field_name in PATTERN_PART_FIELDS.items()
|
||||
if part_name in pattern_groups.keys()
|
||||
]
|
||||
|
||||
all_fields = [field_name for field_name, _ in field_value_items]
|
||||
unique_fields = set(all_fields)
|
||||
duplicate_fields = [f for f in unique_fields if all_fields.count(f) > 1]
|
||||
|
||||
if any(duplicate_fields):
|
||||
err_msg = f"Multiple parts for same field {duplicate_fields}."
|
||||
raise PatternError(err_msg)
|
||||
|
||||
return dict(field_value_items)
|
||||
|
||||
|
||||
def _parse_version_info(pattern_groups: PatternGroups) -> VersionInfo:
|
||||
# TODO reenable doctest
|
||||
# """Parse normalized VersionInfo from groups of a matched pattern.
|
||||
|
||||
# >>> vnfo = _parse_version_info({'year': "2018", 'month': "11", 'bid': "0099"})
|
||||
# >>> (vnfo.year_y, vnfo.month, vnfo.quarter, vnfo.bid, vnfo.tag)
|
||||
# (2018, 11, 4, '0099', 'final')
|
||||
|
||||
# >>> vnfo = _parse_version_info({'year': "2018", 'doy': "11", 'bid': "099", 'tag': "b"})
|
||||
# >>> (vnfo.year_y, vnfo.month, vnfo.dom, vnfo.bid, vnfo.tag)
|
||||
# (2018, 1, 11, '099', 'beta')
|
||||
|
||||
# >>> vnfo = _parse_version_info({'MAJOR': "1", 'MINOR': "23", 'PATCH': "45"})
|
||||
# >>> (vnfo.major, vnfo.minor, vnfo.patch)
|
||||
# (1, 23, 45)
|
||||
|
||||
# >>> vnfo = _parse_version_info({'MAJOR': "1", 'MMM': "023", 'PPPP': "0045"})
|
||||
# >>> (vnfo.major, vnfo.minor, vnfo.patch)
|
||||
# (1, 23, 45)
|
||||
# """
|
||||
field_values = _parse_pattern_groups(pattern_groups)
|
||||
return _parse_field_values(field_values)
|
||||
|
||||
|
||||
def parse_version_info(version_str: str, pattern: str = "vYYYY0M.BUILD[-TAG]") -> VersionInfo:
|
||||
# """Parse normalized VersionInfo.
|
||||
"""Parse normalized VersionInfo.
|
||||
|
||||
# >>> vnfo = parse_version_info("v201712.0033-beta", pattern="vYYYY0M.BUILD[-TAG]")
|
||||
# >>> assert vnfo == _parse_version_info({'year': 2017, 'month': 12, 'bid': "0033", 'tag': "beta"})
|
||||
>>> vnfo = parse_version_info("v201712.0033-beta", pattern="vYYYY0M.BUILD[-TAG]")
|
||||
>>> fvals = {'year_y': 2017, 'month': 12, 'bid': "0033", 'tag': "beta"}
|
||||
>>> assert vnfo == _parse_version_info(fvals)
|
||||
|
||||
# >>> vnfo = parse_version_info("1.23.456", pattern="MAJOR.MINOR.PATCH")
|
||||
# >>> assert vnfo == _parse_version_info({'MAJOR': "1", 'MINOR': "23", 'PATCH': "456"})
|
||||
# """
|
||||
>>> vnfo = parse_version_info("1.23.456", pattern="MAJOR.MINOR.PATCH")
|
||||
>>> fvals = {'major': "1", 'minor': "23", 'patch': "456"}
|
||||
>>> assert vnfo == _parse_version_info(fvals)
|
||||
"""
|
||||
pattern_tup = v2patterns.compile_pattern(pattern)
|
||||
match = pattern_tup.regexp.match(version_str)
|
||||
if match is None:
|
||||
|
|
@ -332,23 +331,23 @@ def parse_version_info(version_str: str, pattern: str = "vYYYY0M.BUILD[-TAG]") -
|
|||
f"for pattern '{pattern}'/'{pattern_tup.regexp.pattern}'"
|
||||
)
|
||||
raise PatternError(err_msg)
|
||||
|
||||
return _parse_version_info(match.groupdict())
|
||||
else:
|
||||
field_values = match.groupdict()
|
||||
return _parse_version_info(field_values)
|
||||
|
||||
|
||||
def is_valid(version_str: str, pattern: str = "{pycalver}") -> bool:
|
||||
# TODO reenable doctest
|
||||
# """Check if a version matches a pattern.
|
||||
def is_valid(version_str: str, pattern: str = "vYYYY0M.BUILD[-TAG]") -> bool:
|
||||
"""Check if a version matches a pattern.
|
||||
|
||||
# >>> is_valid("v201712.0033-beta", pattern="{pycalver}")
|
||||
# True
|
||||
# >>> is_valid("v201712.0033-beta", pattern="{semver}")
|
||||
# False
|
||||
# >>> is_valid("1.2.3", pattern="{semver}")
|
||||
# True
|
||||
# >>> is_valid("v201712.0033-beta", pattern="{semver}")
|
||||
# False
|
||||
# """
|
||||
>>> is_valid("v201712.0033-beta", pattern="vYYYY0M.BUILD[-TAG]")
|
||||
True
|
||||
>>> is_valid("v201712.0033-beta", pattern="MAJOR.MINOR.PATCH")
|
||||
False
|
||||
>>> is_valid("1.2.3", pattern="MAJOR.MINOR.PATCH")
|
||||
True
|
||||
>>> is_valid("v201712.0033-beta", pattern="MAJOR.MINOR.PATCH")
|
||||
False
|
||||
"""
|
||||
try:
|
||||
parse_version_info(version_str, pattern)
|
||||
return True
|
||||
|
|
@ -359,140 +358,106 @@ def is_valid(version_str: str, pattern: str = "{pycalver}") -> bool:
|
|||
TemplateKwargs = typ.Dict[str, typ.Union[str, int, None]]
|
||||
|
||||
|
||||
def _derive_template_kwargs(vinfo: VersionInfo) -> TemplateKwargs:
|
||||
def _format_part_values(vinfo: VersionInfo) -> typ.Dict[str, str]:
|
||||
"""Generate kwargs for template from minimal VersionInfo.
|
||||
|
||||
The VersionInfo Tuple only has the minimal representation
|
||||
of a parsed version, not the values suitable for formatting.
|
||||
It may for example have month=9, but not the formatted
|
||||
representation '09' for '0M'.
|
||||
|
||||
>>> vinfo = parse_version_info("v200709.1033-beta", pattern="vYYYY0M.BUILD[-TAG]")
|
||||
>>> kwargs = _format_part_values(vinfo)
|
||||
>>> (kwargs['YYYY'], kwargs['0M'], kwargs['BUILD'], kwargs['TAG'])
|
||||
('2007', '09', '1033', 'beta')
|
||||
>>> (kwargs['YY'], kwargs['0Y'], kwargs['MM'], kwargs['PYTAG'])
|
||||
('7', '07', '9', 'b')
|
||||
"""
|
||||
kwargs: TemplateKwargs = vinfo._asdict()
|
||||
vnfo_kwargs: TemplateKwargs = vinfo._asdict()
|
||||
kwargs : typ.Dict[str, str] = {}
|
||||
|
||||
tag = vinfo.tag
|
||||
kwargs['TAG'] = tag
|
||||
if tag == 'final':
|
||||
kwargs['PYTAG'] = ""
|
||||
else:
|
||||
kwargs['PYTAG'] = PEP440_TAGS[tag] + "0"
|
||||
for part, field in v2patterns.PATTERN_PART_FIELDS.items():
|
||||
field_val = vnfo_kwargs[field]
|
||||
if field_val is None:
|
||||
continue
|
||||
|
||||
year_y = vinfo.year_y
|
||||
if year_y:
|
||||
kwargs['0Y' ] = str(year_y)[-2:]
|
||||
kwargs['YY' ] = int(str(year_y)[-2:])
|
||||
kwargs['YYYY'] = year_y
|
||||
|
||||
year_g = vinfo.year_g
|
||||
if year_g:
|
||||
kwargs['0G' ] = str(year_g)[-2:]
|
||||
kwargs['GG' ] = int(str(year_g)[-2:])
|
||||
kwargs['GGGG'] = year_g
|
||||
|
||||
kwargs['BUILD'] = int(vinfo.bid, 10)
|
||||
|
||||
for part_name, field in ID_FIELDS_BY_PART.items():
|
||||
val = kwargs[field]
|
||||
if part_name.lower() == field.lower():
|
||||
if isinstance(val, str):
|
||||
kwargs[part_name] = int(val, base=10)
|
||||
else:
|
||||
kwargs[part_name] = val
|
||||
else:
|
||||
assert len(set(part_name)) == 1
|
||||
padded_len = len(part_name)
|
||||
kwargs[part_name] = str(val).zfill(padded_len)
|
||||
format_fn = v2patterns.PART_FORMATS[part]
|
||||
kwargs[part] = format_fn(field_val)
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def _compile_format_template(pattern: str, kwargs: TemplateKwargs) -> str:
|
||||
# NOTE (mb 2020-09-04): Some parts are optional, we need the kwargs to
|
||||
# determine if part is set to its zero value
|
||||
format_tmpl = pattern
|
||||
for part_name, full_part_format in v2patterns.FULL_PART_FORMATS.items():
|
||||
format_tmpl = format_tmpl.replace("{" + part_name + "}", full_part_format)
|
||||
return format_tmpl
|
||||
|
||||
|
||||
def format_version(vinfo: VersionInfo, pattern: str) -> str:
|
||||
# TODO reenable doctest
|
||||
# """Generate version string.
|
||||
"""Generate version string.
|
||||
|
||||
# >>> import datetime as dt
|
||||
# >>> vinfo = parse_version_info("v201712.0033-beta", pattern="{pycalver}")
|
||||
# >>> vinfo_a = vinfo._replace(**cal_info(date=dt.date(2017, 1, 1))._asdict())
|
||||
# >>> vinfo_b = vinfo._replace(**cal_info(date=dt.date(2017, 12, 31))._asdict())
|
||||
>>> import datetime as dt
|
||||
>>> vinfo = parse_version_info("v200712.0033-beta", pattern="vYYYY0M.BUILD[-TAG]")
|
||||
>>> vinfo_a = vinfo._replace(**cal_info(date=dt.date(2007, 1, 1))._asdict())
|
||||
>>> vinfo_b = vinfo._replace(**cal_info(date=dt.date(2007, 12, 31))._asdict())
|
||||
|
||||
# >>> format_version(vinfo_a, pattern="v{yy}.{BID}{release}")
|
||||
# 'v17.33-beta'
|
||||
# >>> format_version(vinfo_a, pattern="vYY.BUILD[-TAG]")
|
||||
# 'v17.33-beta'
|
||||
# >>> format_version(vinfo_a, pattern="YYYY0M.BUILD[PYTAG]")
|
||||
# '201701.33b0'
|
||||
>>> format_version(vinfo_a, pattern="vYY.BUILD[-TAG]")
|
||||
'v7.33-beta'
|
||||
>>> format_version(vinfo_a, pattern="v0Y.BUILD[-TAG]")
|
||||
'v07.33-beta'
|
||||
>>> format_version(vinfo_a, pattern="YYYY0M.BUILD[PYTAG][NUM]")
|
||||
'201701.33b0'
|
||||
|
||||
# >>> format_version(vinfo_a, pattern="{pycalver}")
|
||||
# 'v201701.0033-beta'
|
||||
# >>> format_version(vinfo_b, pattern="{pycalver}")
|
||||
# 'v201712.0033-beta'
|
||||
>>> format_version(vinfo_a, pattern="vYYYY0M.BUILD[-TAG]")
|
||||
'v201701.0033-beta'
|
||||
>>> format_version(vinfo_b, pattern="vYYYY0M.BUILD[-TAG]")
|
||||
'v201712.0033-beta'
|
||||
|
||||
# >>> format_version(vinfo_a, pattern="v{year}w{iso_week}.{BID}{release}")
|
||||
# 'v2017w00.33-beta'
|
||||
# >>> format_version(vinfo_a, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
# 'v2017w00.33-beta'
|
||||
# >>> format_version(vinfo_b, pattern="v{year}w{iso_week}.{BID}{release}")
|
||||
# 'v2017w52.33-beta'
|
||||
# >>> format_version(vinfo_b, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
# 'v2017w52.33-beta'
|
||||
>>> format_version(vinfo_a, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
'v2017w00.33-beta'
|
||||
>>> format_version(vinfo_b, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
'v2017w52.33-beta'
|
||||
|
||||
# >>> format_version(vinfo_a, pattern="v{year}d{doy}.{bid}{release}")
|
||||
# 'v2017d001.0033-beta'
|
||||
# >>> format_version(vinfo_b, pattern="v{year}d{doy}.{bid}{release}")
|
||||
# 'v2017d365.0033-beta'
|
||||
# >>> format_version(vinfo_a, pattern="vYYYYdJJJ.BUILD[-TAG]")
|
||||
# 'v2017d001.0033-beta'
|
||||
# >>> format_version(vinfo_b, pattern="vYYYYdJJJ.BUILD[-TAG]")
|
||||
# 'v2017d365.0033-beta'
|
||||
>>> format_version(vinfo_a, pattern="vYYYYdJJJ.BUILD[-TAG]")
|
||||
'v2017d001.0033-beta'
|
||||
>>> format_version(vinfo_b, pattern="vYYYYdJJJ.BUILD[-TAG]")
|
||||
'v2017d365.0033-beta'
|
||||
|
||||
# >>> format_version(vinfo_a, pattern="vGGGGwVV.BUILD[-TAG]")
|
||||
# 'v2016w52.0033-beta'
|
||||
>>> format_version(vinfo_a, pattern="vGGGGwVV.BUILD[-TAG]")
|
||||
'v2016w52.0033-beta'
|
||||
|
||||
# >>> vinfo_c = vinfo_b._replace(major=1, minor=2, patch=34, tag='final')
|
||||
>>> vinfo_c = vinfo_b._replace(major=1, minor=2, patch=34, tag='final')
|
||||
|
||||
# >>> format_version(vinfo_c, pattern="v{year}w{iso_week}.{BID}-{tag}")
|
||||
# 'v2017w52.33-final'
|
||||
# >>> format_version(vinfo_c, pattern="v{year}w{iso_week}.{BID}{release}")
|
||||
# 'v2017w52.33'
|
||||
# >>> format_version(vinfo_c, pattern="vYYYYwWW.BUILD-TAG")
|
||||
# 'v2017w52.33-final'
|
||||
# >>> format_version(vinfo_c, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
# 'v2017w52.33'
|
||||
>>> format_version(vinfo_c, pattern="vYYYYwWW.BUILD-TAG")
|
||||
'v2017w52.33-final'
|
||||
>>> format_version(vinfo_c, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
'v2017w52.33'
|
||||
|
||||
# >>> format_version(vinfo_c, pattern="v{MAJOR}.{MINOR}.{PATCH}")
|
||||
# 'v1.2.34'
|
||||
# >>> format_version(vinfo_c, pattern="vMAJOR.MINOR.PATCH")
|
||||
# 'v1.2.34'
|
||||
>>> format_version(vinfo_c, pattern="vMAJOR.MINOR.PATCH")
|
||||
'v1.2.34'
|
||||
|
||||
# >>> vinfo_d = vinfo_b._replace(major=1, minor=0, patch=0, tag='final')
|
||||
# >>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH-TAG")
|
||||
# 'v1.0.0-final'
|
||||
# >>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH[-TAG]")
|
||||
# 'v1.0.0'
|
||||
# >>> format_version(vinfo_d, pattern="vMAJOR.MINOR[.PATCH[-TAG]]")
|
||||
# 'v1.0'
|
||||
# >>> format_version(vinfo_d, pattern="vMAJOR.MINOR[.MICRO[-TAG]]")
|
||||
# 'v1.0'
|
||||
# >>> format_version(vinfo_d, pattern="vMAJOR[.MINOR[.PATCH[-TAG]]]")
|
||||
# 'v1'
|
||||
# """
|
||||
kwargs = _derive_template_kwargs(vinfo)
|
||||
format_tmpl = _compile_format_template(pattern, kwargs)
|
||||
>>> vinfo_d = vinfo_b._replace(major=1, minor=0, patch=0, tag='final')
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH-TAGNUM")
|
||||
'v1.0.0-final0'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH-TAG[NUM]")
|
||||
'v1.0.0-final'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH-TAG")
|
||||
'v1.0.0-final'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH[-TAG]")
|
||||
'v1.0.0'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR[.PATCH[-TAG]]")
|
||||
'v1.0'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR[.MICRO[-TAG]]")
|
||||
'v1.0'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR[.MINOR[.PATCH[-TAG]]]")
|
||||
'v1'
|
||||
"""
|
||||
kwargs = _format_part_values(vinfo)
|
||||
part_values = sorted(kwargs.items(), key=lambda item: -len(item[0]))
|
||||
version = pattern
|
||||
for part, value in part_values:
|
||||
version = version.replace(part, value)
|
||||
|
||||
return format_tmpl.format(**kwargs)
|
||||
return version
|
||||
|
||||
|
||||
def incr(
|
||||
old_version: str,
|
||||
pattern : str = "{pycalver}",
|
||||
pattern : str = "vYYYY0M.BUILD[-TAG]",
|
||||
*,
|
||||
release: str = None,
|
||||
major : bool = False,
|
||||
|
|
|
|||
|
|
@ -129,8 +129,25 @@ V2_PART_PATTERN_CASES = [
|
|||
(['0V'], "53", "53"),
|
||||
(['0V'], "54", None),
|
||||
(['MAJOR', 'MINOR', 'PATCH', 'MICRO'], "0", "0"),
|
||||
# ('TAG', ""),
|
||||
# ('PYTAG', ""),
|
||||
(['TAG' ], "alpha" , "alpha"),
|
||||
(['TAG' ], "alfa" , None),
|
||||
(['TAG' ], "beta" , "beta"),
|
||||
(['TAG' ], "dev" , "dev"),
|
||||
(['TAG' ], "rc" , "rc"),
|
||||
(['TAG' ], "post" , "post"),
|
||||
(['TAG' ], "final" , "final"),
|
||||
(['TAG' ], "latest", None),
|
||||
(['PYTAG'], "a" , "a"),
|
||||
(['PYTAG'], "b" , "b"),
|
||||
(['PYTAG'], "dev" , "dev"),
|
||||
(['PYTAG'], "rc" , "rc"),
|
||||
(['PYTAG'], "post" , "post"),
|
||||
(['PYTAG'], "post" , "post"),
|
||||
(['PYTAG'], "x" , None),
|
||||
(['NUM' ], "a" , None),
|
||||
(['NUM' ], "0" , "0"),
|
||||
(['NUM' ], "1" , "1"),
|
||||
(['NUM' ], "10" , "10"),
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -191,16 +208,16 @@ def test_re_pattern_parts(part_name, line, expected):
|
|||
assert result_val == expected, (part_name, line)
|
||||
|
||||
|
||||
PATTERN_CASES = [
|
||||
PATTERN_V1_CASES = [
|
||||
(r"v{year}.{month}.{MINOR}" , "v2017.11.1" , "v2017.11.1"),
|
||||
(r"v{year}.{month}.{MINOR}" , "v2017.07.12", "v2017.07.12"),
|
||||
(r"v{year}.{month_short}.{MINOR}", "v2017.11.1" , "v2017.11.1"),
|
||||
(r"v{year}.{month_short}.{MINOR}", "v2017.7.12" , "v2017.7.12"),
|
||||
(r"v{year}.{month_short}.{PATCH}", "v2017.11.1" , "v2017.11.1"),
|
||||
(r"v{year}.{month_short}.{PATCH}", "v2017.7.12" , "v2017.7.12"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("pattern_str, line, expected", PATTERN_CASES)
|
||||
def test_patterns(pattern_str, line, expected):
|
||||
@pytest.mark.parametrize("pattern_str, line, expected", PATTERN_V1_CASES)
|
||||
def test_patterns_v1(pattern_str, line, expected):
|
||||
pattern = v1patterns.compile_pattern(pattern_str)
|
||||
result = pattern.regexp.search(line)
|
||||
if result is None:
|
||||
|
|
@ -210,6 +227,24 @@ def test_patterns(pattern_str, line, expected):
|
|||
assert result_val == expected, (pattern_str, line)
|
||||
|
||||
|
||||
PATTERN_V2_CASES = [
|
||||
("vYYYY.0M.MINOR" , "v2017.11.1" , "v2017.11.1"),
|
||||
("vYYYY.0M.MINOR" , "v2017.07.12", "v2017.07.12"),
|
||||
("YYYY.MM[.PATCH]", "2017.11.1" , "2017.11.1"),
|
||||
("YYYY.MM[.PATCH]", "2017.7.12" , "2017.7.12"),
|
||||
("YYYY.MM[.PATCH]", "2017.7" , "2017.7"),
|
||||
("YYYY0M.BUILD" , "201707.1000", "201707.1000"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("pattern_str, line, expected", PATTERN_V2_CASES)
|
||||
def test_patterns_v2(pattern_str, line, expected):
|
||||
pattern = v2patterns.compile_pattern(pattern_str)
|
||||
result = pattern.regexp.search(line)
|
||||
result_val = None if result is None else result.group(0)
|
||||
assert result_val == expected, (pattern_str, line, pattern.regexp.pattern)
|
||||
|
||||
|
||||
CLI_MAIN_FIXTURE = """
|
||||
@click.group()
|
||||
@click.version_option(version="v201812.0123-beta")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue