Skip to content

Commit b473a19

Browse files
committed
Added configuration option ignore_missing_files
1 parent b2e4743 commit b473a19

13 files changed

+322
-192
lines changed

bumpversion/cli.py

+8
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,12 @@ def show(args: List[str], config_file: Optional[str], format_: str, increment: O
444444
envvar="BUMPVERSION_IGNORE_MISSING_VERSION",
445445
help="Ignore any Version Not Found errors when searching and replacing in files.",
446446
)
447+
@click.option(
448+
"--ignore-missing-files",
449+
is_flag=True,
450+
envvar="BUMPVERSION_IGNORE_MISSING_FILES",
451+
help="Ignore any missing files when searching and replacing in files.",
452+
)
447453
@click.option(
448454
"--dry-run",
449455
"-n",
@@ -465,6 +471,7 @@ def replace(
465471
regex: bool,
466472
no_configured_files: bool,
467473
ignore_missing_version: bool,
474+
ignore_missing_files: bool,
468475
dry_run: bool,
469476
) -> None:
470477
"""
@@ -492,6 +499,7 @@ def replace(
492499
message=None,
493500
commit_args=None,
494501
ignore_missing_version=ignore_missing_version,
502+
ignore_missing_files=ignore_missing_files,
495503
regex=regex,
496504
)
497505

bumpversion/config/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"replace": "{new_version}",
2323
"regex": False,
2424
"ignore_missing_version": False,
25+
"ignore_missing_files": False,
2526
"tag": False,
2627
"sign_tags": False,
2728
"tag_name": "v{new_version}",

bumpversion/config/files.py

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def update_config_file(
141141
replace=config.replace,
142142
regex=config.regex,
143143
ignore_missing_version=True,
144+
ignore_missing_file=True,
144145
serialize=config.serialize,
145146
parse=config.parse,
146147
)

bumpversion/config/models.py

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class FileChange(BaseModel):
3030
replace: str
3131
regex: bool
3232
ignore_missing_version: bool
33+
ignore_missing_file: bool
3334
filename: Optional[str] = None
3435
glob: Optional[str] = None # Conflicts with filename. If both are specified, glob wins
3536
key_path: Optional[str] = None # If specified, and has an appropriate extension, will be treated as a data file
@@ -84,6 +85,7 @@ class Config(BaseSettings):
8485
replace: str
8586
regex: bool
8687
ignore_missing_version: bool
88+
ignore_missing_files: bool
8789
tag: bool
8890
sign_tags: bool
8991
tag_name: str
@@ -116,6 +118,7 @@ def add_files(self, filename: Union[str, List[str]]) -> None:
116118
replace=self.replace,
117119
regex=self.regex,
118120
ignore_missing_version=self.ignore_missing_version,
121+
ignore_missing_file=self.ignore_missing_files,
119122
)
120123
)
121124
self.files = list(files)

bumpversion/config/utils.py

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def get_all_file_configs(config_dict: dict) -> List[FileChange]:
1818
"search": config_dict["search"],
1919
"replace": config_dict["replace"],
2020
"ignore_missing_version": config_dict["ignore_missing_version"],
21+
"ignore_missing_file": config_dict["ignore_missing_files"],
2122
"regex": config_dict["regex"],
2223
}
2324
files = [{k: v for k, v in filecfg.items() if v is not None} for filecfg in config_dict["files"]]

bumpversion/files.py

+8
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def __init__(
8686
replace=replacement,
8787
regex=file_change.regex or False,
8888
ignore_missing_version=file_change.ignore_missing_version or False,
89+
ignore_missing_file=file_change.ignore_missing_file or False,
8990
filename=file_change.filename,
9091
glob=file_change.glob,
9192
key_path=file_change.key_path,
@@ -176,6 +177,12 @@ def make_file_change(
176177
self.file_change.replace,
177178
)
178179
logger.indent()
180+
if not os.path.exists(self.file_change.filename):
181+
if self.file_change.ignore_missing_file:
182+
logger.info("File not found, but ignoring")
183+
logger.dedent()
184+
return
185+
raise FileNotFoundError(f"File not found: '{self.file_change.filename}'")
179186
logger.debug("Serializing the current version")
180187
logger.indent()
181188
context["current_version"] = self.version_config.serialize(current_version, context)
@@ -273,6 +280,7 @@ def __init__(
273280
search=search or file_change.search or version_config.search,
274281
replace=replace or file_change.replace or version_config.replace,
275282
regex=file_change.regex or False,
283+
ignore_missing_file=file_change.ignore_missing_file or False,
276284
ignore_missing_version=file_change.ignore_missing_version or False,
277285
filename=file_change.filename,
278286
glob=file_change.glob,

tests/fixtures/basic_cfg_expected.txt

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
'excluded_paths': [],
66
'files': [{'filename': 'setup.py',
77
'glob': None,
8+
'ignore_missing_file': False,
89
'ignore_missing_version': False,
910
'key_path': None,
1011
'parse': '(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?',
@@ -15,6 +16,7 @@
1516
'{major}.{minor}.{patch}')},
1617
{'filename': 'bumpversion/__init__.py',
1718
'glob': None,
19+
'ignore_missing_file': False,
1820
'ignore_missing_version': False,
1921
'key_path': None,
2022
'parse': '(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?',
@@ -25,6 +27,7 @@
2527
'{major}.{minor}.{patch}')},
2628
{'filename': 'CHANGELOG.md',
2729
'glob': None,
30+
'ignore_missing_file': False,
2831
'ignore_missing_version': False,
2932
'key_path': None,
3033
'parse': '(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?',
@@ -33,6 +36,7 @@
3336
'search': '**unreleased**',
3437
'serialize': ('{major}.{minor}.{patch}-{release}',
3538
'{major}.{minor}.{patch}')}],
39+
'ignore_missing_files': False,
3640
'ignore_missing_version': False,
3741
'included_paths': [],
3842
'message': 'Bump version: {current_version} → {new_version}',

tests/fixtures/basic_cfg_expected.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ excluded_paths:
77
files:
88
- filename: "setup.py"
99
glob: null
10+
ignore_missing_file: false
1011
ignore_missing_version: false
1112
key_path: null
1213
parse: "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?"
@@ -18,6 +19,7 @@ files:
1819
- "{major}.{minor}.{patch}"
1920
- filename: "bumpversion/__init__.py"
2021
glob: null
22+
ignore_missing_file: false
2123
ignore_missing_version: false
2224
key_path: null
2325
parse: "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?"
@@ -29,6 +31,7 @@ files:
2931
- "{major}.{minor}.{patch}"
3032
- filename: "CHANGELOG.md"
3133
glob: null
34+
ignore_missing_file: false
3235
ignore_missing_version: false
3336
key_path: null
3437
parse: "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?"
@@ -38,6 +41,7 @@ files:
3841
serialize:
3942
- "{major}.{minor}.{patch}-{release}"
4043
- "{major}.{minor}.{patch}"
44+
ignore_missing_files: false
4145
ignore_missing_version: false
4246
included_paths:
4347

tests/fixtures/basic_cfg_expected_full.json

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
{
99
"filename": "setup.py",
1010
"glob": null,
11+
"ignore_missing_file": false,
1112
"ignore_missing_version": false,
1213
"key_path": null,
1314
"parse": "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?",
@@ -22,6 +23,7 @@
2223
{
2324
"filename": "bumpversion/__init__.py",
2425
"glob": null,
26+
"ignore_missing_file": false,
2527
"ignore_missing_version": false,
2628
"key_path": null,
2729
"parse": "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?",
@@ -36,6 +38,7 @@
3638
{
3739
"filename": "CHANGELOG.md",
3840
"glob": null,
41+
"ignore_missing_file": false,
3942
"ignore_missing_version": false,
4043
"key_path": null,
4144
"parse": "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?",
@@ -48,6 +51,7 @@
4851
]
4952
}
5053
],
54+
"ignore_missing_files": false,
5155
"ignore_missing_version": false,
5256
"included_paths": [],
5357
"message": "Bump version: {current_version} \u2192 {new_version}",

tests/test_cli/test_bump.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def test_with_version_part_includes_new_version(self, tmp_path: Path, fixtures_p
8989
"search={current_version}",
9090
"replace={new_version}",
9191
"regex=False",
92+
"ignore_missing_files=False",
9293
"ignore_missing_version=False",
9394
"included_paths=[]",
9495
"tag=True",
@@ -105,19 +106,19 @@ def test_with_version_part_includes_new_version(self, tmp_path: Path, fixtures_p
105106
"'serialize': ('{major}.{minor}.{patch}-{release}', "
106107
"'{major}.{minor}.{patch}'), 'search': '{current_version}', 'replace': "
107108
"'{new_version}', 'regex': False, 'ignore_missing_version': False, "
108-
"'filename': 'setup.py', 'glob': None, 'key_path': None}, {'parse': "
109+
"'ignore_missing_file': False, 'filename': 'setup.py', 'glob': None, 'key_path': None}, {'parse': "
109110
"'(?P<major>\\\\d+)\\\\.(?P<minor>\\\\d+)\\\\.(?P<patch>\\\\d+)(\\\\-(?P<release>[a-z]+))?', "
110111
"'serialize': ('{major}.{minor}.{patch}-{release}', "
111112
"'{major}.{minor}.{patch}'), 'search': '{current_version}', 'replace': "
112113
"'{new_version}', 'regex': False, 'ignore_missing_version': False, "
113-
"'filename': 'bumpversion/__init__.py', 'glob': None, 'key_path': None}, "
114+
"'ignore_missing_file': False, 'filename': 'bumpversion/__init__.py', 'glob': None, 'key_path': None}, "
114115
"{'parse': "
115116
"'(?P<major>\\\\d+)\\\\.(?P<minor>\\\\d+)\\\\.(?P<patch>\\\\d+)(\\\\-(?P<release>[a-z]+))?', "
116117
"'serialize': ('{major}.{minor}.{patch}-{release}', "
117118
"'{major}.{minor}.{patch}'), 'search': '**unreleased**', 'replace': "
118119
"'**unreleased**\\n**v{new_version}**', 'regex': False, "
119-
"'ignore_missing_version': False, 'filename': 'CHANGELOG.md', 'glob': None, "
120-
"'key_path': None}]"
120+
"'ignore_missing_version': False, 'ignore_missing_file': False, 'filename': 'CHANGELOG.md', "
121+
"'glob': None, 'key_path': None}]"
121122
),
122123
}
123124

@@ -148,6 +149,7 @@ def test_without_version_part_excludes_new_version(self, tmp_path: Path, fixture
148149
"search={current_version}",
149150
"replace={new_version}",
150151
"regex=False",
152+
"ignore_missing_files=False",
151153
"ignore_missing_version=False",
152154
"included_paths=[]",
153155
"tag=True",
@@ -164,19 +166,19 @@ def test_without_version_part_excludes_new_version(self, tmp_path: Path, fixture
164166
"'serialize': ('{major}.{minor}.{patch}-{release}', "
165167
"'{major}.{minor}.{patch}'), 'search': '{current_version}', 'replace': "
166168
"'{new_version}', 'regex': False, 'ignore_missing_version': False, "
167-
"'filename': 'setup.py', 'glob': None, 'key_path': None}, {'parse': "
169+
"'ignore_missing_file': False, 'filename': 'setup.py', 'glob': None, 'key_path': None}, {'parse': "
168170
"'(?P<major>\\\\d+)\\\\.(?P<minor>\\\\d+)\\\\.(?P<patch>\\\\d+)(\\\\-(?P<release>[a-z]+))?', "
169171
"'serialize': ('{major}.{minor}.{patch}-{release}', "
170172
"'{major}.{minor}.{patch}'), 'search': '{current_version}', 'replace': "
171173
"'{new_version}', 'regex': False, 'ignore_missing_version': False, "
172-
"'filename': 'bumpversion/__init__.py', 'glob': None, 'key_path': None}, "
174+
"'ignore_missing_file': False, 'filename': 'bumpversion/__init__.py', 'glob': None, 'key_path': None}, "
173175
"{'parse': "
174176
"'(?P<major>\\\\d+)\\\\.(?P<minor>\\\\d+)\\\\.(?P<patch>\\\\d+)(\\\\-(?P<release>[a-z]+))?', "
175177
"'serialize': ('{major}.{minor}.{patch}-{release}', "
176178
"'{major}.{minor}.{patch}'), 'search': '**unreleased**', 'replace': "
177179
"'**unreleased**\\n**v{new_version}**', 'regex': False, "
178-
"'ignore_missing_version': False, 'filename': 'CHANGELOG.md', 'glob': None, "
179-
"'key_path': None}]"
180+
"'ignore_missing_version': False, 'ignore_missing_file': False, 'filename': 'CHANGELOG.md', "
181+
"'glob': None, 'key_path': None}]"
180182
),
181183
}
182184

0 commit comments

Comments
 (0)