Kiln » Kiln Storage Service Read More
Clone URL:  
kilnhook.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# Copyright (c) 2008-2010 Fog Creek Software. All rights reserved. # # This software may be used and distributed according to the terms of the # GNU General Public License version 2, incorporated herein by reference. # # # This hook is only ever designed to be loaded and used by the Kiln runtime. # Do not load it by installing it manually. import simplejson import settings from mercurial import pushkey import urlutil from webtasks import asyncpost, queue_repo_index import bfiles from api.repositories import Repository import syncstatus def _revtuple(rev): "Return a (rev num, rev id) tuple from a changeset context" return (rev.rev(), rev.hex()) def _ctx(ctx): return {'user': _uc(ctx.user()), 'date': ctx.date(), 'rev': (ctx.rev(), ctx.hex()), 'description': _uc(ctx.description()), 'branch': _uc(ctx.branch()), 'extra': dict((_uc(k), _uc(v)) for k, v in ctx.extra().iteritems()), 'tags': [_uc(s) for s in ctx.tags()], 'parents': [(p.rev(), p.hex()) for p in ctx.parents()]} def _uc(s): return unicode(s, encoding='utf8', errors='replace') def prechangehook(ui, repo, hooktype, node, **kwargs): "Check that the user uploaded all bfiles before pushing to the repo" if hooktype not in ('pretxnchangegroup', 'pretxncommit'): ui.warn('kiln postback hook was inappropriately attached\n') ui.flush() return True base = repo[node].rev() tip = repo['tip'].rev() uuid = repo.url().replace('\\', '/').split('/')[-1] success = True #The repo we are passed has uncommited changes that the default repo doesn't have yet, so set the repo r = Repository(uuid, repo=repo) for rev in xrange(base, tip+1): for bfile in r.listbfiles(rev): if not bfiles.instore(r.getbfilesha(bfile, rev)): ui.warn('ERROR: Big file %s at revision %s has not been uploaded to the kiln server.\n' % (bfile, rev)) success = False if not success: ui.warn('ERROR: All big files must be uploaded to the kiln server before the repository is changed.\n') return True def changehook(ui, repo, hooktype, node, **kwargs): "Notify kiln that there have been changes to this repository" if hooktype not in ('changegroup', 'commit', 'strip'): ui.warn('kiln postback hook was inappropriately attached\n') return False base = repo[node].rev() tip = repo['tip'].rev() uuid = repo.url().replace('\\', '/').split('/')[-1] person = int(ui.config('kiln', 'ixperson')) if ui.config('kiln', 'ixperson') else None source = ui.config('kiln', 'source') bookmarks = [tag for tag in pushkey.list(repo, 'bookmarks').keys()] tags = [{'tag': tag, 'rev': (repo[node].rev(), repo[node].hex()), 'bookmark': True} for (tag, node) in pushkey.list(repo, 'bookmarks').items() if node in repo] tags.extend( [{'tag': tag, 'rev': (repo[node].rev(), repo[node].hex()), 'bookmark': False} for (tag, node) in repo.tags().iteritems() if tag not in bookmarks and node in repo]) d = {'heads': [_revtuple(repo[head]) for head in repo.heads()], 'tails': [_revtuple(repo[0])], 'repo': uuid, 'url': kwargs.get('url'), 'person': person, 'source': ui.config('kiln', 'source'), 'tags': tags} d['changesets'] = [_ctx(repo[rev]) for rev in xrange(base, tip + 1)] if ui.config('kiln', 'client') != 'website': changecount = tip + 1 - base if changecount > 1: ui.write('kiln: successfully pushed %d changesets\n' % changecount) else: ui.write('kiln: successfully pushed one changeset\n') url = urlutil.urljoin(ui.config('kiln', 'url'), 'Pingback/Push') asyncpost(url, {'data': simplejson.dumps(d), 'token': ui.config('kiln', 'token')}) if settings.DO_INDEXING: queue_repo_index(uuid) r = Repository(uuid, repo=repo) if settings.HOSTED: syncstatus.update_status(r) site = ui.config('kiln', 'site') if site: peers = dict(ui.configitems('peers')) r.sync(site, peers)