Skip to content

Commit 53e210b

Browse files
authored
Merge pull request #5 from kennytm/etc-updates
Various updates.
2 parents 6d10e4e + 3432e11 commit 53e210b

File tree

1 file changed

+76
-18
lines changed

1 file changed

+76
-18
lines changed

homu/main.py

+76-18
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from .git_helper import SSH_KEY_FILE
2323
import shlex
2424
import random
25+
import weakref
2526

2627
STATUS_TO_PRIORITY = {
2728
'success': 0,
@@ -343,7 +344,13 @@ def blocked_by_closed_tree(self):
343344
def start_testing(self, timeout):
344345
self.test_started = time.time() # FIXME: Save in the local database
345346
self.set_status('pending')
346-
timer = Timer(timeout, self.timed_out)
347+
348+
wm = weakref.WeakMethod(self.timed_out)
349+
def timed_out():
350+
m = wm()
351+
if m:
352+
m()
353+
timer = Timer(timeout, timed_out)
347354
timer.start()
348355
self.timeout_timer = timer
349356

@@ -488,11 +495,20 @@ def parse_commands(body, username, repo_cfg, state, my_username, db, states,
488495
continue
489496

490497
# Ignore WIP PRs
491-
if any(map(state.title.startswith, [
492-
'WIP', 'TODO', '[WIP]', '[TODO]',
493-
])):
494-
if realtime:
495-
state.add_comment(':clipboard: Looks like this PR is still in progress, ignoring approval') # noqa
498+
is_wip = False
499+
for wip_kw in ['WIP', 'TODO', '[WIP]', '[TODO]', '[DO NOT MERGE]']:
500+
if state.title.upper().startswith(wip_kw):
501+
if realtime:
502+
state.add_comment((
503+
':clipboard:'
504+
' Looks like this PR is still in progress,'
505+
' ignoring approval.\n\n'
506+
'Hint: Remove **{}** from this PR\'s title when'
507+
' it is ready for review.'
508+
).format(wip_kw))
509+
is_wip = True
510+
break
511+
if is_wip:
496512
continue
497513

498514
# Sometimes, GitHub sends the head SHA of a PR as 0000000
@@ -642,6 +658,14 @@ def parse_commands(body, username, repo_cfg, state, my_username, db, states,
642658
elif word in ['try', 'try-'] and realtime:
643659
if not _try_auth_verified():
644660
continue
661+
if state.status == '' and state.approved_by:
662+
state.add_comment(
663+
':no_good: '
664+
'Please do not `try` after a pull request has been `r+`ed.'
665+
' If you need to `try`, unapprove (`r-`) it first.'
666+
)
667+
continue
668+
645669
state.try_ = word == 'try'
646670

647671
state.merge_sha = ''
@@ -833,6 +857,32 @@ def create_merge(state, repo_cfg, branch, logger, git_cfg,
833857
state.body)
834858

835859
desc = 'Merge conflict'
860+
comment = (
861+
'This pull request and the master branch diverged in a way that cannot'
862+
' be automatically merged. Please rebase on top of the latest master'
863+
' branch, and let the reviewer approve again.\n'
864+
'\n'
865+
'<details><summary>How do I rebase?</summary>\n\n'
866+
'Assuming `self` is your fork and `upstream` is this repository,'
867+
' you can resolve the conflict following these steps:\n\n'
868+
'1. `git checkout {branch}` *(switch to your branch)*\n'
869+
'2. `git fetch upstream master` *(retrieve the latest master)*\n'
870+
'3. `git rebase upstream/master -p` *(rebase on top of it)*\n'
871+
'4. Follow the on-screen instruction to resolve conflicts'
872+
' (check `git status` if you got lost).\n'
873+
'5. `git push self {branch} --force-with-lease` *(update this PR)*\n\n'
874+
'You may also read'
875+
' [*Git Rebasing to Resolve Conflicts* by Drew Blessing](http://blessing.io/git/git-rebase/open-source/2015/08/23/git-rebasing-to-resolve-conflicts.html)' # noqa
876+
' for a short tutorial.\n\n'
877+
'Please avoid the ["**Resolve conflicts**" button](https://help.github.com/articles/resolving-a-merge-conflict-on-github/) on GitHub.' #noqa
878+
' It uses `git merge` instead of `git rebase` which makes the PR commit'
879+
' history more difficult to read.\n\n'
880+
'Sometimes step 4 will complete without asking for resolution. This is'
881+
' usually due to difference between how `Cargo.lock` conflict is'
882+
' handled during merge and rebase. This is normal, and you should still'
883+
' perform step 5 to update this PR.\n\n'
884+
'</details>\n\n'
885+
).format(branch=state.head_ref.split(':', 1)[1])
836886

837887
if git_cfg['local_git']:
838888

@@ -861,6 +911,7 @@ def create_merge(state, repo_cfg, branch, logger, git_cfg,
861911
utils.silent_call(git_cmd('rebase', '--abort'))
862912
if utils.silent_call(git_cmd('rebase', base_sha)) == 0:
863913
desc = 'Auto-squashing failed'
914+
comment = ''
864915
else:
865916
ap = '<try>' if state.try_ else state.approved_by
866917
text = '\nCloses: #{}\nApproved by: {}'.format(state.num, ap)
@@ -903,22 +954,29 @@ def create_merge(state, repo_cfg, branch, logger, git_cfg,
903954
merge_base_sha, base_sha))
904955
except subprocess.CalledProcessError:
905956
desc = 'Auto-squashing failed'
957+
comment = ''
906958
ok = False
907959

908960
if ok:
909961
utils.logged_call(git_cmd('checkout', '-B', branch, base_sha))
910962
try:
911-
utils.logged_call(git_cmd(
912-
'-c',
913-
'user.name=' + git_cfg['name'],
914-
'-c',
915-
'user.email=' + git_cfg['email'],
916-
'merge',
917-
'heads/homu-tmp',
918-
'--no-ff',
919-
'-m',
920-
merge_msg))
921-
except subprocess.CalledProcessError:
963+
subprocess.check_output(
964+
git_cmd(
965+
'-c',
966+
'user.name=' + git_cfg['name'],
967+
'-c',
968+
'user.email=' + git_cfg['email'],
969+
'merge',
970+
'heads/homu-tmp',
971+
'--no-ff',
972+
'-m',
973+
merge_msg),
974+
stderr=subprocess.STDOUT,
975+
universal_newlines=True)
976+
except subprocess.CalledProcessError as e:
977+
comment += '<details><summary>Error message</summary>\n\n```text\n'
978+
comment += e.output
979+
comment += '\n```\n\n</details>'
922980
pass
923981
else:
924982
if ensure_merge_equal:
@@ -964,7 +1022,7 @@ def create_merge(state, repo_cfg, branch, logger, git_cfg,
9641022
desc,
9651023
context='homu')
9661024

967-
state.add_comment(':lock: ' + desc)
1025+
state.add_comment(':lock: {}\n\n{}'.format(desc, comment))
9681026
state.change_labels(LabelEvent.CONFLICT)
9691027

9701028
return ''

0 commit comments

Comments
 (0)