fix: escaping in patterns

This commit is contained in:
Manuel Barkhau 2018-12-20 15:28:11 +01:00
parent 65446440f7
commit 70c2b27157
4 changed files with 45 additions and 6 deletions

View file

@ -82,6 +82,8 @@ setup.py =
version="{pep440_version}" version="{pep440_version}"
src/pycalver/__init__.py = src/pycalver/__init__.py =
__version__ = "{version}" __version__ = "{version}"
src/pycalver/__main__.py =
click.version_option(version="{version}")
README.md = README.md =
[PyCalVer {version}] [PyCalVer {version}]
https://img.shields.io/badge/PyCalVer-{calver}{build}-{release}-blue.svg https://img.shields.io/badge/PyCalVer-{calver}{build}-{release}-blue.svg

View file

@ -57,7 +57,7 @@ def _init_logging(verbose: int = 0) -> None:
@click.group() @click.group()
@click.version_option() @click.version_option(version="v201812.0010-beta")
@click.help_option() @click.help_option()
@click.option('-v', '--verbose', count=True, help="Control log level. -vv for debug level.") @click.option('-v', '--verbose', count=True, help="Control log level. -vv for debug level.")
def cli(verbose: int = 0): def cli(verbose: int = 0):

View file

@ -21,8 +21,12 @@ PATTERN_ESCAPES = [
("." , "\u005c."), ("." , "\u005c."),
("+" , "\u005c+"), ("+" , "\u005c+"),
("*" , "\u005c*"), ("*" , "\u005c*"),
("{" , "\u005c{{"),
("}" , "\u005c}}"),
("[" , "\u005c["), ("[" , "\u005c["),
("]" , "\u005c]"),
("(" , "\u005c("), ("(" , "\u005c("),
(")" , "\u005c)"),
] ]
# NOTE (mb 2018-09-03): These are matchers for parts, which are # NOTE (mb 2018-09-03): These are matchers for parts, which are
@ -54,17 +58,25 @@ class PatternMatch(typ.NamedTuple):
PatternMatches = typ.Iterable[PatternMatch] PatternMatches = typ.Iterable[PatternMatch]
def _iter_for_pattern(lines: typ.List[str], pattern: str) -> PatternMatches: def compile_pattern(pattern: str) -> typ.Pattern[str] :
# The pattern is escaped, so that everything besides the format
# string variables is treated literally.
pattern_tmpl = pattern pattern_tmpl = pattern
for char, escaped in PATTERN_ESCAPES: for char, escaped in PATTERN_ESCAPES:
pattern_tmpl = pattern_tmpl.replace(char, escaped) pattern_tmpl = pattern_tmpl.replace(char, escaped)
# undo escaping only for valid part names
for part_name in RE_PATTERN_PARTS.keys():
pattern_tmpl = pattern_tmpl.replace("\u005c{{" + part_name + "\u005c}}", "{" + part_name + "}")
pattern_str = pattern_tmpl.format(**RE_PATTERN_PARTS) pattern_str = pattern_tmpl.format(**RE_PATTERN_PARTS)
pattern_re = re.compile(pattern_str) return re.compile(pattern_str)
def _iter_for_pattern(lines: typ.List[str], pattern: str) -> PatternMatches:
# The pattern is escaped, so that everything besides the format
# string variables is treated literally.
pattern_re = compile_pattern(pattern)
for lineno, line in enumerate(lines): for lineno, line in enumerate(lines):
match = pattern_re.search(line) match = pattern_re.search(line)
if match: if match:

View file

@ -115,3 +115,28 @@ def test_badge_parse_patterns():
assert matches[0].match == "badge/CalVer-v201809.0002--beta-blue.svg" assert matches[0].match == "badge/CalVer-v201809.0002--beta-blue.svg"
assert matches[1].match == ":alt: CalVer v201809.0002-beta" assert matches[1].match == ":alt: CalVer v201809.0002-beta"
CLI_MAIN_FIXTURE = """
@click.group()
@click.version_option(version="v201812.0123-beta")
@click.help_option()
"""
def test_pattern_escapes():
pattern_re = parse.compile_pattern(r'click.version_option(version="{version}")')
match = pattern_re.search(CLI_MAIN_FIXTURE)
assert match.group(0) == 'click.version_option(version="v201812.0123-beta")'
CURLY_BRACE_FIXTURE = """
package_metadata = {"name": "mypackage", "version": "v201812.0123-beta"}
"""
def test_curly_escapes():
pattern = r'package_metadata = {"name": "mypackage", "version": "{version}"}'
pattern_re = parse.compile_pattern(pattern)
match = pattern_re.search(CURLY_BRACE_FIXTURE)
assert match.group(0) == 'package_metadata = {"name": "mypackage", "version": "v201812.0123-beta"}'