1
1
"""Bump My Version configuration models."""
2
2
from __future__ import annotations
3
3
4
- from typing import TYPE_CHECKING , Dict , List , Optional , Union
4
+ import logging
5
+ import re
6
+ from typing import TYPE_CHECKING , Dict , List , MutableMapping , Optional , Tuple , Union
5
7
6
8
from pydantic import BaseModel , Field
7
9
from pydantic_settings import BaseSettings , SettingsConfigDict
10
12
from bumpversion .scm import SCMInfo
11
13
from bumpversion .version_part import VersionConfig
12
14
15
+ logger = logging .getLogger (__name__ )
16
+
13
17
14
18
class VersionPartConfig (BaseModel ):
15
19
"""Configuration of a part of the version."""
@@ -21,8 +25,8 @@ class VersionPartConfig(BaseModel):
21
25
independent : bool = False
22
26
23
27
24
- class FileConfig (BaseModel ):
25
- """Search and replace file config ."""
28
+ class FileChange (BaseModel ):
29
+ """A change to make to a file ."""
26
30
27
31
parse : str
28
32
serialize : List [str ]
@@ -34,6 +38,35 @@ class FileConfig(BaseModel):
34
38
glob : Optional [str ] = None # Conflicts with filename. If both are specified, glob wins
35
39
key_path : Optional [str ] = None # If specified, and has an appropriate extension, will be treated as a data file
36
40
41
+ def get_search_pattern (self , context : MutableMapping ) -> Tuple [re .Pattern , str ]:
42
+ """
43
+ Render the search pattern and return the compiled regex pattern and the raw pattern.
44
+
45
+ Args:
46
+ context: The context to use for rendering the search pattern
47
+
48
+ Returns:
49
+ A tuple of the compiled regex pattern and the raw pattern as a string.
50
+ """
51
+ # the default search pattern is escaped, so we can still use it in a regex
52
+ raw_pattern = self .search .format (** context )
53
+ default = re .compile (re .escape (raw_pattern ), re .MULTILINE | re .DOTALL )
54
+ if not self .regex :
55
+ logger .debug ("No RegEx flag detected. Searching for the default pattern: '%s'" , default .pattern )
56
+ return default , raw_pattern
57
+
58
+ re_context = {key : re .escape (str (value )) for key , value in context .items ()}
59
+ regex_pattern = self .search .format (** re_context )
60
+ try :
61
+ search_for_re = re .compile (regex_pattern , re .MULTILINE | re .DOTALL )
62
+ logger .debug ("Searching for the regex: '%s'" , search_for_re .pattern )
63
+ return search_for_re , raw_pattern
64
+ except re .error as e :
65
+ logger .error ("Invalid regex '%s': %s." , default , e )
66
+
67
+ logger .debug ("Invalid regex. Searching for the default pattern: '%s'" , raw_pattern )
68
+ return default , raw_pattern
69
+
37
70
38
71
class Config (BaseSettings ):
39
72
"""Bump Version configuration."""
@@ -55,7 +88,7 @@ class Config(BaseSettings):
55
88
commit_args : Optional [str ]
56
89
scm_info : Optional ["SCMInfo" ]
57
90
parts : Dict [str , VersionPartConfig ]
58
- files : List [FileConfig ]
91
+ files : List [FileChange ]
59
92
included_paths : List [str ] = Field (default_factory = list )
60
93
excluded_paths : List [str ] = Field (default_factory = list )
61
94
model_config = SettingsConfigDict (env_prefix = "bumpversion_" )
@@ -67,7 +100,7 @@ def add_files(self, filename: Union[str, List[str]]) -> None:
67
100
if name in self .resolved_filemap :
68
101
continue
69
102
self .files .append (
70
- FileConfig (
103
+ FileChange (
71
104
filename = name ,
72
105
glob = None ,
73
106
key_path = None ,
@@ -81,7 +114,7 @@ def add_files(self, filename: Union[str, List[str]]) -> None:
81
114
)
82
115
83
116
@property
84
- def resolved_filemap (self ) -> Dict [str , FileConfig ]:
117
+ def resolved_filemap (self ) -> Dict [str , FileChange ]:
85
118
"""Return a map of filenames to file configs, expanding any globs."""
86
119
from bumpversion .config .utils import resolve_glob_files
87
120
@@ -95,7 +128,7 @@ def resolved_filemap(self) -> Dict[str, FileConfig]:
95
128
return {file_cfg .filename : file_cfg for file_cfg in new_files }
96
129
97
130
@property
98
- def files_to_modify (self ) -> List [FileConfig ]:
131
+ def files_to_modify (self ) -> List [FileChange ]:
99
132
"""Return a list of files to modify."""
100
133
files_not_excluded = [
101
134
file_cfg .filename
0 commit comments