Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Gary Benson <gbenson@redhat.com>
To: Joel Brobecker <brobecker@adacore.com>
Cc: Mike Frysinger <vapier@gentoo.org>,
	gdb@sourceware.org,
	       Andreas Arnez <arnez@linux.vnet.ibm.com>
Subject: Re: ChangeLogs in commit messages
Date: Fri, 15 Aug 2014 15:02:00 -0000	[thread overview]
Message-ID: <20140815150202.GA5674@blade.nx> (raw)
In-Reply-To: <20140815132816.GC6019@adacore.com>

Joel Brobecker wrote:
> > Does anybody have any experience writing such checks?  Or, does
> > anybody know of any project that already uses such checks?  I can
> > look into doing it myself (it's a pre-receive hook, right?)
> 
> I have loads of experience writing git hooks, but none with
> this repository's implementation.
> 
> I would typically adjust the "update" hook for that, but it looks
> like the "pre-receive" hook would also work.

I've put together a quick pre-receive hook (inlined below).  Each
received commit on the "master" branch that touches the "gdb"
subdirectory gets its message checked.  The check itself is fairly
cursory: it splits the message using the "YYYY-MM-DD  NAME  <EMAIL>"
headers, checks each is preceeded by a path starting with "gdb/" and
ending with "/", and checks each is followed by more "NAME  <EMAIL>"
lines, blank lines, or lines starting with tab.  I don't know how
comprehensive we want to be here as the message should already have
been checked over by the reviewer.

I've never done anything server-side with git before, so there may
well be things I'm missing here.  I was mainly experimenting to see
how difficult this all was :)

Cheers,
Gary

-- 
#!/usr/bin/env python

import re
import subprocess
import sys

GIT = "/usr/bin/git"
SHA1HASH = re.compile(r"^[0-9a-f]{40}$", re.IGNORECASE)

name_mail = r".*  <[^@]+@[^>]+>$"
CL_HDR_A = re.compile(r"^\d{4}-\d{2}-\d{2}  " + name_mail)
CL_HDR_B = re.compile(r"^\s+" + name_mail)

class MessageChecker:
    def __init__(self, rev):
        self.rev = rev

    def check(self, condition, msg):
        if not condition:
            print "error: %s: bad commit message" % self.rev
            print "error: %s" % msg
            sys.exit(1)

    def check_message(self, lines):
        self.check(len(lines) > 2, "message is too short")
        self.check(lines[1] == "", "second line should be blank")
        splits = [index
                  for index in xrange(2, len(lines))
                  if CL_HDR_A.match(lines[index]) is not None]
        self.check(splits, "no ChangeLog entries found")
        for start, limit in zip(splits, splits[1:] + [0]):
            start -= 1
            limit -= 1
            self.check_changelog(lines[start:limit])

    def check_changelog(self, lines):
        self.check(len(lines) > 2, "ChangeLog entry is too short")
        path = lines.pop(0)
        self.check(path.startswith("gdb/") and path.endswith("/"),
                   "each ChangeLog entry should be preceeded by its path")
        lines.pop(0) # lines[1] has already been checked
        while lines and CL_HDR_B.match(lines[0]) is not None:
            lines.pop(0)
        self.check(lines, "only ChangeLog headers found (no data)")
        for line in lines:
            self.check(not line or line.startswith("\t"),
                       "bad ChangeLog line %s" % repr(line))

def check_hash(hash):
    assert SHA1HASH.match(hash) is not None

def git(*command):
    fp = subprocess.Popen((GIT,) + command, stdout=subprocess.PIPE)
    output = fp.communicate()[0]
    if fp.returncode:
        sys.exit(1)
    return output

def git_rev_list(oldrev, newrev):
    check_hash(oldrev)
    check_hash(newrev)
    return git("rev-list", oldrev + ".." + newrev)

def git_diff_tree(rev):
    check_hash(rev)
    return git("diff-tree", rev)

def git_cat_file_commit(rev):
    check_hash(rev)
    return git("cat-file", "commit", rev)

def commit_touches_gdb(rev):
    lines = git_diff_tree(rev).rstrip().split("\n")
    check = lines.pop(0)
    assert check == rev
    for line in lines:
        if line.split()[-1] == "gdb":
            return True
    return False

def check_commit(rev):
    lines = git_cat_file_commit(rev).rstrip().split("\n")
    while lines and lines[0]:
        lines.pop(0)
    assert lines
    lines.pop(0)
    MessageChecker(rev).check_message(lines)

