From 0f3db0067df41222e415eab91a1417fa412ba621 Mon Sep 17 00:00:00 2001 From: Joel Pepper Date: Wed, 21 Jun 2023 12:44:42 +0200 Subject: [PATCH] fix(completion): Fix completion in deprecated projects Currently, when initializing in a project with deprecated plugins the kubebuilder cli will immediately output a deprecation notice to stdout before even parsing the command. While this is acceptable and even desirable for interactive usage of the cli, it will "randomly" (i.e. dependent on $PWD and not on the command) break automated usage of the kubebuilder output. This, again is fine if kubebuilder makes no guarantees of stable machine readable output, but this does not hold for the completion sub commands which are only ever parsed by machines: The output of "kubebuilder completion " must always only output the exact script generated by cobra and the cobra internal commands __complete and __completeNoDesc must only only return an exact list of completion options. In deprecated projects this will break shell completion if the shell is started in the directory and if the completion script is correctly initialized, all completion options will be polluted by the massive deprecation notice. This commit instead changes the deprecation notice to output to stderr (while maintaining the return code of the actual command). This fixes the completion usecase which only reads in stdout, and should not break existing integrations, unless there exist scripts which use the length of stderr to check for errors rather than the return code of the call. Signed-off-by: Joel Pepper --- pkg/cli/cli.go | 2 +- pkg/cli/cli_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go index 7b74436db7..af50425603 100644 --- a/pkg/cli/cli.go +++ b/pkg/cli/cli.go @@ -444,7 +444,7 @@ func (c *CLI) addExtraCommands() error { func (c CLI) printDeprecationWarnings() { for _, p := range c.resolvedPlugins { if p != nil && p.(plugin.Deprecated) != nil && len(p.(plugin.Deprecated).DeprecationWarning()) > 0 { - fmt.Printf(noticeColor, fmt.Sprintf(deprecationFmt, p.(plugin.Deprecated).DeprecationWarning())) + fmt.Fprintf(os.Stderr, noticeColor, fmt.Sprintf(deprecationFmt, p.(plugin.Deprecated).DeprecationWarning())) } } } diff --git a/pkg/cli/cli_test.go b/pkg/cli/cli_test.go index 7503e2cf18..ae5f8c7023 100644 --- a/pkg/cli/cli_test.go +++ b/pkg/cli/cli_test.go @@ -592,13 +592,13 @@ plugins: ) deprecatedPlugin := newMockDeprecatedPlugin("deprecated", "v1", deprecationWarning, projectVersion) - // Overwrite stdout to read the output and reset it afterwards + // Overwrite stderr to read the deprecation output and reset it afterwards r, w, _ := os.Pipe() - temp := os.Stdout + temp := os.Stderr defer func() { - os.Stdout = temp + os.Stderr = temp }() - os.Stdout = w + os.Stderr = w c, err = New( WithPlugins(deprecatedPlugin),