66import functools
77from . import comments
88from . import utils
9+ from .parse_issue_comment import parse_issue_comment
910from .auth import verify as verify_auth
1011from .utils import lazy_debug
1112import logging
1516import sqlite3
1617import requests
1718from contextlib import contextmanager
18- from itertools import chain
1919from queue import Queue
2020import os
2121import sys
@@ -476,28 +476,20 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
476476 my_username ,
477477 )
478478
479- words = list ( chain . from_iterable ( re . findall ( r'\S+' , x ) for x in body . splitlines () if '@' + my_username in x )) # noqa
480- if words [ 1 :] == [ "are" , "you" , "still" , "there?" ] and realtime :
481- state . add_comment (
482- ":cake: {} \n \n " . format (
483- random . choice ( PORTAL_TURRET_DIALOG ), PORTAL_TURRET_IMAGE )
484- )
485- for i , word in reversed ( list ( enumerate ( words ))) :
479+ hooks = []
480+ if 'hooks' in global_cfg :
481+ hooks = list ( global_cfg [ 'hooks' ]. keys ())
482+
483+ commands = parse_issue_comment ( username , body , sha , my_username , hooks )
484+
485+ for command in commands :
486486 found = True
487- if word == 'r+' or word . startswith ( 'r=' ) :
487+ if command . action == 'approve' :
488488 if not _reviewer_auth_verified ():
489489 continue
490490
491- if not sha and i + 1 < len (words ):
492- cur_sha = sha_or_blank (words [i + 1 ])
493- else :
494- cur_sha = sha
495-
496- approver = word [len ('r=' ):] if word .startswith ('r=' ) else username
497-
498- # Ignore "r=me"
499- if approver == 'me' :
500- continue
491+ approver = command .actor
492+ cur_sha = command .commit
501493
502494 # Ignore WIP PRs
503495 is_wip = False
@@ -582,7 +574,7 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
582574 )
583575 state .change_labels (LabelEvent .APPROVED )
584576
585- elif word == 'r- ' :
577+ elif command . action == 'unapprove ' :
586578 # Allow the author of a pull request to unapprove their own PR. The
587579 # author can already perform other actions that effectively
588580 # unapprove the PR (change the target branch, push more commits,
@@ -601,14 +593,12 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
601593 if realtime :
602594 state .change_labels (LabelEvent .REJECTED )
603595
604- elif word . startswith ( 'p=' ) :
596+ elif command . action == 'prioritize' :
605597 if not verify_auth (username , repo_label , repo_cfg , state ,
606598 AuthState .TRY , realtime , my_username ):
607599 continue
608- try :
609- pvalue = int (word [len ('p=' ):])
610- except ValueError :
611- continue
600+
601+ pvalue = command .priority
612602
613603 if pvalue > global_cfg ['max_priority' ]:
614604 if realtime :
@@ -620,12 +610,12 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
620610 state .priority = pvalue
621611 state .save ()
622612
623- elif word . startswith ( 'delegate=' ) :
613+ elif command . action == 'delegate' :
624614 if not verify_auth (username , repo_label , repo_cfg , state ,
625615 AuthState .REVIEWER , realtime , my_username ):
626616 continue
627617
628- state .delegate = word [ len ( 'delegate=' ):]
618+ state .delegate = command . delegate_to
629619 state .save ()
630620
631621 if realtime :
@@ -634,14 +624,14 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
634624 delegate = state .delegate
635625 ))
636626
637- elif word == 'delegate- ' :
627+ elif command . action == 'undelegate ' :
638628 # TODO: why is this a TRY?
639629 if not _try_auth_verified ():
640630 continue
641631 state .delegate = ''
642632 state .save ()
643633
644- elif word == 'delegate+ ' :
634+ elif command . action == 'delegate-author ' :
645635 if not _reviewer_auth_verified ():
646636 continue
647637
@@ -654,7 +644,7 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
654644 delegate = state .delegate
655645 ))
656646
657- elif word == 'retry' and realtime :
647+ elif command . action == 'retry' and realtime :
658648 if not _try_auth_verified ():
659649 continue
660650 state .set_status ('' )
@@ -663,7 +653,7 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
663653 state .record_retry_log (command_src , body )
664654 state .change_labels (event )
665655
666- elif word in ['try' , 'try- ' ] and realtime :
656+ elif command . action in ['try' , 'untry ' ] and realtime :
667657 if not _try_auth_verified ():
668658 continue
669659 if state .status == '' and state .approved_by :
@@ -674,7 +664,7 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
674664 )
675665 continue
676666
677- state .try_ = word == 'try'
667+ state .try_ = command . action == 'try'
678668
679669 state .merge_sha = ''
680670 state .init_build_res ([])
@@ -689,14 +679,14 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
689679 # any meaningful labeling events.
690680 state .change_labels (LabelEvent .TRY )
691681
692- elif word in WORDS_TO_ROLLUP :
682+ elif command . action == 'rollup' :
693683 if not _try_auth_verified ():
694684 continue
695- state .rollup = WORDS_TO_ROLLUP [ word ]
685+ state .rollup = command . rollup_value
696686
697687 state .save ()
698688
699- elif word == 'force' and realtime :
689+ elif command . action == 'force' and realtime :
700690 if not _try_auth_verified ():
701691 continue
702692 if 'buildbot' in repo_cfg :
@@ -725,61 +715,58 @@ def parse_commands(body, username, repo_label, repo_cfg, state, my_username,
725715 ':bomb: Buildbot returned an error: `{}`' .format (err )
726716 )
727717
728- elif word == 'clean' and realtime :
718+ elif command . action == 'clean' and realtime :
729719 if not _try_auth_verified ():
730720 continue
731721 state .merge_sha = ''
732722 state .init_build_res ([])
733723
734724 state .save ()
735- elif (word == 'hello?' or word == 'ping' ) and realtime :
736- state .add_comment (":sleepy: I'm awake I'm awake" )
737- elif word .startswith ('treeclosed=' ):
725+
726+ elif command .action == 'ping' and realtime :
727+ if command .ping_type == 'portal' :
728+ state .add_comment (
729+ ":cake: {}\n \n " .format (
730+ random .choice (PORTAL_TURRET_DIALOG ),
731+ PORTAL_TURRET_IMAGE )
732+ )
733+ else :
734+ state .add_comment (":sleepy: I'm awake I'm awake" )
735+
736+ elif command .action == 'treeclosed' :
738737 if not _reviewer_auth_verified ():
739738 continue
740- try :
741- treeclosed = int (word [len ('treeclosed=' ):])
742- state .change_treeclosed (treeclosed , command_src )
743- except ValueError :
744- pass
739+ state .change_treeclosed (command .treeclosed_value , command_src )
745740 state .save ()
746- elif word == 'treeclosed-' :
741+
742+ elif command .action == 'untreeclosed' :
747743 if not _reviewer_auth_verified ():
748744 continue
749745 state .change_treeclosed (- 1 , None )
750746 state .save ()
751- elif 'hooks' in global_cfg :
752- hook_found = False
753- for hook in global_cfg ['hooks' ]:
754- hook_cfg = global_cfg ['hooks' ][hook ]
755- if hook_cfg ['realtime' ] and not realtime :
747+
748+ elif command .action == 'hook' :
749+ hook = command .hook_name
750+ hook_cfg = global_cfg ['hooks' ][hook ]
751+ if hook_cfg ['realtime' ] and not realtime :
752+ continue
753+ if hook_cfg ['access' ] == "reviewer" :
754+ if not _reviewer_auth_verified ():
756755 continue
757- if word == hook or word .startswith ('%s=' % hook ):
758- if hook_cfg ['access' ] == "reviewer" :
759- if not _reviewer_auth_verified ():
760- continue
761- else :
762- if not _try_auth_verified ():
763- continue
764- hook_found = True
765- extra_data = ""
766- if word .startswith ('%s=' % hook ):
767- extra_data = word .split ("=" )[1 ]
768- Thread (
769- target = handle_hook_response ,
770- args = [state , hook_cfg , body , extra_data ]
771- ).start ()
772- if not hook_found :
773- found = False
756+ else :
757+ if not _try_auth_verified ():
758+ continue
759+ Thread (
760+ target = handle_hook_response ,
761+ args = [state , hook_cfg , body , command .hook_extra ]
762+ ).start ()
774763
775764 else :
776765 found = False
777766
778767 if found :
779768 state_changed = True
780769
781- words [i ] = ''
782-
783770 return state_changed
784771
785772
0 commit comments