-
Notifications
You must be signed in to change notification settings - Fork 212
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
Extend version command to help troubleshoot porter #642
Conversation
@carolynvs am I on the right path |
@phillipahereza Yes, this is what I was looking for. 👍 Once you are ready for a review, just take the PR out of draft, by clicking the button "Ready for Review" or maybe it's called "Request Reviews". Then I'll go over it and provide detailed feedback. I just redid our CI pipeline, so I'll kick off a new test run for you right now. |
/azp run |
Azure Pipelines successfully started running 2 pipeline(s). |
pkg/porter/version.go
Outdated
return errors.Wrap(err, "Failed to print version") | ||
} | ||
|
||
printSectionHeader(p.Context.Out, "System") |
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.
You can achieve this functionality using go templates. I think it will more readable. Just a opinion
example:
const ts = `
version: {{.Version}}
{{if .Sys -}}
System
--------
os: {{.Sys.OS}}
arch: {{.Sys.Arch}}
{{- end}}
`
v := Version{
Version: "1.0.0",
Sys: nil,
}
tmpl, _ := template.New("system").Parse(ts)
tmpl.Execute(p.Context.Out, v)
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.
Please ignore the failed CI test, I am looking into that.
I have a few requested changes but this is looking very good!
cmd/porter/version.go
Outdated
@@ -7,15 +7,18 @@ import ( | |||
) | |||
|
|||
func buildVersionCommand(p *porter.Porter) *cobra.Command { | |||
opts := version.Options{} | |||
opts := version.VersionOpts{} |
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.
Would you please move VersionOpts
into pkg/porter/version.go
. The version
package is intended for other mixins to reuse when they implement the version command.
That will change this line to look like to opts := porter.VersionOpts{}
but won't otherwise change much. It's just to help with the organization of the code.
cmd/porter/version.go
Outdated
cmd := &cobra.Command{ | ||
Use: "version", | ||
Short: "Print the application version", | ||
PreRunE: func(cmd *cobra.Command, args []string) error { | ||
return opts.Validate() | ||
return opts.Options.Validate() |
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.
Please simplify the here back to:
return opts.Options.Validate() | |
return opts.Validate() |
We can do that because Options
is embedded in VersionOpts
(it isn't a named field) so functions available on that type can be called without having to specify that it's coming from Options
. Apologies if you knew about that, I'm just sharing Go tips in case they are helpful! 😀
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, this is all very helpful 🙏🏾
cmd/porter/version.go
Outdated
}, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return p.PrintVersion(opts) | ||
if opts.System { |
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.
The convention in Porter is that all logic should be in pkg/porter
, and cmd/porter
should just wire up cobra to functions defined in that package.
Please move the check against opts.System
into PrintVersion
, so that the code in this file goes back to looking like:
RunE: func(cmd *cobra.Command, args []string) error {
return p.PrintVersion(opts)
}
If you are curious about why, I did a talk about how Porter is designed at GopherCon. The short answer is that it helps us test, and allows for people to build on top of porter's libraries.
pkg/porter/version.go
Outdated
} | ||
|
||
func (p *Porter) PrintDebugInfo(opts version.Options) error { | ||
// force opts to print version as plaintext |
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.
Apologies for not catching this when I first checked the PR, but this new --system
flag needs to work in conjunction with the --output plaintext|json
flag. So PrintDebugInfo
needs to support printing to json as well.
pkg/porter/version_test.go
Outdated
p.TestConfig.SetupPorterHome() | ||
err := opts.Validate() | ||
require.Nil(t, err) | ||
err = p.PrintDebugInfo(opts) |
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.
After you move this method and the check for opts.System
into p.PrintVersion
, I recommend updating this unit test, to exercise your if statement as well. So it should create VersionOptions {System: true}
and pass that to p.PrintVersion(opts)
.
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.
Just some tweaks to the error handling and then this is ready to merge! 💪
pkg/porter/version.go
Outdated
if err != nil { | ||
return errors.Wrap(err, "Failed to print version") | ||
_ = errors.Wrap(err, "Failed to get list of mixins") |
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.
Instead of ignoring the error (like it's doing now), or returning it (which would make it very hard to use this command for troubleshooting problems 😅 ), we can have it print a debug message and then keep going:
The contributing guide has a section on how to handle debug logging:
https://github.com/deislabs/porter/blob/master/CONTRIBUTING.md#logging
You can check p.Debug
and then print to p.Err
following the example in the guide, then have the rest of the command continue. That way even if we can't print any mixin data, at least we are able to print the data we do have.
pkg/porter/version.go
Outdated
` | ||
tmpl, err := template.New("systemDebugInfo").Parse(plaintextTmpl) | ||
if err != nil { | ||
_ = errors.Wrap(err, "Failed to print system debug information") |
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.
At this point, if we can't parse the template, then we should return the error, and not ignore it with _
because it's an unrecoverable error.
If the template isn't parsed, then continuing on to call Execute on the template (which is nil when err is populated) will cause a nil reference exception.
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 for adding this into Porter! It's going to really help out when people submit bug reports. 💯
My pleasure, thanks for guiding me through the whole process |
What does this change
Adds
--system
flag to theversion
command to print additional information about what the system on which porter is being run and any installed mixinsWhat issue does it fix
Closes #614
Notes for the reviewer
This is a draft PR to get help
Checklist