mercurial/progress.py
changeset 43076 2372284d9457
parent 41143 7b80406b8271
child 43077 687b865b95ad
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
    12 import time
    12 import time
    13 
    13 
    14 from .i18n import _
    14 from .i18n import _
    15 from . import encoding
    15 from . import encoding
    16 
    16 
       
    17 
    17 def spacejoin(*args):
    18 def spacejoin(*args):
    18     return ' '.join(s for s in args if s)
    19     return ' '.join(s for s in args if s)
    19 
    20 
       
    21 
    20 def shouldprint(ui):
    22 def shouldprint(ui):
    21     return not (ui.quiet or ui.plain('progress')) and (
    23     return not (ui.quiet or ui.plain('progress')) and (
    22         ui._isatty(ui.ferr) or ui.configbool('progress', 'assume-tty'))
    24         ui._isatty(ui.ferr) or ui.configbool('progress', 'assume-tty')
       
    25     )
       
    26 
    23 
    27 
    24 def fmtremaining(seconds):
    28 def fmtremaining(seconds):
    25     """format a number of remaining seconds in human readable way
    29     """format a number of remaining seconds in human readable way
    26 
    30 
    27     This will properly display seconds, minutes, hours, days if needed"""
    31     This will properly display seconds, minutes, hours, days if needed"""
    28     if seconds < 60:
    32     if seconds < 60:
    29         # i18n: format XX seconds as "XXs"
    33         # i18n: format XX seconds as "XXs"
    30         return _("%02ds") % (seconds)
    34         return _("%02ds") % seconds
    31     minutes = seconds // 60
    35     minutes = seconds // 60
    32     if minutes < 60:
    36     if minutes < 60:
    33         seconds -= minutes * 60
    37         seconds -= minutes * 60
    34         # i18n: format X minutes and YY seconds as "XmYYs"
    38         # i18n: format X minutes and YY seconds as "XmYYs"
    35         return _("%dm%02ds") % (minutes, seconds)
    39         return _("%dm%02ds") % (minutes, seconds)
    59     years = weeks // 52
    63     years = weeks // 52
    60     weeks -= years * 52
    64     weeks -= years * 52
    61     # i18n: format X years and YY weeks as "XyYYw"
    65     # i18n: format X years and YY weeks as "XyYYw"
    62     return _("%dy%02dw") % (years, weeks)
    66     return _("%dy%02dw") % (years, weeks)
    63 
    67 
       
    68 
    64 # file_write() and file_flush() of Python 2 do not restart on EINTR if
    69 # file_write() and file_flush() of Python 2 do not restart on EINTR if
    65 # the file is attached to a "slow" device (e.g. a terminal) and raise
    70 # the file is attached to a "slow" device (e.g. a terminal) and raise
    66 # IOError. We cannot know how many bytes would be written by file_write(),
    71 # IOError. We cannot know how many bytes would be written by file_write(),
    67 # but a progress text is known to be short enough to be written by a
    72 # but a progress text is known to be short enough to be written by a
    68 # single write() syscall, so we can just retry file_write() with the whole
    73 # single write() syscall, so we can just retry file_write() with the whole
    77         except IOError as err:
    82         except IOError as err:
    78             if err.errno == errno.EINTR:
    83             if err.errno == errno.EINTR:
    79                 continue
    84                 continue
    80             raise
    85             raise
    81 
    86 
       
    87 
    82 class progbar(object):
    88 class progbar(object):
    83     def __init__(self, ui):
    89     def __init__(self, ui):
    84         self.ui = ui
    90         self.ui = ui
    85         self._refreshlock = threading.Lock()
    91         self._refreshlock = threading.Lock()
    86         self.resetstate()
    92         self.resetstate()
    89         self.topics = []
    95         self.topics = []
    90         self.topicstates = {}
    96         self.topicstates = {}
    91         self.starttimes = {}
    97         self.starttimes = {}
    92         self.startvals = {}
    98         self.startvals = {}
    93         self.printed = False
    99         self.printed = False
    94         self.lastprint = time.time() + float(self.ui.config(
   100         self.lastprint = time.time() + float(
    95             'progress', 'delay'))
   101             self.ui.config('progress', 'delay')
       
   102         )
    96         self.curtopic = None
   103         self.curtopic = None
    97         self.lasttopic = None
   104         self.lasttopic = None
    98         self.indetcount = 0
   105         self.indetcount = 0
    99         self.refresh = float(self.ui.config(
   106         self.refresh = float(self.ui.config('progress', 'refresh'))
   100             'progress', 'refresh'))
   107         self.changedelay = max(
   101         self.changedelay = max(3 * self.refresh,
   108             3 * self.refresh, float(self.ui.config('progress', 'changedelay'))
   102                                float(self.ui.config(
   109         )
   103                                    'progress', 'changedelay')))
       
   104         self.order = self.ui.configlist('progress', 'format')
   110         self.order = self.ui.configlist('progress', 'format')
   105         self.estimateinterval = self.ui.configwith(
   111         self.estimateinterval = self.ui.configwith(
   106             float, 'progress', 'estimateinterval')
   112             float, 'progress', 'estimateinterval'
       
   113         )
   107 
   114 
   108     def show(self, now, topic, pos, item, unit, total):
   115     def show(self, now, topic, pos, item, unit, total):
   109         if not shouldprint(self.ui):
   116         if not shouldprint(self.ui):
   110             return
   117             return
   111         termwidth = self.width()
   118         termwidth = self.width()
   167                 self.indetcount += 1
   174                 self.indetcount += 1
   168                 # mod the count by twice the width so we can make the
   175                 # mod the count by twice the width so we can make the
   169                 # cursor bounce between the right and left sides
   176                 # cursor bounce between the right and left sides
   170                 amt = self.indetcount % (2 * progwidth)
   177                 amt = self.indetcount % (2 * progwidth)
   171                 amt -= progwidth
   178                 amt -= progwidth
   172                 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
   179                 bar = (
   173                        ' ' * int(abs(amt)))
   180                     ' ' * int(progwidth - abs(amt))
       
   181                     + '<=>'
       
   182                     + ' ' * int(abs(amt))
       
   183                 )
   174             prog = ''.join(('[', bar, ']'))
   184             prog = ''.join(('[', bar, ']'))
   175             out = spacejoin(head, prog, tail)
   185             out = spacejoin(head, prog, tail)
   176         else:
   186         else:
   177             out = spacejoin(head, tail)
   187             out = spacejoin(head, tail)
   178         self._writeerr('\r' + encoding.trim(out, termwidth))
   188         self._writeerr('\r' + encoding.trim(out, termwidth))
   226             return _('%d %s/sec') % (delta / elapsed, unit)
   236             return _('%d %s/sec') % (delta / elapsed, unit)
   227         return ''
   237         return ''
   228 
   238 
   229     def _oktoprint(self, now):
   239     def _oktoprint(self, now):
   230         '''Check if conditions are met to print - e.g. changedelay elapsed'''
   240         '''Check if conditions are met to print - e.g. changedelay elapsed'''
   231         if (self.lasttopic is None # first time we printed
   241         if (
       
   242             self.lasttopic is None  # first time we printed
   232             # not a topic change
   243             # not a topic change
   233             or self.curtopic == self.lasttopic
   244             or self.curtopic == self.lasttopic
   234             # it's been long enough we should print anyway
   245             # it's been long enough we should print anyway
   235             or now - self.lastprint >= self.changedelay):
   246             or now - self.lastprint >= self.changedelay
       
   247         ):
   236             return True
   248             return True
   237         else:
   249         else:
   238             return False
   250             return False
   239 
   251 
   240     def _calibrateestimate(self, topic, now, pos):
   252     def _calibrateestimate(self, topic, now, pos):
   291                 self.complete()
   303                 self.complete()
   292                 self.resetstate()
   304                 self.resetstate()
   293             # truncate the list of topics assuming all topics within
   305             # truncate the list of topics assuming all topics within
   294             # this one are also closed
   306             # this one are also closed
   295             if topic in self.topics:
   307             if topic in self.topics:
   296                 self.topics = self.topics[:self.topics.index(topic)]
   308                 self.topics = self.topics[: self.topics.index(topic)]
   297                 # reset the last topic to the one we just unwound to,
   309                 # reset the last topic to the one we just unwound to,
   298                 # so that higher-level topics will be stickier than
   310                 # so that higher-level topics will be stickier than
   299                 # lower-level topics
   311                 # lower-level topics
   300                 if self.topics:
   312                 if self.topics:
   301                     self.lasttopic = self.topics[-1]
   313                     self.lasttopic = self.topics[-1]