Selaa lähdekoodia

Merge pull request #1874 from Abogical/cache-progress

Add progress display for cache commit
enkore 8 vuotta sitten
vanhempi
sitoutus
1250b14ce2
2 muutettua tiedostoa jossa 44 lisäystä ja 19 poistoa
  1. 6 0
      src/borg/cache.py
  2. 38 19
      src/borg/helpers.py

+ 6 - 0
src/borg/cache.py

@@ -18,6 +18,7 @@ from .helpers import get_cache_dir
 from .helpers import decode_dict, int_to_bigint, bigint_to_int, bin_to_hex
 from .helpers import format_file_size
 from .helpers import yes
+from .helpers import ProgressIndicatorMessage
 from .item import Item, ArchiveItem
 from .key import PlaintextKey
 from .locking import Lock
@@ -246,7 +247,9 @@ Chunk index:    {0.total_unique_chunks:20d} {0.total_chunks:20d}"""
         """
         if not self.txn_active:
             return
+        pi = ProgressIndicatorMessage()
         if self.files is not None:
+            pi.output('Saving files cache')
             ttl = int(os.environ.get('BORG_FILES_CACHE_TTL', 20))
             with SaveFile(os.path.join(self.path, 'files'), binary=True) as fd:
                 for path_hash, item in self.files.items():
@@ -257,17 +260,20 @@ Chunk index:    {0.total_unique_chunks:20d} {0.total_chunks:20d}"""
                     if entry.age == 0 and bigint_to_int(entry.mtime) < self._newest_mtime or \
                        entry.age > 0 and entry.age < ttl:
                         msgpack.pack((path_hash, entry), fd)
+        pi.output('Saving cache config')
         self.config.set('cache', 'manifest', self.manifest.id_str)
         self.config.set('cache', 'timestamp', self.manifest.timestamp)
         self.config.set('cache', 'key_type', str(self.key.TYPE))
         self.config.set('cache', 'previous_location', self.repository._location.canonical_path())
         with SaveFile(os.path.join(self.path, 'config')) as fd:
             self.config.write(fd)
+        pi.output('Saving chunks cache')
         self.chunks.write(os.path.join(self.path, 'chunks').encode('utf-8'))
         os.rename(os.path.join(self.path, 'txn.active'),
                   os.path.join(self.path, 'txn.tmp'))
         shutil.rmtree(os.path.join(self.path, 'txn.tmp'))
         self.txn_active = False
+        pi.finish()
 
     def rollback(self):
         """Roll back partial and aborted transactions

+ 38 - 19
src/borg/helpers.py

@@ -1210,23 +1210,10 @@ def ellipsis_truncate(msg, space):
     return msg + ' ' * (space - msg_width)
 
 
-class ProgressIndicatorPercent:
+class ProgressIndicatorBase:
     LOGGER = 'borg.output.progress'
 
-    def __init__(self, total=0, step=5, start=0, msg="%3.0f%%"):
-        """
-        Percentage-based progress indicator
-
-        :param total: total amount of items
-        :param step: step size in percent
-        :param start: at which percent value to start
-        :param msg: output message, must contain one %f placeholder for the percentage
-        """
-        self.counter = 0  # 0 .. (total-1)
-        self.total = total
-        self.trigger_at = start  # output next percentage value when reaching (at least) this
-        self.step = step
-        self.msg = msg
+    def __init__(self):
         self.handler = None
         self.logger = logging.getLogger(self.LOGGER)
 
@@ -1248,6 +1235,41 @@ class ProgressIndicatorPercent:
             self.logger.removeHandler(self.handler)
             self.handler.close()
 
+
+def justify_to_terminal_size(message):
+    terminal_space = get_terminal_size(fallback=(-1, -1))[0]
+    # justify only if we are outputting to a terminal
+    if terminal_space != -1:
+        return message.ljust(terminal_space)
+    return message
+
+
+class ProgressIndicatorMessage(ProgressIndicatorBase):
+    def output(self, msg):
+        self.logger.info(justify_to_terminal_size(msg))
+
+    def finish(self):
+        self.output('')
+
+
+class ProgressIndicatorPercent(ProgressIndicatorBase):
+    def __init__(self, total=0, step=5, start=0, msg="%3.0f%%"):
+        """
+        Percentage-based progress indicator
+
+        :param total: total amount of items
+        :param step: step size in percent
+        :param start: at which percent value to start
+        :param msg: output message, must contain one %f placeholder for the percentage
+        """
+        self.counter = 0  # 0 .. (total-1)
+        self.total = total
+        self.trigger_at = start  # output next percentage value when reaching (at least) this
+        self.step = step
+        self.msg = msg
+
+        super().__init__()
+
     def progress(self, current=None, increase=1):
         if current is not None:
             self.counter = current
@@ -1280,10 +1302,7 @@ class ProgressIndicatorPercent:
 
     def output(self, message, justify=True):
         if justify:
-            terminal_space = get_terminal_size(fallback=(-1, -1))[0]
-            # no need to ljust if we're not outputing to a terminal
-            if terminal_space != -1:
-                message = message.ljust(terminal_space)
+            message = justify_to_terminal_size(message)
         self.logger.info(message)
 
     def finish(self):