mercurial/util.py
changeset 870 a82eae840447
parent 869 1e3a23719662
child 871 c2e77581bc84
equal deleted inserted replaced
869:1e3a23719662 870:a82eae840447
    14     for f in g:
    14     for f in g:
    15         if f not in seen:
    15         if f not in seen:
    16             seen[f] = 1
    16             seen[f] = 1
    17             yield f
    17             yield f
    18 
    18 
    19 class CommandError(Exception): pass
    19 class Abort(Exception):
       
    20     """Raised if a command needs to print an error and exit."""
    20 
    21 
    21 def always(fn): return True
    22 def always(fn): return True
    22 def never(fn): return False
    23 def never(fn): return False
    23 
    24 
    24 def globre(pat, head = '^', tail = '$'):
    25 def globre(pat, head = '^', tail = '$'):
    66             res += re.escape(c)
    67             res += re.escape(c)
    67     return head + res + tail
    68     return head + res + tail
    68 
    69 
    69 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
    70 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
    70 
    71 
    71 def matcher(cwd, names, inc, exc, head = ''):
    72 def canonpath(repo, cwd, myname):
       
    73     rootsep = repo.root + os.sep
       
    74     name = myname
       
    75     if not name.startswith(os.sep):
       
    76         name = os.path.join(repo.root, cwd, name)
       
    77     name = os.path.normpath(name)
       
    78     if name.startswith(rootsep):
       
    79         return name[len(rootsep):]
       
    80     elif name == repo.root:
       
    81         return ''
       
    82     else:
       
    83         raise Abort('%s not under repository root' % myname)
       
    84     
       
    85 def matcher(repo, cwd, names, inc, exc, head = ''):
    72     def patkind(name):
    86     def patkind(name):
    73         for prefix in 're:', 'glob:', 'path:':
    87         for prefix in 're:', 'glob:', 'path:':
    74             if name.startswith(prefix): return name.split(':', 1)
    88             if name.startswith(prefix): return name.split(':', 1)
    75         for c in name:
    89         for c in name:
    76             if c in _globchars: return 'glob', name
    90             if c in _globchars: return 'glob', name
    77         return 'relpath', name
    91         return 'relpath', name
    78 
       
    79     cwdsep = cwd + os.sep
       
    80 
    92 
    81     def regex(name, tail):
    93     def regex(name, tail):
    82         '''convert a pattern into a regular expression'''
    94         '''convert a pattern into a regular expression'''
    83         kind, name = patkind(name)
    95         kind, name = patkind(name)
    84         if kind == 're':
    96         if kind == 're':
    85             return name
    97             return name
    86         elif kind == 'path':
    98         elif kind == 'path':
    87             return '^' + re.escape(name) + '$'
    99             return '^' + re.escape(name) + '$'
    88         if cwd: name = os.path.join(cwdsep, name)
       
    89         name = os.path.normpath(name)
       
    90         if name == '.': name = '**'
       
    91         return head + globre(name, '', tail)
   100         return head + globre(name, '', tail)
    92 
   101 
    93     def matchfn(pats, tail):
   102     def matchfn(pats, tail):
    94         """build a matching function from a set of patterns"""
   103         """build a matching function from a set of patterns"""
    95         if pats:
   104         if pats:
   102         for p in pat.split(os.sep):
   111         for p in pat.split(os.sep):
   103             if patkind(p)[0] == 'glob': break
   112             if patkind(p)[0] == 'glob': break
   104             root.append(p)
   113             root.append(p)
   105         return os.sep.join(root)
   114         return os.sep.join(root)
   106 
   115 
   107     patkinds = map(patkind, names)
   116     pats = []
   108     pats = [name for (kind, name) in patkinds if kind != 'relpath']
   117     files = []
   109     files = [name for (kind, name) in patkinds if kind == 'relpath']
   118     roots = []
   110     roots = filter(None, map(globprefix, pats)) + files
   119     for kind, name in map(patkind, names):
   111     if cwd: roots = [cwdsep + r for r in roots]
   120         if kind in ('glob', 'relpath'):
       
   121             name = canonpath(repo, cwd, name)
       
   122             if name == '':
       
   123                 kind, name = 'glob', '**'
       
   124         if kind in ('glob', 're'):
       
   125             pats.append(name)
       
   126         if kind == 'glob':
       
   127             root = globprefix(name)
       
   128             if root: roots.append(root)
       
   129         elif kind == 'relpath':
       
   130             files.append(name)
       
   131             roots.append(name)
   112         
   132         
   113     patmatch = matchfn(pats, '$') or always
   133     patmatch = matchfn(pats, '$') or always
   114     filematch = matchfn(files, '(?:/|$)') or always
   134     filematch = matchfn(files, '(?:/|$)') or always
   115     incmatch = matchfn(inc, '(?:/|$)') or always
   135     incmatch = matchfn(inc, '(?:/|$)') or always
   116     excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False)
   136     excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False)
   127     if rc:
   147     if rc:
   128         errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]),
   148         errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]),
   129                             explain_exit(rc)[0])
   149                             explain_exit(rc)[0])
   130         if errprefix:
   150         if errprefix:
   131             errmsg = "%s: %s" % (errprefix, errmsg)
   151             errmsg = "%s: %s" % (errprefix, errmsg)
   132         raise CommandError(errmsg)
   152         raise Abort(errmsg)
   133 
   153 
   134 def rename(src, dst):
   154 def rename(src, dst):
   135     try:
   155     try:
   136         os.rename(src, dst)
   156         os.rename(src, dst)
   137     except:
   157     except: