Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -urN -x '*.pyc' -x '*.svn*' -x '*.egg*' mercurial-plugin/setup.py mercurial-plugin-aliaspatch/setup.py
- --- mercurial-plugin/setup.py 2012-03-24 15:43:07.602219567 +0100
- +++ mercurial-plugin-aliaspatch/setup.py 2012-03-24 16:25:03.821921368 +0100
- @@ -32,7 +32,7 @@
- except ImportError:
- pass
- -
- +
- TracMercurial = 'http://trac.edgewall.org/wiki/TracMercurial'
- setup(name='TracMercurial',
- @@ -55,5 +55,10 @@
- '': ['COPYING', 'README'],
- 'tracext.hg': ['locale/*.*', 'locale/*/LC_MESSAGES/*.*'],
- },
- - entry_points={'trac.plugins': 'hg = tracext.hg.backend'},
- + entry_points={
- + 'trac.plugins': [
- + 'tracext.hg.admin = tracext.hg.admin',
- + 'tracext.hg.backend = tracext.hg.backend',
- + ]
- + },
- **extra)
- diff -urN -x '*.pyc' -x '*.svn*' -x '*.egg*' mercurial-plugin/tracext/hg/admin.py mercurial-plugin-aliaspatch/tracext/hg/admin.py
- --- mercurial-plugin/tracext/hg/admin.py 1970-01-01 01:00:00.000000000 +0100
- +++ mercurial-plugin-aliaspatch/tracext/hg/admin.py 2012-03-24 16:34:28.045531375 +0100
- @@ -0,0 +1,102 @@
- +from trac.core import Component, implements
- +from trac.perm import IPermissionRequestor
- +from trac.admin import IAdminPanelProvider
- +from trac.web.chrome import ITemplateProvider
- +from trac.util.translation import gettext as _
- +from pkg_resources import resource_filename
- +
- +try:
- + from hashlib import sha1
- +except ImportError:
- + from sha import new as sha1
- +
- +u = unicode
- +
- +class MercurialAliasAdminPage(Component):
- +
- + implements(IAdminPanelProvider, IPermissionRequestor, ITemplateProvider)
- +
- + def __init__(self):
- + self.db = self.env.get_db_cnx()
- +
- + # IPermissionRequestor
- + def get_permission_actions(self):
- + return ['HG_ALIAS_ADMIN']
- +
- + # IAdminPanelProvider
- + def get_admin_panels(self, req):
- + #if req.perm.has_permission('HG_ALIAS_ADMIN'):
- + yield ('versioncontrol', _("Version Control"), 'mercurialalias', _("Mercurial Aliases"))
- +
- + # IAdminPanelProvider
- + def render_admin_panel(self, req, cat, page, path_info):
- + req.perm.require('HG_ALIAS_ADMIN')
- +
- + if req.method == 'POST':
- + if req.args.get('add'):
- + self._add_alias(u(req.args.get('user')), u(req.args.get('alias')))
- + elif req.args.get('remove') and req.args.get('sel'):
- + sel = req.args.get('sel')
- + sel = isinstance(sel, list) and sel or [sel]
- + for r in sel:
- + user, key = r.rsplit('.', 1)
- + self._delete_alias_by_key(user, key)
- +
- + data = {
- + 'aliases': self._list_aliases(),
- + }
- +
- + return 'admin_mercurialalias.html', data
- +
- + def _list_aliases(self):
- + cursor = self.db.cursor()
- + cursor.execute("SELECT sid, name, value "
- + "FROM session_attribute "
- + "WHERE authenticated = 1 "
- + "AND name LIKE 'mercurialalias.%' "
- + "ORDER BY sid, value")
- + for user, key, alias in cursor:
- + yield dict(user=user, key=key.split('.', 1)[1], alias=alias)
- +
- + def _get_alias(self, alias):
- + cursor = self.db.cursor()
- + cursor.execute("SELECT sid "
- + "FROM session_attribute "
- + "WHERE authenticated = 1 "
- + "AND name LIKE 'mercurialalias.%' "
- + "AND value = %s", (alias,))
- + for sid, in cursor:
- + return sid
- +
- + def _add_alias(self, user, alias):
- + if self._get_alias(alias):
- + return False
- + cursor = self.db.cursor()
- + cursor.execute("INSERT INTO session_attribute (sid, authenticated, name, value) "
- + "VALUES (%s, 1, %s, %s)", (user, self._gen_key(alias), alias))
- + return True
- +
- + def _delete_alias_by_key(self, user, key):
- + cursor = self.db.cursor()
- + cursor.execute("DELETE FROM session_attribute "
- + "WHERE authenticated = 1 "
- + "AND sid = %s "
- + "AND name = %s", (user, 'mercurialalias.%s' % key))
- +
- + def _delete_alias(self, alias):
- + cursor = self.db.cursor()
- + cursor.execute("DELETE FROM session_attribute "
- + "WHERE authenticated = 1 "
- + "AND name LIKE 'mercurialalias.%' "
- + "AND value = %s", (alias,))
- +
- + def _gen_key(self, alias):
- + return u'mercurialalias.%s' % sha1(alias.encode('utf-8')).hexdigest()[:16]
- +
- + # ITemplateProvider
- + def get_htdocs_dirs(self):
- + return []
- +
- + # ITemplateProvider
- + def get_templates_dirs(self):
- + return [resource_filename(__name__, 'templates')]
- diff -urN -x '*.pyc' -x '*.svn*' -x '*.egg*' mercurial-plugin/tracext/hg/backend.py mercurial-plugin-aliaspatch/tracext/hg/backend.py
- --- mercurial-plugin/tracext/hg/backend.py 2012-03-24 15:43:07.662219243 +0100
- +++ mercurial-plugin-aliaspatch/tracext/hg/backend.py 2012-03-24 16:25:03.835254629 +0100
- @@ -57,7 +57,7 @@
- # before loading mercurial modules, and desactivate it afterwards.
- #
- # See http://www.selenic.com/mercurial/bts/issue605
- -
- +
- try:
- from mercurial import demandimport
- demandimport.enable();
- @@ -93,7 +93,7 @@
- # Force local encoding to be non-lossy (#7217)
- os.environ['HGENCODING'] = 'utf-8'
- encoding.tolocal = str
- -
- +
- if demandimport:
- demandimport.disable()
- @@ -105,7 +105,7 @@
- else:
- from mercurial.scmutil import match
- -
- +
- except ImportError, e:
- hg_import_error = e
- ui = object
- @@ -140,14 +140,14 @@
- if check(s):
- return s
- -
- +
- class trac_ui(ui):
- # Note: will be dropped in 0.13, see MercurialConnector._setup_ui
- def __init__(self, *args, **kwargs):
- ui.__init__(self, *args)
- self.setconfig('ui', 'interactive', 'off')
- self.log = kwargs.get('log', args and args[0].log or None)
- -
- +
- def write(self, *args, **opts):
- for a in args:
- self.log.info('(mercurial status) %s', a)
- @@ -159,7 +159,7 @@
- def plain(self, *args, **kw):
- return False # so that '[hg] hgrc' file can specify [ui] options
- - def interactive(self):
- + def interactive(self):
- return False
- def readline(self):
- @@ -176,26 +176,26 @@
- return (name.startswith('hg-') and
- name[3:] in ('Parents', 'Children', 'Tags', 'Branch') and
- mode == 'revprop') and 4 or 0
- -
- +
- def render_property(self, name, mode, context, props):
- - return RenderedProperty(name=gettext(name[3:] + ':'),
- + return RenderedProperty(name=gettext(name[3:] + ':'),
- name_attributes=[("class", "property")],
- content=self._render_property(name, mode, context, props))
- def _render_property(self, name, mode, context, props):
- repos, revs = props[name]
- -
- +
- if name in ('hg-Parents', 'hg-Children'):
- label = repos.display_rev
- else:
- label = lambda rev: rev
- -
- +
- def link(rev):
- chgset = repos.get_changeset(rev)
- return tag.a(label(rev), class_="changeset",
- title=shorten_line(chgset.message),
- href=context.href.changeset(rev, repos.reponame))
- -
- +
- if name == 'hg-Parents' and len(revs) == 2: # merge
- new = context.resource.id
- parent_links = [
- @@ -231,7 +231,7 @@
- def match_property(self, name, mode):
- return name in ('hg-transplant_source', 'hg-convert_revision') and \
- mode == 'revprop' and 4 or 0
- -
- +
- def render_property(self, name, mode, context, props):
- repos, value = props[name]
- if name == 'hg-transplant_source':
- @@ -246,7 +246,7 @@
- title=_("no such changeset"), rel="nofollow")
- return RenderedProperty(name=_("Transplant:"), content=link,
- name_attributes=[("class", "property")])
- -
- +
- elif name == 'hg-convert_revision':
- text = repos.to_u(value)
- if value.startswith('svn:'):
- @@ -271,11 +271,11 @@
- def match_property(self, name, mode):
- return name.startswith('hg-') and mode == 'revprop' and 1 or 0
- -
- +
- def render_property(self, name, mode, context, props):
- - return RenderedProperty(name=name[3:] + ':',
- + return RenderedProperty(name=name[3:] + ':',
- name_attributes=[("class", "property")],
- - content=self._render_property(name, mode,
- + content=self._render_property(name, mode,
- context, props))
- def _render_property(self, name, mode, context, props):
- @@ -335,7 +335,7 @@
- self._version = version()
- # development version assumed to be always the ''newest'' one,
- # i.e. old development version won't be supported
- - self._version_info = (999, 0, 0)
- + self._version_info = (999, 0, 0)
- m = re.match(r'(\d+)\.(\d+)(?:\.(\d+))?', self._version or '')
- if m:
- self._version_info = tuple([int(n or 0) for n in m.groups()])
- @@ -359,7 +359,7 @@
- self.ui.check_trusted = False
- self.ui.readconfig(hgrc_path)
- except IOError, e:
- - self.log.warn("'[hg] hgrc' file (%s) can't be read: %s",
- + self.log.warn("'[hg] hgrc' file (%s) can't be read: %s",
- hgrc_path, e)
- extensions.loadall(self.ui)
- @@ -380,7 +380,7 @@
- yield 'Mercurial', self._version
- # IRepositoryConnector methods
- -
- +
- def get_supported_types(self):
- """Support for `repository_type = hg`"""
- if hg_import_error:
- @@ -398,7 +398,7 @@
- return repos
- # IWikiSyntaxProvider methods
- -
- +
- def get_wiki_syntax(self):
- yield (r'!?(?P<hgrev>[0-9a-f]{12,40})(?P<hgpath>/\S+\b)?',
- lambda formatter, label, match:
- @@ -454,7 +454,7 @@
- ### Version Control API
- -
- +
- class MercurialRepository(Repository):
- """Repository implementation based on the mercurial API.
- @@ -466,6 +466,7 @@
- def __init__(self, path, params, log, connector):
- self.ui = connector.ui
- + self.env = connector.env
- self._show_rev = connector.show_rev
- self._node_fmt = connector.node_format
- # TODO 0.13: per repository ui and options
- @@ -513,7 +514,7 @@
- fsencoding = [sys.getfilesystemencoding() or 'utf-8'] + encoding
- str_path = checked_encode(path, fsencoding, os.path.exists)
- if str_path is None:
- - raise TracError(_("Repository path '%(path)s' does not exist.",
- + raise TracError(_("Repository path '%(path)s' does not exist.",
- path=path))
- try:
- self.repo = hg.repository(ui=self.ui, path=str_path)
- @@ -534,7 +535,20 @@
- def changectx(self, rev=None):
- """Produce a Mercurial `context.changectx` from given Trac revision."""
- - return self.repo[self.short_rev(rev)]
- + return self._changectx_resolve_alias(self.repo[self.short_rev(rev)])
- +
- + def _changectx_resolve_alias(self, ctx):
- + db = self.env.get_db_cnx()
- + cursor = db.cursor()
- + cursor.execute("SELECT sid "
- + "FROM session_attribute "
- + "WHERE authenticated = 1 "
- + "AND name LIKE 'mercurialalias.%' "
- + "AND value = %s", (self.to_u(ctx.user()),))
- + for sid, in cursor:
- + ctx.user = lambda: self.to_u(sid)
- + break
- + return ctx
- def close(self):
- self.repo = None
- @@ -614,7 +628,7 @@
- else:
- return ''
- # branches
- - for ctx, b in sorted(branches.items(), reverse=True,
- + for ctx, b in sorted(branches.items(), reverse=True,
- key=lambda (ctx, b): ctx.rev()):
- yield ('branches', b + taginfo(ctx), '/', self._display(ctx))
- # heads
- @@ -631,7 +645,7 @@
- except (KeyError, RepoLookupError):
- pass
- # closed branches
- - for ctx, b in sorted(closed_branches.items(), reverse=True,
- + for ctx, b in sorted(closed_branches.items(), reverse=True,
- key=lambda (ctx, b): ctx.rev()):
- yield ('closed branches', b + taginfo(ctx), '/', self._display(ctx))
- @@ -648,7 +662,7 @@
- # Note: link to matching location in Mercurial's file browser
- #rev = rev is not None and short(n) or 'tip'
- #return '/'.join([url, 'file', rev, path])
- -
- +
- def get_changeset(self, rev):
- return MercurialChangeset(self, self.changectx(rev))
- @@ -660,7 +674,7 @@
- FIXME: this can only be handled correctly and efficiently by
- using the db repository cache.
- -
- +
- The code below is only an heuristic, and doesn't work in the
- general case. E.g. look at the mercurial repository timeline
- for 2006-10-18, you need to give ''38'' daysback in order to
- @@ -686,14 +700,14 @@
- continue # assume no ancestor is younger and use next seed
- # (and that assumption is wrong for 3448 in the example above)
- elif time < stop:
- - yield MercurialChangeset(self, ctx)
- + yield MercurialChangeset(self, self._changectx_resolve_alias(ctx))
- for p in ctx.parents():
- if p.rev() not in seen:
- seen[p.rev()] = 1
- seeds.append(p)
- def get_node(self, path, rev=None):
- - return MercurialNode(self, self.normalize_path(path),
- + return MercurialNode(self, self.normalize_path(path),
- self.changectx(rev))
- def get_oldest_rev(self):
- @@ -701,12 +715,12 @@
- def get_youngest_rev(self):
- return self.changectx().hex()
- -
- +
- def previous_rev(self, rev, path=''): # FIXME: path ignored for now
- for p in self.changectx(rev).parents():
- if p:
- return p.hex() # always follow first parent
- -
- +
- def next_rev(self, rev, path=''):
- ctx = self.changectx(rev)
- if path: # might be a file
- @@ -721,7 +735,7 @@
- # it might be a directory (not supported for now) FIXME
- for c in ctx.children():
- return c.hex() # always follow first child
- -
- +
- def rev_older_than(self, rev1, rev2):
- # FIXME use == and ancestors?
- return self.short_rev(rev1) < self.short_rev(rev2)
- @@ -732,7 +746,7 @@
- def get_changes(self, old_path, old_rev, new_path, new_rev,
- ignore_ancestry=1):
- """Generates changes corresponding to generalized diffs.
- -
- +
- Generator that yields change tuples (old_node, new_node, kind,
- change) for each node change between the two arbitrary
- (path,rev) pairs.
- @@ -755,7 +769,7 @@
- # Correct change info from changelog(revlog)
- # Finding changes between two revs requires tracking back
- # several routes.
- -
- +
- if new_node.isdir:
- # TODO: Should we follow rename and copy?
- # As temporary workaround, simply compare entry names.
- @@ -793,7 +807,7 @@
- if old_node.manifest[old_node.str_path] != \
- new_node.manifest[new_node.str_path]:
- yield(old_node, new_node, Node.FILE, Changeset.EDIT)
- -
- +
- class MercurialNode(Node):
- """A path in the repository, at a given revision.
- @@ -805,10 +819,10 @@
- than for files, except when created as a `subnode()` of an
- existing MercurialNode.
- """
- -
- +
- filectx = dirnode = None
- - def __init__(self, repos, path, changectx,
- + def __init__(self, repos, path, changectx,
- manifest=None, dirctx=None, str_entry=None):
- """
- :param repos: the `MercurialRepository`
- @@ -836,7 +850,7 @@
- str_path = str_entry
- else:
- # Fast path: check for existing file
- - str_path = checked_encode(path, repos.encoding,
- + str_path = checked_encode(path, repos.encoding,
- lambda s: s in self.manifest)
- if str_path is None:
- # Slow path: this might be a directory node
- @@ -905,9 +919,9 @@
- def find_dirctx(self, max_rev, str_dirnames, str_entries):
- """Find most recent modification for each given directory path.
- -
- +
- :param max_rev: find no revision more recent than this one
- - :param str_dirnames: directory paths to consider
- + :param str_dirnames: directory paths to consider
- (as `str` ending with '/')
- :param str_entries: optionally maps directories to their file content
- @@ -925,7 +939,7 @@
- changelog and detect the first occurrence of a change in
- each directory; this is much faster but can still be slow
- if some folders are only modified in the distant past
- -
- +
- It is possible to combine both approach, and this can yield
- excellent results in some cases (e.g. browsing the Linux repos
- @ 118733 takes several minutes with the first approach, 11s
- @@ -970,8 +984,8 @@
- str_dirnames.remove(str_dir)
- if not str_dirnames:
- return str_dirctxs
- -
- -
- +
- +
- def subnode(self, str_path, subctx=None):
- """Return a node with the same revision information but for
- another path
- @@ -989,7 +1003,7 @@
- def read(self, size=None):
- if self.isdir:
- - return TracError(_("Can't read from directory %(path)s",
- + return TracError(_("Can't read from directory %(path)s",
- path=self.path))
- if self.data is None:
- self.data = self.filectx.data()
- @@ -1003,7 +1017,7 @@
- def get_entries(self):
- if self.isfile:
- return
- -
- +
- # dirnames are entries which are sub-directories
- str_entries = {}
- str_dirnames = []
- @@ -1029,7 +1043,7 @@
- # pre-computing the changectx for the last change in each sub-directory
- if str_dirnames:
- - dirctxs = self.find_dirctx(self.created_rev, str_dirnames,
- + dirctxs = self.find_dirctx(self.created_rev, str_dirnames,
- str_entries)
- else:
- dirctxs = {}
- @@ -1090,7 +1104,7 @@
- get = cachefunc(changefn)
- if self.isfile:
- fncache = {}
- - chgiter, matchfn = cmdutil.walkchangerevs(self.repos.ui, repo, pats,
- + chgiter, matchfn = cmdutil.walkchangerevs(self.repos.ui, repo, pats,
- get, opts)
- # keep one lookahead entry so that we can detect renames
- path = self.path
- @@ -1122,7 +1136,7 @@
- for fc, line in self.filectx.annotate(follow=True):
- annotations.append(fc.rev() or '0')
- return annotations
- -
- +
- def get_properties(self):
- if self.isfile and 'x' in self.manifest.flags(self.str_path):
- return {'exe': '*'}
- @@ -1153,7 +1167,7 @@
- files changes are obtained by comparing the current manifest to
- the parent manifest(s).
- """
- -
- +
- def __init__(self, repos, ctx):
- self.repos = repos
- self.ctx = ctx
- @@ -1165,6 +1179,7 @@
- desc = repos.to_u(ctx.description())
- user = repos.to_u(ctx.user())
- time = repos.from_hg_time(ctx.date())
- +
- Changeset.__init__(self, repos, ctx.hex(), desc, user, time)
- hg_properties = [
- @@ -1175,7 +1190,7 @@
- properties = {}
- parents = self.ctx.parents()
- if len(parents) > 1:
- - properties['hg-Parents'] = (self.repos,
- + properties['hg-Parents'] = (self.repos,
- [p.hex() for p in parents if p])
- children = self.ctx.children()
- if len(children) > 1:
- @@ -1185,7 +1200,7 @@
- properties['hg-Branch'] = (self.repos, [self.branch])
- tags = self.ctx.tags()
- if len(tags):
- - properties['hg-Tags'] = (self.repos,
- + properties['hg-Tags'] = (self.repos,
- [self.repos.to_u(t) for t in tags])
- for k, v in self.ctx.extra().iteritems():
- if k != 'branch':
- @@ -1226,7 +1241,7 @@
- action = Changeset.MOVE
- else:
- action = Changeset.COPY
- - changes.append((f, Node.FILE, action, u(str_base_path),
- + changes.append((f, Node.FILE, action, u(str_base_path),
- base_ctx.rev()))
- # remaining str_deletions are real deletions
- for str_file, p in str_deletions.items():
- @@ -1238,5 +1253,5 @@
- def get_branches(self):
- """Yield branch names to which this changeset belong."""
- - return self.branch and [(self.branch,
- + return self.branch and [(self.branch,
- len(self.ctx.children()) == 0)] or []
- diff -urN -x '*.pyc' -x '*.svn*' -x '*.egg*' mercurial-plugin/tracext/hg/templates/admin_mercurialalias.html mercurial-plugin-aliaspatch/tracext/hg/templates/admin_mercurialalias.html
- --- mercurial-plugin/tracext/hg/templates/admin_mercurialalias.html 1970-01-01 01:00:00.000000000 +0100
- +++ mercurial-plugin-aliaspatch/tracext/hg/templates/admin_mercurialalias.html 2012-03-24 16:32:39.472786230 +0100
- @@ -0,0 +1,60 @@
- +<!DOCTYPE html
- + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- +<html xmlns="http://www.w3.org/1999/xhtml"
- + xmlns:xi="http://www.w3.org/2001/XInclude"
- + xmlns:py="http://genshi.edgewall.org/">
- + <xi:include href="admin.html" />
- + <head>
- + <title>Mercurial Aliases</title>
- + </head>
- +
- + <body>
- + <h2>Manage Mercurial Aliases</h2>
- +
- + <form id="hgalias-editor" class="addnew" method="post">
- + <fieldset>
- + <legend>Add Alias:</legend>
- + <div class="field">
- + <label>Username:<br />
- + <input type="text" name="user" class="textwidget" />
- + </label>
- + </div>
- + <div class="field">
- + <label>Alias:<br />
- + <input type="text" name="alias" class="textwidget" />
- + </label>
- + </div>
- + <p class="help">Add a new alias.</p>
- + <div class="buttons">
- + <input type="submit" name="add" value="Add" />
- + </div>
- + </fieldset>
- + </form>
- +
- + <form method="post">
- + <div id="aliaslist">
- + <table class="listing">
- + <thead>
- + <tr>
- + <th class="sel"> </th>
- + <th>Username</th><th>Alias</th>
- + </tr>
- + </thead>
- + <tbody>
- + <tr py:for="alias in aliases">
- + <td>
- + <input type="checkbox" name="sel" value="${alias.user}.${alias.key}" />
- + </td>
- + <td>${alias.user}</td>
- + <td>${alias.alias}</td>
- + </tr>
- + </tbody>
- + </table>
- + </div>
- + <div class="buttons">
- + <input type="submit" name="remove" value="Remove" />
- + </div>
- + </form>
- + </body>
- +</html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement