Work around variable scoping in local function
[trackgit.git] / notes.py
blobff5a64735b715370cf30d23c9acae2a94b0a527b
1 import os
2 import sys
3 import time
4 from collections import defaultdict
5 from sqlalchemy.orm import join
7 import db
8 from git import git
10 NOTES_INDEX = '.git/git-notes-index'
11 notes_env = {
12 'GIT_INDEX_FILE': NOTES_INDEX,
14 NOTES_REF = 'refs/heads/mailnotes'
16 def write_notes(commit_sha1, notes):
17 blob_sha1 = git('hash-object', '-w', '--stdin', input=notes)[0]
18 git('update-index', '--add', '--cacheinfo', '0644', blob_sha1, commit_sha1, env=notes_env)
20 def finalize_notes():
21 previous, ret = git('rev-parse', NOTES_REF)
22 if ret != 0:
23 args = []
24 previous_arg = []
25 else:
26 args = ['-p', previous.strip()]
27 previous_arg = [previous.strip()]
28 tree_sha1 = git('write-tree', env=notes_env)[0].strip()
29 head_sha1 = git('commit-tree', tree_sha1, *args,
30 input='Mass annotation by notes.py')[0].strip()
31 git('update-ref', '-m', 'Mass annotation by notes.py',
32 NOTES_REF, head_sha1, *previous_arg)
34 def compute_notes(session, commit, mail):
35 notes = []
36 notes.append('Mail-From: %s\n' % mail.author)
37 notes.append('Message-Id: %s\n' % mail.message_id)
38 notes.append('Posted-Date: %s\n'
39 % time.strftime("%c", time.localtime(mail.post_date)))
40 if mail.in_reply_to:
41 notes.append('In-Reply-To: %s\n' % mail.in_reply_to)
42 if mail.references:
43 notes.append('References:\n')
44 for r in mail.references:
45 notes.append('\t%s\n' % r.message_id)
46 if len(mail.patch)>0 and mail.patch[0].extra_notes:
47 notes.append('Extra-notes:\n')
48 for line in str(mail.patch[0].extra_notes).splitlines():
49 notes.append('\t%s\n' % line)
50 return notes
53 def _redo_patches(session, notes):
54 for cmt, mail in (session.query(db.Commit, db.Mail)
55 .select_from(join(db.Mail, db.Commit,
56 db.Mail.patch_id==db.Commit.patch_id))
57 .filter(db.Commit.upstream==True)
58 .filter(db.Mail.has_patch==True)):
59 nts = compute_notes(session, cmt, mail)
60 if not nts:
61 continue
62 if notes[cmt.sha1]:
63 notes[cmt.sha1].append('\n')
64 notes[cmt.sha1].extend(nts)
65 sys.stdout.write('\r%6d' % count)
66 sys.stdout.flush()
67 count = count + 1
68 count = 0
69 sys.stdout.write('\n')
71 def _redo_all():
72 session = db.Session()
73 count = 0
74 notes = defaultdict(list)
75 _redo_patches(session, notes)
76 os.unlink(NOTES_INDEX)
77 for cmt, nts in notes.iteritems():
78 sys.stdout.write('\r%6d' % count)
79 sys.stdout.flush()
80 write_notes(cmt, ''.join(nts))
81 count = count + 1
82 sys.stdout.write('\n')
83 finalize_notes()
85 if __name__ == '__main__':
86 if len(sys.argv) > 1:
87 session = db.Session()
88 cmt = session.query(db.Commit).filter(db.Commit.sha1==sys.argv[1]).one()
89 print compute_notes(session, cmt)
90 else:
91 _redo_all()