Skip to content
This repository was archived by the owner on Apr 13, 2023. It is now read-only.

Commit 1d5d123

Browse files
author
Thiago C. D'Ávila
authored
Merge pull request #70 from staticdev/config-refactor
Config refactor
2 parents 813c555 + ba47e9b commit 1d5d123

File tree

8 files changed

+288
-136
lines changed

8 files changed

+288
-136
lines changed

src/git_portfolio/__main__.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
"""Command-line interface."""
2+
import sys
23
from typing import Tuple
34

45
import click
56

67
import git_portfolio.config_manager as cm
8+
import git_portfolio.github_manager as ghm
79
import git_portfolio.local_manager as lm
8-
import git_portfolio.portfolio_manager as pm
10+
11+
12+
try:
13+
CONFIG_MANAGER = cm.ConfigManager()
14+
except TypeError as type_error:
15+
click.secho(
16+
f"Error: {type_error}", fg="red", err=True,
17+
)
18+
sys.exit()
919

1020

1121
@click.group("cli")
@@ -19,9 +29,7 @@ def main() -> None:
1929
def checkout(args: Tuple[str]) -> None:
2030
"""CLI `git checkout BRANCH` command."""
2131
# TODO add -b option
22-
config_manager = cm.ConfigManager()
23-
configs = config_manager.load_configs()
24-
if not configs.github_selected_repos:
32+
if not CONFIG_MANAGER.config.github_selected_repos:
2533
click.secho(
2634
"Error: no repos selected. Please run `gitp config init`.", fg="red",
2735
)
@@ -34,7 +42,11 @@ def checkout(args: Tuple[str]) -> None:
3442
fg="red",
3543
)
3644
else:
37-
click.secho(lm.LocalManager().checkout(configs.github_selected_repos, args))
45+
click.secho(
46+
lm.LocalManager().checkout(
47+
CONFIG_MANAGER.config.github_selected_repos, args
48+
)
49+
)
3850

3951

4052
@click.group("config")
@@ -68,40 +80,52 @@ def delete() -> None:
6880
pass
6981

7082

83+
def _save_config(config: cm.Config) -> None:
84+
"""Save config with ConfigManager."""
85+
CONFIG_MANAGER.config = config
86+
CONFIG_MANAGER.save_config()
87+
click.secho("gitp successfully configured.", fg="blue")
88+
89+
7190
@configure.command("init")
7291
def config_init() -> None:
7392
"""Config init command."""
74-
pm.PortfolioManager()
93+
github_manager = ghm.GithubManager(CONFIG_MANAGER.config)
94+
_save_config(github_manager.config)
7595

7696

7797
@configure.command("repos")
7898
def config_repos() -> None:
7999
"""Config repos command."""
80-
pm.PortfolioManager().config_repos()
100+
config = ghm.GithubManager(CONFIG_MANAGER.config).config_repos()
101+
if config:
102+
_save_config(config)
103+
else:
104+
click.secho("Error: no config found, please run `gitp config init`.", fg="red")
81105

82106

83107
@create.command("issues")
84108
def create_issues() -> None:
85109
"""Create issues command."""
86-
pm.PortfolioManager().create_issues()
110+
ghm.GithubManager(CONFIG_MANAGER.config).create_issues()
87111

88112

89113
@create.command("prs")
90114
def create_prs() -> None:
91115
"""Create prs command."""
92-
pm.PortfolioManager().create_pull_requests()
116+
ghm.GithubManager(CONFIG_MANAGER.config).create_pull_requests()
93117

94118

95119
@merge.command("prs")
96120
def merge_prs() -> None:
97121
"""Merge prs command."""
98-
pm.PortfolioManager().merge_pull_requests()
122+
ghm.GithubManager(CONFIG_MANAGER.config).merge_pull_requests()
99123

100124

