6
6
from commitizen import cmd
7
7
8
8
9
+ class GitObject :
10
+ def __eq__ (self , other ):
11
+ if not isinstance (other , GitObject ):
12
+ return False
13
+ return self .rev == other .rev
14
+
15
+
16
+ class GitCommit (GitObject ):
17
+ def __init__ (self , rev , title , body = "" ):
18
+ self .rev = rev .strip ()
19
+ self .title = title .strip ()
20
+ self .body = body .strip ()
21
+
22
+ @property
23
+ def message (self ):
24
+ return f"{ self .title } \n \n { self .body } "
25
+
26
+ def __repr__ (self ):
27
+ return f"{ self .title } ({ self .rev } )"
28
+
29
+
30
+ class GitTag (GitObject ):
31
+ def __init__ (self , name , rev , date ):
32
+ self .rev = rev .strip ()
33
+ self .name = name .strip ()
34
+ self .date = date .strip ()
35
+
36
+ def __repr__ (self ):
37
+ return f"{ self .name } ({ self .rev } )"
38
+
39
+
9
40
def tag (tag : str ):
10
41
c = cmd .run (f"git tag { tag } " )
11
42
return c
@@ -20,38 +51,69 @@ def commit(message: str, args=""):
20
51
return c
21
52
22
53
23
- def get_commits (start : str , end : str = "HEAD" , from_beginning : bool = False ) -> list :
54
+ def get_commits (
55
+ start : Optional [str ] = None ,
56
+ end : str = "HEAD" ,
57
+ * ,
58
+ log_format : str = "%H%n%s%n%b" ,
59
+ delimiter : str = "----------commit-delimiter----------" ,
60
+ ) -> List [GitCommit ]:
61
+ """
62
+ Get the commits betweeen start and end
63
+ """
64
+ git_log_cmd = f"git log --pretty={ log_format } { delimiter } "
24
65
25
- c = cmd . run ( f"git log --pretty=format:%s%n%b { start } ... { end } " )
26
-
27
- if from_beginning :
28
- c = cmd .run (f"git log --pretty=format:%s%n%b { end } " )
66
+ if start :
67
+ c = cmd . run ( f" { git_log_cmd } { start } ... { end } " )
68
+ else :
69
+ c = cmd .run (f"{ git_log_cmd } { end } " )
29
70
30
71
if not c .out :
31
72
return []
32
- return c .out .split ("\n " )
73
+
74
+ git_commits = []
75
+ for rev_and_commit in c .out .split (delimiter ):
76
+ rev_and_commit = rev_and_commit .strip ()
77
+ if not rev_and_commit :
78
+ continue
79
+ rev , title , * body_list = rev_and_commit .split ("\n " )
80
+
81
+ if rev_and_commit :
82
+ git_commit = GitCommit (
83
+ rev = rev .strip (), title = title .strip (), body = "\n " .join (body_list ).strip ()
84
+ )
85
+ git_commits .append (git_commit )
86
+ return git_commits
87
+
88
+
89
+ def get_tags (dateformat : str = "%Y-%m-%d" ) -> List [GitTag ]:
90
+ inner_delimiter = "---inner_delimiter---"
91
+ formatter = (
92
+ f"'%(refname:lstrip=2){ inner_delimiter } "
93
+ f"%(objectname){ inner_delimiter } "
94
+ f"%(committerdate:format:{ dateformat } )'"
95
+ )
96
+ c = cmd .run (f"git tag --format={ formatter } --sort=-committerdate" )
97
+ if c .err or not c .out :
98
+ return []
99
+
100
+ git_tags = [GitTag (* line .split (inner_delimiter )) for line in c .out .split ("\n " )[:- 1 ]]
101
+ return git_tags
33
102
34
103
35
104
def tag_exist (tag : str ) -> bool :
36
105
c = cmd .run (f"git tag --list { tag } " )
37
106
return tag in c .out
38
107
39
108
40
- def is_staging_clean () -> bool :
41
- """Check if staing is clean"""
42
- c = cmd .run ("git diff --no-ext-diff --name-only" )
43
- c_cached = cmd .run ("git diff --no-ext-diff --cached --name-only" )
44
- return not (bool (c .out ) or bool (c_cached .out ))
45
-
46
-
47
- def get_latest_tag () -> Optional [str ]:
109
+ def get_latest_tag_name () -> Optional [str ]:
48
110
c = cmd .run ("git describe --abbrev=0 --tags" )
49
111
if c .err :
50
112
return None
51
113
return c .out .strip ()
52
114
53
115
54
- def get_all_tags () -> Optional [List [str ]]:
116
+ def get_tag_names () -> Optional [List [str ]]:
55
117
c = cmd .run ("git tag --list" )
56
118
if c .err :
57
119
return []
@@ -63,3 +125,10 @@ def find_git_project_root() -> Optional[Path]:
63
125
if not c .err :
64
126
return Path (c .out .strip ())
65
127
return None
128
+
129
+
130
+ def is_staging_clean () -> bool :
131
+ """Check if staing is clean"""
132
+ c = cmd .run ("git diff --no-ext-diff --name-only" )
133
+ c_cached = cmd .run ("git diff --no-ext-diff --cached --name-only" )
134
+ return not (bool (c .out ) or bool (c_cached .out ))
0 commit comments