Sfoglia il codice sorgente

Fixed repository check progress reporting.

Jonas Borgström 11 anni fa
parent
commit
5abd254a11
2 ha cambiato i file con 18 aggiunte e 11 eliminazioni
  1. 2 3
      attic/archiver.py
  2. 16 8
      attic/repository.py

+ 2 - 3
attic/archiver.py

@@ -66,8 +66,7 @@ class Archiver:
         if args.progress is None:
             args.progress = is_a_terminal(sys.stdout) or args.verbose
         if not repository.check(progress=args.progress):
-            if args.progress:
-                print('No problems found', file=sys.stderr)
+            self.exit_code = 1
         return self.exit_code
 
     def do_change_passphrase(self, args):
@@ -372,7 +371,7 @@ class Archiver:
                                help='select encryption method')
 
         check_epilog = """
-        Progress status will be reported on the standard output stream by default when
+        Progress status will be reported on the standard error stream by default when
         it is attached to a terminal. Any problems found are printed to the standard error
         stream and the command will have a non zero exit code.
         """

+ 16 - 8
attic/repository.py

@@ -6,6 +6,7 @@ import re
 import shutil
 import struct
 import sys
+import time
 from zlib import crc32
 
 from .hashindex import NSIndex
@@ -205,33 +206,40 @@ class Repository(object):
         This method verifies all segment checksums and makes sure
         the index is consistent with the data stored in the segments.
         """
+        progress_time = None
         error_found = False
-        def report_error(msg):
+        def report_progress(msg, error=False):
             nonlocal error_found
-            error_found = True
-            print(msg, file=sys.stderr)
+            if error:
+                error_found = True
+            if error or progress:
+                print(msg, file=sys.stderr, flush=True)
         seen = set()
         for segment, filename in self.io._segment_names():
             if progress:
-                print('Checking segment {}/{}'.format(segment, self.io.head))
+                if int(time.time()) != progress_time:
+                    progress_time = int(time.time())
+                    report_progress('Checking segment {}/{}'.format(segment, self.io.head))
             try:
                 objects = list(self.io.iter_objects(segment))
             except (IntegrityError, struct.error):
-                report_error('Error reading segment {}'.format(segment))
+                report_progress('Error reading segment {}'.format(segment), error=True)
                 objects = []
             for tag, key, offset in objects:
                 if tag == TAG_PUT:
                     if key in seen:
-                        report_error('Key found in more than one segment. Segment={}, key={}'.format(segment, hexlify(key)))
+                        report_progress('Key found in more than one segment. Segment={}, key={}'.format(segment, hexlify(key)), error=True)
                     seen.add(key)
                     if self.index.get(key, (0, 0)) != (segment, offset):
-                        report_error('Index vs segment header mismatch. Segment={}, key={}'.format(segment, hexlify(key)))
+                        report_progress('Index vs segment header mismatch. Segment={}, key={}'.format(segment, hexlify(key)), error=True)
                 elif tag == TAG_COMMIT:
                     continue
                 else:
                     raise self.RepositoryCheckFailed(self.path, 'Unexpected tag {} in segment {}'.format(tag, segment))
         if len(self.index) != len(seen):
-            report_error('Index object count mismatch. {} != {}'.format(len(self.index), len(seen)))
+            report_progress('Index object count mismatch. {} != {}'.format(len(self.index), len(seen)), error=True)
+        if not error_found:
+            report_progress('Check complete, no errors found.')
         return not error_found
 
     def rollback(self):