Skip to content

Commit 95276ef

Browse files
committed
refactor: add typings in all classes and methods
1 parent 6d08978 commit 95276ef

File tree

5 files changed

+144
-117
lines changed

5 files changed

+144
-117
lines changed

src/git_changelog/build.py

Lines changed: 74 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import sys
2-
from datetime import datetime
2+
from datetime import datetime, date as date_type
33
from subprocess import check_output # nosec
4+
from typing import List, Dict, Union, Type
45

5-
from .providers import GitHub, GitLab
6+
from .providers import GitHub, GitLab, ProviderRefParser, Ref
67
from .style import AngularStyle, AtomStyle, BasicStyle, CommitStyle
78

89

9-
def bump(version, part="patch"):
10+
def bump(version: str, part: str = "patch") -> str:
1011
major, minor, patch = version.split(".", 2)
1112
patch = patch.split("-", 1)
1213
pre = ""
@@ -28,44 +29,45 @@ def bump(version, part="patch"):
2829
class Commit:
2930
def __init__(
3031
self,
31-
hash,
32-
author_name="",
33-
author_email="",
34-
author_date="",
35-
committer_name="",
36-
committer_email="",
37-
committer_date="",
38-
refs="",
39-
subject="",
40-
body=None,
41-
url="",
32+
hash: str,
33+
author_name: str = "",
34+
author_email: str = "",
35+
author_date: str = "",
36+
committer_name: str = "",
37+
committer_email: str = "",
38+
committer_date: str = "",
39+
refs: str = "",
40+
subject: str = "",
41+
body: List[str] = None,
42+
url: str = "",
4243
):
43-
self.hash = hash
44-
self.author_name = author_name
45-
self.author_email = author_email
46-
self.author_date = datetime.utcfromtimestamp(float(author_date))
47-
self.committer_name = committer_name
48-
self.committer_email = committer_email
49-
self.committer_date = datetime.utcfromtimestamp(float(committer_date))
50-
self.subject = subject
51-
self.body = body or []
52-
self.url = url
44+
self.hash: str = hash
45+
self.author_name: str = author_name
46+
self.author_email: str = author_email
47+
self.author_date: datetime = datetime.utcfromtimestamp(float(author_date))
48+
self.committer_name: str = committer_name
49+
self.committer_email: str = committer_email
50+
self.committer_date: datetime = datetime.utcfromtimestamp(float(committer_date))
51+
self.subject: str = subject
52+
self.body: List[str] = body or []
53+
self.url: str = url
5354

5455
tag = ""
5556
for ref in refs.split(","):
5657
ref = ref.strip()
5758
if ref.startswith("tag: "):
5859
tag = ref.replace("tag: ", "")
5960
break
60-
self.tag = self.version = tag
61+
self.tag: str = tag
62+
self.version: str = tag
6163

62-
self.text_refs = {}
63-
self.style = {}
64+
self.text_refs: Dict[str, List[Ref]] = {}
65+
self.style: Dict[str, Union[str, bool]] = {}
6466

65-
def update_with_style(self, style):
67+
def update_with_style(self, style: CommitStyle):
6668
self.style.update(style.parse_commit(self))
6769

68-
def update_with_provider(self, provider):
70+
def update_with_provider(self, provider: ProviderRefParser):
6971
# set the commit url based on provider
7072
# FIXME: hardcoded 'commits'
7173
if "commits" in provider.REF:
@@ -86,44 +88,49 @@ def update_with_provider(self, provider):
8688

8789

8890
class Section:
89-
def __init__(self, type="", commits=None):
90-
self.type = type
91-
self.commits = commits or []
91+
def __init__(self, type: str = "", commits: List[Commit] = None):
92+
self.type: str = type
93+
self.commits: List[Commit] = commits or []
9294

9395

9496
class Version:
95-
def __init__(self, tag="", date="", sections=None, commits=None, url="", compare_url=""):
96-
self.tag = tag
97-
self.date = date
98-
99-
self.sections_list = sections or []
100-
self.sections_dict = {s.type: s for s in self.sections_list}
101-
self.commits = commits or []
102-
self.url = url
103-
self.compare_url = compare_url
104-
self.previous_version = None
105-
self.next_version = None
97+
def __init__(self,
98+
tag: str = "",
99+
date: date_type = "",
100+
sections: List[Section] = None,
101+
commits: List[Commit] = None,
102+
url: str = "", compare_url: str = ""):
103+
self.tag: str = tag
104+
self.date: date_type = date
105+
106+
self.sections_list: List[Section] = sections or []
107+
self.sections_dict: Dict[str, Section] = {s.type: s for s in self.sections_list}
108+
self.commits: List[Commit] = commits or []
109+
self.url: str = url
110+
self.compare_url: str = compare_url
111+
self.previous_version: Union[Version, None] = None
112+
self.next_version: Union[Version, None] = None
106113

107114
@property
108-
def typed_sections(self):
115+
def typed_sections(self) -> List[Section]:
109116
return [s for s in self.sections_list if s.type]
110117

111118
@property
112-
def untyped_section(self):
119+
def untyped_section(self) -> Section:
113120
return self.sections_dict.get("", None)
114121

115122
@property
116-
def is_major(self):
123+
def is_major(self) -> bool:
117124
return self.tag.split(".", 1)[1].startswith("0.0")
118125

