diff --git a/bumpversion/cli.py b/bumpversion/cli.py index 7b9cc86e..bcb08d26 100644 --- a/bumpversion/cli.py +++ b/bumpversion/cli.py @@ -141,7 +141,7 @@ def cli(ctx: Context) -> None: ) @click.option( "--regex/--no-regex", - default=False, + default=None, envvar="BUMPVERSION_REGEX", help="Treat the search parameter as a regular expression or explicitly do not treat it as a regular expression.", ) @@ -232,7 +232,7 @@ def bump( serialize: Optional[List[str]], search: Optional[str], replace: Optional[str], - regex: bool, + regex: Optional[bool], no_configured_files: bool, ignore_missing_version: bool, dry_run: bool, diff --git a/bumpversion/files.py b/bumpversion/files.py index efccdd3a..a5f8c1e1 100644 --- a/bumpversion/files.py +++ b/bumpversion/files.py @@ -1,4 +1,5 @@ """Methods for changing files.""" +import os.path import re from copy import deepcopy from difflib import context_diff @@ -94,7 +95,18 @@ def __init__( self._newlines: Optional[str] = None def get_file_contents(self) -> str: - """Return the contents of the file.""" + """ + Return the contents of the file. + + Raises: + FileNotFoundError: if the file doesn't exist + + Returns: + The contents of the file + """ + if not os.path.exists(self.file_change.filename): + raise FileNotFoundError(f"File not found: '{self.file_change.filename}'") + with open(self.file_change.filename, "rt", encoding="utf-8") as f: contents = f.read() self._newlines = f.newlines[0] if isinstance(f.newlines, tuple) else f.newlines diff --git a/bumpversion/version_part.py b/bumpversion/version_part.py index 6058fd59..13430d35 100644 --- a/bumpversion/version_part.py +++ b/bumpversion/version_part.py @@ -150,6 +150,18 @@ def __init__( self.search = search self.replace = replace + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: Any) -> bool: + return ( + self.parse_regex.pattern == other.parse_regex.pattern + and self.serialize_formats == other.serialize_formats + and self.part_configs == other.part_configs + and self.search == other.search + and self.replace == other.replace + ) + @property def order(self) -> List[str]: """ diff --git a/tests/fixtures/basic_cfg.toml b/tests/fixtures/basic_cfg.toml index a1b14936..7808ae95 100644 --- a/tests/fixtures/basic_cfg.toml +++ b/tests/fixtures/basic_cfg.toml @@ -41,6 +41,6 @@ replace = """**unreleased** [tool.bumpversion.parts.release] optional_value = "gamma" values =[ - "dev", - "gamma", + "dev", + "gamma", ] diff --git a/tests/fixtures/regex_test_config.toml b/tests/fixtures/regex_test_config.toml new file mode 100644 index 00000000..46eeca1a --- /dev/null +++ b/tests/fixtures/regex_test_config.toml @@ -0,0 +1,8 @@ +[tool.bumpversion] +current_version = "4.7.1" +regex = true + +[[tool.bumpversion.files]] +filename = "./citation.cff" +search = "date-released: \\d{{4}}-\\d{{2}}-\\d{{2}}" +replace = "date-released: {utcnow:%Y-%m-%d}" diff --git a/tests/test_cli.py b/tests/test_cli.py index 14314cac..638d7df4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2,6 +2,7 @@ import shutil import subprocess import traceback +from datetime import datetime from pathlib import Path import pytest @@ -45,6 +46,32 @@ def test_bump_no_configured_files(mocker, tmp_path): assert len(call_args[2].files) == 0 +def test_bump_nested_regex(tmp_path: Path, fixtures_path: Path, caplog): + """ + Arrange/Act: Run the `bump` subcommand with --no-configured-files. + + Assert: There is no configured files specified to modify + """ + cff_path = tmp_path / "citation.cff" + cff_path.write_text("cff-version: 1.2.0\ndate-released: 2023-09-19\n") + content = fixtures_path.joinpath("regex_test_config.toml").read_text() + config_path = tmp_path / ".bumpversion.toml" + config_path.write_text(content) + + runner: CliRunner = CliRunner() + with inside_dir(tmp_path): + result: Result = runner.invoke(cli.cli, ["bump", "-vv", "patch"]) + + if result.exit_code != 0: + print(result.output) + print(caplog.text) + + assert result.exit_code == 0 + + now = datetime.now().isoformat()[:10] + assert cff_path.read_text() == f"cff-version: 1.2.0\ndate-released: {now}\n" + + def test_bump_legacy(mocker, tmp_path): """ Arrange/Act: Run the `bump` subcommand with --no-configured-files.