diff --git a/cmd/test/test.go b/cmd/test/test.go index f017fbeee..4430f3b8c 100644 --- a/cmd/test/test.go +++ b/cmd/test/test.go @@ -25,6 +25,7 @@ package test import ( "encoding/json" "fmt" + "io" "os" "github.com/open-policy-agent/conftest/output" @@ -118,6 +119,7 @@ func newTestCommand() *cobra.Command { "no-fail", "suppress-exceptions", "output", + "file", "parser", "policy", "proto-file-dirs", @@ -150,6 +152,11 @@ func newTestCommand() *cobra.Command { return fmt.Errorf("unmarshal parameters: %w", err) } + outputFilePath, err := cmd.Flags().GetString("file") + if err != nil { + return fmt.Errorf("reading flag: %w", err) + } + results, resultsErr := runner.Run(ctx, fileList) var exitCode int if runner.FailOnWarn { @@ -171,6 +178,10 @@ func newTestCommand() *cobra.Command { if err != nil { return appstudioErrorHandler(runner.NoFail, "output results", err) } + + if outputFilePath != "" { + os.WriteFile(outputFilePath, reportOutput, 0644) + } fmt.Printf("%s\n", reportOutput) } else { @@ -180,15 +191,29 @@ func newTestCommand() *cobra.Command { return fmt.Errorf("running test: %w", resultsErr) } + var outputFile *os.File + if outputFilePath != "" { + outputFile, err = os.Create(outputFilePath) + if err != nil { + return fmt.Errorf("creating output file: %w", err) + } + defer outputFile.Close() + } + outputter := output.Get(runner.Output, output.Options{ NoColor: runner.NoColor, SuppressExceptions: runner.SuppressExceptions, Tracing: runner.Trace, JUnitHideMessage: viper.GetBool("junit-hide-message"), + File: outputFile, }) if err := outputter.Output(results); err != nil { return fmt.Errorf("output results: %w", err) } + + if outputFilePath != "" { + io.Copy(outputFile, os.Stdout) + } } // When the no-fail parameter is set, there is no need to figure out the error code @@ -219,6 +244,7 @@ func newTestCommand() *cobra.Command { cmd.Flags().String("capabilities", "", "Path to JSON file that can restrict opa functionality against a given policy. Default: all operations allowed") cmd.Flags().StringP("output", "o", output.OutputStandard, fmt.Sprintf("Output format for conftest results - valid options are: %s", append(output.Outputs(), OutputAppstudio))) + cmd.Flags().String("file", "", "File path to write output to") cmd.Flags().Bool("junit-hide-message", false, "Do not include the violation message in the JUnit test name") cmd.Flags().StringSliceP("policy", "p", []string{"policy"}, "Path to the Rego policy files directory")