Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/bumpver/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@
class Pattern(typ.NamedTuple):

version_pattern: str # "{pycalver}", "{year}.{month}", "vYYYY0M.BUILD"
raw_pattern : str # '__version__ = "{version}"', "Copyright (c) YYYY"
regexp : typ.Pattern[str]
# This should be called 'norm_pattern' or similar:
raw_pattern : str # '__version__ = "{version}"', "Copyright (c) YYYY"
regexp : typ.Pattern[str]
replacement_pattern : str = None


RE_PATTERN_ESCAPES = [
("\u005c", "\u005c\u005c"),
("-" , "\u005c-"),
("." , "\u005c."),
("+" , "\u005c+"),
("*" , "\u005c*"),
("?" , "\u005c?"),
# ("+" , "\u005c+"),
# ("*" , "\u005c*"),
# ("?" , "\u005c?"),
("{" , "\u005c{"),
("}" , "\u005c}"),
("[" , "\u005c["),
Expand Down
26 changes: 22 additions & 4 deletions src/bumpver/v2patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,31 @@ def _compile_pattern_re(normalized_pattern: str) -> typ.Pattern[str]:
pattern_str = _replace_pattern_parts(escaped_pattern)
return re.compile(pattern_str)

def _compile_replacement_pattern(version_pattern, raw_pattern) -> typ.Optional[typ.Pattern[str]]:
if not raw_pattern:
return None
if "{version}" not in raw_pattern:
return None

replacement_target = "{version}"
version_match = re.search(replacement_target, raw_pattern)
if not version_match:
return None

span_l, span_r = version_match.span()
group_1 = raw_pattern[:span_l]
group_3 = raw_pattern[span_r:]
replacement_pattern = re.compile(f"({group_1})(.+?)({group_3})")
return replacement_pattern

@utils.memo
def compile_pattern(version_pattern: str, raw_pattern: typ.Optional[str] = None) -> Pattern:
_raw_pattern = version_pattern if raw_pattern is None else raw_pattern
normalized_pattern = normalize_pattern(version_pattern, _raw_pattern)
regexp = _compile_pattern_re(normalized_pattern)
return Pattern(version_pattern, normalized_pattern, regexp)
_raw_pattern = version_pattern if raw_pattern is None else raw_pattern
normalized_pattern = normalize_pattern(version_pattern, _raw_pattern)
regexp = _compile_pattern_re(normalized_pattern)
replacement_pattern = _compile_replacement_pattern(version_pattern, raw_pattern)

return Pattern(version_pattern, normalized_pattern, regexp, replacement_pattern)


def compile_patterns(version_pattern: str, raw_patterns: typ.List[str]) -> typ.List[Pattern]:
Expand Down
19 changes: 13 additions & 6 deletions src/bumpver/v2rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""Rewrite files, updating occurences of version strings."""

import io
import re
import typing as typ
import logging

Expand All @@ -32,12 +33,18 @@ def rewrite_lines(
new_lines = old_lines[:]
for match in parse.iter_matches(old_lines, patterns):
found_patterns.add(match.pattern)
normalized_pattern = v2patterns.normalize_pattern(
match.pattern.version_pattern, match.pattern.raw_pattern
)
replacement = v2version.format_version(new_vinfo, normalized_pattern)
span_l, span_r = match.span
new_line = match.line[:span_l] + replacement + match.line[span_r:]

if match.pattern.replacement_pattern is not None:
replacement_version = v2version.format_version(new_vinfo, match.pattern.version_pattern)
new_line = match.pattern.replacement_pattern.sub(rf"\g<1>{replacement_version}\g<3>", match.line)
else:
normalized_pattern = v2patterns.normalize_pattern(
match.pattern.version_pattern, match.pattern.raw_pattern
)
replacement = v2version.format_version(new_vinfo, normalized_pattern)
span_l, span_r = match.span
new_line = match.line[:span_l] + replacement + match.line[span_r:]

new_lines[match.lineno] = new_line

if set(patterns) == found_patterns:
Expand Down
16 changes: 16 additions & 0 deletions test/test_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,22 @@ def test_v2_patterns(pattern_str, line, expected):
assert result_val == expected, (pattern_str, line, pattern.regexp.pattern)


def test_v2_patterns_with_whitespace():
pattern_str = r'^__version__\s+=\s+"{version}"'
pattern = v2patterns.compile_pattern("MAJOR.MINOR.PATCH", pattern_str)
result = pattern.regexp.search('__version__ = "0.1.0"')
assert(result is not None)

result = pattern.regexp.search('__version__ = "0.1.0"')
assert(result is not None)

result = pattern.regexp.search('__version__ = "0.1.0"')
assert(result is not None)

result = pattern.regexp.search('__version__ = "0.1.0" ')
assert(result is not None)


def test_epoch_pattern():
raw_pattern = v2patterns.normalize_pattern("v1!MAJOR.MINOR.PATCH", "{version}")
pattern = v2patterns.compile_pattern(raw_pattern)
Expand Down
9 changes: 9 additions & 0 deletions test/test_rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ def test_v2_rewrite_lines():
lines = v2rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
assert lines == ['__version__ = "201811.123b0"']

def test_v2_rewrite_lines_whitespace():
version_pattern = "MAJOR.MINOR.PATCH"
base_pattern = r'__version__\s+=\s+"{version}"'
new_version = "0.2.0"
new_vinfo = v2version.parse_version_info(new_version, version_pattern)
patterns = [v2patterns.compile_pattern(version_pattern, base_pattern)]
lines = v2rewrite.rewrite_lines(patterns, new_vinfo, ['__version__ = "0.1.0" '])
assert lines == ['__version__ = "0.2.0" ']


def test_v1_rewrite_final():
# Patterns written with {release_tag} placeholder preserve
Expand Down