From a8ab4dabaa4a61b6f99db9c67534955f2fceb40f Mon Sep 17 00:00:00 2001 From: Jeff McCune Date: Sun, 24 Nov 2024 16:18:21 -0800 Subject: [PATCH] cue: fix holos cue vet exit code (#358) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this patch `holos cue vet` always returns exit code 0, even when there are errors. This patch fixes the problem by catching the error and returning it to our own top level error handler. Note the final error, "could not run: terminating because of errors" which wraps the generic error reported by cue in the presence of multiple errors. Result: ``` ❯ holos cue vet ./policy --path 'strings.ToLower(kind)' /tmp/podinfo.gen.yaml deployment.kind: conflicting values "Forbidden" and "Deployment": ./policy/validations.cue:18:8 ../../../../../tmp/podinfo.gen.yaml:25:7 deployment.spec.template.spec.containers.0.resources.limits: conflicting values null and {[string]:"k8s.io/apimachinery/pkg/api/resource".#Quantity} (mismatched types null and struct): ./cue.mod/gen/k8s.io/api/apps/v1/types_go_gen.cue:355:9 ./cue.mod/gen/k8s.io/api/apps/v1/types_go_gen.cue:376:12 ./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:2840:11 ./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:2968:14 ./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:3882:15 ./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:3882:18 ./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:5027:9 ./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:6407:16 ./policy/validations.cue:17:13 ../../../../../tmp/podinfo.gen.yaml:104:19 could not run: terminating because of errors ``` --- cmd/holos/tests/cli/cue-vet.txt | 12 ++++++++++++ internal/cli/root.go | 20 ++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 cmd/holos/tests/cli/cue-vet.txt diff --git a/cmd/holos/tests/cli/cue-vet.txt b/cmd/holos/tests/cli/cue-vet.txt new file mode 100644 index 00000000..4bd0834f --- /dev/null +++ b/cmd/holos/tests/cli/cue-vet.txt @@ -0,0 +1,12 @@ +# https://github.com/holos-run/holos/issues/358 +# holos cue vet should fail verifications with exit code 1 +! exec holos cue vet ./policy --path strings.ToLower(kind) ./data/secret.yaml +# holos cue vet should report validation errors to stderr +stderr 'Forbidden. Use an ExternalSecret instead.' + +-- data/secret.yaml -- +kind: Secret +-- policy/validators.cue -- +package policy + +secret: kind: "Forbidden. Use an ExternalSecret instead." diff --git a/internal/cli/root.go b/internal/cli/root.go index f6d6336c..4ee3c46f 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -4,7 +4,6 @@ import ( _ "embed" "fmt" "log/slog" - "os" "github.com/spf13/cobra" @@ -119,7 +118,20 @@ func newOrgCmd(feature holos.Flagger) (cmd *cobra.Command) { } func newCueCmd() (cmd *cobra.Command) { - cueCmd, _ := cue.New(os.Args[1:]) - cmd = cueCmd.Command - return + // Get a handle on the cue root command fields. + root, _ := cue.New([]string{}) + // Copy the fields to our embedded command. + cmd = command.New("cue") + cmd.Short = root.Short + cmd.Long = root.Long + // Pass all arguments through to RunE. + cmd.DisableFlagParsing = true + cmd.Args = cobra.ArbitraryArgs + + // We do it this way so we handle errors correctly. + cmd.RunE = func(cmd *cobra.Command, args []string) error { + cueRootCommand, _ := cue.New(args) + return cueRootCommand.Run(cmd.Root().Context()) + } + return cmd }