101125
@delete.command("branches")
102126
def delete_branches() -> None:
103127
"""Delete branches command."""
104-
pm.PortfolioManager().delete_branches()
128+
ghm.GithubManager(CONFIG_MANAGER.config).delete_branches()
105129

106130

107131
main.add_command(configure)

src/git_portfolio/config_manager.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,37 @@ def __init__(
2424
class ConfigManager:
2525
"""Configuration manager class."""
2626

27-
CONFIG_FOLDER = os.path.join(os.path.expanduser("~"), ".gitp")
28-
CONFIG_FILE = "config.yaml"
29-
30-
def load_configs(self) -> Config:
31-
"""Get configs if it exists."""
32-
if os.path.exists(os.path.join(self.CONFIG_FOLDER, self.CONFIG_FILE)):
33-
print("Loading previous configs\n")
34-
with open(
35-
os.path.join(self.CONFIG_FOLDER, self.CONFIG_FILE)
36-
) as config_file:
37-
data = yaml.safe_load(config_file)
38-
return Config(**data)
39-
return Config("", "", [])
40-
41-
def save_configs(self, configs: Config) -> None:
27+
def __init__(self, config_filename: str = "config.yaml") -> None:
28+
"""Load config if it exists."""
29+
self.config_folder = os.path.join(os.path.expanduser("~"), ".gitp")
30+
self.config_path = os.path.join(self.config_folder, config_filename)
31+
32+
if os.path.exists(self.config_path):
33+
print("Loading previous config...\n")
34+
with open(self.config_path) as config_file:
35+
try:
36+
data = yaml.safe_load(config_file)
37+
except yaml.scanner.ScannerError:
38+
raise TypeError("Invalid YAML file.")
39+
if data:
40+
try:
41+
self.config = Config(**data)
42+
return
43+
except TypeError:
44+
raise TypeError("Invalid config file.")
45+
self.config = Config("", "", [])
46+
47+
def _config_is_empty(self) -> bool:
48+
if self.config.github_selected_repos and self.config.github_access_token:
49+
return False
50+
return True
51+
52+
def save_config(self) -> None:
4253
"""Write config to YAML file."""
43-
pathlib.Path(self.CONFIG_FOLDER).mkdir(parents=True, exist_ok=True)
44-
configs_dict = vars(configs)
45-
with open(
46-
os.path.join(self.CONFIG_FOLDER, self.CONFIG_FILE), "w"
47-
) as config_file:
48-
yaml.dump(configs_dict, config_file)
54+
if not self._config_is_empty():
55+
pathlib.Path(self.config_folder).mkdir(parents=True, exist_ok=True)
56+
config_dict = vars(self.config)
57+
with open(self.config_path, "w") as config_file:
58+
yaml.dump(config_dict, config_file)
59+
else:
60+
raise AttributeError

src/git_portfolio/portfolio_manager.py renamed to src/git_portfolio/github_manager.py

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import github
1111
import requests
1212

13-
import git_portfolio.config_manager as config_manager
13+
import git_portfolio.config_manager as cm
1414
import git_portfolio.prompt as prompt
1515

1616
# starting log
@@ -20,15 +20,14 @@
2020
LOGGER = logging.getLogger(__name__)
2121

2222

23-
class PortfolioManager:
24-
"""Portfolio manager class."""
23+
class GithubManager:
24+
"""Github manager class."""
2525

26-
def __init__(self) -> None:
26+
def __init__(self, config: cm.Config) -> None:
2727
"""Constructor."""
28-
self.config_manager = config_manager.ConfigManager()
29-
self.configs = self.config_manager.load_configs()
30-
if self.configs.github_access_token:
31-
self.github_setup()
28+
self.config = config
29+
if config.github_access_token:
30+
self._github_setup()
3231
else:
3332
self.config_ini()
3433

@@ -37,15 +36,15 @@ def create_issues(
3736
) -> None:
3837
"""Create issues."""
3938
if not issue:
40-
issue = prompt.create_issues(self.configs.github_selected_repos)
39+
issue = prompt.create_issues(self.config.github_selected_repos)
4140
labels = (
4241
[label.strip() for label in issue.labels.split(",")] if issue.labels else []
4342
)
4443

4544
if github_repo:
4645
self._create_issue_from_repo(github_repo, issue, labels)
4746
else:
48-
for github_repo in self.configs.github_selected_repos:
47+
for github_repo in self.config.github_selected_repos:
4948
self._create_issue_from_repo(github_repo, issue, labels)
5049

5150
def _create_issue_from_repo(
@@ -72,12 +71,12 @@ def create_pull_requests(
7271
) -> None:
7372
"""Create pull requests."""
7473
if not pr:
75-
pr = prompt.create_pull_requests(self.configs.github_selected_repos)
74+
pr = prompt.create_pull_requests(self.config.github_selected_repos)
7675

7776
if github_repo:
7877
self._create_pull_request_from_repo(github_repo, pr)
7978
else:
80-
for github_repo in self.configs.github_selected_repos:
79+
for github_repo in self.config.github_selected_repos:
8180
self._create_pull_request_from_repo(github_repo, pr)
8281

8382
def _create_pull_request_from_repo(self, github_repo: str, pr: Any) -> None:
@@ -127,7 +126,7 @@ def merge_pull_requests(
127126
"""Merge pull requests."""
128127
if not pr_merge:
129128
pr_merge = prompt.merge_pull_requests(
130-
self.github_username, self.configs.github_selected_repos
129+
self.github_username, self.config.github_selected_repos
131130
)
132131
# Important note: base and head arguments have different import formats.
133132
# https://developer.github.com/v3/pulls/#list-pull-requests
@@ -138,7 +137,7 @@ def merge_pull_requests(
138137
if github_repo:
139138
self._merge_pull_request_from_repo(github_repo, head, pr_merge, state)
140139
else:
141-
for github_repo in self.configs.github_selected_repos:
140+
for github_repo in self.config.github_selected_repos:
142141
self._merge_pull_request_from_repo(github_repo, head, pr_merge, state)
143142

144143
def _merge_pull_request_from_repo(
@@ -175,12 +174,12 @@ def _merge_pull_request_from_repo(
175174
def delete_branches(self, branch: str = "", github_repo: str = "") -> None:
176175
"""Delete branches."""
177176
if not branch:
178-
branch = prompt.delete_branches(self.configs.github_selected_repos)
177+
branch = prompt.delete_branches(self.config.github_selected_repos)
179178

180179
if github_repo:
181180
self._delete_branch_from_repo(github_repo, branch)
182181
else:
183-
for github_repo in self.configs.github_selected_repos:
182+
for github_repo in self.config.github_selected_repos:
184183
self._delete_branch_from_repo(github_repo, branch)
185184

186185
def _delete_branch_from_repo(self, github_repo: str, branch: str) -> None:
@@ -196,13 +195,13 @@ def _delete_branch_from_repo(self, github_repo: str, branch: str) -> None:
196195
def get_github_connection(self) -> github.Github:
197196
"""Get Github connection."""
198197
# GitHub Enterprise
199-
if self.configs.github_hostname:
200-
base_url = f"https://{self.configs.github_hostname}/api/v3"
198+
if self.config.github_hostname:
199+
base_url = f"https://{self.config.github_hostname}/api/v3"
201200
return github.Github(
202-
base_url=base_url, login_or_token=self.configs.github_access_token
201+
base_url=base_url, login_or_token=self.config.github_access_token
203202
)
204203
# GitHub.com
205-
return github.Github(self.configs.github_access_token)
204+
return github.Github(self.config.github_access_token)
206205

207206
def get_github_username(
208207
self,
@@ -216,9 +215,14 @@ def get_github_username(
216215
except (github.BadCredentialsException, github.GithubException):
217216
return ""
218217
except requests.exceptions.ConnectionError:
219-
sys.exit("Unable to reach server. Please check you network.")
218+
sys.exit(
219+
(
220+
"Unable to reach server. Please check you network and credentials "
221+
"and try again."
222+
)
223+
)
220224

221-
def get_github_repos(
225+
def _get_github_repos(
222226
self,
223227
user: Union[
224228
github.AuthenticatedUser.AuthenticatedUser, github.NamedUser.NamedUser
@@ -227,42 +231,36 @@ def get_github_repos(
227231
"""Get Github repos from user."""
228232
return user.get_repos()
229233

230-
def config_repos(self) -> None:
234+
def config_ini(self) -> None:
235+
"""Initialize app configuration."""
236+
# only config if gets a valid connection
237+
valid = False
238+
while not valid:
239+
answers = prompt.connect_github(self.config.github_access_token)
240+
self.config.github_access_token = answers.github_access_token.strip()
241+
self.config.github_hostname = answers.github_hostname
242+
valid = self._github_setup()
243+
if not valid:
244+
print("Wrong GitHub token/permissions. Please try again.")
245+
self.config_repos()
246+
247+
def config_repos(self) -> Optional[cm.Config]:
231248
"""Configure repos in use."""
232-
if self.configs.github_selected_repos:
233-
print("\nThe configured repos will be used:")
234-
for repo in self.configs.github_selected_repos:
235-
print(" *", repo)
236-
new_repos = prompt.new_repos()
249+
if self.config.github_selected_repos:
250+
new_repos = prompt.new_repos(self.config.github_selected_repos)
237251
if not new_repos:
238-
print("gitp successfully configured.")
239-
return
252+
return None
240253

241254
repo_names = [repo.full_name for repo in self.github_repos]
255+
self.config.github_selected_repos = prompt.select_repos(repo_names)
256+
return self.config
242257

243-
self.configs.github_selected_repos = prompt.select_repos(repo_names)
244-
self.config_manager.save_configs(self.configs)
245-
print("gitp successfully configured.")
246-
247-
def github_setup(self) -> bool:
258+
def _github_setup(self) -> bool:
248259
"""Setup Github connection properties."""
249260
self.github_connection = self.get_github_connection()
250261
user = self.github_connection.get_user()
251262
self.github_username = self.get_github_username(user)
252263
if not self.github_username:
253264
return False
254-
self.github_repos = self.get_github_repos(user)
265+
self.github_repos = self._get_github_repos(user)
255266
return True
256-
257-
def config_ini(self) -> None:
258-
"""Initialize app configuration."""
259-
# only config if gets a valid connection
260-
valid = False
261-
while not valid:
262-
answers = prompt.connect_github(self.configs.github_access_token)
263-
self.configs.github_access_token = answers.github_access_token.strip()
264-
self.configs.github_hostname = answers.github_hostname
265-
valid = self.github_setup()
266-
if not valid:
267-
print("Wrong GitHub token/permissions. Please try again.")
268-
self.config_repos()

src/git_portfolio/prompt.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,13 @@ def connect_github(github_access_token: str) -> ConnectGithub:
233233
return ConnectGithub(answers["github_access_token"], answers["github_hostname"])
234234

235235

236-
def new_repos() -> Any:
236+
def new_repos(github_selected_repos: List[str]) -> Any:
237237
"""Prompt question to know if you want to select new repositories."""
238-
answer = inquirer.prompt(
239-
[inquirer.Confirm("", message="Do you want to select new repositories?")]
240-
)[""]
238+
message = "\nThe configured repos will be used:"
239+
for repo in github_selected_repos:
240+
message += f" * {repo}\n"
241+
message += "Do you want to select new repositories?"
242+
answer = inquirer.prompt([inquirer.Confirm("", message=message)])[""]
241243
return answer
242244

243245

0 commit comments

Comments
 (0)