diff --git a/README.md b/README.md index 4f6fbf3..9bad4fc 100644 --- a/README.md +++ b/README.md @@ -296,7 +296,11 @@ values = ### Configuration file -- File specific configuration -This configuration is in the section: `[bumpversion:file:…]` +This configuration is in the section: `[bumpversion:file:…]` or `[bumpversion:glob:…]` + +Both, `file:` and `glob:` are configured the same. Their difference is that +file will match file names directly like `requirements.txt`. While glob also +matches multiple files via wildcards like `**/pom.xml`. Note: The configuration file format requires each section header to be unique. If you want to process a certain file multiple times, diff --git a/bumpversion/cli.py b/bumpversion/cli.py index 67652eb..8825adf 100644 --- a/bumpversion/cli.py +++ b/bumpversion/cli.py @@ -1,5 +1,6 @@ import argparse from datetime import datetime +import glob import io import itertools import logging @@ -49,7 +50,7 @@ # bumpversion:file ( suffix with spaces):value RE_DETECT_SECTION_TYPE = re.compile( r"^bumpversion:" - r"((?Pfile)(\s*\(\s*(?P[^\):]+)\)?)?|(?Ppart)):" + r"((?Pfile|glob)(\s*\(\s*(?P[^\):]+)\)?)?|(?Ppart)):" r"(?P.+)", ) @@ -353,8 +354,12 @@ def _load_configuration(config_file, explicit_config, defaults): if "replace" not in section_config: section_config["replace"] = defaults.get("replace", "{new_version}") - files.append(ConfiguredFile(filename, VersionConfig(**section_config))) - + version_config = VersionConfig(**section_config) + if section_type.get("file") == "glob": + for filename_glob in glob.glob(filename, recursive=True): + files.append(ConfiguredFile(filename_glob, version_config)) + else: + files.append(ConfiguredFile(filename, version_config)) return config, config_file_exists, config_newlines, part_configs, files diff --git a/tests/test_cli.py b/tests/test_cli.py index 9ee3b86..8a33b0d 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -292,6 +292,36 @@ def test_default_config_files(tmpdir, configfile): assert "0.10.3" == tmpdir.join("file2").read() +def test_glob_keyword(tmpdir, configfile): + tmpdir.join("file1.txt").write("0.9.34") + tmpdir.join("file2.txt").write("0.9.34") + tmpdir.join(configfile).write("""[bumpversion] +current_version: 0.9.34 +new_version: 0.9.35 +[bumpversion:glob:*.txt]""") + + tmpdir.chdir() + main(["patch"]) + assert "0.9.35" == tmpdir.join("file1.txt").read() + assert "0.9.35" == tmpdir.join("file2.txt").read() + +def test_glob_keyword_recursive(tmpdir, configfile): + tmpdir.mkdir("subdir").mkdir("subdir2") + file1 = tmpdir.join("subdir").join("file1.txt") + file1.write("0.9.34") + file2 = tmpdir.join("subdir").join("subdir2").join("file2.txt") + file2.write("0.9.34") + tmpdir.join(configfile).write("""[bumpversion] +current_version: 0.9.34 +new_version: 0.9.35 +[bumpversion:glob:**/*.txt]""") + + tmpdir.chdir() + main(["patch"]) + assert "0.9.35" == file1.read() + assert "0.9.35" == file2.read() + + def test_file_keyword_with_suffix_is_accepted(tmpdir, configfile, file_keyword): tmpdir.join("file2").write("0.10.2") tmpdir.join(configfile).write(