3
3
import os
4
4
import re
5
5
from collections import OrderedDict
6
- from collections .abc import Iterable
6
+ from collections .abc import Callable , Iterable
7
7
from glob import iglob
8
8
from logging import getLogger
9
9
from string import Template
10
- from typing import cast
10
+ from typing import TextIO , cast
11
+
12
+ from typing_extensions import Never
11
13
12
14
from commitizen .defaults import BUMP_MESSAGE , ENCODING , MAJOR , MINOR , PATCH
13
15
from commitizen .exceptions import CurrentVersionNotFoundError
@@ -75,36 +77,46 @@ def update_version_in_files(
75
77
76
78
Returns the list of updated files.
77
79
"""
78
- # TODO: separate check step and write step
79
80
updated = []
80
- for path , regex in _files_and_regexes (files , current_version ):
81
- current_version_found , version_file = _bump_with_regex (
82
- path ,
83
- current_version ,
84
- new_version ,
85
- regex ,
86
- encoding = encoding ,
81
+
82
+ for path , pattern in _resolve_files_and_regexes (files , current_version ):
83
+ error = CurrentVersionNotFoundError (
84
+ f"Current version { current_version } is not found in { path } .\n "
85
+ "The version defined in commitizen configuration and the ones in "
86
+ "version_files are possibly inconsistent."
87
+ )
88
+ error_on_not_found = (
89
+ None if not check_consistency else lambda : (_ for _ in ()).throw (error )
87
90
)
88
91
89
- if check_consistency and not current_version_found :
90
- raise CurrentVersionNotFoundError (
91
- f"Current version { current_version } is not found in { path } .\n "
92
- "The version defined in commitizen configuration and the ones in "
93
- "version_files are possibly inconsistent."
92
+ def bump_line (line : str ) -> str :
93
+ return (
94
+ line .replace (current_version , new_version )
95
+ if pattern .search (line )
96
+ else line
97
+ )
98
+
99
+ with open (path , encoding = encoding ) as file :
100
+ bumped_version_file_content = _get_bumped_version_file_content (
101
+ file ,
102
+ bump_line ,
103
+ error_on_not_found ,
94
104
)
95
105
96
106
# Write the file out again
97
107
with smart_open (path , "w" , encoding = encoding ) as file :
98
- file .write (version_file )
108
+ file .write (bumped_version_file_content )
99
109
updated .append (path )
100
110
return updated
101
111
102
112
103
- def _files_and_regexes (patterns : Iterable [str ], version : str ) -> list [tuple [str , str ]]:
113
+ def _resolve_files_and_regexes (
114
+ patterns : Iterable [str ], version : str
115
+ ) -> list [tuple [str , re .Pattern ]]:
104
116
"""
105
117
Resolve all distinct files with their regexp from a list of glob patterns with optional regexp
106
118
"""
107
- out : set [tuple [str , str ]] = set ()
119
+ out : set [tuple [str , re . Pattern ]] = set ()
108
120
for pattern in patterns :
109
121
drive , tail = os .path .splitdrive (pattern )
110
122
path , _ , regex = tail .partition (":" )
@@ -113,33 +125,30 @@ def _files_and_regexes(patterns: Iterable[str], version: str) -> list[tuple[str,
113
125
regex = re .escape (version )
114
126
115
127
for file in iglob (filepath ):
116
- out .add ((file , regex ))
128
+ out .add ((file , re . compile ( regex ) ))
117
129
118
130
return sorted (out )
119
131
120
132
121
- def _bump_with_regex (
122
- version_filepath : str ,
123
- current_version : str ,
124
- new_version : str ,
125
- regex : str ,
126
- encoding : str = ENCODING ,
127
- ) -> tuple [bool , str ]:
133
+ def _get_bumped_version_file_content (
134
+ version_file : TextIO ,
135
+ bump_line : Callable [[str ], str ],
136
+ error_on_not_found : Callable [[], Never ] | None ,
137
+ ) -> str :
128
138
current_version_found = False
129
139
lines = []
130
- pattern = re .compile (regex )
131
- with open (version_filepath , encoding = encoding ) as f :
132
- for line in f :
133
- if not pattern .search (line ):
134
- lines .append (line )
135
- continue
136
-
137
- bumped_line = line .replace (current_version , new_version )
138
- if bumped_line != line :
139
- current_version_found = True
140
- lines .append (bumped_line )
141
-
142
- return current_version_found , "" .join (lines )
140
+
141
+ for line in version_file :
142
+ bumped_line = bump_line (line )
143
+ if bumped_line != line :
144
+ current_version_found = True
145
+
146
+ lines .append (bumped_line )
147
+
148
+ if error_on_not_found is not None and not current_version_found :
149
+ error_on_not_found ()
150
+
151
+ return "" .join (lines )
143
152
144
153
145
154
def create_commit_message (
0 commit comments