-
Notifications
You must be signed in to change notification settings - Fork 38
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
Set non-zero exit code for invalid manifests #62
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: MaGaroo The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@@ -10,6 +9,6 @@ import ( | |||
func main() { | |||
rootCmd := cmd.NewRootCommand() | |||
if err := rootCmd.Execute(); err != nil { | |||
fmt.Fprintln(os.Stderr, err.Error()) | |||
os.Exit(1) |
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.
Does this mean that we're not going to print the errors anymore?
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.
Cobra prints the error itself. I think we should either print the error manually and set SilenceError
attribute in cobra.Command
or not print the error explicitly and let cobra print it for us.
data, e := json.MarshalIndent(res, "", " ") | ||
if e != nil { | ||
return fmt.Errorf("failed to render results into JSON: %w", e) | ||
if err := printJsonErrors(filesErrors, cmd.OutOrStdout(), cmd.ErrOrStderr()); err != nil { |
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.
json.Marshal
is stable since it sorts the keys, so this is not going to change the behavior, but printHumanErrors
is now going to show files in a random order. Not sure how much it matters but I wanted to point that out.
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.
Currently not sure about the best approach, but wanted to note another change in behavior of human formatter.
Previously, if a file had occurred twice in the args, human output printed it twice too. Now, it only prints its errors once.
if filesErrors.hasError() { | ||
return errors.New("found some errors in the manifests") | ||
} else { | ||
return nil | ||
} |
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'm not super excited about that.
Something you could do is:
- Give FilesErrors a "Append" function that supports self being nil
- return the instance here without checking for nil, nor creating a dummy error
So probably something like this:
type Error struct {
path string
err error
}
type FilesErrors []Error
func (e *FilesError) Append(path string, err error) *FilesError {
if err == nil {
return e
}
return append(e, Error{path: path, err: err})
}
func (e *FilesError) Error(format string) string {
// print according to format, can call separate functions if needed.
}
... // In Run()
var errs *FileErrors // Get a nil pointer to errors
for _, path := range files {
errs = errs.Append(path, ValidateFile(path, factory))
}
...
return errs // Will be null if we've never added any error.
... // in main()
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err.Error(rootCmd.outputFormat))
os.Exit(1)
}
I think this has a lot less conditions to keep track of.
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 generally agree, but there are some concerns. I start with two of them which are the most important ones:
First, each file can contain multiple documents.1 ValidateFile
function generates an error (possibly nil
) for each document and returns a list of errors. 2 So, it's important to keep track of nil
errors as json formatter needs it.
Second, in order for the FilesErrors
type to be considered a golang error, we have to implement Error
method without any arguments. So, what's your opinion about declaring FilesErrors
as a struct
with errors
and outputFormat
fields, and using outputFormat
field to implement the logic of Error()
method?
Footnotes
-
It runs
ValidateDocument
over all documents of the file, which returns exactly one error per document. So,ValidateFile
returns a slice containing those errors, i'th error for the i'th document. ↩ -
I think the human output is a little ambiguous when a file contains multiple documents. For example, if the first and third documents in a file have an error and the second document is sane, the human formatter prints the first and third errors and prints nothing about the sanity of the second document. However, this issue is out of scope and I intended to address it in another issue/pr. ↩
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.
Sorry for the delay, code freeze in k/k is approaching and I lost track of that.
Yeah, I made the invalid assumption that we weren't printing anything if there was no error.
Considering that, I don't see how we can return a relevant error out of the Run
method, maybe it's fine to just os.Exit
directly from it, and always return nil when no errors occur?
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'd prefer for the cobra command to return an errors.Join
of a slice of the Error
type @apelisse posted above, then in main we can exit if the execution returns non-nil error.
PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
I've opened up #63 since this PR has gotten stale and this change is super high priority. after that merges you may like it keep working on your refactoring, or close this PR |
Sorry for the delay, for some reason I didn't receive any notification about this PR. |
I think we can close, thank you! |
Hi!
This PR is supposed to resolve #61
I also refactored a small part of the code in order to remove redundancy in the print section.
I'd be glad if you could review these changes.