hgext/schemes.py
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Tue, 21 Feb 2017 01:21:00 +0900
changeset 31054 59e69ed81776
parent 30640 7a3e67bfa417
child 31181 150cd5125722
permissions -rw-r--r--
localrepo: check HG_PENDING strictly Before this patch, checking HG_PENDING for changelog in localrepo.py might cause unintentional reading unrelated '00changelog.i.a' in, because HG_PENDING is checked by str.startswith(). An external hook spawned by inner repository in nested ones satisfies this condition. This patch uses txnutil.mayhavepending() to check HG_PENDING strictly. BTW, this patch may cause failure of bisect in the repository of Mercurial itself, if examination at bisecting assumes that an external hook can see all pending changes while nested transactions across repositories. This invisibility issue will be fixed by subsequent patch, which allows HG_PENDING to refer multiple repositories.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     1
# Copyright 2009, Alexander Solovyov <piranha@piranha.org.ua>
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     2
#
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     3
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10070
diff changeset
     4
# GNU General Public License version 2 or any later version.
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     5
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     6
"""extend schemes with shortcuts to repository swarms
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     7
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     8
This extension allows you to specify shortcuts for parent URLs with a
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     9
lot of repositories to act like a scheme, for example::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    10
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    11
  [schemes]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    12
  py = http://code.python.org/hg/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    13
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    14
After that you can use it like::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    15
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    16
  hg clone py://trunk/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    17
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    18
Additionally there is support for some more complex schemas, for
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    19
example used by Google Code::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    20
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    21
  [schemes]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    22
  gcode = http://{1}.googlecode.com/hg/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    23
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    24
The syntax is taken from Mercurial templates, and you have unlimited
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    25
number of variables, starting with ``{1}`` and continuing with
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    26
``{2}``, ``{3}`` and so on. This variables will receive parts of URL
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    27
supplied, split by ``/``. Anything not specified as ``{part}`` will be
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    28
just appended to an URL.
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    29
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    30
For convenience, the extension adds these schemes by default::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    31
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    32
  [schemes]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    33
  py = http://hg.python.org/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    34
  bb = https://bitbucket.org/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    35
  bb+ssh = ssh://hg@bitbucket.org/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    36
  gcode = https://{1}.googlecode.com/hg/
10777
bdc3256a318e schemes: add Kiln On Demand to default schemes
Benjamin Pollack <benjamin@bitquabit.com>
parents: 10282
diff changeset
    37
  kiln = https://{1}.kilnhg.com/Repo/
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    38
9965
963ed04a8fde schemes: fixed typos in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 9964
diff changeset
    39
You can override a predefined scheme by defining a new scheme with the
963ed04a8fde schemes: fixed typos in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 9964
diff changeset
    40
same name.
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    41
"""
28379
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    42
from __future__ import absolute_import
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    43
28379
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    44
import os
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    45
import re
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28379
diff changeset
    46
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28379
diff changeset
    47
