From 2f8ace1fd1be005cb4abb63b1a84ec99635e4233 Mon Sep 17 00:00:00 2001 From: Vamshi99 Date: Tue, 28 Nov 2017 18:59:54 +0530 Subject: [PATCH] Give useful error message Give proper usage of command when a command is used without args. Fixes https://github.com/coala/corobo/issues/356 --- plugins/explain.py | 11 +++++--- plugins/ghetto.py | 7 ++++-- plugins/labhub.py | 58 ++++++++++++++++++++++++++++--------------- plugins/lmgtfy.py | 7 ++++-- tests/explain_test.py | 1 + tests/ghetto_test.py | 1 + tests/labhub_test.py | 9 +++++++ tests/lmgtfy_test.py | 1 + 8 files changed, 67 insertions(+), 28 deletions(-) diff --git a/plugins/explain.py b/plugins/explain.py index 936d2e83..21c214c5 100644 --- a/plugins/explain.py +++ b/plugins/explain.py @@ -90,14 +90,17 @@ class Explain(BotPlugin): '\n- '.join(MSGS.keys()) ) - @re_botcmd(pattern=r'^explain\s+(\w+)(?:\s+to\s+@?([\w-]+))?$', + @re_botcmd(pattern=r'^explain((?:\s+(\w+)(?:\s+to\s+@?([\w-]+))?)|)$', re_cmd_name_help='explain ', flags=re.IGNORECASE) def explain(self, msg, match): """Explain various terms.""" # Ignore QuotesBear - return ('{}'.format('@{}: \n'.format(match.group(2)) - if match.group(2) else '') + + if match.group(1) is None: + return('Invalid command args. Usage: `{} ' + 'explain `.'.format(self.bot_config.BOT_PREFIX)) + return ('{}'.format('@{}: \n'.format(match.group(3)) + if match.group(3) else '') + self.MSGS.get( - match.group(1).lower(), + match.group(2).lower(), self.ERROR_MSG ).format(bot_prefix=self.bot_config.BOT_PREFIX)) diff --git a/plugins/ghetto.py b/plugins/ghetto.py index 91ab5669..df30b977 100755 --- a/plugins/ghetto.py +++ b/plugins/ghetto.py @@ -10,15 +10,18 @@ class Ghetto(BotPlugin): Real talk yo """ - @re_botcmd(pattern=r'ghetto\s+(.+)', + @re_botcmd(pattern=r'ghetto((?:\s+(.+))|)', re_cmd_name_help='ghetto ', flags=re.IGNORECASE) def ghetto(self, msg, match): """ Real talk yo """ + if match.group(1) is None: + return('Invalid command args. Usage: `{} ' + 'ghetto `'.format(self.bot_config.BOT_PREFIX)) rq = requests.post('http://www.gizoogle.net/textilizer.php', - data={'translatetext': match.group(1)}) + data={'translatetext': match.group(2)}) translated_text = re.search( r'', rq.text) diff --git a/plugins/labhub.py b/plugins/labhub.py index 39816db7..ae46676d 100644 --- a/plugins/labhub.py +++ b/plugins/labhub.py @@ -96,14 +96,18 @@ def TEAMS(self, new): self._teams = new # Ignore LineLengthBear, PycodestyleBear - @re_botcmd(pattern=r'^(?:(?:welcome)|(?:inv)|(?:invite))\s+(?:(?:@?([\w-]+)(?:\s*(?:to)\s+(\w+))?)|(me))$', + @re_botcmd(pattern=r'^(?:(?:welcome)|(?:inv)|(?:invite))((?:\s+(?:(?:@?([\w-]+)(?:\s*(?:to)\s+(\w+))?)|(me)))|)$', re_cmd_name_help='invite [to team]') def invite_cmd(self, msg, match): """ Invite given user to given team. By default it invites to "newcomers" team. """ - invitee = match.group(1) + if match.group(1) is None: + return('Invalid command args. Usage: `{} (invite|inv) ' + '((member|member to [team])|me)`'.format( + self.bot_config.BOT_PREFIX)) + invitee = match.group(2) inviter = msg.frm.nick if invitee == 'me': @@ -113,7 +117,7 @@ def invite_cmd(self, msg, match): self.invited_users.add(user) return - team = 'newcomers' if match.group(2) is None else match.group(2) + team = 'newcomers' if match.group(3) is None else match.group(3) self.log.info('{} invited {} to {}'.format(inviter, invitee, team)) @@ -146,14 +150,17 @@ def callback_message(self, msg): self.TEAMS[self.GH_ORG_NAME + ' newcomers'].invite(user) self.invited_users.add(user) - @re_botcmd(pattern=r'(?:new|file) issue ([\w\-\.]+?)(?: |\n)(.+?)(?:$|\n((?:.|\n)*))', # Ignore LineLengthBear, PyCodeStyleBear + @re_botcmd(pattern=r'(?:new|file) issue((?: ([\w\-\.]+?)(?: |\n)(.+?)(?:$|\n((?:.|\n)*)))|)', # Ignore LineLengthBear, PyCodeStyleBear re_cmd_name_help='new issue repo-name title\n[description]', flags=re.IGNORECASE) def create_issue_cmd(self, msg, match): """Create issues on GitHub and GitLab repositories.""" # Ignore QuotesBear, LineLengthBear, PyCodeStyleBear - repo_name = match.group(1) - iss_title = match.group(2) - iss_description = match.group(3) if match.group(3) is not None else '' + if match.group(1) is None: + return('Invalid command args. Usage: `{} (new|file) issue repo-name' + ' title\n[description]`'.format(self.bot_config.BOT_PREFIX)) + repo_name = match.group(2) + iss_title = match.group(3) + iss_description = match.group(4) if match.group(4) is not None else '' extra_msg = '\nOpened by @{username} at [{backend}]({msg_link})'.format( username=msg.frm.nick, backend=self.bot_config.BACKEND, @@ -169,14 +176,17 @@ def create_issue_cmd(self, msg, match): 'exist. Please ensure that the repository is available ' 'and owned by the org.') - @re_botcmd(pattern=r'^unassign\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/issues/(\d+)', # Ignore LineLengthBear, PyCodeStyleBear + @re_botcmd(pattern=r'^unassign((?:\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/issues/(\d+))|)', # Ignore LineLengthBear, PyCodeStyleBear re_cmd_name_help='unassign ', flags=re.IGNORECASE) def unassign_cmd(self, msg, match): """Unassign from an issue.""" # Ignore QuotesBear - org = match.group(2) - repo_name = match.group(3) - issue_number = match.group(4) + if match.group(1) is None: + return('Invalid command args. Usage: `{} unassign ' + '`'.format(self.bot_config.BOT_PREFIX)) + org = match.group(3) + repo_name = match.group(4) + issue_number = match.group(5) user = msg.frm.nick @@ -196,13 +206,15 @@ def unassign_cmd(self, msg, match): else: return 'You are not an assignee on the issue.' - @re_botcmd(pattern=r'mark\s+(wip|pending(?:(?:-|\s+)review)?\b)\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/(pull|merge_requests)/(\d+)', # Ignore LineLengthBear, PyCodeStyleBear + @re_botcmd(pattern=r'mark((?:\s+(wip|pending(?:(?:-|\s+)review)?\b)\s+https://(github|gitlab)\.com/([^/]+)/([^/]+)/(pull|merge_requests)/(\d+))|)', # Ignore LineLengthBear, PyCodeStyleBear re_cmd_name_help='mark (wip|pending) ', flags=re.IGNORECASE) def mark_cmd(self, msg, match): """Mark a given PR/MR with status labels.""" # Ignore QuotesBear - state, host, org, repo_name, xr, number = match.groups() - + arg, state, host, org, repo_name, xr, number = match.groups() + if arg is None: + return('Invalid command args. Usage: `{} mark (wip|pending) ' + '`'.format(self.bot_config.BOT_PREFIX)) if host.lower() == 'github': assert xr.lower() == 'pull' elif host.lower() == 'gitlab': @@ -251,14 +263,17 @@ def mark_cmd(self, msg, match): bot_prefix=self.bot_config.BOT_PREFIX) ) - @re_botcmd(pattern=r'^assign\s+https://(github|gitlab)\.com/([^/]+)/([^/]+/)+issues/(\d+)', # Ignore LineLengthBear, PyCodeStyleBear + @re_botcmd(pattern=r'^assign((?:\s+https://(github|gitlab)\.com/([^/]+)/([^/]+/)+issues/(\d+))|)', # Ignore LineLengthBear, PyCodeStyleBear re_cmd_name_help='assign ', flags=re.IGNORECASE) def assign_cmd(self, msg, match): """Assign to GitLab and GitHub issues.""" # Ignore QuotesBear - org = match.group(2) - repo_name = match.group(3)[:-1] - iss_number = match.group(4) + if match.group(1) is None: + return('Invalid command args. Usage: `{} assign ' + '`'.format(self.bot_config.BOT_PREFIX)) + org = match.group(3) + repo_name = match.group(4)[:-1] + iss_number = match.group(5) user = msg.frm.nick @@ -353,9 +368,12 @@ def community_state(pr_count: dict): else: return 'dead' - @re_botcmd(pattern=r'pr\s+stats\s+(\d+)(?:hours|hrs)') + @re_botcmd(pattern=r'pr\s+stats((?:\s+(\d+)(?:hours|hrs))|)') def pr_stats(self, msg, match): - hours = match.group(1) + if match.group(1) is None: + return('Invalid command args. Usage: `{} pr stats ' + '(hours|hrs)`'.format(self.bot_config.BOT_PREFIX)) + hours = match.group(2) pr_count = dict() start = time.time() for count, (name, repo) in enumerate(self.gh_repos.items(), 1): diff --git a/plugins/lmgtfy.py b/plugins/lmgtfy.py index e1d2738c..9220ed5a 100644 --- a/plugins/lmgtfy.py +++ b/plugins/lmgtfy.py @@ -19,9 +19,12 @@ class Lmgtfy(BotPlugin): 'help you even faster!' ) - @re_botcmd(pattern=r'lmgtfy\s+(.+)', + @re_botcmd(pattern=r'lmgtfy((?:\s+(.+))|)', re_cmd_name_help='lmgtfy ') def lmgtfy(self, msg, match): """I'm lazy, please google for me.""" # Ignore QuotesBear - link = 'https://www.lmgtfy.com/?q=' + match.group(1) + if match.group(1) is None: + return('Invalid command args. Usage: `{} lmgtfy ' + '`'.format(self.bot_config.BOT_PREFIX)) + link = 'https://www.lmgtfy.com/?q=' + match.group(2) return self.MSG.format(link) diff --git a/tests/explain_test.py b/tests/explain_test.py index 948b4ce9..0a6fdd05 100644 --- a/tests/explain_test.py +++ b/tests/explain_test.py @@ -21,3 +21,4 @@ def test_explain(testbot): '@meet') testbot.assertCommand("!please explain review", "Command \"please\" / \"please explain\" not found.") + testbot.assertCommand("!explain", "Invalid command args.") diff --git a/tests/ghetto_test.py b/tests/ghetto_test.py index 06da4af2..e36b4a9c 100644 --- a/tests/ghetto_test.py +++ b/tests/ghetto_test.py @@ -8,6 +8,7 @@ @vcr.use_cassette('tests/cassettes/ghetto.yaml') def test_ghetto(testbot): testbot.assertCommand("!ghetto hi, whats up?", "hi, wassup?") + testbot.assertCommand("!ghetto", "Invalid command args.") with requests_mock.Mocker() as m: m.register_uri('POST', 'http://www.gizoogle.net/textilizer.php', text='test text which will not match with the regex') diff --git a/tests/labhub_test.py b/tests/labhub_test.py index 8bbb7771..302a80d6 100644 --- a/tests/labhub_test.py +++ b/tests/labhub_test.py @@ -58,6 +58,7 @@ def test_invite_cmd(self): testbot.assertCommand('!invite meet to developers', ':poop:') + testbot.assertCommand('!invite', 'Invalid command args.') def test_hello_world_callback(self): teams = { @@ -118,6 +119,7 @@ def test_create_issue_cmd(self): testbot_public.assertCommand('!new issue coala title', 'repository that does not exist') + testbot_public.assertCommand('!new issue', 'Invalid command args.') def test_unassign_cmd(self): plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub) plugins.labhub.GitLab = create_autospec(IGitt.GitLab.GitLab.GitLab) @@ -147,6 +149,7 @@ def test_unassign_cmd(self): testbot.assertCommand('!unassign https://gitlab.com/ala/am/issues/532', 'Repository not owned by our org.') + testbot.assertCommand('!unassign', 'Invalid command args.') def test_assign_cmd(self): plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub) @@ -228,6 +231,8 @@ def test_assign_cmd(self): # unknown org testbot.assertCommand(cmd.format('coa', 'a', '23'), 'Repository not owned by our org.') + # command without args + testbot.assertCommand('!assign', 'Invalid command args.') def test_mark_cmd(self): labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR) @@ -275,6 +280,8 @@ def test_mark_cmd(self): 'marked pending review') testbot.assertCommand(cmd_github.format('pending review', 'coala', 'a', '23'), 'marked pending review') + # command without args + testbot.assertCommand('!mark', 'Invalid command args.') def test_alive(self): labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR) @@ -312,6 +319,8 @@ def test_alive(self): testbot.assertCommand('!pr stats 3hours', '10 PRs opened in last 3 hours\n' 'The community is on fire') + testbot.assertCommand('!pr stats', + 'Invalid command args.', timeout=100) def test_invite_me(self): teams = { diff --git a/tests/lmgtfy_test.py b/tests/lmgtfy_test.py index f9c5bfad..744b30bb 100644 --- a/tests/lmgtfy_test.py +++ b/tests/lmgtfy_test.py @@ -13,3 +13,4 @@ def test_lmgtfy(testbot): text.convert( Lmgtfy.MSG.format("https://www.lmgtfy.com/?q=py c") )) + testbot.assertCommand('!lmgtfy', 'Invalid command args.')