Mute progress animation while Git is running so it doesn't overwrite credential prompts.
BUG=https://code.google.com/p/dart/issues/detail?id=21839
[email protected]
Review URL: https://codereview.chromium.org//845543003
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge@42722 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/lib/src/git.dart b/lib/src/git.dart
index 2c522eb..53d69d8 100644
--- a/lib/src/git.dart
+++ b/lib/src/git.dart
@@ -50,10 +50,14 @@
"Please ensure Git is correctly installed.");
}
+ log.muteProgress();
return runProcess(_gitCommand, args, workingDir: workingDir,
environment: environment).then((result) {
if (!result.success) throw new GitException(args, result.stderr.join("\n"));
+
return result.stdout;
+ }).whenComplete(() {
+ log.unmuteProgress();
});
}
diff --git a/lib/src/log.dart b/lib/src/log.dart
index 1462712..107970b 100644
--- a/lib/src/log.dart
+++ b/lib/src/log.dart
@@ -42,9 +42,6 @@
/// [recordTranscript()] is called.
Transcript<Entry> _transcript;
-/// All currently-running progress indicators.
-final _progresses = new Set<Progress>();
-
/// The currently-animated progress indicator, if any.
///
/// This will also be in [_progresses].
@@ -374,13 +371,10 @@
/// information will only be visible at [Level.FINE].
Future progress(String message, Future callback(), {bool fine: false}) {
_stopProgress();
+
var progress = new Progress(message, fine: fine);
_animatedProgress = progress;
- _progresses.add(progress);
- return callback().whenComplete(() {
- progress.stop();
- _progresses.remove(progress);
- });
+ return callback().whenComplete(progress.stop);
}
/// Stops animating the running progress indicator, if currently running.
@@ -389,6 +383,31 @@
_animatedProgress = null;
}
+/// The number of outstanding calls to [muteProgress] that have not been unmuted
+/// yet.
+int _numMutes = 0;
+
+/// Whether progress animation should be muted or not.
+bool get isMuted => _numMutes > 0;
+
+/// Stops animating any ongoing progress.
+///
+/// This is called before spawning Git since Git sometimes writes directly to
+/// the terminal to ask for login credentials, which would then get overwritten
+/// by the progress animation.
+///
+/// Each call to this must be paired with a call to [unmuteProgress].
+void muteProgress() {
+ _numMutes++;
+}
+
+/// Resumes animating any ongoing progress once all calls to [muteProgress]
+/// have made their matching [unmuteProgress].
+void unmuteProgress() {
+ assert(_numMutes > 0);
+ _numMutes--;
+}
+
/// Wraps [text] in the ANSI escape codes to make it bold when on a platform
/// that supports that.
///
diff --git a/lib/src/progress.dart b/lib/src/progress.dart
index 6c0ffdc..5029f61 100644
--- a/lib/src/progress.dart
+++ b/lib/src/progress.dart
@@ -48,10 +48,11 @@
return;
}
- _update();
_timer = new Timer.periodic(new Duration(milliseconds: 100), (_) {
_update();
});
+
+ _update();
}
/// Stops the progress indicator.
@@ -88,11 +89,11 @@
/// Refreshes the progress line.
void _update() {
+ if (log.isMuted) return;
+
stdout.write(log.format("\r$_message... "));
// Show the time only once it gets noticeably long.
- if (_stopwatch.elapsed.inSeconds > 0) {
- stdout.write(log.gray(_time));
- }
+ if (_stopwatch.elapsed.inSeconds > 0) stdout.write("${log.gray(_time)} ");
}
}