119126
@property
120-
def is_minor(self):
127+
def is_minor(self) -> bool:
121128
return bool(self.tag.split(".", 2)[2])
122129

123130

124131
class Changelog:
125-
MARKER = "--GITOLOG MARKER--"
126-
FORMAT = (
132+
MARKER: str = "--GITOLOG MARKER--"
133+
FORMAT: str = (
127134
"%H%n" # commit hash
128135
"%an%n" # author name
129136
"%ae%n" # author email
@@ -135,10 +142,13 @@ class Changelog:
135142
"%s%n" # subject
136143
"%b%n" + MARKER # body
137144
)
138-
STYLE = {"basic": BasicStyle, "angular": AngularStyle, "atom": AtomStyle}
145+
STYLE: Dict[str, Type[CommitStyle]] = {"basic": BasicStyle, "angular": AngularStyle, "atom": AtomStyle}
139146

140-
def __init__(self, repository, provider=None, style=None):
141-
self.repository = repository
147+
def __init__(self,
148+
repository: str,
149+
provider: str = None,
150+
style: Union[str, CommitStyle, Type[CommitStyle]] = None):
151+
self.repository: str = repository
142152

143153
# set provider
144154
if not provider:
@@ -150,8 +160,8 @@ def __init__(self, repository, provider=None, style=None):
150160
provider = GitHub(namespace, project, url=provider_url)
151161
elif "gitlab" in provider_url:
152162
provider = GitLab(namespace, project, url=provider_url)
153-
self.remote_url = remote_url
154-
self.provider = provider
163+
self.remote_url: str = remote_url
164+
self.provider: ProviderRefParser = provider
155165

156166
# set style
157167
if isinstance(style, str):
@@ -166,17 +176,17 @@ def __init__(self, repository, provider=None, style=None):
166176
style = style()
167177
elif isinstance(style, CommitStyle):
168178
pass
169-
self.style = style
179+
self.style: CommitStyle = style
170180

171181
# get git log and parse it into list of commits
172-
self.raw_log = self.get_log()
173-
self.commits = self.parse_commits()
182+
self.raw_log: str = self.get_log()
183+
self.commits: List[Commit] = self.parse_commits()
174184

175185
# apply dates to commits and group them by version
176186
dates = self.apply_versions_to_commits()
177187
versions = self.group_commits_by_version(dates)
178-
self.versions_list = versions["as_list"]
179-
self.versions_dict = versions["as_dict"]
188+
self.versions_list: List[Version] = versions["as_list"]
189+
self.versions_dict: Dict[str, Version] = versions["as_dict"]
180190

181191
# guess the next version number based on last version and recent commits
182192
last_version = self.versions_list[0]
@@ -201,7 +211,7 @@ def __init__(self, repository, provider=None, style=None):
201211
base=last_version.previous_version.tag, target=last_version.planned_tag
202212
)
203213

204-
def get_remote_url(self):
214+
def get_remote_url(self) -> str:
205215
git_url = (
206216
check_output(["git", "config", "--get", "remote.origin.url"], cwd=self.repository) # nosec
207217
.decode("utf-8")
@@ -213,12 +223,12 @@ def get_remote_url(self):
213223
git_url = git_url[:-4]
214224
return git_url
215225

216-
def get_log(self):
226+
def get_log(self) -> str:
217227
return check_output(
218228
["git", "log", "--date=unix", "--format=" + self.FORMAT], cwd=self.repository # nosec
219229
).decode("utf-8")
220230

221-
def parse_commits(self):
231+
def parse_commits(self) -> List[Commit]:
222232
lines = self.raw_log.split("\n")
223233
size = len(lines) - 1 # don't count last blank line
224234
commits = []
@@ -260,7 +270,7 @@ def parse_commits(self):
260270

261271
return commits
262272

263-
def apply_versions_to_commits(self):
273+
def apply_versions_to_commits(self) -> Dict[str, date_type]:
264274
versions_dates = {"": None}
265275
version = None
266276
for commit in self.commits:
@@ -271,7 +281,7 @@ def apply_versions_to_commits(self):
271281
commit.version = version
272282
return versions_dates
273283

274-
def group_commits_by_version(self, dates):
284+
def group_commits_by_version(self, dates: Dict[str, date_type]):
275285
versions_list = []
276286
versions_dict = {}
277287
versions_types_dict = {}

src/git_changelog/cli.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import argparse
1919
import sys
20+
from typing import List
2021

2122
from . import templates
2223
from .build import Changelog
@@ -25,11 +26,11 @@
2526

2627

2728
class Templates(tuple):
28-
def __contains__(self, item):
29+
def __contains__(self, item: str) -> bool:
2930
return item.startswith("path:") or super(Templates, self).__contains__(item)
3031

3132

32-
def get_parser():
33+
def get_parser() -> argparse.ArgumentParser:
3334
"""Return a parser for the command-line arguments."""
3435
parser = argparse.ArgumentParser(
3536
add_help=False, prog="git-changelog", description="Command line tool for git-changelog Python package."
@@ -70,7 +71,7 @@ def get_parser():
7071
return parser
7172

7273

73-
def main(args=None):
74+
def main(args: List[str] = None) -> int:
7475
parser = get_parser()
7576
args = parser.parse_args(args=args)
7677

0 commit comments

Comments
 (0)