def check(self, ctx): if self.is_uplift: return True # Ignore merge changesets if len(ctx.parents()) > 1: return True # Ignore backouts if is_backout(ctx.description()): return True # Ignore changes that don't touch sync-messages.ini ipc_files = [f for f in ctx.files() if f == 'ipc/ipdl/sync-messages.ini'] if not ipc_files: return True # Allow patches authored by peers if self._is_peer_email(util.email(ctx.user())): return True # Allow if reviewed by any peer requal = list(parse_requal_reviewers(ctx.description())) if any(self._is_peer_nick(nick) for nick in requal): return True # Reject print_banner(self.ui, 'error', MISSING_REVIEW % short(ctx.node())) return False
def check(self, ctx): if self.is_uplift: return True # Ignore merge changesets if len(ctx.parents()) > 1: return True # Ignore backouts if is_backout(ctx.description()): return True # Ignore changes that don't touch .webidl files webidl_files = [f for f in ctx.files() if f.endswith('.webidl')] if not webidl_files: return True # Allow patches authored by peers if is_peer_email(util.email(ctx.user())): return True # Categorise files file_counts = collections.Counter() review_required_files = [] for f in webidl_files: file_counts['total'] += 1 if f.startswith(CHROME_WEBIDL_ROOT): file_counts['chrome'] += 1 elif f.startswith(SERVO_ROOT): file_counts['servo'] += 1 else: review_required_files.append(f) # Allow chrome-only and servo-only changes if file_counts['chrome'] + file_counts['servo'] == file_counts[ 'total']: if file_counts['chrome']: print_notice(self.ui, CHROME_ONLY) if file_counts['servo']: print_notice(self.ui, SERVO_ONLY) return True # Allow if reviewed by any peer requal = list(parse_requal_reviewers(ctx.description())) if any(is_peer_nick(nick) for nick in requal): return True # Reject print_banner( self.ui, 'error', MISSING_REVIEW % (short(ctx.node()), '\n'.join(review_required_files))) return False
def check(self, ctx): if len(ctx.parents()) > 1: # Skip merge changesets return True if is_backout(ctx.description()): # Ignore backouts return True if any(f.endswith('.ftl') for f in ctx.files()): requal = [ r.lower() for r in parse_requal_reviewers(ctx.description()) ] reviewers = [nick for (name, nick) in FTL_DRIVERS] if any(nick in reviewers for nick in requal): return True print_banner(self.ui, 'error', FTL_COMMIT_FOUND) return False return True
def is_backout(self): return commitparser.is_backout(self.commit.message)
def is_good_message(ui, c): def message(fmt): formatted_fmt = fmt % {b'rev': c.hex()[:12]} ui.write( b'\n\n' b'************************** ERROR ****************************\n' b'%s\n%s\n%s\n' b'*************************************************************\n' b'\n\n' % (formatted_fmt, c.user(), c.description())) desc = c.description() firstline = desc.splitlines()[0] # Ensure backout commit descriptions are well formed. if commitparser.is_backout(desc): try: if not commitparser.parse_backouts(desc, strict=True): raise ValueError('Rev %(rev)s has malformed backout message.') nodes, bugs = commitparser.parse_backouts(desc, strict=True) if not nodes: raise ValueError( 'Rev %(rev)s is missing backed out revisions.') except ValueError as e: # Reject invalid backout messages on vendored paths, warn otherwise. if is_vendor_ctx(c): message(pycompat.bytestr(e)) return False ui.write(b'Warning: %s\n' % (pycompat.bytestr(e) % { b'rev': c.hex()[:12] })) # Vendored merges must reference source revisions. if b'Source-Revision: ' in desc and is_vendor_ctx(c): ui.write(b'(%s looks like a vendoring change; ignoring commit message ' b'hook)\n' % short(c.node())) return True if c.user() in [b"ffxbld", b"seabld", b"tbirdbld", b"cltbld"]: return True if trySyntax.search(desc): message(b"Rev %(rev)s uses try syntax. (Did you mean to push to Try " b"instead?)") return False # Match against [PATCH] and [PATCH n/m] if b"[PATCH" in desc: message(b'Rev %(rev)s contains git-format-patch "[PATCH]" cruft. Use ' b'git-format-patch -k to avoid this.') return False if INVALID_REVIEW_FLAG_RE.search(firstline): message(b"Rev %(rev)s contains 'r?' in the commit message. Please use " b"'r=' instead.") return False for r in goodMessage: if r.search(firstline): return True desc_lower = desc.lower() if desc_lower.startswith((b'merge', b'merging', b'automated merge')): if len(c.parents()) == 2: return True else: message(b"Rev %(rev)s claims to be a merge, but it has only one " b"parent.") return False if desc_lower.startswith((b'back', b'revert')): # Purposely ambiguous: it's ok to say "backed out rev N" or # "reverted to rev N-1" message(b"Backout rev %(rev)s needs a bug number or a rev id.") else: message( b'Rev %(rev)s needs "Bug N" or "No bug" in the commit message.') return False
def is_backout(self): # type: () -> bool return commitparser.is_backout(self.msg)
def is_backout(self): return commitparser.is_backout(self.msg)