From 0530409bd5340d6e84b68e61a5a0faedd771b57c Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 30 May 2008 08:56:47 +0200 Subject: [PATCH] initial version --- alsatool | 532 ++++++++++++++++++++++++++++++ hooks/alsa-kernel.git/pre-receive | 410 +++++++++++++++++++++++ 2 files changed, 942 insertions(+) create mode 100755 alsatool create mode 100755 hooks/alsa-kernel.git/pre-receive diff --git a/alsatool b/alsatool new file mode 100755 index 0000000..ad46af3 --- /dev/null +++ b/alsatool @@ -0,0 +1,532 @@ +#! /usr/bin/python +# -*- Python -*- + +"""HG ALSA Tool + +Do operations on ALSA GIT repositories. + +Usage: + %(PROGRAM)s [options] command +""" + +import os +import sys +import getopt + +VERSION="2.0" + +PROGRAM = sys.argv[0] +ROOT = os.path.abspath(os.getcwd()) +USER = os.getenv('USER') +VERBOSE = False +REPOSITORIES = [ + 'alsa', 'alsa-driver', 'alsa-kmirror', 'alsa-lib', 'alsa-utils', + 'alsa-tools', 'alsa-firmware', 'alsa-oss', 'alsa-plugins', + 'alsa-python' +] + +def eprint(msg): + sys.stderr.write(msg + '\n') + +def selectrepos(repos): + if repos == None or len(repos) == 0: + return REPOSITORIES[:] + else: + neg = repos[0][0] == '-' + for repo in repos: + if (neg and repo[0] != '-') or \ + (not neg and repo[0] == '-'): + raise ValueError, "inverted and non-inverted repo specifications cannot be mixed!" + if neg: + res = REPOSITORIES + for repo in repos: + res.remove(repo[1:]) + return res + for repo in repos: + if not repo in REPOSITORIES: + raise ValueError, "repository '%s' is unknown" % repo + return repos + +def xlist(argv=None): + s = '' + for i in REPOSITORIES: + s += i + ' ' + print s[:-1] + +def git(repo): + dir = ROOT + '/' + repo + return "git --work-tree=%s --git-dir=%s" % (dir, dir + '/.git') + +def clone(argv=None): + repos = selectrepos(argv) + for repo in repos: + print "clone", repo + +def diff(argv=None): + repos = selectrepos(argv) + for repo in repos: + pull([repo]) + if os.system("%s --no-pager diff origin/master..master" % git(repo)): + raise ValueError, "diff %s" % repo + +def pull(argv=None): + repos = selectrepos(argv) + for repo in repos: + if os.system("%s checkout master" % git(repo)): + raise ValueError, "checkout %s" % repo + os.chdir(ROOT + '/' + repo) + if os.system("%s pull" % git(repo)): + raise ValueError, "pull %s" % repo + +def push(argv=None): + repos = selectrepos(argv) + for repo in repos: + if os.system("%s checkout master" % git(repo)): + raise ValueError, "checkout %s" % repo + if os.system("%s push master:refs/heads/master" % git(repo)): + raise ValueError, "push %s" % repo + +def version_sort(tags): + tags1 = [] + tags2 = {} + for tag in tags: + tag = tag.strip() + if tag == "tip": + continue + try: + a, b, c = tag.split('.') + if a[0] != 'v': + raise ValueError + a = int(a[1:]) + b = int(b) + idx = 0 + while idx < len(c) and ord(c[idx]) <= ord('9'): + idx += 1 + c1 = int(c[:idx]) + c2 = c[idx:] + str = "%08i.%08i.%08i.%s" % (a, b, c1, c2) + tags1.append(str) + tags2[str] = tag + except: + from traceback import print_exc + print_exc() + pass + tags1.sort() + res = [] + for tag in tags1: + res.append(tags2[tag]) + if len(res) > 0: + return res + return None + +def showchanges1(repos): + res = {} + for repo in repos: + if repo == 'alsa': + continue + res[repo] = [] + tags = version_sort(os.popen("%s tag" % git(repo)).readlines()) + if not tags: + raise ValueError, "cannot obtain tags for repo %s" % repo + fp = os.popen("%s diff --stat %s..HEAD" % (git(repo), tags[-1])) + while 1: + line = fp.readline() + if not line or line.find('|') <= 0: + break + a, b = line.split('|') + a = a.strip() + if a in ['.hgignore', '.hgtags']: + continue + if a.endswith('.gitignore'): + continue + if VERBOSE: + print ' ', line.strip() + res[repo].append(a) + del fp + return res + +def showchanged(argv=None): + if argv == None: + tag = "last" + repos = selectrepos(None) + else: + tag = argv[0] + repos = selectrepos(argv[1:]) + res = showchanges1(repos) + for repo in res: + print 'Repository %s has %s changed files' % (repo, len(res[repo])) + if VERBOSE: + print ' ', line.strip() + +def release1(repo, tag): + print + print 'Repository %s' % repo + print ''.rjust(11 + len(repo), '*') + version = tag[1:] + pull([repo]) + if repo == 'alsa-driver': + pull(['alsa-kmirror']) + if repo == 'alsa-driver': + lines = open(ROOT + '/' + repo + '/configure.in').readlines() + for idx in range(0, len(lines)): + if lines[idx].startswith('CONFIG_SND_VERSION="'): + lines[idx] = 'CONFIG_SND_VERSION="%s"\n' % version + print lines[idx][:-1] + break + open(ROOT + '/' + repo + '/configure.in', "w+").write(''.join(lines)) + os.chdir(ROOT + '/' + repo) + if os.path.exists('include/version.h'): + os.remove('include/version.h') + if os.path.exists('alsa-kernel/include/version.h'): + os.remove('alsa-kernel/include/version.h') + if os.system("make ALSAKERNELDIR=../alsa-kernel all-deps"): + raise ValueError, "make" + if os.system("aclocal"): + raise ValueError, "aclocal" + if os.system("autoconf"): + raise ValueError, "autoconf" + if os.system("./configure --with-debug=full --with-isapnp=yes --with-sequencer=yes --with-kernel=%s" % (ROOT + '/alsa-kernel')): + raise ValueError, "configure" + if os.system("make include/sound/version.h"): + raise ValueError, "include/sound/version.h" + elif repo in ['alsa-lib', 'alsa-plugins', 'alsa-utils', + 'alsa-firmware', 'alsa-oss']: + lines = open(ROOT + '/' + repo + '/configure.in').readlines() + for idx in range(0, len(lines)): + if lines[idx].startswith('AM_INIT_AUTOMAKE(%s, ' % repo): + lines[idx] = 'AM_INIT_AUTOMAKE(%s, %s)"\n' % (repo, version) + print lines[idx][:-1] + break + open(ROOT + '/' + repo + '/configure.in', "w+").write(''.join(lines)) + elif repo == 'alsa-tools': + lines = open(ROOT + '/' + repo + '/Makefile').readlines() + for idx in range(0, len(lines)): + if lines[idx].startswith("VERSION = "): + lines[idx] = "VERSION = %s\n" % version + print lines[idx][:-1] + break + open(ROOT + '/' + repo + '/Makefile', "w+").write(''.join(lines)) + elif repo == 'alsa-python': + lines = open(ROOT + '/' + repo + '/setup.py').readlines() + for idx in range(0, len(lines)): + if lines[idx].startswith("VERSION='"): + lines[idx] = "VERSION='%s'\n" % version + print lines[idx][:-1] + break + open(ROOT + '/' + repo + '/setup.py', "w+").write(''.join(lines)) + lines = open(ROOT + '/' + repo + '/PKG-INFO').readlines() + for idx in range(0, len(lines)): + if lines[idx].startswith("Version: "): + lines[idx] = "Version: %s\n" % version + print lines[idx][:-1] + break + open(ROOT + '/' + repo + '/PKG-INFO', "w+").write(''.join(lines)) + +def release(argv): + if argv == None or argv[0][0] != 'v': + raise ValueError, "specify release version in tag form" + tag = argv[0] + argv = argv[1:] + if len(argv) == 0: + repos = selectrepos(None) + elif argv[0] == 'auto': + res = showchanges1(selectrepos(None)) + repos = res.keys() + else: + repos = selectrepos(argv) + if 'alsa' in repos: + repos.remove('alsa') + if 'alsa-kmirror' in repos: + repos.remove('alsa-kmirror') + print 'Doing release for: %s' % ','.join(repos) + for repo in repos: + release1(repo, tag) + +def changes(argv): + + def rev_to_dot(rev): + if rev[0] == 'v': + return rev[1:] + else: + return rev + + def print_underline(c, str): + i = len(str) + while i > 0: + sys.stdout.write(c) + i -= 1 + print + + def store_changes(changes, logs, module, xrev): + if module == 'alsa-kernel': + module = 'alsa-driver' + for a in logs: + if a.has_key('branch'): + return + already = False + idx1 = 0 + for change in changes: + if a['user'] == change['user'] and \ + a['description'] == change['description']: + # print 'SAME!!!' + already = True + break + if a['date'] < change['date']: + a['xrev'] = xrev + a['module'] = module + changes.insert(idx1, a) + # print 'INSERTED!!!' + already = True + break + idx1 += 1 + if not already: + a['xrev'] = xrev + a['module'] = module + changes.append(a) + + def merge_members(changes): + global GERRORS + + res = {} + try: + os.remove("/tmp/changes-log.txt") + except OSError: + pass + for change in changes: + module = change['module'] + if not res.has_key(module): + res[module] = {} + members = cvsps_merge_members(change['files'], module) + if len(members) == 0: + continue + members = members[0] + mems = string.split(members, ',') + for mem in mems: + if mem == 'IGNORE': + continue + if not res[module].has_key(mem): + res[module][mem] = [] + res[module][mem].append(change) + if GERRORS > 0: + print 'Bailing out...' + sys.exit(1); + return res + + def get_items(allitems): + items = [] + idx = 0 + for item in ['Sound Core', 'ALSA Core']: + items.append([item]) + idx += 1 + core = idx + items.append([]) # Core + midlevel = idx + 1 + items.append([]) # Midlevel + all = idx + 2 + items.append(allitems) + items[all].sort() + for item in items[all]: + if string.find(item, 'Core') >= 0: + items[core].append(item) + if string.find(item, 'Midlevel') >= 0: + items[midlevel].append(item) + if string.find(item, 'API') >= 0: + items[midlevel].append(item) + idx1 = core + while idx1 < all: + for item in items[idx1]: + items[all].remove(item) + idx1 += 1 + for items1 in items[:idx]: + for item in items1: + idx1 = idx + while idx1 < len(items): + if item in items[idx1]: + items[idx1].remove(item) + idx1 += 1 + return items + + def check_tag(tags, rev): + for tag in tags: + a = tag[41:-1] + if len(a) != len(rev): + continue + if a == rev: + return True + return False + + try: + rev1 = argv[0] + rev2 = argv[1] + except: + sys.stderr.write('Please, specify oldtag and newtag\n') + sys.exit(1) + + changes = [] + fullset = REPOSITORIES + fromrev = {} + for module in fullset: + xrev = rev1 + fp = os.popen("%s tag" % git(module)) + tags = fp.readlines() + fp.close() + if not check_tag(tags, rev2): + continue + tags1 = [] + base = rev2 + while not check_tag(tags, xrev): + if rev2[-3:-1] == "rc": + base = rev2[:-3] + elif rev2[-1:] >= "a": + base = rev2[:-1] + for tag in tags: + a = tag[41:-1].strip() + if a >= rev2: + continue + tags1.append(tag[40:-1].strip()) + tags1 = version_sort(tags1) + if len(tags1) != 0: + xrev = tags1[len(tags1)-1] + break + major, minor, subminor = base.split('.') + subminor = int(subminor) - 1 + if subminor < 0: + raise ValueError + base = "%s.%s.%s" % (major, minor, subminor) + fromrev[module] = xrev + lines = my_popen("hg log -r %s:%s -v" % (xrev, rev2)) + store_changes(changes, parse_hg_log(lines, module), module, xrev) + res = merge_members(changes) + modules1 = res.keys() + modules = [] + groups = {} + for module in fullset: + if module in modules1: + modules.append(module) + rev = fromrev[module] + if not groups.has_key(rev): + groups[rev] = [] + groups[rev].append(module) + print '{| align="right"\n| __TOC__\n|}' + for rev in groups: + str = '=Changelog between %s and %s releases=' % (rev_to_dot(rev), rev_to_dot(rev2)) + print str + for module in groups[rev]: + print '==%s==' % module + items = get_items(res[module].keys()) + for items1 in items: + for b in items1: + if not res[module].has_key(b): + continue + print '===%s===' % b + for a in res[module][b]: + log = a['description'][0] + if log[:9] == 'Summary: ': + log = log[9:] + elif log[:8] == 'Summary:': + log = log[8:] + print ': %s' % log[:-1] + for rev in groups: + str = '=Detailed changelog between %s and %s releases=' % (rev_to_dot(rev), rev_to_dot(rev2)) + print str + for module in groups[rev]: + print '==%s==' % module + items = get_items(res[module].keys()) + for items1 in items: + for b in items1: + if not res[module].has_key(b): + continue + print '===%s===' % b + for a in res[module][b]: + log = a['description'] + first = "-" + for l in log: + if l[:13] == "Patch-level: ": + continue + if l[:13] == "Patch-Level: ": + continue + print ': %s %s' % (first, l[:-1]) + first = " " + +def usage(code=0, msg=''): + print __doc__ % globals() + print 'Where options is:' + for opt in OPTS: + print + print "\t-%s %s" % (opt[0].replace(':', ''), opt[3]) + print "\t--%s %s" % (opt[1].replace('=', ''), opt[3]) + print "\t\t%s" % opt[4] + print + print 'Where command is:' + for cmd in CMDS: + print + print "\t%s %s" % (cmd[0], cmd[2]) + print "\t\t%s" % cmd[3] + if msg: + print + print msg + sys.exit(code) + +def root(argv): + global ROOT + if argv == None: + eprint('Specify root directory.') + sys.exit(1) + ROOT=os.path.abspath(argv[0]) + +def verbose(argv): + global VERBOSE + VERBOSE=True + +OPTS=[ + ['h', 'help', usage, '', 'Print this help'], + ['r', 'root', root, '', 'Set GIT root directory (default is %s)' % ROOT], + ['v', 'verbose', verbose, '', 'Set verbose mode'] +] +CMDS=[ + ['list', xlist, '', 'Show ALSA repository names'], + ['clone', clone, '[repo]', 'Clone all (default) or selected repositories'], + ['diff', diff, '[repo]', 'Do diff on selected or all (default) repositories'], + ['pull', pull, '[repo]', 'Do pull on selected or all (default) repositories'], + ['push', push, '[repo]', 'Do push on selected or all (default) repositories'], + ['showchanged', showchanged, 'tag [repo]', 'Show which repositories were changed since tag'], + ['release', release, 'tag [repo]', 'Do an ALSA release (auto = automatic change control)'], + ['changes', changes, 'oldtag newtag', 'Show changes between oldtag and newtag'] +] + +def main(): + global ROOT + if os.path.exists(ROOT + '/../alsa-kernel'): + ROOT = os.path.abspath(ROOT + '/..') + opts = '' + lopts = [] + for opt in OPTS: + opts += opt[0] + lopt = opt[1] + if opt[3] != '': + opts += ':' + lopt += '=' + lopts.append(lopt) + try: + opts, args = getopt.getopt(sys.argv[1:], opts, lopts) + except getopt.error, msg: + usage(1, msg) + for opt, arg in opts: + for xopt in OPTS: + if opt in ("-" + xopt[0], "-" + xopt[1]): + xopt[2](arg) + if not args: + eprint("Command not specified, for help type '%s -h'" % PROGRAM[PROGRAM.rfind('/')+1:]) + sys.exit(1) + for cmd in CMDS: + if cmd[0] == args[0]: + if len(args) < 2: + cmd[1]() + else: + cmd[1](args[1:]) + sys.exit(0) + usage(1, 'Unknown command "%s"' % args[0]) + +if __name__ == '__main__': + main() + sys.exit(0) diff --git a/hooks/alsa-kernel.git/pre-receive b/hooks/alsa-kernel.git/pre-receive new file mode 100755 index 0000000..7ea845b --- /dev/null +++ b/hooks/alsa-kernel.git/pre-receive @@ -0,0 +1,410 @@ +#!/usr/bin/python + +from sys import exit, stdin, stderr, stdout +from os import popen, mkdir, system, chdir, getcwd, remove +from os.path import isdir, exists +from shutil import rmtree +import re + +TMP_PATH = '/dev/shm' + +REPO_DIR = '/home/alsa-server/home/repositories' +KMIRROR_REPO = REPO_DIR + '/alsa-kmirror.git' +KERNEL_REPO = REPO_DIR + '/alsa-kernel.git' + +VALID_COMMITERS = ( + 'Jaroslav Kysela ', + 'Takashi Iwai ', + 'Clemens Ladisch ', + 'James Courtier-Dutton ', + 'Linus Torvalds ', +) + +ALSA_FILES = ( + 'Documentation/sound/alsa/', + 'sound/', + 'include/sound/' +) + +NOT_ALSA_FILES = ( + 'sound/sound_core.c', + 'sound/sound_firmware.c', + 'sound/oss/', +) + +ALSA_FILES1 = { + 'Documentation/sound/alsa/': 'Documentation/', + 'sound/': '', + 'include/sound/': 'include/' +} + +ALSA_COMMITS = {} +ALSA_OK_COMMITS = [] +ALSA_LAST_COMMIT = '' +UPSTREAM_COMMITS = [] + +def error(lines, msg, *args): + for line in lines: + stderr.write('===> %s' % line) + stderr.write('PRE-RECEIVE ERROR: ' + msg % args) + +def fail(): + if ALSA_LAST_COMMIT: + stderr.write('PRE-RECEIVE: Reverting alsa-kmirror.git repo to original state\n') + if system('git --git-dir=%s update-ref HEAD "refs/heads/master"' % KMIRROR_REPO): + raise ValueError, "update-ref failed" + if system('git --git-dir=%s reset -q --mixed %s > /dev/null' % (KMIRROR_REPO, ALSA_LAST_COMMIT)): + raise ValueError, "reset failed" + exit(1) + +def is_alsa_file(file): + for i in NOT_ALSA_FILES: + if file.startswith(i): + return False + for i in ALSA_FILES: + if file.startswith(i): + return True + return False + +def to_alsa_file(gitfile, prefix=''): + if gitfile == '/dev/null': + return '/dev/null' + if prefix and gitfile.startswith(prefix): + gitfile = gitfile[len(prefix):] + for i in ALSA_FILES1: + if gitfile.startswith(i): + return prefix + ALSA_FILES1[i] + gitfile[len(i):] + raise ValueError, repr(gitfile) + +def check_email(lines, fullemail, commit = False): + #print 'E-mail: "%s"' % fullemail + name, email = fullemail.split('<') + name = name.strip() + email = email.strip() + if not email.endswith('>'): + error(lines, 'E-mail address "%s" is not valid...\n' % (line)) + return False + email = email[:-1] + if email.find('@') <= 0 or len(name) < 5 or fullemail.find('root@') >= 0: + error(lines, 'E-mail address "%s" is not valid...\n' % (line)) + return False + if not commit: + return True + full = name + ' <' + email + '>' + if not full in VALID_COMMITERS: + error(lines, 'Commiter "%s" e-mail unknown. We know only these committers:\n' % full) + for line in VALID_COMMITERS: + stderr.write('***** %s\n' % line) + return False + return True + +def read_kmirror_commits(): + global ALSA_LAST_COMMIT + if ALSA_COMMITS: + return + stderr.write('PRE-RECEIVE: Analyzing alsa-kmirror commits\n') + fp = popen("git --git-dir=%s log --pretty=fuller --date=iso" % KMIRROR_REPO) + commitref = '' + commit = {} + while 1: + line = fp.readline() + if not line: + break + if line.startswith('commit '): + if commitref: + ALSA_COMMITS[commitref] = commit + commit = {} + commitref = line[7:].strip() + if not ALSA_LAST_COMMIT: + ALSA_LAST_COMMIT = commitref + elif line.startswith('Author:') or line.startswith('AuthorDate:') or \ + line.startswith('Commit:') or line.startswith('CommitDate:'): + a, b = line.split(': ') + commit[a.strip()] = b.strip() + if commitref: + ALSA_COMMITS[commitref] = commit + fp.close() + + worktree = TMP_PATH + '/alsa-kmirror-repo' + rmtree(worktree, ignore_errors=True) + mkdir(worktree) + if system("git --work-tree=%s --git-dir=%s checkout -q master scripts" % (worktree, KMIRROR_REPO)): + raise ValueError, 'git checkout' + if exists(worktree + '/scripts/git-ok-commits'): + fp = open(worktree + '/scripts/git-ok-commits') + while 1: + line = fp.readline() + if not line: + break + if line.startswith('#'): + continue + ALSA_OK_COMMITS.append(line.strip()) + fp.close() + rmtree(worktree, ignore_errors=True) + +def check_alsa_commit(commit): + subject = commit['comment'][0][:-1] + if not ALSA_COMMITS: + read_kmirror_commits() + for c in ALSA_COMMITS: + if ALSA_COMMITS[c]['AuthorDate'] == commit['AuthorDate'] and \ + ALSA_COMMITS[c]['Author'] == commit['Author'] and \ + ALSA_COMMITS[c]['CommitDate'] == commit['CommitDate'] and \ + ALSA_COMMITS[c]['Commit'] == commit['Commit']: + stderr.write('PRE-RECEIVE: Already merged %s %s\n' % (commit['commit'][:7], subject)) + return True + okstr = '"' + commit['Author'] + '" "' + commit['AuthorDate'] + '" "' + commit['Commit'] + '" "' + commit['CommitDate'] + '"' + if okstr in ALSA_OK_COMMITS: + stderr.write('PRE-RECEIVE: Already merged (manually) %s %s\n' % (commit['commit'][:7], subject)) + return True + return False + +def read_upstream_commits(old): + stderr.write('PRE-RECEIVE: Analyzing alsa-kernel#linux-2.6 commits\n') + head = popen("git rev-parse linux-2.6").readline().strip() + stderr.write('PRE-RECEIVE: linux-2.6 head %s old %s\n' % (head, old)) + if head == old: + return + fp = popen("git log --pretty=oneline --date=iso %s..%s" % (old, head)) + while 1: + line = fp.readline() + if not line: + break + a = line.split(' ') + UPSTREAM_COMMITS.append(a[0]) + del fp + stderr.write('PRE-RECEIVE: linux-2.6 has %s new commits\n' % len(UPSTREAM_COMMITS)) + +def try_to_merge(commit): + stderr.write('PRE-RECEIVE: Merging %s %s' % (commit['commit'][:7], commit['comment'][0])) + + ref = commit['commit'] + fp = popen("git diff %s~1..%s" % (ref, ref)) + rlines = [] + ok = False + addfiles = [] + rmfiles = [] + while 1: + line = fp.readline() + if not line: + break + if line.startswith('diff --git a/'): + file1, file2 = line[11:].split(' ') + file1 = file1.strip() + file2 = file2.strip() + ok1 = is_alsa_file(file1[2:]) + ok2 = is_alsa_file(file2[2:]) + if ok1 or ok2: + afile1 = to_alsa_file(file1, 'a/') + afile2 = to_alsa_file(file2, 'b/') + rlines.append('diff --git %s %s\n' % (afile1, afile2)) + if ok2: + addfiles.append(afile2[2:]) + elif ok1: + rmfiles.append(afile1[2:]) + ok = True + elif ok and (line.startswith('--- a/') or line.startswith('+++ b/')): + rlines.append(line[:6] + to_alsa_file(line[6:].strip()) + '\n') + elif ok: + rlines.append(line) + fp.close() + + patchfile = TMP_PATH + '/alsa-kmirror-patch' + fp = open(patchfile, 'w+') + fp.write(''.join(rlines)) + fp.close() + + commentfile = TMP_PATH + '/alsa-kmirror-comment' + fp = open(commentfile, 'w+') + fp.write(''.join(commit['comment'])) + fp.close() + + elems = re.compile('(.*?)\s+<(.*)>').match(commit['Author']) + exports = 'export GIT_AUTHOR_NAME="%s" ; ' % elems.group(1) + exports += 'export GIT_AUTHOR_EMAIL="%s" ; ' % elems.group(2) + exports += 'export GIT_AUTHOR_DATE="%s" ; ' % commit['AuthorDate'] + elems = re.compile('(.*?)\s+<(.*)>').match(commit['Commit']) + exports += 'export GIT_COMMITER_NAME="%s" ; ' % elems.group(1) + exports += 'export GIT_COMMITER_EMAIL="%s" ; ' % elems.group(2) + exports += 'export GIT_COMMITER_DATE="%s" ; ' % commit['CommitDate'] + exports += 'export GIT_COMMITTER_NAME="%s" ; ' % elems.group(1) + exports += 'export GIT_COMMITTER_EMAIL="%s" ; ' % elems.group(2) + exports += 'export GIT_COMMITTER_DATE="%s" ; ' % commit['CommitDate'] + + curdir = getcwd() + worktree = TMP_PATH + '/alsa-kmirror-repo' + rmtree(worktree, ignore_errors=True) + mkdir(worktree) + if system("git --work-tree=%s --git-dir=%s checkout -f -q master" % (worktree, KMIRROR_REPO)): + raise ValueError, 'git checkout' + chdir(worktree) + if system("patch -p 1 --dry-run < %s" % patchfile): + chdir(curdir) + error(rlines, "Patch failed - is it already merged?\n") + error([], "You may consider to add this commit to alsa-kmirror.git/scripts/git-ok-commits .\n") + error([], "Please, check if patch was merged to alsa-kmirror.git at first!\n") + error([], 'line: "%s" "%s" "%s" "%s"\n' % (commit['Author'], commit['AuthorDate'], commit['Commit'], commit['CommitDate'])) + fail() + if system("git --work-tree=%s --git-dir=%s apply -v %s" % (worktree, KMIRROR_REPO, patchfile)): + chdir(curdir) + raise ValueError, 'git apply' + if addfiles and system("git --work-tree=%s --git-dir=%s add %s" % (worktree, KMIRROR_REPO, ' '.join(addfiles))): + chdir(curdir) + raise ValueError, 'git add' + if rmfiles and system("git --work-tree=%s --git-dir=%s rm %s" % (worktree, KMIRROR_REPO, ' '.join(rmfiles))): + chdir(curdir) + raise ValueError, 'git rm' + if system("%sgit --work-tree=%s --git-dir=%s commit -F %s" % (exports, worktree, KMIRROR_REPO, commentfile)): + chdir(curdir) + raise ValueError, 'git commit' + chdir(curdir) + rmtree(worktree, ignore_errors=True) + stderr.write('PRE-RECEIVE: Merge complete %s %s' % (ref[:7], commit['comment'][0])) + +def do_check_commit(lines): + alsafiles = 0 + otherfiles = 0 + header = True + commit = {'comment':[], 'files':[]} + for line in lines: + if header: + if line.startswith('commit '): + commit['commit'] = line[7:].strip() + elif line.startswith('Merge:') or line.startswith('Author:') or \ + line.startswith('AuthorDate:') or line.startswith('Commit:') or \ + line.startswith('CommitDate:'): + a, b = line.split(': ') + commit[a.strip()] = b.strip() + elif line.startswith(' '): + header = False + if line.startswith(' '): + commit['comment'].append(line[4:]) + elif not header and line != '\n': + commit['files'].append(line[:-1]) + check = is_alsa_file(line[:-1]) + if check: + alsafiles += 1 + else: + otherfiles += 1 + while commit['comment'][-1] == '\n': + del commit['comment'][-1] + if not alsafiles: + return + if check_alsa_commit(commit): + return + try_to_merge(commit) + if commit['commit'] in UPSTREAM_COMMITS: + stderr.write('PRE-RECEIVE: Upstream patch %s %s\n' % (commit['commit'][:7], lines[6][4:])) + return + if otherfiles: + stderr.write('PRE-RECEIVE: ALSA files %s other files %s\n' % (alsafiles, otherfiles)) + return + if not check_email(lines, commit['Author']) or \ + not check_email(lines, commit['Commit']): + fail() + #if not check_email(lines, committer, commit=True): + # exit(1) + if not lines[6][4:].upper().startswith('[ALSA] ') and \ + not lines[6][4:].upper().startswith('ALSA: '): + error(lines, 'First log line does not start with "[ALSA] "\n') + fail() + lastsigned = '' + for line in lines[6:]: + if not line.startswith(' '): + break + line = line[4:-1] + line1 = line.lower() + if line1.startswith('signed-off-by:'): + if not line.startswith('Signed-off-by:'): + error(lines, 'Wrong Signed-off-by: line: "%s"\n' % line) + fail() + lastsigned = line[15:].strip() + if not lastsigned: + error(lines, 'Commit has no Signed-off-by: line\n') + fail() + if not lastsigned in VALID_COMMITERS: + error(lines, 'Last Signed-off-by: line has an invalid ALSA committer\n') + fail() + +def do_check(sha1old, sha1new, refname): + lines = popen("git log --reverse --name-only --pretty=fuller --date=iso %s..%s" % (sha1old, sha1new)).readlines() + count = len(lines) + idx = 1 + while idx < count: + oldidx = idx - 1 + commit = [] + while idx < count and not lines[idx].startswith('commit '): + idx += 1 + do_check_commit(lines[oldidx:idx]) + idx += 1 + +def compare_trees(lastref): + stderr.write('PRE-RECEIVE: comparing alsa-kmirror (old) and alsa-kernel (new) repos\n') + worktree = TMP_PATH + '/alsa-kmirror-repo' + worktreek = TMP_PATH + '/alsa-kernel-repo' + rmtree(worktree, ignore_errors=True) + rmtree(worktreek, ignore_errors=True) + mkdir(worktree) + mkdir(worktreek) + if system("git --work-tree=%s --git-dir=%s checkout -f -q master" % (worktree, KMIRROR_REPO)): + raise ValueError, 'git checkout (kmirror)' + if system("git --work-tree=%s --git-dir=%s checkout -q %s sound include/sound Documentation/sound/alsa" % (worktreek, KERNEL_REPO, lastref)): + raise ValueError, 'git checkout (kernel)' + curdir = getcwd() + chdir(TMP_PATH) + system("mv alsa-kernel-repo/sound/* alsa-kernel-repo") + rmtree("alsa-kernel-repo/sound") + system("mv alsa-kernel-repo/include/sound/* alsa-kernel-repo/include") + rmtree("alsa-kernel-repo/include/sound") + system("mv alsa-kernel-repo/Documentation/sound/alsa/* alsa-kernel-repo/Documentation") + rmtree("alsa-kernel-repo/Documentation/sound") + for i in ['.git-ok-commits', '.hgignore', '.hgtags', '.gitignore', 'kernel', 'scripts', 'oss']: + if isdir("alsa-kmirror-repo/%s" % i): + rmtree("alsa-kmirror-repo/%s" % i) + elif exists("alsa-kmirror-repo/%s" % i): + remove("alsa-kmirror-repo/%s" % i) + for i in ['oss']: + if isdir("alsa-kernel-repo/%s" % i): + rmtree("alsa-kernel-repo/%s" % i) + elif exists("alsa-kernel-repo/%s" % i): + remove("alsa-kernel-repo/%s" % i) + fp = popen("diff -ruNp alsa-kmirror-repo alsa-kernel-repo") + notempty = False + while 1: + line = fp.readline() + if not line: + break + stderr.write(line) + notempty = True + if notempty: + stderr.write('\n') + rmtree(worktree, ignore_errors=True) + rmtree(worktreek, ignore_errors=True) + if notempty: + stderr.write('PRE-RECEIVE: repositories does not match, please, fix it\n') + fail() + +lines = stdin.readlines() +read_upstream_commits(lines[0][:-1].split(' ')[0]) +lastref = '' +for line in lines: + sha1old, sha1new, refname = line[:-1].split(' ') + if refname in ['refs/heads/linux-2.6', 'refs/heads/for-linus']: + continue + elif refname.startswith('refs/tags/') or \ + refname.startswith('refs/heads/private-') or \ + refname.startswith('refs/heads/stable-2.6.'): + continue + elif refname != 'refs/heads/master': + stderr.write('PRE-RECEIVE: invalid branch "%s"\n' % refname) + fail() + do_check(sha1old, sha1new, refname) + lastref = sha1new +if lastref: + compare_trees(lastref) + stderr.write('PRE-RECEIVE: Trees match...\n') +stderr.write('PRE-RECEIVE: All done\n') +if 0: + stderr.write('PRE-RECEIVE: Test mode active (try later)...\n') + fail() +exit(0) -- 2.47.1