Skip to content

Commit fe4553a

Browse files
authored
Merge pull request #119 from druids/INFRA-137
Infra 137
2 parents 07db024 + 898f6ac commit fe4553a

File tree

13 files changed

+362
-206
lines changed

13 files changed

+362
-206
lines changed

developers_chamber/bin/pydev.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@
5757
# Import external scripts
5858
for base_path in (Path.home(), Path.cwd()):
5959
if (base_path / ".pydev" / "scripts" / "__init__.py").exists():
60-
SourceFileLoader('*', str(base_path / ".pydev" / "scripts" / "__init__.py")).load_module()
60+
SourceFileLoader(
61+
"*", str(base_path / ".pydev" / "scripts" / "__init__.py")
62+
).load_module()
6163

6264
from developers_chamber.scripts.init_aliasses import *
6365

developers_chamber/click/alias.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import re
2+
import shlex
3+
from gettext import gettext as _
4+
5+
import click
6+
from click.formatting import wrap_text
7+
8+
9+
def find_and_replace_command_variable(arg, command, index):
10+
match = re.match(r"^--(?P<arg_name>[^=\ ]+)[\ =](?P<arg_value>.+)", arg)
11+
if match:
12+
arg_name, arg_value = match.groups()
13+
if f"${arg_name}" in command:
14+
return True, command.replace(f"${arg_name}", arg_value)
15+
elif f'${arg_name.replace("-", "_")}' in command:
16+
return True, command.replace(f'${arg_name.replace("-", "_")}', arg_value)
17+
if f"${index}" in command:
18+
return True, command.replace(f"${index}", arg)
19+
return False, command
20+
21+
22+
def parse_alias(alias):
23+
from developers_chamber.scripts import cli
24+
25+
command_parts = list(shlex.split(alias))
26+
used_command_parts = []
27+
28+
click_command = cli
29+
while command_parts:
30+
command_part = command_parts[0]
31+
current_click_command = click_command.get_command(None, command_part)
32+
if current_click_command is None:
33+
raise click.ClickException(
34+
'Command to the alias "{}" cannot be found'.format(alias)
35+
)
36+
37+
used_command_parts.append(command_parts.pop(0))
38+
click_command = current_click_command
39+
if not isinstance(current_click_command, click.Group):
40+
break
41+
return used_command_parts, command_parts, click_command, alias
42+
43+
44+
class AliasCommand(click.Command):
45+
46+
def __init__(self, commands, *args, **kwargs):
47+
super().__init__(*args, **kwargs)
48+
self._parse_alias(commands)
49+
50+
def _parse_alias(self, commands):
51+
if isinstance(commands, str):
52+
commands = [commands]
53+
description = ""
54+
elif isinstance(commands, list):
55+
commands = commands
56+
description = ""
57+
elif isinstance(commands, dict):
58+
description = commands["description"]
59+
commands = commands["command"]
60+
else:
61+
raise click.ClickException("Invalid alias type")
62+
63+
commands = [commands] if isinstance(commands, str) else commands
64+
self.aliases = [(parse_alias(alias)) for alias in commands]
65+
self.short_help = description
66+
67+
def format_help_text(self, ctx, formatter) -> None:
68+
formatter.write_paragraph()
69+
with formatter.indentation():
70+
if self.short_help:
71+
formatter.write_text(self.short_help)
72+
formatter.write_paragraph()
73+
formatter.write_text("Alias to commands: ")
74+
with formatter.indentation():
75+
for (
76+
used_command_parts,
77+
remaining_command_parts,
78+
click_command,
79+
alias_str,
80+
) in self.aliases:
81+
formatter.write_text("* " + " ".join(used_command_parts))
82+
if remaining_command_parts:
83+
with formatter.indentation(), formatter.indentation():
84+
formatter.write_text(" ".join(remaining_command_parts))
85+
86+
def format_epilog(self, ctx, formatter) -> None:
87+
with formatter.section(_("Commands in alias help")):
88+
for (
89+
used_command_parts,
90+
remaining_command_parts,
91+
click_command,
92+
alias_str,
93+
) in self.aliases:
94+
with formatter.indentation():
95+
formatter.write_paragraph()
96+
formatter.write_text("* " + " ".join(used_command_parts))
97+
with formatter.indentation(), formatter.indentation():
98+
click_command.format_help_text(ctx, formatter)
99+
click_command.format_options(ctx, formatter)
100+
formatter.write_paragraph()
101+
102+
def invoke(self, ctx):
103+
from developers_chamber.scripts import cli
104+
105+
for i, (
106+
used_command_parts,
107+
remaining_command_parts,
108+
click_command,
109+
alias_str,
110+
) in enumerate(self.aliases):
111+
if i == 0:
112+
alias_args = []
113+
114+
for index, arg in enumerate(ctx.args, start=1):
115+
replaced_arg, alias_str = find_and_replace_command_variable(
116+
arg, alias_str, index
117+
)
118+
if not replaced_arg:
119+
alias_args.append(arg)
120+
121+
if "$@" in alias_str:
122+
alias_str = alias_str.replace("$@", " ".join(ctx.args))
123+
alias_args = []
124+
125+
cli.main(args=shlex.split(alias_str) + alias_args, standalone_mode=False)

developers_chamber/git_utils.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import git
44
from click import BadParameter, UsageError
5-
from git import GitCommandError
5+
from git import GitCommandError, InvalidGitRepositoryError
66

77
from .types import ReleaseType, VersionFileType
88
from .version_utils import bump_to_next_version, bump_version, get_version
@@ -31,7 +31,9 @@ def create_release_branch(version, release_type, remote_name=None, branch_name=N
3131
return release_branch_name
3232

3333

34-
def create_release(version_file, release_type, remote_name=None, branch_name=None, file_type=None):
34+
def create_release(
35+
version_file, release_type, remote_name=None, branch_name=None, file_type=None
36+
):
3537
repo = git.Repo(".")
3638
g = repo.git
3739

@@ -214,3 +216,19 @@ def get_current_issue_key():
214216
return match.group("issue_key")
215217
else:
216218
return None
219+
220+
221+
def get_remote_url():
222+
try:
223+
repo = git.Repo(".")
224+
return f"https://{repo.remotes.origin.url.split('@')[1].split(':')[0]}"
225+
except InvalidGitRepositoryError:
226+
raise UsageError("Git repository not found in the current directory")
227+
228+
229+
def get_remote_path():
230+
try:
231+
repo = git.Repo(".")
232+
return repo.remotes.origin.url.split("@")[1].split(":")[1]
233+
except InvalidGitRepositoryError:
234+
raise UsageError("Git repository not found in the current directory")

developers_chamber/gitlab_utils.py

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33
import time
44
import requests
55
from click import UsageError
6+
from urllib.parse import quote
67

78

89
def create_merge_request(
9-
api_url, token, title, description, source_branch, target_branch, project, assignee_id=None, automerge=False
10+
url,
11+
token,
12+
title,
13+
description,
14+
source_branch,
15+
target_branch,
16+
project,
17+
assignee_id=None,
18+
automerge=False,
1019
):
1120
response = requests.post(
12-
f"{api_url}/projects/{quote_plus(project)}/merge_requests",
21+
f"{url}/api/v4/projects/{quote_plus(project)}/merge_requests",
1322
headers={
1423
"PRIVATE-TOKEN": token,
1524
},
@@ -18,42 +27,38 @@ def create_merge_request(
1827
"target_branch": target_branch,
1928
"title": title,
2029
"description": description,
21-
"assignee_id": assignee_id
30+
"assignee_id": assignee_id,
2231
},
2332
)
2433

2534
if response.status_code != 201:
2635
raise UsageError(f'GitLab error: {response.content.decode("utf-8")}')
2736

2837
if automerge:
29-
time.sleep(5)
30-
message = activate_automerge(api_url, token, project, response.json()['iid'])
38+
message = activate_automerge(url, token, project, response.json()["iid"])
3139
return f"{response.json()['web_url']} ({message})"
3240

33-
return response.json()['web_url']
41+
return response.json()["web_url"]
3442

3543

36-
def activate_automerge(
37-
api_url, token, project, merge_request_id
38-
):
39-
merge_response = requests.put(
40-
f"{api_url}/projects/{quote_plus(project)}/merge_requests/{merge_request_id}/merge",
41-
json={"merge_when_pipeline_succeeds": True},
42-
headers={
43-
"PRIVATE-TOKEN": token,
44-
},
45-
)
46-
if merge_response.status_code != 200:
47-
return "Automerge activation failed"
48-
else:
49-
return "Automerge activated"
44+
def activate_automerge(url, token, project, merge_request_id, retries=5):
45+
for _ in range(retries):
46+
merge_response = requests.put(
47+
f"{url}/api/v4/projects/{quote_plus(project)}/merge_requests/{merge_request_id}/merge",
48+
json={"merge_when_pipeline_succeeds": True},
49+
headers={
50+
"PRIVATE-TOKEN": token,
51+
},
52+
)
53+
if merge_response.status_code == 200:
54+
return "Automerge activated"
55+
time.sleep(5)
56+
return "Automerge activation failed"
5057

5158

52-
def run_job(
53-
api_url, token, project, ref, variables
54-
):
59+
def run_job(url, token, project, ref, variables):
5560
response = requests.post(
56-
f"{api_url}/projects/{quote_plus(project)}/pipeline",
61+
f"{url}/api/v4/projects/{quote_plus(project)}/pipeline",
5762
headers={
5863
"PRIVATE-TOKEN": token,
5964
},
@@ -66,10 +71,24 @@ def run_job(
6671
"variable_type": "env_var",
6772
}
6873
for key, value in variables.items()
69-
]
74+
],
7075
},
7176
)
7277
if response.status_code != 201:
7378
raise UsageError(f'GitLab error: {response.content.decode("utf-8")}')
7479
else:
7580
return response.json()["web_url"]
81+
82+
83+
def get_project_id(url, project, token):
84+
response = requests.get(
85+
f"{url}/api/v4/projects/{quote_plus(project)}",
86+
headers={
87+
"PRIVATE-TOKEN": token,
88+
"Content-type": "application/json",
89+
},
90+
)
91+
if response.status_code != 200:
92+
raise UsageError(f'GitLab error: {response.content.decode("utf-8")}')
93+
else:
94+
return response.json()["id"]
Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,49 @@
11
import click
2+
from click.formatting import HelpFormatter
3+
from gettext import gettext as _
4+
from developers_chamber.click.alias import AliasCommand
25

36

4-
@click.group()
7+
class FullHelpGroup(click.Group):
8+
def format_commands(self, ctx, formatter) -> None:
9+
"""Extra format methods for multi methods that adds all the commands
10+
after the options.
11+
"""
12+
all_commands = []
13+
for subcommand in self.list_commands(ctx):
14+
cmd = self.get_command(ctx, subcommand)
15+
# What is this, the tool lied about a command. Ignore it
16+
if cmd is None:
17+
continue
18+
if cmd.hidden:
19+
continue
20+
21+
all_commands.append((subcommand, cmd))
22+
23+
alias_commands = [
24+
command for command in all_commands if isinstance(command[1], AliasCommand)
25+
]
26+
commands = [
27+
command for command in all_commands if command not in alias_commands
28+
]
29+
30+
limit = formatter.width - 6 - max(len(cmd[0]) for cmd in all_commands)
31+
32+
for commands, label in [
33+
(alias_commands, _("Aliases")),
34+
(commands, _("Commands")),
35+
]:
36+
if len(commands):
37+
rows = []
38+
for subcommand, cmd in commands:
39+
help = cmd.get_short_help_str(limit)
40+
rows.append((subcommand, help))
41+
42+
if rows:
43+
with formatter.section(label):
44+
formatter.write_dl(rows)
45+
46+
47+
@click.group(cls=FullHelpGroup)
548
def cli():
649
pass

developers_chamber/scripts/git.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ def git():
4848
"--file",
4949
"-f",
5050
help="path to the version file",
51-
type=str,
5251
default=default_version_files[0],
5352
required=True,
53+
type=click.Path(exists=True),
5454
)
5555
@click.option(
5656
"--remote-name",
@@ -96,9 +96,9 @@ def create_release_branch(release_type, file, remote_name, branch_name):
9696
"--file",
9797
"-f",
9898
help="path to the version file",
99-
type=str,
10099
default=default_version_files[0],
101100
required=True,
101+
type=click.Path(exists=True),
102102
)
103103
@click.option(
104104
"--remote-name",
@@ -119,7 +119,7 @@ def create_release_branch(release_type, file, remote_name, branch_name):
119119
help="version file type",
120120
type=EnumType(VersionFileType),
121121
default=default_version_file_type,
122-
required=False
122+
required=False,
123123
)
124124
def create_release(release_type, file, remote_name, branch_name, file_type):
125125
"""
@@ -170,10 +170,10 @@ def checkout_to_release_branch():
170170
"--file",
171171
"-f",
172172
help="path to the version file",
173-
type=str,
174173
default=default_version_files,
175174
required=True,
176175
multiple=True,
176+
type=click.Path(exists=True),
177177
)
178178
def bump_version_from_release_tag(file):
179179
"""
@@ -189,10 +189,10 @@ def bump_version_from_release_tag(file):
189189
"--file",
190190
"-f",
191191
help="path to the version file",
192-
type=str,
193192
default=default_version_files,
194193
required=True,
195194
multiple=True,
195+
type=click.Path(exists=True),
196196
)
197197
@click.option(
198198
"--remote-name",

0 commit comments

Comments
 (0)