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: |
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") |
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: |