3
3
from __future__ import annotations
4
4
5
5
from contextlib import nullcontext
6
+ from datetime import datetime
6
7
from logging import getLogger
7
8
from pathlib import Path
8
9
from typing import TYPE_CHECKING
@@ -48,23 +49,36 @@ def logger(self) -> Logger:
48
49
return self ._logger
49
50
50
51
def _get_custom_environment (
51
- self , repo : Repo
52
+ self ,
53
+ repo : Repo ,
54
+ custom_vars : dict [str , str ] | None = None ,
52
55
) -> nullcontext [None ] | _GeneratorContextManager [None ]:
53
56
"""
54
57
git.custom_environment is a context manager but
55
58
is not reentrant, so once we have "used" it
56
59
we need to throw it away and re-create it in
57
60
order to use it again
58
61
"""
62
+ author_vars = (
63
+ {
64
+ "GIT_AUTHOR_NAME" : self ._commit_author .name ,
65
+ "GIT_AUTHOR_EMAIL" : self ._commit_author .email ,
66
+ "GIT_COMMITTER_NAME" : self ._commit_author .name ,
67
+ "GIT_COMMITTER_EMAIL" : self ._commit_author .email ,
68
+ }
69
+ if self ._commit_author
70
+ else {}
71
+ )
72
+
73
+ custom_env_vars = {
74
+ ** author_vars ,
75
+ ** (custom_vars or {}),
76
+ }
77
+
59
78
return (
60
79
nullcontext ()
61
- if not self ._commit_author
62
- else repo .git .custom_environment (
63
- GIT_AUTHOR_NAME = self ._commit_author .name ,
64
- GIT_AUTHOR_EMAIL = self ._commit_author .email ,
65
- GIT_COMMITTER_NAME = self ._commit_author .name ,
66
- GIT_COMMITTER_EMAIL = self ._commit_author .email ,
67
- )
80
+ if not custom_env_vars
81
+ else repo .git .custom_environment (** custom_env_vars )
68
82
)
69
83
70
84
def is_dirty (self ) -> bool :
@@ -182,19 +196,32 @@ def git_commit(
182
196
self .logger .exception (str (err ))
183
197
raise GitCommitError ("Failed to commit changes" ) from err
184
198
185
- def git_tag (self , tag_name : str , message : str , noop : bool = False ) -> None :
199
+ def git_tag (
200
+ self , tag_name : str , message : str , isotimestamp : str , noop : bool = False
201
+ ) -> None :
202
+ try :
203
+ datetime .fromisoformat (isotimestamp )
204
+ except ValueError as err :
205
+ raise ValueError ("Invalid timestamp format" ) from err
206
+
186
207
if noop :
187
- command = (
188
- f"""\
189
- GIT_AUTHOR_NAME={ self ._commit_author .name } \\
190
- GIT_AUTHOR_EMAIL={ self ._commit_author .email } \\
191
- GIT_COMMITTER_NAME={ self ._commit_author .name } \\
192
- GIT_COMMITTER_EMAIL={ self ._commit_author .email } \\
193
- """
194
- if self ._commit_author
195
- else ""
208
+ command = str .join (
209
+ " " ,
210
+ [
211
+ f"GIT_COMMITTER_DATE={ isotimestamp } " ,
212
+ * (
213
+ [
214
+ f"GIT_AUTHOR_NAME={ self ._commit_author .name } " ,
215
+ f"GIT_AUTHOR_EMAIL={ self ._commit_author .email } " ,
216
+ f"GIT_COMMITTER_NAME={ self ._commit_author .name } " ,
217
+ f"GIT_COMMITTER_EMAIL={ self ._commit_author .email } " ,
218
+ ]
219
+ if self ._commit_author
220
+ else ["" ]
221
+ ),
222
+ f"git tag -a { tag_name } -m '{ message } '" ,
223
+ ],
196
224
)
197
- command += f"git tag -a { tag_name } -m '{ message } '"
198
225
199
226
noop_report (
200
227
indented (
@@ -206,7 +233,10 @@ def git_tag(self, tag_name: str, message: str, noop: bool = False) -> None:
206
233
)
207
234
return
208
235
209
- with Repo (str (self .project_root )) as repo , self ._get_custom_environment (repo ):
236
+ with Repo (str (self .project_root )) as repo , self ._get_custom_environment (
237
+ repo ,
238
+ {"GIT_COMMITTER_DATE" : isotimestamp },
239
+ ):
210
240
try :
211
241
repo .git .tag ("-a" , tag_name , m = message )
212
242
except GitCommandError as err :
0 commit comments