def process_pack(oldrev, newrev, refname):
    if refname == "refs/heads/master":
        revs = git_rev_list(oldrev, newrev).rstrip().split("\n")
        revs.reverse()
        for rev in revs:
            if commit_touches_gdb(rev):
                check_commit(rev)
            print "%s: ok" % rev

def main():
    for line in sys.stdin.xreadlines():
        bits = line.rstrip().split()
        assert len(bits) == 3
        process_pack(*bits)

if __name__ == "__main__":
    main()


  reply	other threads:[~2014-08-15 15:02 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-14  8:32 Gary Benson
2014-08-14 12:52 ` Joel Brobecker
2014-08-14 13:15   ` Gary Benson
2014-08-14 13:25     ` Joel Brobecker
2014-08-14 15:22     ` Eli Zaretskii
2014-08-15  8:05       ` Gary Benson
2014-08-15  8:41         ` Eli Zaretskii
2014-08-15 11:45           ` Andreas Schwab
2014-09-03 20:54   ` Sergio Durigan Junior
2014-09-03 21:22     ` Sergio Durigan Junior
2014-09-03 22:18       ` Andreas Schwab
2014-09-04  9:06         ` Gary Benson
2014-09-04 14:23           ` Sergio Durigan Junior
2014-09-04 16:08             ` Doug Evans
2014-09-04 17:36               ` Gary Benson
2014-09-05 10:13                 ` Gary Benson
2014-09-05 16:43                   ` Doug Evans
2014-09-08  9:50                     ` Gary Benson
2014-09-08 13:08                       ` James Hogan
2014-09-08 13:21                         ` James Hogan
2014-09-08 13:24                         ` Joel Brobecker
2014-09-08 15:31                           ` Gary Benson
2014-09-09  8:51                           ` James Hogan
2014-09-09 16:25                             ` Doug Evans
     [not found]   ` <54102ED8.7060307@redhat.com>
2014-09-10 16:12     ` Doug Evans
2014-09-10 16:28       ` Joel Brobecker
2014-09-15 10:30         ` Gary Benson
2014-09-15 12:45           ` Joel Brobecker
2014-09-15 15:30           ` Doug Evans
2014-09-15 16:05             ` Joel Brobecker
2014-09-15 17:47               ` Doug Evans
2014-09-16  9:31                 ` Gary Benson
2014-09-16 15:50                   ` Doug Evans
     [not found]                     ` <0CEE46EB9C50E44486A861D738D3E20645F67101@rsex2.realsil.com.cn>
2014-10-03 18:22                       ` GDB bugs Pedro Alves
2014-08-14 12:57 ` ChangeLogs in commit messages Mike Frysinger
2014-08-14 13:12   ` Gary Benson
2014-08-14 13:29     ` Joel Brobecker
2014-08-14 13:39       ` Andreas Schwab
2014-08-14 13:48         ` Joel Brobecker
2014-08-14 13:57           ` Andreas Schwab
2014-08-14 14:22             ` Joel Brobecker
2014-08-14 14:45               ` Andreas Schwab
2014-08-14 15:01                 ` Joel Brobecker
2014-08-14 15:13                   ` Andreas Schwab
2014-08-14 15:22                     ` Joel Brobecker
2014-08-14 15:44                       ` Andreas Schwab
2014-08-14 15:49                         ` Joel Brobecker
2014-08-14 19:04       ` Sergio Durigan Junior
2014-08-15  8:48       ` Gary Benson
2014-08-15 12:11         ` Joel Brobecker
2014-08-15 13:09           ` Gary Benson
2014-08-15 13:28             ` Joel Brobecker
2014-08-15 15:02               ` Gary Benson [this message]
2014-08-15 15:27                 ` Andreas Arnez
2014-08-15 16:08                 ` Joel Brobecker
2014-08-18  8:31                   ` Gary Benson
2014-08-18 14:54                     ` Doug Evans
2014-08-18 15:05                       ` Joel Brobecker
2014-08-18 15:27                         ` Gary Benson
2014-08-20 12:20                           ` Gary Benson
2014-08-14 16:22     ` Andreas Arnez
2014-08-14 13:23   ` Mike Frysinger
2014-08-14 13:36 ` Siva Chandra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140815150202.GA5674@blade.nx \
    --to=gbenson@redhat.com \
    --cc=arnez@linux.vnet.ibm.com \
    --cc=brobecker@adacore.com \
    --cc=gdb@sourceware.org \
    --cc=vapier@gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox