Edgewall Software

source: plugins/0.13/mercurial-plugin/tracext/hg/hooks.py

Last change on this file was 10900, checked in by Christian Boos, 12 years ago

TracMercurial for 0.13: merged r10899 from 0.12 version

  • Property svn:eol-style set to native
File size: 4.7 KB
Line 
1# -*- coding: iso-8859-1 -*-
2#
3# Copyright (C) 2011-2012 Edgewall Software
4# All rights reserved.
5#
6# This software may be used and distributed according to the terms
7# of the GNU General Public License, incorporated herein by reference.
8#
9# This software consists of voluntary contributions made by many
10# individuals. For the exact contribution history, see the revision
11# history and logs, available at http://trac.edgewall.org/log/.
12
13
14"""
15Mercurial hook calling `trac-admin $ENV changeset added` for newly added
16changesets
17
18The Trac environments to be notified are configured in the `[trac]` section
19of `hgrc`. The path to an environment is specified in the `env` key. More
20environments can be specified by adding a suffix separated by a dot.
21
22The path to the `trac-admin` executable can be specified in the `trac-admin`
23key. A specific path can be set for each environment, by adding the same
24suffix to the `trac-admin` key.
25
26The maximum number of changesets to pass per call to `trac-admin` can be
27configured with the `revs_per_call` key. The default is relatively low (80
28on Windows, 500 on other systems) for maximum compatibility, and can be
29increased if you often push thousands of changesets and the system supports
30it.
31
32If the `trac-admin` option is left empty, the hook opens the Trac environment
33and calls the relevant Trac hook directly in the same process. This will only
34work if Trac can be imported by the Python interpreter running Mercurial (e.g.
35if both are installed globally). Note that this may result in increased memory
36usage if Mercurial is executed as a long-running process (e.g. hgweb in WSGI
37mode). In this last case, the option `cache_env` can be set to `true` to
38cache the Trac environments across invocations, therefore avoiding the
39environment setup time on each invocation.
40
41If the Mercurial plugin is installed globally (i.e. not in one of Trac's
42plugins directories), the hooks can be configured as follows:
43{{{
44[hooks]
45commit = python:tracext.hg.hooks.add_changesets
46changegroup = python:tracext.hg.hooks.add_changesets
47}}}
48
49Otherwise, place this file somewhere accessible, and configure the hooks as
50follows:
51{{{
52[hooks]
53commit = python:/path/to/hooks.py:add_changesets
54changegroup = python:/path/to/hooks.py:add_changesets
55}}}
56
57A typical configuration for three environments looks like this:
58{{{
59[trac]
60; For a single Trac environment
61env = /path/to/env
62trac-admin = /path/to/trac-admin
63
64; Two more environments, with a specific trac-admin for the second
65env.other = /path/to/other/env
66env.third = /path/to/third/env
67trac-admin.third = /path/to/third/trac-admin
68}}}
69"""
70
71import os.path
72import subprocess
73
74close_fds = os.name == 'posix'
75
76
77def expand_path(path):
78 """Expand user references and environment variables in a path."""
79 return os.path.expanduser(os.path.expandvars(path))
80
81
82def add_changesets(ui, repo, node, **kwargs):
83 """Commit hook calling `trac-admin $ENV changeset added $REPO $NODE ...`
84 on all configured Trac environments, for all newly added changesets.
85 """
86 revs = range(repo[node].rev(), len(repo))
87 error = False
88 for name, env in ui.configitems('trac'):
89 p = name.split('.', 1)
90 if p[0] != 'env' or not env:
91 continue
92 env = expand_path(env)
93
94 trac_admin = ui.config('trac', 'trac-admin', '')
95 if len(p) > 1:
96 trac_admin = ui.config('trac', 'trac-admin.' + p[1], trac_admin)
97
98 if not trac_admin:
99 cache_env = ui.configbool('trac', 'cache_env')
100 from trac.env import open_environment
101 from trac.versioncontrol.api import RepositoryManager
102 env = open_environment(env, use_cache=cache_env)
103 RepositoryManager(env).notify('changeset_added', repo.root, revs)
104 continue
105
106 try:
107 revs_per_call = int(ui.config('trac', 'revs_per_call'))
108 except (TypeError, ValueError):
109 revs_per_call = 160 if os.name == 'nt' else 1000
110
111 trac_admin = expand_path(trac_admin)
112 for i in xrange(0, len(revs), revs_per_call):
113 command = [trac_admin, env, 'changeset', 'added', repo.root]
114 command.extend(str(r) for r in revs[i : i + revs_per_call])
115 ui.debug("Calling %r\n" % (command,))
116 proc = subprocess.Popen(command, close_fds=close_fds,
117 stdout=subprocess.PIPE,
118 stderr=subprocess.STDOUT)
119 for line in proc.stdout:
120 ui.write(line)
121 proc.wait()
122 if proc.returncode != 0:
123 error = True
124 ui.warn("trac-admin failed with return code %d for "
125 "environment:\n %s\n" % (proc.returncode, env))
126 return error
Note: See TracBrowser for help on using the repository browser.