229 self._terminfoparams = {} |
229 self._terminfoparams = {} |
230 self._styles = {} |
230 self._styles = {} |
231 self._uninterruptible = False |
231 self._uninterruptible = False |
232 |
232 |
233 if src: |
233 if src: |
234 self.fout = src.fout |
234 self._fout = src._fout |
235 self.ferr = src.ferr |
235 self._ferr = src._ferr |
236 self.fin = src.fin |
236 self._fin = src._fin |
237 self._finoutredirected = src._finoutredirected |
237 self._finoutredirected = src._finoutredirected |
238 self.pageractive = src.pageractive |
238 self.pageractive = src.pageractive |
239 self._disablepager = src._disablepager |
239 self._disablepager = src._disablepager |
240 self._tweaked = src._tweaked |
240 self._tweaked = src._tweaked |
241 |
241 |
254 self.fixconfig() |
254 self.fixconfig() |
255 |
255 |
256 self.httppasswordmgrdb = src.httppasswordmgrdb |
256 self.httppasswordmgrdb = src.httppasswordmgrdb |
257 self._blockedtimes = src._blockedtimes |
257 self._blockedtimes = src._blockedtimes |
258 else: |
258 else: |
259 self.fout = procutil.stdout |
259 self._fout = procutil.stdout |
260 self.ferr = procutil.stderr |
260 self._ferr = procutil.stderr |
261 self.fin = procutil.stdin |
261 self._fin = procutil.stdin |
262 self._finoutredirected = False |
262 self._finoutredirected = False |
263 self.pageractive = False |
263 self.pageractive = False |
264 self._disablepager = False |
264 self._disablepager = False |
265 self._tweaked = False |
265 self._tweaked = False |
266 |
266 |
882 |
882 |
883 @util.propertycache |
883 @util.propertycache |
884 def paths(self): |
884 def paths(self): |
885 return paths(self) |
885 return paths(self) |
886 |
886 |
|
887 @property |
|
888 def fout(self): |
|
889 return self._fout |
|
890 |
|
891 @fout.setter |
|
892 def fout(self, f): |
|
893 self._fout = f |
|
894 |
|
895 @property |
|
896 def ferr(self): |
|
897 return self._ferr |
|
898 |
|
899 @ferr.setter |
|
900 def ferr(self, f): |
|
901 self._ferr = f |
|
902 |
|
903 @property |
|
904 def fin(self): |
|
905 return self._fin |
|
906 |
|
907 @fin.setter |
|
908 def fin(self, f): |
|
909 self._fin = f |
|
910 |
887 def pushbuffer(self, error=False, subproc=False, labeled=False): |
911 def pushbuffer(self, error=False, subproc=False, labeled=False): |
888 """install a buffer to capture standard output of the ui object |
912 """install a buffer to capture standard output of the ui object |
889 |
913 |
890 If error is True, the error output will be captured too. |
914 If error is True, the error output will be captured too. |
891 |
915 |
912 self._bufferapplylabels = None |
936 self._bufferapplylabels = None |
913 |
937 |
914 return "".join(self._buffers.pop()) |
938 return "".join(self._buffers.pop()) |
915 |
939 |
916 def _isbuffered(self, dest): |
940 def _isbuffered(self, dest): |
917 if dest is self.fout: |
941 if dest is self._fout: |
918 return bool(self._buffers) |
942 return bool(self._buffers) |
919 if dest is self.ferr: |
943 if dest is self._ferr: |
920 return bool(self._bufferstates and self._bufferstates[-1][0]) |
944 return bool(self._bufferstates and self._bufferstates[-1][0]) |
921 return False |
945 return False |
922 |
946 |
923 def canwritewithoutlabels(self): |
947 def canwritewithoutlabels(self): |
924 '''check if write skips the label''' |
948 '''check if write skips the label''' |
945 |
969 |
946 When labeling output for a specific command, a label of |
970 When labeling output for a specific command, a label of |
947 "cmdname.type" is recommended. For example, status issues |
971 "cmdname.type" is recommended. For example, status issues |
948 a label of "status.modified" for modified files. |
972 a label of "status.modified" for modified files. |
949 ''' |
973 ''' |
950 self._write(self.fout, *args, **opts) |
974 self._write(self._fout, *args, **opts) |
951 |
975 |
952 def write_err(self, *args, **opts): |
976 def write_err(self, *args, **opts): |
953 self._write(self.ferr, *args, **opts) |
977 self._write(self._ferr, *args, **opts) |
954 |
978 |
955 def _write(self, dest, *args, **opts): |
979 def _write(self, dest, *args, **opts): |
956 if self._isbuffered(dest): |
980 if self._isbuffered(dest): |
957 if self._bufferapplylabels: |
981 if self._bufferapplylabels: |
958 label = opts.get(r'label', '') |
982 label = opts.get(r'label', '') |
967 msg = b''.join(args) |
991 msg = b''.join(args) |
968 |
992 |
969 # opencode timeblockedsection because this is a critical path |
993 # opencode timeblockedsection because this is a critical path |
970 starttime = util.timer() |
994 starttime = util.timer() |
971 try: |
995 try: |
972 if dest is self.ferr and not getattr(self.fout, 'closed', False): |
996 if dest is self._ferr and not getattr(self._fout, 'closed', False): |
973 self.fout.flush() |
997 self._fout.flush() |
974 if self._colormode == 'win32': |
998 if self._colormode == 'win32': |
975 # windows color printing is its own can of crab, defer to |
999 # windows color printing is its own can of crab, defer to |
976 # the color module and that is it. |
1000 # the color module and that is it. |
977 color.win32print(self, dest.write, msg, **opts) |
1001 color.win32print(self, dest.write, msg, **opts) |
978 else: |
1002 else: |
980 label = opts.get(r'label', '') |
1004 label = opts.get(r'label', '') |
981 msg = self.label(msg, label) |
1005 msg = self.label(msg, label) |
982 dest.write(msg) |
1006 dest.write(msg) |
983 # stderr may be buffered under win32 when redirected to files, |
1007 # stderr may be buffered under win32 when redirected to files, |
984 # including stdout. |
1008 # including stdout. |
985 if dest is self.ferr and not getattr(self.ferr, 'closed', False): |
1009 if dest is self._ferr and not getattr(self._ferr, 'closed', False): |
986 dest.flush() |
1010 dest.flush() |
987 except IOError as err: |
1011 except IOError as err: |
988 if (dest is self.ferr |
1012 if (dest is self._ferr |
989 and err.errno in (errno.EPIPE, errno.EIO, errno.EBADF)): |
1013 and err.errno in (errno.EPIPE, errno.EIO, errno.EBADF)): |
990 # no way to report the error, so ignore it |
1014 # no way to report the error, so ignore it |
991 return |
1015 return |
992 raise error.StdioError(err) |
1016 raise error.StdioError(err) |
993 finally: |
1017 finally: |
997 def flush(self): |
1021 def flush(self): |
998 # opencode timeblockedsection because this is a critical path |
1022 # opencode timeblockedsection because this is a critical path |
999 starttime = util.timer() |
1023 starttime = util.timer() |
1000 try: |
1024 try: |
1001 try: |
1025 try: |
1002 self.fout.flush() |
1026 self._fout.flush() |
1003 except IOError as err: |
1027 except IOError as err: |
1004 if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF): |
1028 if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF): |
1005 raise error.StdioError(err) |
1029 raise error.StdioError(err) |
1006 finally: |
1030 finally: |
1007 try: |
1031 try: |
1008 self.ferr.flush() |
1032 self._ferr.flush() |
1009 except IOError as err: |
1033 except IOError as err: |
1010 if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF): |
1034 if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF): |
1011 raise error.StdioError(err) |
1035 raise error.StdioError(err) |
1012 finally: |
1036 finally: |
1013 self._blockedtimes['stdio_blocked'] += \ |
1037 self._blockedtimes['stdio_blocked'] += \ |
1253 ''' |
1277 ''' |
1254 i = self.configbool("ui", "interactive") |
1278 i = self.configbool("ui", "interactive") |
1255 if i is None: |
1279 if i is None: |
1256 # some environments replace stdin without implementing isatty |
1280 # some environments replace stdin without implementing isatty |
1257 # usually those are non-interactive |
1281 # usually those are non-interactive |
1258 return self._isatty(self.fin) |
1282 return self._isatty(self._fin) |
1259 |
1283 |
1260 return i |
1284 return i |
1261 |
1285 |
1262 def termwidth(self): |
1286 def termwidth(self): |
1263 '''how wide is the terminal in columns? |
1287 '''how wide is the terminal in columns? |
1291 |
1315 |
1292 i = self.configbool("ui", "formatted") |
1316 i = self.configbool("ui", "formatted") |
1293 if i is None: |
1317 if i is None: |
1294 # some environments replace stdout without implementing isatty |
1318 # some environments replace stdout without implementing isatty |
1295 # usually those are non-interactive |
1319 # usually those are non-interactive |
1296 return self._isatty(self.fout) |
1320 return self._isatty(self._fout) |
1297 |
1321 |
1298 return i |
1322 return i |
1299 |
1323 |
1300 def _readline(self): |
1324 def _readline(self): |
1301 # Replacing stdin/stdout temporarily is a hard problem on Python 3 |
1325 # Replacing stdin/stdout temporarily is a hard problem on Python 3 |
1302 # because they have to be text streams with *no buffering*. Instead, |
1326 # because they have to be text streams with *no buffering*. Instead, |
1303 # we use rawinput() only if call_readline() will be invoked by |
1327 # we use rawinput() only if call_readline() will be invoked by |
1304 # PyOS_Readline(), so no I/O will be made at Python layer. |
1328 # PyOS_Readline(), so no I/O will be made at Python layer. |
1305 usereadline = (self._isatty(self.fin) and self._isatty(self.fout) |
1329 usereadline = (self._isatty(self._fin) and self._isatty(self._fout) |
1306 and procutil.isstdin(self.fin) |
1330 and procutil.isstdin(self._fin) |
1307 and procutil.isstdout(self.fout)) |
1331 and procutil.isstdout(self._fout)) |
1308 if usereadline: |
1332 if usereadline: |
1309 try: |
1333 try: |
1310 # magically add command line editing support, where |
1334 # magically add command line editing support, where |
1311 # available |
1335 # available |
1312 import readline |
1336 import readline |
1324 # When stdin is in binary mode on Windows, it can cause |
1348 # When stdin is in binary mode on Windows, it can cause |
1325 # raw_input() to emit an extra trailing carriage return |
1349 # raw_input() to emit an extra trailing carriage return |
1326 if pycompat.oslinesep == b'\r\n' and line.endswith(b'\r'): |
1350 if pycompat.oslinesep == b'\r\n' and line.endswith(b'\r'): |
1327 line = line[:-1] |
1351 line = line[:-1] |
1328 else: |
1352 else: |
1329 self.fout.write(b' ') |
1353 self._fout.write(b' ') |
1330 self.fout.flush() |
1354 self._fout.flush() |
1331 line = self.fin.readline() |
1355 line = self._fin.readline() |
1332 if not line: |
1356 if not line: |
1333 raise EOFError |
1357 raise EOFError |
1334 line = line.rstrip(pycompat.oslinesep) |
1358 line = line.rstrip(pycompat.oslinesep) |
1335 |
1359 |
1336 return line |
1360 return line |
1341 """ |
1365 """ |
1342 if not self.interactive(): |
1366 if not self.interactive(): |
1343 self.write(msg, ' ', label='ui.prompt') |
1367 self.write(msg, ' ', label='ui.prompt') |
1344 self.write(default or '', "\n", label='ui.promptecho') |
1368 self.write(default or '', "\n", label='ui.promptecho') |
1345 return default |
1369 return default |
1346 self._writenobuf(self.fout, msg, label='ui.prompt') |
1370 self._writenobuf(self._fout, msg, label='ui.prompt') |
1347 self.flush() |
1371 self.flush() |
1348 try: |
1372 try: |
1349 r = self._readline() |
1373 r = self._readline() |
1350 if not r: |
1374 if not r: |
1351 r = default |
1375 r = default |
1409 self.write_err(self.label(prompt or _('password: '), 'ui.prompt')) |
1433 self.write_err(self.label(prompt or _('password: '), 'ui.prompt')) |
1410 # disable getpass() only if explicitly specified. it's still valid |
1434 # disable getpass() only if explicitly specified. it's still valid |
1411 # to interact with tty even if fin is not a tty. |
1435 # to interact with tty even if fin is not a tty. |
1412 with self.timeblockedsection('stdio'): |
1436 with self.timeblockedsection('stdio'): |
1413 if self.configbool('ui', 'nontty'): |
1437 if self.configbool('ui', 'nontty'): |
1414 l = self.fin.readline() |
1438 l = self._fin.readline() |
1415 if not l: |
1439 if not l: |
1416 raise EOFError |
1440 raise EOFError |
1417 return l.rstrip('\n') |
1441 return l.rstrip('\n') |
1418 else: |
1442 else: |
1419 return getpass.getpass('') |
1443 return getpass.getpass('') |
1535 if blockedtag is None: |
1559 if blockedtag is None: |
1536 # Long cmds tend to be because of an absolute path on cmd. Keep |
1560 # Long cmds tend to be because of an absolute path on cmd. Keep |
1537 # the tail end instead |
1561 # the tail end instead |
1538 cmdsuffix = cmd.translate(None, _keepalnum)[-85:] |
1562 cmdsuffix = cmd.translate(None, _keepalnum)[-85:] |
1539 blockedtag = 'unknown_system_' + cmdsuffix |
1563 blockedtag = 'unknown_system_' + cmdsuffix |
1540 out = self.fout |
1564 out = self._fout |
1541 if any(s[1] for s in self._bufferstates): |
1565 if any(s[1] for s in self._bufferstates): |
1542 out = self |
1566 out = self |
1543 with self.timeblockedsection(blockedtag): |
1567 with self.timeblockedsection(blockedtag): |
1544 rc = self._runsystem(cmd, environ=environ, cwd=cwd, out=out) |
1568 rc = self._runsystem(cmd, environ=environ, cwd=cwd, out=out) |
1545 if rc and onerr: |
1569 if rc and onerr: |
1680 if config is None or not self.configbool('devel', config): |
1704 if config is None or not self.configbool('devel', config): |
1681 return |
1705 return |
1682 msg = 'devel-warn: ' + msg |
1706 msg = 'devel-warn: ' + msg |
1683 stacklevel += 1 # get in develwarn |
1707 stacklevel += 1 # get in develwarn |
1684 if self.tracebackflag: |
1708 if self.tracebackflag: |
1685 util.debugstacktrace(msg, stacklevel, self.ferr, self.fout) |
1709 util.debugstacktrace(msg, stacklevel, self._ferr, self._fout) |
1686 self.log('develwarn', '%s at:\n%s' % |
1710 self.log('develwarn', '%s at:\n%s' % |
1687 (msg, ''.join(util.getstackframes(stacklevel)))) |
1711 (msg, ''.join(util.getstackframes(stacklevel)))) |
1688 else: |
1712 else: |
1689 curframe = inspect.currentframe() |
1713 curframe = inspect.currentframe() |
1690 calframe = inspect.getouterframes(curframe, 2) |
1714 calframe = inspect.getouterframes(curframe, 2) |