Skip to content

Commit 22f2fde

Browse files
committed
Give useful error message
Give proper usage of command when a command is used without args. Fixes #356
1 parent f3ba1ec commit 22f2fde

8 files changed

+70
-28
lines changed

plugins/explain.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,17 @@ class Explain(BotPlugin):
9090
'\n- '.join(MSGS.keys())
9191
)
9292

93-
@re_botcmd(pattern=r'^explain\s+(\w+)(?:\s+to\s+@?([\w-]+))?$',
93+
@re_botcmd(pattern=r'^explain(\s+(\w+)(?:\s+to\s+@?([\w-]+))?)?$',
9494
re_cmd_name_help='explain <term>',
9595
flags=re.IGNORECASE)
9696
def explain(self, msg, match):
9797
"""Explain various terms.""" # Ignore QuotesBear
98-
return ('{}'.format('@{}: \n'.format(match.group(2))
99-
if match.group(2) else '') +
98+
if match.group(1) is None:
99+
return('Invalid command args. Usage: `{} '
100+
'explain <term>`.'.format(self.bot_config.BOT_PREFIX))
101+
return ('{}'.format('@{}: \n'.format(match.group(3))
102+
if match.group(3) else '') +
100103
self.MSGS.get(
101-
match.group(1).lower(),
104+
match.group(2).lower(),
102105
self.ERROR_MSG
103106
).format(bot_prefix=self.bot_config.BOT_PREFIX))

plugins/ghetto.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ class Ghetto(BotPlugin):
1010
Real talk yo
1111
"""
1212

13-
@re_botcmd(pattern=r'ghetto\s+(.+)',
13+
@re_botcmd(pattern=r'ghetto(\s+(.+))?',
1414
re_cmd_name_help='ghetto <sentence>',
1515
flags=re.IGNORECASE)
1616
def ghetto(self, msg, match):
1717
"""
1818
Real talk yo
1919
"""
20+
if match.group(1) is None:
21+
return('Invalid command args. Usage: `{} '
22+
'ghetto <sentence>`'.format(self.bot_config.BOT_PREFIX))
2023
rq = requests.post('http://www.gizoogle.net/textilizer.php',
21-
data={'translatetext': match.group(1)})
24+
data={'translatetext': match.group(2)})
2225

2326
translated_text = re.search(
2427
r'<textarea .*;\"/>(.+)</textarea>', rq.text)

plugins/labhub.py

+38-20
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,18 @@ def TEAMS(self, new):
9696
self._teams = new
9797

9898
# Ignore LineLengthBear, PycodestyleBear
99-
@re_botcmd(pattern=r'^(?:(?:welcome)|(?:inv)|(?:invite))\s+(?:(?:@?([\w-]+)(?:\s*(?:to)\s+(\w+))?)|(me))$',
99+
@re_botcmd(pattern=r'^(?:(?:welcome)|(?:inv)|(?:invite))(\s+(?:(?:@?([\w-]+)(?:\s*(?:to)\s+(\w+))?)|(me)))?$',
100100
re_cmd_name_help='invite [to team]')
101101
def invite_cmd(self, msg, match):
102102
"""
103103
Invite given user to given team. By default it invites to
104104
"newcomers" team.
105105
"""
106-
invitee = match.group(1)
106+
if match.group(1) is None:
107+
return('Invalid command args. Usage: `{} (invite|inv) '
108+
'((member|member to [team])|me)`'.format(
109+
self.bot_config.BOT_PREFIX))
110+
invitee = match.group(2)
107111
inviter = msg.frm.nick
108112

109113
if invitee == 'me':
@@ -113,7 +117,7 @@ def invite_cmd(self, msg, match):
113117
self.invited_users.add(user)
114118
return
115119

116-
team = 'newcomers' if match.group(2) is None else match.group(2)
120+
team = 'newcomers' if match.group(3) is None else match.group(3)
117121

118122
self.log.info('{} invited {} to {}'.format(inviter, invitee, team))
119123

@@ -146,14 +150,17 @@ def callback_message(self, msg):
146150
self.TEAMS[self.GH_ORG_NAME + ' newcomers'].invite(user)
147151
self.invited_users.add(user)
148152

149-
@re_botcmd(pattern=r'(?:new|file) issue ([\w\-\.]+?)(?: |\n)(.+?)(?:$|\n((?:.|\n)*))', # Ignore LineLengthBear, PyCodeStyleBear
153+
@re_botcmd(pattern=r'(?:new|file) issue( ([\w\-\.]+?)(?: |\n)(.+?)(?:$|\n((?:.|\n)*)))?', # Ignore LineLengthBear, PyCodeStyleBear
150154
re_cmd_name_help='new issue repo-name title\n[description]',
151155
flags=re.IGNORECASE)
152156
def create_issue_cmd(self, msg, match):
153157
"""Create issues on GitHub and GitLab repositories.""" # Ignore QuotesBear, LineLengthBear, PyCodeStyleBear
154-
repo_name = match.group(1)
155-
iss_title = match.group(2)
156-
iss_description = match.group(3) if match.group(3) is not None else ''
158+
if match.group(1) is None:
159+
return('Invalid command args. Usage: `{} (new|file) issue repo-name'
160+
' title\n[description]`'.format(self.bot_config.BOT_PREFIX))
161+
repo_name = match.group(2)
162+
iss_title = match.group(3)
163+
iss_description = match.group(4) if match.group(4) is not None else ''
157164
extra_msg = '\nOpened by @{username} at [{backend}]({msg_link})'.format(
158165
username=msg.frm.nick,
159166
backend=self.bot_config.BACKEND,
@@ -169,14 +176,17 @@ def create_issue_cmd(self, msg, match):
169176
'exist. Please ensure that the repository is available '
170177
'and owned by the org.')
171178

172-
@re_botcmd(pattern=r'^unassign\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/issues/(\d+)', # Ignore LineLengthBear, PyCodeStyleBear
179+
@re_botcmd(pattern=r'^unassign(\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/issues/(\d+))?', # Ignore LineLengthBear, PyCodeStyleBear
173180
re_cmd_name_help='unassign <complete-issue-URL>',
174181
flags=re.IGNORECASE)
175182
def unassign_cmd(self, msg, match):
176183
"""Unassign from an issue.""" # Ignore QuotesBear
177-
org = match.group(2)
178-
repo_name = match.group(3)
179-
issue_number = match.group(4)
184+
if match.group(1) is None:
185+
return('Invalid command args. Usage: `{} unassign '
186+
'<complete-issue-URL>`'.format(self.bot_config.BOT_PREFIX))
187+
org = match.group(3)
188+
repo_name = match.group(4)
189+
issue_number = match.group(5)
180190

181191
user = msg.frm.nick
182192

@@ -196,13 +206,15 @@ def unassign_cmd(self, msg, match):
196206
else:
197207
return 'You are not an assignee on the issue.'
198208

199-
@re_botcmd(pattern=r'mark\s+(wip|pending(?:(?:-|\s+)review)?\b)\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/(pull|merge_requests)/(\d+)', # Ignore LineLengthBear, PyCodeStyleBear
209+
@re_botcmd(pattern=r'mark(\s+(wip|pending(?:(?:-|\s+)review)?\b)\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/(pull|merge_requests)/(\d+))?', # Ignore LineLengthBear, PyCodeStyleBear
200210
re_cmd_name_help='mark (wip|pending) <complete-PR-URL>',
201211
flags=re.IGNORECASE)
202212
def mark_cmd(self, msg, match):
203213
"""Mark a given PR/MR with status labels.""" # Ignore QuotesBear
204-
state, host, org, repo_name, xr, number = match.groups()
205-
214+
arg, state, host, org, repo_name, xr, number = match.groups()
215+
if arg is None:
216+
return('Invalid command args. Usage: `{} mark (wip|pending) '
217+
'<complete-PR-URL>`'.format(self.bot_config.BOT_PREFIX))
206218
if host.lower() == 'github':
207219
assert xr.lower() == 'pull'
208220
elif host.lower() == 'gitlab':
@@ -251,14 +263,17 @@ def mark_cmd(self, msg, match):
251263
bot_prefix=self.bot_config.BOT_PREFIX)
252264
)
253265

254-
@re_botcmd(pattern=r'^assign\s+https://(github|gitlab)\.com/([^/]+)/([^/]+/)+issues/(\d+)', # Ignore LineLengthBear, PyCodeStyleBear
266+
@re_botcmd(pattern=r'^assign(\s+https://(github|gitlab)\.com/([^/]+)/([^/]+/)+issues/(\d+))?', # Ignore LineLengthBear, PyCodeStyleBear
255267
re_cmd_name_help='assign <complete-issue-URL>',
256268
flags=re.IGNORECASE)
257269
def assign_cmd(self, msg, match):
258270
"""Assign to GitLab and GitHub issues.""" # Ignore QuotesBear
259-
org = match.group(2)
260-
repo_name = match.group(3)[:-1]
261-
iss_number = match.group(4)
271+
if match.group(1) is None:
272+
return('Invalid command args. Usage: `{} assign '
273+
'<complete-issue-URL>`'.format(self.bot_config.BOT_PREFIX))
274+
org = match.group(3)
275+
repo_name = match.group(4)[:-1]
276+
iss_number = match.group(5)
262277

263278
user = msg.frm.nick
264279

@@ -353,9 +368,12 @@ def community_state(pr_count: dict):
353368
else:
354369
return 'dead'
355370

356-
@re_botcmd(pattern=r'pr\s+stats\s+(\d+)(?:hours|hrs)')
371+
@re_botcmd(pattern=r'pr\s+stats(\s+(\d+)(?:hours|hrs))?')
357372
def pr_stats(self, msg, match):
358-
hours = match.group(1)
373+
if match.group(1) is None:
374+
return('Invalid command args. Usage: `{} pr stats <number-of-hours>'
375+
'(hours|hrs)`'.format(self.bot_config.BOT_PREFIX))
376+
hours = match.group(2)
359377
pr_count = dict()
360378
start = time.time()
361379
for count, (name, repo) in enumerate(self.gh_repos.items(), 1):

plugins/lmgtfy.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ class Lmgtfy(BotPlugin):
1919
'help you even faster!'
2020
)
2121

22-
@re_botcmd(pattern=r'lmgtfy\s+(.+)',
22+
@re_botcmd(pattern=r'lmgtfy(\s+(.+))?',
2323
re_cmd_name_help='lmgtfy <search-string>')
2424
def lmgtfy(self, msg, match):
2525
"""I'm lazy, please google for me.""" # Ignore QuotesBear
26-
link = 'https://www.lmgtfy.com/?q=' + match.group(1)
26+
if match.group(1) is None:
27+
return('Invalid command args. Usage: `{} lmgtfy '
28+
'<search-string>`'.format(self.bot_config.BOT_PREFIX))
29+
link = 'https://www.lmgtfy.com/?q=' + match.group(2)
2730
return self.MSG.format(link)

tests/explain_test.py

+1
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ def test_explain(testbot):
2121
'@meet')
2222
testbot.assertCommand("!please explain review",
2323
"Command \"please\" / \"please explain\" not found.")
24+
testbot.assertCommand("!explain", "Invalid command args.")

tests/ghetto_test.py

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
@vcr.use_cassette('tests/cassettes/ghetto.yaml')
99
def test_ghetto(testbot):
1010
testbot.assertCommand("!ghetto hi, whats up?", "hi, wassup?")
11+
testbot.assertCommand("!ghetto", "Invalid command args.")
1112
with requests_mock.Mocker() as m:
1213
m.register_uri('POST', 'http://www.gizoogle.net/textilizer.php',
1314
text='test text which will not match with the regex')

tests/labhub_test.py

+12
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def test_invite_cmd(self):
5858

5959
testbot.assertCommand('!invite meet to developers',
6060
':poop:')
61+
testbot.assertCommand('!invite', 'Invalid command args.')
6162

6263
def test_hello_world_callback(self):
6364
teams = {
@@ -118,6 +119,7 @@ def test_create_issue_cmd(self):
118119

119120
testbot_public.assertCommand('!new issue coala title', 'repository that does not exist')
120121

122+
testbot_public.assertCommand('!new issue', 'Invalid command args.')
121123
def test_unassign_cmd(self):
122124
plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub)
123125
plugins.labhub.GitLab = create_autospec(IGitt.GitLab.GitLab.GitLab)
@@ -147,6 +149,7 @@ def test_unassign_cmd(self):
147149

148150
testbot.assertCommand('!unassign https://gitlab.com/ala/am/issues/532',
149151
'Repository not owned by our org.')
152+
testbot.assertCommand('!unassign', 'Invalid command args.')
150153

151154
def test_assign_cmd(self):
152155
plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub)
@@ -228,6 +231,10 @@ def test_assign_cmd(self):
228231
# unknown org
229232
testbot.assertCommand(cmd.format('coa', 'a', '23'),
230233
'Repository not owned by our org.')
234+
# command without args
235+
testbot.assertCommand('!assign', 'Invalid command args.')
236+
with self.assertRaises(queue.Empty):
237+
testbot.pop_message()
231238

232239
def test_mark_cmd(self):
233240
labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR)
@@ -275,6 +282,8 @@ def test_mark_cmd(self):
275282
'marked pending review')
276283
testbot.assertCommand(cmd_github.format('pending review', 'coala', 'a', '23'),
277284
'marked pending review')
285+
# command without args
286+
testbot.assertCommand('!mark', 'Invalid command args.')
278287

279288
def test_alive(self):
280289
labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR)
@@ -312,6 +321,9 @@ def test_alive(self):
312321
testbot.assertCommand('!pr stats 3hours',
313322
'10 PRs opened in last 3 hours\n'
314323
'The community is on fire')
324+
testbot.assertCommand('!pr stats', 'Invalid command args.')
325+
with self.assertRaises(queue.Empty):
326+
testbot.pop_message()
315327

316328
def test_invite_me(self):
317329
teams = {

tests/lmgtfy_test.py

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ def test_lmgtfy(testbot):
1313
text.convert(
1414
Lmgtfy.MSG.format("https://www.lmgtfy.com/?q=py c")
1515
))
16+
testbot.assertCommand('!lmgtfy', 'Invalid command args.')

0 commit comments

Comments
 (0)