From 78e87dbe6c5d3c0effed5d5fd747a8175d24c78d Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 2 Jan 2016 12:05:01 -0600 Subject: [PATCH 1/4] (GH-8) PowerShell host execution improvements - In a terminating error, write the script stack trace if available - If running with debug, output the stacktrace. - Empty WriteLine() should write out an empty line in the log - If the script times out, throw the cancellation token. --- .../services/PowershellService.cs | 19 ++++++++++++++++++- .../infrastructure/commands/Execute.cs | 10 ++++++++-- .../powershell/PoshHostUserInterface.cs | 2 +- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/PowershellService.cs b/src/chocolatey/infrastructure.app/services/PowershellService.cs index 140756815d..ab652db687 100644 --- a/src/chocolatey/infrastructure.app/services/PowershellService.cs +++ b/src/chocolatey/infrastructure.app/services/PowershellService.cs @@ -450,10 +450,27 @@ private PowerShellExecutionResults run_host(ChocolateyConfiguration config, stri { pipeline.Invoke(); } + catch (RuntimeException ex) + { + var errorStackTrace = ex.StackTrace; + var record = ex.ErrorRecord; + if (record != null) + { + // not available in v1 + //errorStackTrace = record.ScriptStackTrace; + var scriptStackTrace = record.GetType().GetProperty("ScriptStackTrace"); + if (scriptStackTrace != null) + { + var scriptError = scriptStackTrace.GetValue(record, null).to_string(); + if (!string.IsNullOrWhiteSpace(scriptError)) errorStackTrace = scriptError; + } + } + this.Log().Error("ERROR: {0}{1}".format_with(ex.Message, !config.Debug ? string.Empty : "{0} {1}".format_with(Environment.NewLine,errorStackTrace))); + } catch (Exception ex) { // Unfortunately this doesn't print line number and character. It might be nice to get back to those items unless it involves tons of work. - this.Log().Error("ERROR: {0}".format_with(ex.Message)); //, !config.Debug ? string.Empty : "{0} {1}".format_with(Environment.NewLine,ex.StackTrace))); + this.Log().Error("ERROR: {0}{1}".format_with(ex.Message, !config.Debug ? string.Empty : "{0} {1}".format_with(Environment.NewLine,ex.StackTrace))); } if (pipeline.PipelineStateInfo != null) diff --git a/src/chocolatey/infrastructure/commands/Execute.cs b/src/chocolatey/infrastructure/commands/Execute.cs index a64640d15e..0e0455ee6a 100644 --- a/src/chocolatey/infrastructure/commands/Execute.cs +++ b/src/chocolatey/infrastructure/commands/Execute.cs @@ -16,6 +16,7 @@ namespace chocolatey.infrastructure.commands { using System; + using System.Threading; using System.Threading.Tasks; /// @@ -61,10 +62,15 @@ public T command(Func function, T timeoutDefaultValue) { if (function == null) return timeoutDefaultValue; - var task = Task.Factory.StartNew(function); + var cancelToken = new CancellationTokenSource(); + cancelToken.Token.ThrowIfCancellationRequested(); + var task = Task.Factory.StartNew(function, cancelToken.Token); //,TaskCreationOptions.LongRunning| TaskCreationOptions.AttachedToParent); + task.Wait(_timespan); - if (task.IsCompleted) return task.Result; + + cancelToken.Cancel(); + return timeoutDefaultValue; //T result = timeoutDefaultValue; diff --git a/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs b/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs index 38ce8c2d6e..8e62ba155e 100644 --- a/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs +++ b/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs @@ -84,7 +84,7 @@ public override void Write(ConsoleColor foregroundColor, ConsoleColor background public override void WriteLine() { - base.WriteLine(); + this.Log().Info(""); } public override void WriteLine(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value) From ab82a7877718548bbe6af297083e1226ab2743f3 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 2 Jan 2016 12:07:24 -0600 Subject: [PATCH 2/4] (GH-525) Improve Write-Progress As a continuation of GH-8, download progress should be written inline, but needs some improvements: - Write an empty line when it has completed so that the next log item doesn't write to the same line. - Improve the content of the progress message with both percentage and the status message. --- .../powershell/PoshHostUserInterface.cs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs b/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs index 8e62ba155e..40d0f548bd 100644 --- a/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs +++ b/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs @@ -118,14 +118,27 @@ public override void WriteDebugLine(string message) this.Log().Debug(message); } + private bool hasLoggedStartProgress = false; + private bool hasLoggedFinalProgress = false; public override void WriteProgress(long sourceId, ProgressRecord record) - { + { if (record.PercentComplete == -1) return; - - if (record.PercentComplete == 100) this.Log().Debug(() => "Progress: 100%{0}".format_with(" ".PadRight(20))); + if (hasLoggedFinalProgress) return; + if (!hasLoggedStartProgress) + { + hasLoggedStartProgress = true; + this.Log().Debug(record.Activity); + } // http://stackoverflow.com/a/888569/18475 - Console.Write("\rProgress: {0}%{1}".format_with(record.PercentComplete, " ".PadRight(20))); + Console.Write("\rProgress: {0}% - {1}".format_with(record.PercentComplete.to_string(), record.StatusDescription.PadRight(50, ' '))); + + if (record.PercentComplete == 100 && !hasLoggedFinalProgress) + { + hasLoggedFinalProgress = true; + this.Log().Info(""); + this.Log().Info(record.StatusDescription.Replace("Saving","Finished downloading. Saved")); + } } public override void WriteVerboseLine(string message) From 16d769ea63b14d2c229d523334e3deb11c807a57 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 2 Jan 2016 12:55:53 -0600 Subject: [PATCH 3/4] (GH-525) Improve write-progress The write-progress doesn't always write the 100% line out, so have Get-WebFile state that it has finished downloading the file. --- src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 | 4 +++- .../infrastructure/powershell/PoshHostUserInterface.cs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 b/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 index 142edd6009..e3c64e025b 100644 --- a/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 @@ -162,10 +162,12 @@ param( } if ($total -eq $goal) { - Write-Progress "Completed download of $url." "Completed a total of $total bytes of $fileName" -id 0 -Completed + Write-Progress "Completed download of $url." "Completed download of $fileName ($goalFormatted)." -id 0 -Completed } } } while ($count -gt 0) + Write-Host "" + Write-Host "Download of $([System.IO.Path]::GetFileName($fileName)) ($goalFormatted) completed." } catch { throw $_.Exception } finally { diff --git a/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs b/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs index 40d0f548bd..6e6ee21814 100644 --- a/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs +++ b/src/chocolatey/infrastructure/powershell/PoshHostUserInterface.cs @@ -136,8 +136,8 @@ public override void WriteProgress(long sourceId, ProgressRecord record) if (record.PercentComplete == 100 && !hasLoggedFinalProgress) { hasLoggedFinalProgress = true; - this.Log().Info(""); - this.Log().Info(record.StatusDescription.Replace("Saving","Finished downloading. Saved")); + //this.Log().Info(""); + //this.Log().Info(record.StatusDescription.Replace("Saving","Finished downloading. Saved")); } } From dbf0d2292bcc6de84751098c579283e6b7873b5f Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Sat, 2 Jan 2016 12:56:38 -0600 Subject: [PATCH 4/4] (specs) start setting up host for executing specs Right now when run from code, the powershell host seems to block forever. --- src/chocolatey.tests.integration/Scenario.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chocolatey.tests.integration/Scenario.cs b/src/chocolatey.tests.integration/Scenario.cs index 3a5b5b60d5..1b0f30b10f 100644 --- a/src/chocolatey.tests.integration/Scenario.cs +++ b/src/chocolatey.tests.integration/Scenario.cs @@ -128,6 +128,9 @@ private static ChocolateyConfiguration baseline_configuration() config.Verbose = false; config.Input = config.PackageNames = string.Empty; config.ListCommand.LocalOnly = false; + //config.Features.UsePowerShellHost = true; + //config.Features.AutoUninstaller = true; + //config.Features.CheckSumFiles = true; return config; }