from mercurial.i18n import _
28379
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    48
from mercurial import (
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    49
    cmdutil,
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    50
    error,
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    51
    extensions,
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    52
    hg,
30640
7a3e67bfa417 py3: replace os.name with pycompat.osname (part 2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29841
diff changeset
    53
    pycompat,
28379
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    54
    templater,
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    55
    util,
27a9032374a7 schemas: use absolute_import
timeless <timeless@mozdev.org>
parents: 27982
diff changeset
    56
)
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    57
27982
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
    58
cmdtable = {}
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
    59
command = cmdutil.command(cmdtable)
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29205
diff changeset
    60
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 18910
diff changeset
    61
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 18910
diff changeset
    62
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 18910
diff changeset
    63
# leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29205
diff changeset
    64
testedwith = 'ships-with-hg-core'
16743
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 15609
diff changeset
    65
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    66
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    67
class ShortRepository(object):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    68
    def __init__(self, url, scheme, templater):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    69
        self.scheme = scheme
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    70
        self.templater = templater
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    71
        self.url = url
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    72
        try:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    73
            self.parts = max(map(int, re.findall(r'\{(\d+)\}', self.url)))
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    74
        except ValueError:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    75
            self.parts = 0
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    76
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    77
    def __repr__(self):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    78
        return '<ShortRepository: %s>' % self.scheme
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    79
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    80
    def instance(self, ui, url, create):
27981
d630eac3a5db schemes: extract scheme expansion as its own method on ShortRepository
Jason R. Coombs <jaraco@jaraco.com>
parents: 26587
diff changeset
    81
        url = self.resolve(url)
d630eac3a5db schemes: extract scheme expansion as its own method on ShortRepository
Jason R. Coombs <jaraco@jaraco.com>
parents: 26587
diff changeset
    82
        return hg._peerlookup(url).instance(ui, url, create)
d630eac3a5db schemes: extract scheme expansion as its own method on ShortRepository
Jason R. Coombs <jaraco@jaraco.com>
parents: 26587
diff changeset
    83
d630eac3a5db schemes: extract scheme expansion as its own method on ShortRepository
Jason R. Coombs <jaraco@jaraco.com>
parents: 26587
diff changeset
    84
    def resolve(self, url):
17425
e95ec38f86b0 fix wording and not-completely-trivial spelling errors and bad docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 16743
diff changeset
    85
        # Should this use the util.url class, or is manual parsing better?
18910
b52404a914a9 scheme: don't crash on invalid URLs
Mads Kiilerich <madski@unity3d.com>
parents: 17425
diff changeset
    86
        try:
b52404a914a9 scheme: don't crash on invalid URLs
Mads Kiilerich <madski@unity3d.com>
parents: 17425
diff changeset
    87
            url = url.split('://', 1)[1]
b52404a914a9 scheme: don't crash on invalid URLs
Mads Kiilerich <madski@unity3d.com>
parents: 17425
diff changeset
    88
        except IndexError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25186
diff changeset
    89
            raise error.Abort(_("no '://' in scheme url '%s'") % url)
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    90
        parts = url.split('/', self.parts)
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    91
        if len(parts) > self.parts:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    92
            tail = parts[-1]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    93
            parts = parts[:-1]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    94
        else:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    95
            tail = ''
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    96
        context = dict((str(i + 1), v) for i, v in enumerate(parts))
27981
d630eac3a5db schemes: extract scheme expansion as its own method on ShortRepository
Jason R. Coombs <jaraco@jaraco.com>
parents: 26587
diff changeset
    97
        return ''.join(self.templater.process(self.url, context)) + tail
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    98
13827
f1823b9f073b url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents: 13822
diff changeset
    99
def hasdriveletter(orig, path):
15609
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
   100
    if path:
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
   101
        for scheme in schemes:
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
   102
            if path.startswith(scheme + ':'):
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
   103
                return False
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   104
    return orig(path)
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   105
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   106
schemes = {
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   107
    'py': 'http://hg.python.org/',
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   108
    'bb': 'https://bitbucket.org/',
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   109
    'bb+ssh': 'ssh://hg@bitbucket.org/',
10777
bdc3256a318e schemes: add Kiln On Demand to default schemes
Benjamin Pollack <benjamin@bitquabit.com>
parents: 10282
diff changeset
   110
    'gcode': 'https://{1}.googlecode.com/hg/',
bdc3256a318e schemes: add Kiln On Demand to default schemes
Benjamin Pollack <benjamin@bitquabit.com>
parents: 10282
diff changeset
   111
    'kiln': 'https://{1}.kilnhg.com/Repo/'
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   112
    }
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   113
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   114
def extsetup(ui):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   115
    schemes.update(dict(ui.configitems('schemes')))
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   116
    t = templater.engine(lambda x: x)
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   117
    for scheme, url in schemes.items():
30640
7a3e67bfa417 py3: replace os.name with pycompat.osname (part 2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29841
diff changeset
   118
        if (pycompat.osname == 'nt' and len(scheme) == 1 and scheme.isalpha()
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   119
            and os.path.exists('%s:\\' % scheme)):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25186
diff changeset
   120
            raise error.Abort(_('custom scheme %s:// conflicts with drive '
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   121
                               'letter %s:\\\n') % (scheme, scheme.upper()))
14606
6e631c24c6d9 hg: move peerschemes back to schemes
Matt Mackall <mpm@selenic.com>
parents: 14605
diff changeset
   122
        hg.schemes[scheme] = ShortRepository(url, scheme, t)
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   123
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   124
    extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter)
27982
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   125
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   126
@command('debugexpandscheme', norepo=True)
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   127
def expandscheme(ui, url, **opts):
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   128
    """given a repo path, provide the scheme-expanded path
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   129
    """
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   130
    repo = hg._peerlookup(url)
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   131
    if isinstance(repo, ShortRepository):
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   132
        url = repo.resolve(url)
bf1d5c223ac0 schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs <jaraco@jaraco.com>
parents: 27981
diff changeset
   133
    ui.write(url + '\n')