From 4d57a8f2ce974937052fa5fe55ef2eacfb8e9fd1 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 22 Sep 2020 14:42:05 +0100 Subject: [PATCH 1/4] gitauth: ensure auth prompts can be shown over TTY Ensure authentication prompts shown by Git and any configured credential helpers can write to the terminal/TTY and capture information. Explicitly pass the userInteractive=true argument down the call stack to the construction of the Git process, and move the setting of GIT_TERMINAL_PROMPT=0 into the if-not-user-interactive block. --- Scalar.Common/Git/GitProcess.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Scalar.Common/Git/GitProcess.cs b/Scalar.Common/Git/GitProcess.cs index 93a2d180fd..6f41731366 100644 --- a/Scalar.Common/Git/GitProcess.cs +++ b/Scalar.Common/Git/GitProcess.cs @@ -305,7 +305,8 @@ public virtual bool TryGetCredential( Result gitCredentialOutput = this.InvokeGitAgainstDotGitFolder( GenerateCredentialVerbCommand("fill"), stdin => stdin.Write($"url={repoUrl}\n\n"), - parseStdOutLine: null); + parseStdOutLine: null, + userInteractive: true); if (gitCredentialOutput.ExitCodeIsFailure) { @@ -614,11 +615,11 @@ private Process GetGitProcess( } } - processInfo.EnvironmentVariables["GIT_TERMINAL_PROMPT"] = "0"; processInfo.EnvironmentVariables["GCM_VALIDATE"] = "0"; if (!userInteractive) { + processInfo.EnvironmentVariables["GIT_TERMINAL_PROMPT"] = "0"; processInfo.EnvironmentVariables["GCM_INTERACTIVE"] = "Never"; } @@ -844,7 +845,8 @@ private Result InvokeGitAgainstDotGitFolder( string command, Action writeStdIn, Action parseStdOutLine, - string gitObjectsDirectory = null) + string gitObjectsDirectory = null, + bool userInteractive = true) { // This git command should not need/use the working directory of the repo. // Run git.exe in Environment.SystemDirectory to ensure the git.exe process @@ -857,7 +859,8 @@ private Result InvokeGitAgainstDotGitFolder( writeStdIn: writeStdIn, parseStdOutLine: parseStdOutLine, timeoutMs: -1, - gitObjectsDirectory: gitObjectsDirectory); + gitObjectsDirectory: gitObjectsDirectory, + userInteractive: userInteractive); } public class Result From 4183579d858e8fc633804834afc2be1f981e48b8 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 22 Sep 2020 14:40:27 +0100 Subject: [PATCH 2/4] console: remove progress spinners from all commands Remove all progress spinners from all commands. Git may need to prompt for authentication or other prompts during a command invocation, and the spinner interferes with this. --- Scalar.Common/ConsoleHelper.cs | 71 +++----------------------- Scalar.Upgrader/UpgradeOrchestrator.cs | 3 +- Scalar/CommandLine/ScalarVerb.cs | 4 +- 3 files changed, 8 insertions(+), 70 deletions(-) diff --git a/Scalar.Common/ConsoleHelper.cs b/Scalar.Common/ConsoleHelper.cs index 9f73ad8e30..f9559b5d55 100644 --- a/Scalar.Common/ConsoleHelper.cs +++ b/Scalar.Common/ConsoleHelper.cs @@ -16,9 +16,7 @@ public enum ActionResult public static bool ShowStatusWhileRunning( Func action, string message, - TextWriter output, - bool showSpinner, - int initialDelayMs = 0) + TextWriter output) { Func actionResultAction = () => @@ -29,9 +27,7 @@ public static bool ShowStatusWhileRunning( ActionResult result = ShowStatusWhileRunning( actionResultAction, message, - output, - showSpinner, - initialDelayMs: initialDelayMs); + output); return result == ActionResult.Success; } @@ -39,78 +35,23 @@ public static bool ShowStatusWhileRunning( public static ActionResult ShowStatusWhileRunning( Func action, string message, - TextWriter output, - bool showSpinner, - int initialDelayMs) + TextWriter output) { ActionResult result = ActionResult.Failure; bool initialMessageWritten = false; try { - if (!showSpinner) - { - output.Write(message + "..."); - initialMessageWritten = true; - result = action(); - } - else - { - ManualResetEvent actionIsDone = new ManualResetEvent(false); - bool isComplete = false; - Thread spinnerThread = new Thread( - () => - { - int retries = 0; - char[] waiting = { '\u2014', '\\', '|', '/' }; - - while (!isComplete) - { - if (retries == 0) - { - actionIsDone.WaitOne(initialDelayMs); - } - else - { - output.Write("\r{0}...{1}", message, waiting[(retries / 2) % waiting.Length]); - initialMessageWritten = true; - actionIsDone.WaitOne(100); - } - - retries++; - } - if (initialMessageWritten) - { - // Clear out any trailing waiting character - output.Write("\r{0}...", message); - } - }); - spinnerThread.Start(); - - try - { - result = action(); - } - finally - { - isComplete = true; - - actionIsDone.Set(); - spinnerThread.Join(); - } - } + output.WriteLine(message + "..."); + initialMessageWritten = true; + result = action(); } finally { switch (result) { case ActionResult.Success: - if (initialMessageWritten) - { - output.WriteLine("Succeeded"); - } - break; case ActionResult.CompletedWithErrors: diff --git a/Scalar.Upgrader/UpgradeOrchestrator.cs b/Scalar.Upgrader/UpgradeOrchestrator.cs index 3afdc3d23c..4cdcc3d5f7 100644 --- a/Scalar.Upgrader/UpgradeOrchestrator.cs +++ b/Scalar.Upgrader/UpgradeOrchestrator.cs @@ -143,8 +143,7 @@ protected bool LaunchInsideSpinner(Func method, string message) return ConsoleHelper.ShowStatusWhileRunning( method, message, - this.output, - this.output == Console.Out && !ScalarPlatform.Instance.IsConsoleOutputRedirectedToFile()); + this.output); } private JsonTracer CreateTracer() diff --git a/Scalar/CommandLine/ScalarVerb.cs b/Scalar/CommandLine/ScalarVerb.cs index 15e0216637..4e2538f913 100644 --- a/Scalar/CommandLine/ScalarVerb.cs +++ b/Scalar/CommandLine/ScalarVerb.cs @@ -157,9 +157,7 @@ protected bool ShowStatusWhileRunning( return ConsoleHelper.ShowStatusWhileRunning( action, message, - this.Output, - showSpinner: !this.Unattended && this.Output == Console.Out && !ScalarPlatform.Instance.IsConsoleOutputRedirectedToFile(), - initialDelayMs: 0); + this.Output); } protected GitAuthentication.Result TryAuthenticate(ITracer tracer, ScalarEnlistment enlistment, out string authErrorMessage) From 6323364156d45d5a19cba543b3c5dd656e214c33 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 22 Sep 2020 14:48:59 +0100 Subject: [PATCH 3/4] clone: add final "Complete" message after clone After the clone completes, add a final success (or failure) message. --- Scalar/CommandLine/CloneVerb.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Scalar/CommandLine/CloneVerb.cs b/Scalar/CommandLine/CloneVerb.cs index 8216996848..f4bed49f59 100644 --- a/Scalar/CommandLine/CloneVerb.cs +++ b/Scalar/CommandLine/CloneVerb.cs @@ -309,6 +309,15 @@ private Result DoClone(string fullEnlistmentRootPathParameter, string normalized cloneResult = this.TryRegisterRepo(); } + if (cloneResult.Success) + { + this.Output.WriteLine("Complete!"); + } + else + { + this.Output.WriteLine("Complete with errors."); + } + return cloneResult; } From 6ac3f9e8592039dc2676a0daa6fe7ea9f2da2630 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 22 Sep 2020 14:51:53 +0100 Subject: [PATCH 4/4] Update readme with new output --- Readme.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index 084f37fa5d..84a40947f7 100644 --- a/Readme.md +++ b/Readme.md @@ -120,13 +120,14 @@ Clone parameters: Local Cache: C:\.scalarCache Destination: C:\_git\ForTests FullClone: False -Authenticating...Succeeded -Querying remote for config...Succeeded +Authenticating... +Querying remote for config... Using cache server: None (https://dev.azure.com/gvfs/ci/_git/ForTests) -Cloning...Succeeded -Fetching commits and trees from origin (no cache server)...Succeeded -Configuring Watchman...Succeeded. -Validating repo...Succeeded +Cloning... +Fetching commits and trees from origin (no cache server)... +Configuring Watchman... +Validating repo... +Complete! ``` Then, navigate into the repository's `src` directory.