Explorar el Código

Merge pull request #9055 from ThomasWaldmann/non-tty-progress-1.4

improved tty-less progress reporting (1.4-maint)
TW hace 6 días
padre
commit
cb19d62057
Se han modificado 2 ficheros con 40 adiciones y 6 borrados
  1. 13 2
      src/borg/archive.py
  2. 27 4
      src/borg/testsuite/archive.py

+ 13 - 2
src/borg/archive.py

@@ -141,9 +141,12 @@ class Statistics:
     def csize_fmt(self):
         return format_file_size(self.csize, iec=self.iec)
 
+    PROGRESS_FMT = '{0.osize_fmt} O {0.csize_fmt} C {0.usize_fmt} D {0.nfiles} N '
+
     def show_progress(self, item=None, final=False, stream=None, dt=None):
         now = time.monotonic()
         if dt is None or now - self.last_progress > dt:
+            stream = stream or sys.stderr
             self.last_progress = now
             if self.output_json:
                 if not final:
@@ -158,10 +161,18 @@ class Statistics:
                 })
                 msg = json.dumps(data)
                 end = '\n'
+            elif not stream.isatty():
+                # if we don't output to a terminal, use normal linefeeds and assume line length is unlimited
+                if not final:
+                    msg = self.PROGRESS_FMT.format(self)
+                    msg += remove_surrogates(item.path) if item else ''
+                else:
+                    msg = ''
+                end = '\n'
             else:
                 columns, lines = get_terminal_size()
                 if not final:
-                    msg = '{0.osize_fmt} O {0.csize_fmt} C {0.usize_fmt} D {0.nfiles} N '.format(self)
+                    msg = self.PROGRESS_FMT.format(self)
                     path = remove_surrogates(item.path) if item else ''
                     space = columns - swidth(msg)
                     if space < 12:
@@ -172,7 +183,7 @@ class Statistics:
                 else:
                     msg = ' ' * columns
                 end = '\r'
-            print(msg, end=end, file=stream or sys.stderr, flush=True)
+            print(msg, end=end, file=stream, flush=True)
 
 
 def is_special(mode):

+ 27 - 4
src/borg/testsuite/archive.py

@@ -32,27 +32,50 @@ def test_stats_basic(stats):
     assert stats.usize == 10
 
 
-def tests_stats_progress(stats, monkeypatch, columns=80):
+def tests_stats_progress_tty(stats, monkeypatch, columns=80):
+    class TTYStringIO(StringIO):
+        def isatty(self):
+            return True
+
     monkeypatch.setenv('COLUMNS', str(columns))
-    out = StringIO()
+    out = TTYStringIO()
     stats.show_progress(stream=out)
     s = '20 B O 10 B C 10 B D 0 N '
     buf = ' ' * (columns - len(s))
     assert out.getvalue() == s + buf + "\r"
 
-    out = StringIO()
+    out = TTYStringIO()
     stats.update(10**3, 0, unique=False)
     stats.show_progress(item=Item(path='foo'), final=False, stream=out)
     s = '1.02 kB O 10 B C 10 B D 0 N foo'
     buf = ' ' * (columns - len(s))
     assert out.getvalue() == s + buf + "\r"
-    out = StringIO()
+    out = TTYStringIO()
     stats.show_progress(item=Item(path='foo'*40), final=False, stream=out)
     s = '1.02 kB O 10 B C 10 B D 0 N foofoofoofoofoofoofoofo...oofoofoofoofoofoofoofoofoo'
     buf = ' ' * (columns - len(s))
     assert out.getvalue() == s + buf + "\r"
 
 
+def tests_stats_progress_file(stats, monkeypatch):
+    out = StringIO()
+    stats.show_progress(stream=out)
+    s = '20 B O 10 B C 10 B D 0 N '
+    assert out.getvalue() == s + "\n"
+
+    out = StringIO()
+    stats.update(10**3, 0, unique=False)
+    path = 'foo'
+    stats.show_progress(item=Item(path=path), final=False, stream=out)
+    s = f'1.02 kB O 10 B C 10 B D 0 N {path}'
+    assert out.getvalue() == s + "\n"
+    out = StringIO()
+    path = 'foo' * 40
+    stats.show_progress(item=Item(path=path), final=False, stream=out)
+    s = f'1.02 kB O 10 B C 10 B D 0 N {path}'
+    assert out.getvalue() == s + "\n"
+
+
 def test_stats_format(stats):
     assert str(stats) == """\
 This archive:                   20 B                 10 B                 10 B"""