fixes for new style patterns

This commit is contained in:
Manuel Barkhau 2020-09-18 16:52:28 +00:00
parent 8edb001782
commit 09299f30f1
3 changed files with 104 additions and 63 deletions

View file

@ -23,18 +23,23 @@ def rewrite_lines(
new_vinfo : v2version.VersionInfo, new_vinfo : v2version.VersionInfo,
old_lines : typ.List[str], old_lines : typ.List[str],
) -> typ.List[str]: ) -> typ.List[str]:
# TODO reenable doctest """Replace occurances of pattern_strs in old_lines with new_vinfo.
# """Replace occurances of pattern_strs in old_lines with new_vinfo.
# >>> new_vinfo = version.parse_version_info("v201811.0123-beta") >>> new_vinfo = v2version.parse_version_info("v201811.0123-beta")
# >>> pattern_strs = ['__version__ = "{pycalver}"'] >>> pattern_strs = ['__version__ = "vYYYY0M.BUILD[-TAG]"']
# >>> rewrite_lines(pattern_strs, new_vinfo, ['__version__ = "v201809.0002-beta"']) >>> old_lines = ['__version__ = "v201809.0002-alpha" ']
# ['__version__ = "v201811.0123-beta"'] >>> rewrite_lines(pattern_strs, new_vinfo, old_lines)
['__version__ = "v201811.0123-beta" ']
# >>> pattern_strs = ['__version__ = "{pep440_version}"'] >>> old_lines = ['__version__ = "v201809.0002-alpha" # comment']
# >>> rewrite_lines(pattern_strs, new_vinfo, ['__version__ = "201809.2b0"']) >>> rewrite_lines(pattern_strs, new_vinfo, old_lines)
# ['__version__ = "201811.123b0"'] ['__version__ = "v201811.0123-beta" # comment']
# """
>>> pattern_strs = ['__version__ = "YYYY0M.BLD[PYTAGNUM]"']
>>> old_lines = ['__version__ = "201809.2a0"']
>>> rewrite_lines(pattern_strs, new_vinfo, old_lines)
['__version__ = "201811.123b0"']
"""
new_lines = old_lines[:] new_lines = old_lines[:]
found_patterns = set() found_patterns = set()

View file

@ -411,10 +411,70 @@ def _make_segments(pattern: str) -> typ.List[str]:
pattern_segs_r.append(seg_r) pattern_segs_r.append(seg_r)
pattern_segs_l.append(pattern_rest) pattern_segs_l.append(pattern_rest)
return pattern_segs_l + list(reversed(pattern_segs_r))
# NOTE (mb 2020-09-18): The pivot makes subsequent code a bit more simple
pivot = [""] def _clear_zero_segments(
return pattern_segs_l + pivot + list(reversed(pattern_segs_r)) formatted_segs: typ.List[str], is_zero_segment: typ.List[bool]
) -> typ.List[str]:
non_zero_segs = list(formatted_segs)
has_val_to_right = False
for idx, is_zero in reversed(list(enumerate(is_zero_segment))):
is_optional = 0 < idx < len(formatted_segs) - 1
if is_optional:
if is_zero and not has_val_to_right:
non_zero_segs[idx] = ""
else:
has_val_to_right = True
return non_zero_segs
def _format_segments(
vinfo : VersionInfo,
pattern_segs: typ.List[str],
) -> typ.List[str]:
kwargs = _format_part_values(vinfo)
part_values = sorted(kwargs.items(), key=lambda item: -len(item[0]))
is_zero_segment = [True] * len(pattern_segs)
formatted_segs_l: typ.List[str] = []
formatted_segs_r: typ.List[str] = []
idx_l = 0
idx_r = len(pattern_segs) - 1
while idx_l <= idx_r:
# NOTE (mb 2020-09-18): All segments are optional,
# except the most left and the most right,
# i.e the ones NOT surrounded by braces.
# Empty string is a valid segment.
is_optional = idx_l > 0
seg_l = pattern_segs[idx_l]
seg_r = pattern_segs[idx_r]
for part, part_value in part_values:
if part in seg_l:
seg_l = seg_l.replace(part, part_value)
if not (is_optional and str(part_value) == ZERO_VALUES.get(part)):
is_zero_segment[idx_l] = False
if part in seg_r:
seg_r = seg_r.replace(part, part_value)
if not (is_optional and str(part_value) == ZERO_VALUES[part]):
is_zero_segment[idx_r] = False
formatted_segs_l.append(seg_l)
if idx_l < idx_r:
formatted_segs_r.append(seg_r)
idx_l += 1
idx_r -= 1
formatted_segs = formatted_segs_l + list(reversed(formatted_segs_r))
return _clear_zero_segments(formatted_segs, is_zero_segment)
def format_version(vinfo: VersionInfo, pattern: str) -> str: def format_version(vinfo: VersionInfo, pattern: str) -> str:
@ -500,57 +560,13 @@ def format_version(vinfo: VersionInfo, pattern: str) -> str:
>>> vinfo_d = vinfo_b._replace(major=1, minor=0, patch=0, tag='rc', num=2) >>> vinfo_d = vinfo_b._replace(major=1, minor=0, patch=0, tag='rc', num=2)
>>> format_version(vinfo_d, pattern="vMAJOR[.MINOR[.PATCH[-TAG[NUM]]]]") >>> format_version(vinfo_d, pattern="vMAJOR[.MINOR[.PATCH[-TAG[NUM]]]]")
'v1.0.0-rc2' 'v1.0.0-rc2'
>>> vinfo_d = vinfo_b._replace(major=1, minor=0, patch=0, tag='rc', num=2)
>>> format_version(vinfo_d, pattern='__version__ = "vMAJOR[.MINOR[.PATCH[-TAG[NUM]]]]"')
'__version__ = "v1.0.0-rc2"'
""" """
kwargs = _format_part_values(vinfo)
part_values = sorted(kwargs.items(), key=lambda item: -len(item[0]))
pattern_segs = _make_segments(pattern) pattern_segs = _make_segments(pattern)
formatted_segs = _format_segments(vinfo, pattern_segs)
iszero_segment = [True] * len(pattern_segs)
formatted_segs_l: typ.List[str] = []
formatted_segs_r: typ.List[str] = []
used_part_values = []
idx_l = 0
idx_r = len(pattern_segs) - 1
while idx_l < idx_r:
# NOTE (mb 2020-09-18): All segments are optional,
# except the most left and the most right,
# i.e the ones NOT surrounded by braces.
# Empty string is a valid segment.
is_optional = idx_l > 0
seg_l = pattern_segs[idx_l]
seg_r = pattern_segs[idx_r]
for part, part_value in part_values:
if part in seg_l:
used_part_values.append(part + "=" + part_value)
seg_l = seg_l.replace(part, part_value)
if not (is_optional and str(part_value) == ZERO_VALUES.get(part)):
iszero_segment[idx_l] = False
if part in seg_r:
used_part_values.append(part + "=" + part_value)
seg_r = seg_r.replace(part, part_value)
if not (is_optional and str(part_value) == ZERO_VALUES[part]):
iszero_segment[idx_r] = False
formatted_segs_l.append(seg_l)
formatted_segs_r.append(seg_r)
idx_l += 1
idx_r -= 1
formatted_segs = formatted_segs_l + list(reversed(formatted_segs_r))
has_val_to_right = False
for idx, is_zero in reversed(list(enumerate(iszero_segment))):
if is_zero and not has_val_to_right:
formatted_segs[idx] = ""
else:
has_val_to_right = True
return "".join(formatted_segs) return "".join(formatted_segs)

View file

@ -205,6 +205,17 @@ def test_v2_parse_versions():
assert vnfo == v2version._parse_version_info(fvals) assert vnfo == v2version._parse_version_info(fvals)
def test_make_segments():
segs = v2version._make_segments("vYYYY0M.BUILD[-TAG[NUM]]")
assert segs == ["vYYYY0M.BUILD", "-TAG", "NUM", "", ""]
segs = v2version._make_segments('__version__ = "YYYY0M.BLD[PYTAGNUM]"')
assert segs == ['__version__ = "YYYY0M.BLD', 'PYTAGNUM', '"']
segs = v2version._make_segments('__version__ = "YYYY.BUILD[-TAG]"')
assert segs == ['__version__ = "YYYY.BUILD', '-TAG', '"']
def test_v2_format_version(): def test_v2_format_version():
pattern = "vYYYY0M.BUILD[-TAG[NUM]]" pattern = "vYYYY0M.BUILD[-TAG[NUM]]"
in_version = "v200701.0033-beta" in_version = "v200701.0033-beta"
@ -218,3 +229,12 @@ def test_v2_format_version():
result = v2version.format_version(vinfo, pattern="vYY.BLD[-TAG]") result = v2version.format_version(vinfo, pattern="vYY.BLD[-TAG]")
assert result == "v7.33-beta" assert result == "v7.33-beta"
result = v2version.format_version(vinfo, pattern="vYY.BLD-TAG")
assert result == "v7.33-beta"
result = v2version.format_version(vinfo, pattern='__version__ = "YYYY.BUILD[-TAG]"')
assert result == '__version__ = "2007.0033-beta"'
result = v2version.format_version(vinfo, pattern='__version__ = "YYYY.BLD"')
assert result == '__version__ = "2007.33"'