-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Return exit code for local Windows command #533
Return exit code for local Windows command #533
Conversation
Partly addresses inspec#288 but that issue also requires the stderr to be provided. Signed-off-by: James Stocks <jstocks@chef.io>
Hello james-stocks! Thanks for the pull request! Here is what will happen next:
Thank you for contributing! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @james-stocks 👍
@@ -199,10 +199,12 @@ def start_pipe_server(pipe_name) | |||
$scriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock($command) | |||
try { | |||
$stdout = & $scriptBlock | Out-String | |||
$result = @{ 'stdout' = $stdout ; 'stderr' = ''; 'exitstatus' = 0 } | |||
$exit_code = $LastExitCode | |||
$result = @{ 'stdout' = $stdout ; 'stderr' = ''; 'exitstatus' = $exit_code } | |||
} catch { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only need the exit code but at some point we should fix #288 fully and get stderr for passing scripts and stdout for failing scripts.
This whole section should maybe change because the catch
block only applies to PowerShell scripts that throw
. The catch block isn't entered for PowerShell scripts that "fail" by calling exit n
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the change that's given here, this seems fine - you're not making the lack of STDOUT/STDERR worse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks reasonable as long as you are looking for the last exit code from the most recent Win32 process, and not the last PowerShell command was successful - use $?
for that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was taking the previous code's use of 0
to assume that it meant exit code and not exit status (in spite of the variable name)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looks fine, but could we also get a test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looks fine, but could we also get a test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a powershell expert - I've requested someone with more PowerShell than I to review to look it over.
I'd like a test too - see test/windows/local_test.rb
@@ -199,10 +199,12 @@ def start_pipe_server(pipe_name) | |||
$scriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock($command) | |||
try { | |||
$stdout = & $scriptBlock | Out-String | |||
$result = @{ 'stdout' = $stdout ; 'stderr' = ''; 'exitstatus' = 0 } | |||
$exit_code = $LastExitCode | |||
$result = @{ 'stdout' = $stdout ; 'stderr' = ''; 'exitstatus' = $exit_code } | |||
} catch { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the change that's given here, this seems fine - you're not making the lack of STDOUT/STDERR worse.
@miah @clintoncwolfe I added a test that mimics my own need (running a PS1 script that may or may not work). e.g. if I attempt this test:
it causes this error:
I can put this failing test on a different branch and file an issue for it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good now that we have a couple tests. Thank you.
If you have resources you referenced while you were doing this work, it'd be great if you cited them in a comment somewhere close to the impl. We suck at powershell.
$exit_code = $LastExitCode | ||
if ($exit_code -eq $null) | ||
{ | ||
$exit_code = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This treats an unset $LastExitCode
as 0
.
This is fiddling the result, but it preserves the previous behaviour where we set the exit_code to 0 if nothing went wrong.
I could not do this, but it might break workflow if any current users are testing that 0 is returned for their command.
This runs test fixture scripts. There seems to be an outstanding issue where the command being run cannot directly exit non-zero because it results in a `Input/output error - TerminateProcess (Errno::EIO)` exception. Signed-off-by: James Stocks <jstocks@chef.io>
Previously local Windows commands hardcoded the exit code as 0. After changing this to get the real exit code; there are cases where LASTEXITCODE is not set and is `$null`. `$null` is probably the correct value to reflect in this case; but to maintain compatibility with previous versions of train that returned 0, this commit has train return 0 when LASTEXITCODE is `$null` Signed-off-by: James Stocks <jstocks@chef.io>
d767739
to
a2b30f7
Compare
@zenspider good call - I added 1 more unit test and a code comment to define the desired behaviour. *note potential confusing behaviour here - To represent this properly, Windows and Linux might not be able to share a uniform |
Make sure the behaviour of Windows exit status is well defined. Signed-off-by: James Stocks <jstocks@chef.io>
a9b2955
to
79aa959
Compare
Code Climate has analyzed commit 79aa959 and detected 4 issues on this pull request. Here's the issue category breakdown:
View more on Code Climate. |
@@ -146,6 +146,12 @@ def initialize(powershell_cmd = "powershell") | |||
raise PipeError if @pipe.nil? | |||
end | |||
|
|||
# @param cmd The command to execute | |||
# @return Local::ComandResult with stdout, stderr and exitstatus | |||
# Note that exitstatus ($?) in PowerShell is boolean, but we use a numeric exit code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Climate says these comment lines are too long; but the Rakefile rubocop task doesn't mind them.
I'd rather have them this length for human readability. Do I need to shorten them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: James Stocks jstocks@chef.io
Description
The exit code might not be 0 for a script that does not
throw
a PowerShell exception. We should get the actual exit code and return it.Note that PowerShell has a
$?
which is boolean as well as a numeric last exit code. The variable name train is usingexitstatus
is ambiguous on which it represents, maybe.Related Issue
Partly addresses #288 but that issue also requires the stderr to be provided.
Types of changes
If anyone is currently depending on the inaccurate 0 and 1 exit codes then they will get different behaviour when train starts returning the real exit code.
Checklist: