diff --git a/src/pycalver/config.py b/src/pycalver/config.py index 3d47155..99353a8 100644 --- a/src/pycalver/config.py +++ b/src/pycalver/config.py @@ -248,44 +248,69 @@ def _compile_v2_file_patterns(raw_cfg: RawConfig) -> typ.Iterable[FilePatternsIt yield filepath, compiled_patterns +def _compile_file_patterns(raw_cfg: RawConfig, is_new_pattern: bool) -> PatternsByFile: + if is_new_pattern: + _file_pattern_items = _compile_v2_file_patterns(raw_cfg) + else: + _file_pattern_items = _compile_v1_file_patterns(raw_cfg) + + # NOTE (mb 2020-10-03): There can be multiple items for the same + # path, so this is not an option: + # + # return dict(_file_pattern_items) + + file_patterns: PatternsByFile = {} + for path, patterns in _file_pattern_items: + if path in file_patterns: + file_patterns[path].extend(patterns) + else: + file_patterns[path] = patterns + return file_patterns + + +def _validate_version_with_pattern( + current_version: str, + version_pattern: str, + is_new_pattern : bool, +) -> None: + """Provoke ValueError if version_pattern and current_version are not compatible.""" + if is_new_pattern: + v2version.parse_version_info(current_version, version_pattern) + else: + v1version.parse_version_info(current_version, version_pattern) + + if is_new_pattern: + invalid_chars = re.search(r"([\s]+)", version_pattern) + if invalid_chars: + errmsg = ( + f"Invalid character(s) '{invalid_chars.group(1)}'" + f' in pycalver.version_pattern = "{version_pattern}"' + ) + raise ValueError(errmsg) + if not v2version.is_valid_week_pattern(version_pattern): + errmsg = f"Invalid week number pattern: {version_pattern}" + raise ValueError(errmsg) + + def _parse_config(raw_cfg: RawConfig) -> Config: """Parse configuration which was loaded from an .ini/.cfg or .toml file.""" + commit_message: str = raw_cfg.get('commit_message', DEFAULT_COMMIT_MESSAGE) + commit_message = raw_cfg['commit_message'] = commit_message.strip("'\" ") + current_version: str = raw_cfg['current_version'] current_version = raw_cfg['current_version'] = current_version.strip("'\" ") version_pattern: str = raw_cfg['version_pattern'] version_pattern = raw_cfg['version_pattern'] = version_pattern.strip("'\" ") - commit_message: str = raw_cfg.get('commit_message', DEFAULT_COMMIT_MESSAGE) - commit_message = raw_cfg['commit_message'] = commit_message.strip("'\" ") - is_new_pattern = "{" not in version_pattern and "}" not in version_pattern - - if is_new_pattern: - invalid_chars = re.search(r"([\s]+)", raw_cfg['version_pattern']) - if invalid_chars: - raise ValueError( - f"Invalid character(s) '{invalid_chars.group(1)}'" - f" in pycalver.version_pattern = {raw_cfg['version_pattern']}" - ) - if not v2version.is_valid_week_pattern(version_pattern): - raise ValueError(f"Invalid week number pattern: {version_pattern}") - - # TODO (mb 2020-09-18): Validate Pattern - # detect YY with WW or UU -> suggest GG with VV - # detect YYMM -> suggest YY0M - # detect YYWW -> suggest YY0W - - # NOTE (mb 2019-01-05): Provoke ValueError if version_pattern - # and current_version are not compatible. - if is_new_pattern: - v2version.parse_version_info(current_version, version_pattern) - else: - v1version.parse_version_info(current_version, version_pattern) + _validate_version_with_pattern(current_version, version_pattern, is_new_pattern) pep440_version = version.to_pep440(current_version) + file_patterns = _compile_file_patterns(raw_cfg, is_new_pattern) + commit = raw_cfg['commit'] tag = raw_cfg['tag'] push = raw_cfg['push'] @@ -301,11 +326,6 @@ def _parse_config(raw_cfg: RawConfig) -> Config: if push and not commit: raise ValueError("pycalver.commit = true required if pycalver.push = true") - if is_new_pattern: - file_patterns = dict(_compile_v2_file_patterns(raw_cfg)) - else: - file_patterns = dict(_compile_v1_file_patterns(raw_cfg)) - cfg = Config( current_version=current_version, version_pattern=version_pattern, diff --git a/test/test_cli.py b/test/test_cli.py index eed8c2b..f225101 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -734,3 +734,33 @@ def test_grep(runner): search_re = r"^\s+3:\s+\[aka\. 201701\.1002a0 \!\]" assert re.search(search_re, result.output, flags=re.MULTILINE) + + +SETUP_CFG_MULTIMATCH_FILE_PATTERNS_FIXTURE = r""" +[pycalver] +current_version = "v201701.1002-alpha" +version_pattern = "{pycalver}" + +[pycalver:file_patterns] +setup.cfg = + current_version = "{version}" +README.md = + Hello World {version} ! +README.* = + [aka. {pep440_version} !] +""" + + +def test_multimatch_file_patterns(runner): + _add_project_files("README.md") + with pl.Path("setup.cfg").open(mode="w", encoding="utf-8") as fobj: + fobj.write(SETUP_CFG_MULTIMATCH_FILE_PATTERNS_FIXTURE) + + result = runner.invoke(cli, ['bump', '--release', 'beta']) + assert result.exit_code == 0 + + with pl.Path("README.md").open(mode="r", encoding="utf-8") as fobj: + readme_text = fobj.read() + + assert "Hello World v202010.1003-beta !" in readme_text + assert "[aka. 202010.1003b0 !]" in readme_text