hgext/convert/common.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43085 eef9a2d67051
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    44     def get_token(self):
    44     def get_token(self):
    45         return _encodeornone(self._l.get_token())
    45         return _encodeornone(self._l.get_token())
    46 
    46 
    47     @property
    47     @property
    48     def infile(self):
    48     def infile(self):
    49         return self._l.infile or '<unknown>'
    49         return self._l.infile or b'<unknown>'
    50 
    50 
    51     @property
    51     @property
    52     def lineno(self):
    52     def lineno(self):
    53         return self._l.lineno
    53         return self._l.lineno
    54 
    54 
    55 
    55 
    56 def shlexer(data=None, filepath=None, wordchars=None, whitespace=None):
    56 def shlexer(data=None, filepath=None, wordchars=None, whitespace=None):
    57     if data is None:
    57     if data is None:
    58         if pycompat.ispy3:
    58         if pycompat.ispy3:
    59             data = open(filepath, 'r', encoding=r'latin1')
    59             data = open(filepath, b'r', encoding=r'latin1')
    60         else:
    60         else:
    61             data = open(filepath, 'r')
    61             data = open(filepath, b'r')
    62     else:
    62     else:
    63         if filepath is not None:
    63         if filepath is not None:
    64             raise error.ProgrammingError(
    64             raise error.ProgrammingError(
    65                 'shlexer only accepts data or filepath, not both'
    65                 b'shlexer only accepts data or filepath, not both'
    66             )
    66             )
    67         if pycompat.ispy3:
    67         if pycompat.ispy3:
    68             data = data.decode('latin1')
    68             data = data.decode('latin1')
    69     l = shlex.shlex(data, infile=filepath, posix=True)
    69     l = shlex.shlex(data, infile=filepath, posix=True)
    70     if whitespace is not None:
    70     if whitespace is not None:
    85 
    85 
    86 def encodeargs(args):
    86 def encodeargs(args):
    87     def encodearg(s):
    87     def encodearg(s):
    88         lines = base64.encodestring(s)
    88         lines = base64.encodestring(s)
    89         lines = [l.splitlines()[0] for l in lines]
    89         lines = [l.splitlines()[0] for l in lines]
    90         return ''.join(lines)
    90         return b''.join(lines)
    91 
    91 
    92     s = pickle.dumps(args)
    92     s = pickle.dumps(args)
    93     return encodearg(s)
    93     return encodearg(s)
    94 
    94 
    95 
    95 
   107     if not procutil.findexe(exe):
   107     if not procutil.findexe(exe):
   108         if abort:
   108         if abort:
   109             exc = error.Abort
   109             exc = error.Abort
   110         else:
   110         else:
   111             exc = MissingTool
   111             exc = MissingTool
   112         raise exc(_('cannot find required "%s" tool') % name)
   112         raise exc(_(b'cannot find required "%s" tool') % name)
   113 
   113 
   114 
   114 
   115 class NoRepo(Exception):
   115 class NoRepo(Exception):
   116     pass
   116     pass
   117 
   117 
   118 
   118 
   119 SKIPREV = 'SKIP'
   119 SKIPREV = b'SKIP'
   120 
   120 
   121 
   121 
   122 class commit(object):
   122 class commit(object):
   123     def __init__(
   123     def __init__(
   124         self,
   124         self,
   133         saverev=True,
   133         saverev=True,
   134         phase=phases.draft,
   134         phase=phases.draft,
   135         optparents=None,
   135         optparents=None,
   136         ctx=None,
   136         ctx=None,
   137     ):
   137     ):
   138         self.author = author or 'unknown'
   138         self.author = author or b'unknown'
   139         self.date = date or '0 0'
   139         self.date = date or b'0 0'
   140         self.desc = desc
   140         self.desc = desc
   141         self.parents = parents  # will be converted and used as parents
   141         self.parents = parents  # will be converted and used as parents
   142         self.optparents = optparents or []  # will be used if already converted
   142         self.optparents = optparents or []  # will be used if already converted
   143         self.branch = branch
   143         self.branch = branch
   144         self.rev = rev
   144         self.rev = rev
   158         self.ui = ui
   158         self.ui = ui
   159         self.path = path
   159         self.path = path
   160         self.revs = revs
   160         self.revs = revs
   161         self.repotype = repotype
   161         self.repotype = repotype
   162 
   162 
   163         self.encoding = 'utf-8'
   163         self.encoding = b'utf-8'
   164 
   164 
   165     def checkhexformat(self, revstr, mapname='splicemap'):
   165     def checkhexformat(self, revstr, mapname=b'splicemap'):
   166         """ fails if revstr is not a 40 byte hex. mercurial and git both uses
   166         """ fails if revstr is not a 40 byte hex. mercurial and git both uses
   167             such format for their revision numbering
   167             such format for their revision numbering
   168         """
   168         """
   169         if not re.match(br'[0-9a-fA-F]{40,40}$', revstr):
   169         if not re.match(br'[0-9a-fA-F]{40,40}$', revstr):
   170             raise error.Abort(
   170             raise error.Abort(
   171                 _('%s entry %s is not a valid revision' ' identifier')
   171                 _(b'%s entry %s is not a valid revision' b' identifier')
   172                 % (mapname, revstr)
   172                 % (mapname, revstr)
   173             )
   173             )
   174 
   174 
   175     def before(self):
   175     def before(self):
   176         pass
   176         pass
   234         """
   234         """
   235         raise NotImplementedError
   235         raise NotImplementedError
   236 
   236 
   237     def recode(self, s, encoding=None):
   237     def recode(self, s, encoding=None):
   238         if not encoding:
   238         if not encoding:
   239             encoding = self.encoding or 'utf-8'
   239             encoding = self.encoding or b'utf-8'
   240 
   240 
   241         if isinstance(s, pycompat.unicode):
   241         if isinstance(s, pycompat.unicode):
   242             return s.encode("utf-8")
   242             return s.encode("utf-8")
   243         try:
   243         try:
   244             return s.decode(pycompat.sysstr(encoding)).encode("utf-8")
   244             return s.decode(pycompat.sysstr(encoding)).encode("utf-8")
   290 
   290 
   291         Bookmark names are to be UTF-8 strings.
   291         Bookmark names are to be UTF-8 strings.
   292         """
   292         """
   293         return {}
   293         return {}
   294 
   294 
   295     def checkrevformat(self, revstr, mapname='splicemap'):
   295     def checkrevformat(self, revstr, mapname=b'splicemap'):
   296         """revstr is a string that describes a revision in the given
   296         """revstr is a string that describes a revision in the given
   297            source control system.  Return true if revstr has correct
   297            source control system.  Return true if revstr has correct
   298            format.
   298            format.
   299         """
   299         """
   300         return True
   300         return True
   410     def _cmdline(self, cmd, *args, **kwargs):
   410     def _cmdline(self, cmd, *args, **kwargs):
   411         kwargs = pycompat.byteskwargs(kwargs)
   411         kwargs = pycompat.byteskwargs(kwargs)
   412         cmdline = [self.command, cmd] + list(args)
   412         cmdline = [self.command, cmd] + list(args)
   413         for k, v in kwargs.iteritems():
   413         for k, v in kwargs.iteritems():
   414             if len(k) == 1:
   414             if len(k) == 1:
   415                 cmdline.append('-' + k)
   415                 cmdline.append(b'-' + k)
   416             else:
   416             else:
   417                 cmdline.append('--' + k.replace('_', '-'))
   417                 cmdline.append(b'--' + k.replace(b'_', b'-'))
   418             try:
   418             try:
   419                 if len(k) == 1:
   419                 if len(k) == 1:
   420                     cmdline.append('' + v)
   420                     cmdline.append(b'' + v)
   421                 else:
   421                 else:
   422                     cmdline[-1] += '=' + v
   422                     cmdline[-1] += b'=' + v
   423             except TypeError:
   423             except TypeError:
   424                 pass
   424                 pass
   425         cmdline = [procutil.shellquote(arg) for arg in cmdline]
   425         cmdline = [procutil.shellquote(arg) for arg in cmdline]
   426         if not self.ui.debugflag:
   426         if not self.ui.debugflag:
   427             cmdline += ['2>', pycompat.bytestr(os.devnull)]
   427             cmdline += [b'2>', pycompat.bytestr(os.devnull)]
   428         cmdline = ' '.join(cmdline)
   428         cmdline = b' '.join(cmdline)
   429         return cmdline
   429         return cmdline
   430 
   430 
   431     def _run(self, cmd, *args, **kwargs):
   431     def _run(self, cmd, *args, **kwargs):
   432         def popen(cmdline):
   432         def popen(cmdline):
   433             p = subprocess.Popen(
   433             p = subprocess.Popen(
   447     def _run3(self, cmd, *args, **kwargs):
   447     def _run3(self, cmd, *args, **kwargs):
   448         return self._dorun(procutil.popen3, cmd, *args, **kwargs)
   448         return self._dorun(procutil.popen3, cmd, *args, **kwargs)
   449 
   449 
   450     def _dorun(self, openfunc, cmd, *args, **kwargs):
   450     def _dorun(self, openfunc, cmd, *args, **kwargs):
   451         cmdline = self._cmdline(cmd, *args, **kwargs)
   451         cmdline = self._cmdline(cmd, *args, **kwargs)
   452         self.ui.debug('running: %s\n' % (cmdline,))
   452         self.ui.debug(b'running: %s\n' % (cmdline,))
   453         self.prerun()
   453         self.prerun()
   454         try:
   454         try:
   455             return openfunc(cmdline)
   455             return openfunc(cmdline)
   456         finally:
   456         finally:
   457             self.postrun()
   457             self.postrun()
   464 
   464 
   465     def runlines(self, cmd, *args, **kwargs):
   465     def runlines(self, cmd, *args, **kwargs):
   466         p = self._run(cmd, *args, **kwargs)
   466         p = self._run(cmd, *args, **kwargs)
   467         output = p.stdout.readlines()
   467         output = p.stdout.readlines()
   468         p.wait()
   468         p.wait()
   469         self.ui.debug(''.join(output))
   469         self.ui.debug(b''.join(output))
   470         return output, p.returncode
   470         return output, p.returncode
   471 
   471 
   472     def checkexit(self, status, output=''):
   472     def checkexit(self, status, output=b''):
   473         if status:
   473         if status:
   474             if output:
   474             if output:
   475                 self.ui.warn(_('%s error:\n') % self.command)
   475                 self.ui.warn(_(b'%s error:\n') % self.command)
   476                 self.ui.warn(output)
   476                 self.ui.warn(output)
   477             msg = procutil.explainexit(status)
   477             msg = procutil.explainexit(status)
   478             raise error.Abort('%s %s' % (self.command, msg))
   478             raise error.Abort(b'%s %s' % (self.command, msg))
   479 
   479 
   480     def run0(self, cmd, *args, **kwargs):
   480     def run0(self, cmd, *args, **kwargs):
   481         output, status = self.run(cmd, *args, **kwargs)
   481         output, status = self.run(cmd, *args, **kwargs)
   482         self.checkexit(status, output)
   482         self.checkexit(status, output)
   483         return output
   483         return output
   484 
   484 
   485     def runlines0(self, cmd, *args, **kwargs):
   485     def runlines0(self, cmd, *args, **kwargs):
   486         output, status = self.runlines(cmd, *args, **kwargs)
   486         output, status = self.runlines(cmd, *args, **kwargs)
   487         self.checkexit(status, ''.join(output))
   487         self.checkexit(status, b''.join(output))
   488         return output
   488         return output
   489 
   489 
   490     @propertycache
   490     @propertycache
   491     def argmax(self):
   491     def argmax(self):
   492         # POSIX requires at least 4096 bytes for ARG_MAX
   492         # POSIX requires at least 4096 bytes for ARG_MAX
   538 
   538 
   539     def _read(self):
   539     def _read(self):
   540         if not self.path:
   540         if not self.path:
   541             return
   541             return
   542         try:
   542         try:
   543             fp = open(self.path, 'rb')
   543             fp = open(self.path, b'rb')
   544         except IOError as err:
   544         except IOError as err:
   545             if err.errno != errno.ENOENT:
   545             if err.errno != errno.ENOENT:
   546                 raise
   546                 raise
   547             return
   547             return
   548         for i, line in enumerate(util.iterfile(fp)):
   548         for i, line in enumerate(util.iterfile(fp)):
   549             line = line.splitlines()[0].rstrip()
   549             line = line.splitlines()[0].rstrip()
   550             if not line:
   550             if not line:
   551                 # Ignore blank lines
   551                 # Ignore blank lines
   552                 continue
   552                 continue
   553             try:
   553             try:
   554                 key, value = line.rsplit(' ', 1)
   554                 key, value = line.rsplit(b' ', 1)
   555             except ValueError:
   555             except ValueError:
   556                 raise error.Abort(
   556                 raise error.Abort(
   557                     _('syntax error in %s(%d): key/value pair expected')
   557                     _(b'syntax error in %s(%d): key/value pair expected')
   558                     % (self.path, i + 1)
   558                     % (self.path, i + 1)
   559                 )
   559                 )
   560             if key not in self:
   560             if key not in self:
   561                 self.order.append(key)
   561                 self.order.append(key)
   562             super(mapfile, self).__setitem__(key, value)
   562             super(mapfile, self).__setitem__(key, value)
   563         fp.close()
   563         fp.close()
   564 
   564 
   565     def __setitem__(self, key, value):
   565     def __setitem__(self, key, value):
   566         if self.fp is None:
   566         if self.fp is None:
   567             try:
   567             try:
   568                 self.fp = open(self.path, 'ab')
   568                 self.fp = open(self.path, b'ab')
   569             except IOError as err:
   569             except IOError as err:
   570                 raise error.Abort(
   570                 raise error.Abort(
   571                     _('could not open map file %r: %s')
   571                     _(b'could not open map file %r: %s')
   572                     % (self.path, encoding.strtolocal(err.strerror))
   572                     % (self.path, encoding.strtolocal(err.strerror))
   573                 )
   573                 )
   574         self.fp.write(util.tonativeeol('%s %s\n' % (key, value)))
   574         self.fp.write(util.tonativeeol(b'%s %s\n' % (key, value)))
   575         self.fp.flush()
   575         self.fp.flush()
   576         super(mapfile, self).__setitem__(key, value)
   576         super(mapfile, self).__setitem__(key, value)
   577 
   577 
   578     def close(self):
   578     def close(self):
   579         if self.fp:
   579         if self.fp: