summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2019-08-26 15:22:36 -0400
committerMike Frysinger <vapier@google.com>2019-09-13 02:58:07 +0000
commit70d861fa2938d1f8f84eb8ce76ebc9f719197934 (patch)
tree614262a60162e3595c5d503f9d030e2e522bd32f
parent9100f7fadd6cf67cb37421247c6cc3d2357b4f49 (diff)
downloadgit-repo-70d861fa2938d1f8f84eb8ce76ebc9f719197934.tar.gz
sync: improve output with intermingled progress bars and status
When displaying progress bars, we use \r to reset the cursor to the start of the line before showing the new update. This assumes the new line will fully erase whatever was displayed there previously. The "done" codepath tries to handle this by including a few extra spaces at the end of the message to "white out" what was there. Lets replace that hack with the standard ECMA escape sequence that clears the current line completely. This is the CSI "erase in line" sequence that the terminal will use to delete all content. The \r is still needed to move the cursor to the start of the line. Using this sequence should be OK since we're already assuming the terminal is ECMA compliant with our use of coloring sequences. We also put the \r after the CSI sequence on the off chance the terminal can't process it and displays a few bytes of garbage. The other improvement is to the syncbuffer API. When it dumps its status information, it almost always comes after a progress bar update which leads to confusing comingled output. Something like: Fetching projects: 100% (2/2) error: src/platform2/: branch ... Since the progress bar is "throw away", have the syncbuffer reset the current output to the start of the line before showing whatever messages it has queued. Bug: https://crbug.com/gerrit/11293 Change-Id: I6544d073fe993d98ee7e91fca5e501ba5fecfe4c Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/236615 Reviewed-by: David Pursehouse <dpursehouse@collab.net> Tested-by: Mike Frysinger <vapier@google.com>
-rw-r--r--progress.py17
-rwxr-xr-xproject.py6
2 files changed, 19 insertions, 4 deletions
diff --git a/progress.py b/progress.py
index 7d4f71f1..1eff04ac 100644
--- a/progress.py
+++ b/progress.py
@@ -21,6 +21,11 @@ from repo_trace import IsTrace
21 21
22_NOT_TTY = not os.isatty(2) 22_NOT_TTY = not os.isatty(2)
23 23
24# This will erase all content in the current line (wherever the cursor is).
25# It does not move the cursor, so this is usually followed by \r to move to
26# column 0.
27CSI_ERASE_LINE = '\x1b[2K'
28
24class Progress(object): 29class Progress(object):
25 def __init__(self, title, total=0, units='', print_newline=False, 30 def __init__(self, title, total=0, units='', print_newline=False,
26 always_print_percentage=False): 31 always_print_percentage=False):
@@ -47,7 +52,8 @@ class Progress(object):
47 return 52 return
48 53
49 if self._total <= 0: 54 if self._total <= 0:
50 sys.stderr.write('\r%s: %d, ' % ( 55 sys.stderr.write('%s\r%s: %d,' % (
56 CSI_ERASE_LINE,
51 self._title, 57 self._title,
52 self._done)) 58 self._done))
53 sys.stderr.flush() 59 sys.stderr.flush()
@@ -56,7 +62,8 @@ class Progress(object):
56 62
57 if self._lastp != p or self._always_print_percentage: 63 if self._lastp != p or self._always_print_percentage:
58 self._lastp = p 64 self._lastp = p
59 sys.stderr.write('\r%s: %3d%% (%d%s/%d%s)%s' % ( 65 sys.stderr.write('%s\r%s: %3d%% (%d%s/%d%s)%s' % (
66 CSI_ERASE_LINE,
60 self._title, 67 self._title,
61 p, 68 p,
62 self._done, self._units, 69 self._done, self._units,
@@ -69,13 +76,15 @@ class Progress(object):
69 return 76 return
70 77
71 if self._total <= 0: 78 if self._total <= 0:
72 sys.stderr.write('\r%s: %d, done. \n' % ( 79 sys.stderr.write('%s\r%s: %d, done.\n' % (
80 CSI_ERASE_LINE,
73 self._title, 81 self._title,
74 self._done)) 82 self._done))
75 sys.stderr.flush() 83 sys.stderr.flush()
76 else: 84 else:
77 p = (100 * self._done) / self._total 85 p = (100 * self._done) / self._total
78 sys.stderr.write('\r%s: %3d%% (%d%s/%d%s), done. \n' % ( 86 sys.stderr.write('%s\r%s: %3d%% (%d%s/%d%s), done.\n' % (
87 CSI_ERASE_LINE,
79 self._title, 88 self._title,
80 p, 89 p,
81 self._done, self._units, 90 self._done, self._units,
diff --git a/project.py b/project.py
index 4076bc5d..03a75f49 100755
--- a/project.py
+++ b/project.py
@@ -39,6 +39,7 @@ from error import GitError, HookError, UploadError, DownloadError
39from error import ManifestInvalidRevisionError 39from error import ManifestInvalidRevisionError
40from error import NoManifestException 40from error import NoManifestException
41import platform_utils 41import platform_utils
42import progress
42from repo_trace import IsTrace, Trace 43from repo_trace import IsTrace, Trace
43 44
44from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M 45from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M
@@ -3113,6 +3114,11 @@ class SyncBuffer(object):
3113 return True 3114 return True
3114 3115
3115 def _PrintMessages(self): 3116 def _PrintMessages(self):
3117 if self._messages or self._failures:
3118 if os.isatty(2):
3119 self.out.write(progress.CSI_ERASE_LINE)
3120 self.out.write('\r')
3121
3116 for m in self._messages: 3122 for m in self._messages:
3117 m.Print(self) 3123 m.Print(self)
3118 for m in self._failures: 3124 for m in self._failures: