44 "context"
55 "encoding/json"
66 "fmt"
7+ "io"
78 "io/fs"
89 "maps"
910 "os"
@@ -33,6 +34,7 @@ type evalOpts struct {
3334 filename string
3435 printOutput bool
3536 fields []string
37+ platform string
3638 builder * string
3739}
3840
@@ -49,9 +51,14 @@ func evalCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
4951 return runEval (cmd .Context (), dockerCli , args [0 ], opts )
5052 },
5153 }
52- cmd .Flags ().StringVar (& opts .filename , "filename" , "Dockerfile" , "Policy filename to evaluate" )
53- cmd .Flags ().BoolVar (& opts .printOutput , "print" , false , "Print policy output" )
54- cmd .Flags ().StringSliceVar (& opts .fields , "fields" , nil , "Fields to evaluate" )
54+ flags := cmd .Flags ()
55+ flags .StringVarP (& opts .filename , "file" , "f" , "Dockerfile" , "Policy filename to evaluate" )
56+ flags .BoolVar (& opts .printOutput , "print" , false , "Print policy output" )
57+ flags .StringSliceVar (& opts .fields , "fields" , nil , "Fields to evaluate" )
58+ flags .StringVar (& opts .platform , "platform" , "" , "Target platform for policy evaluation" )
59+ // Deprecated: use --file instead
60+ flags .StringVar (& opts .filename , "filename" , "Dockerfile" , "Policy filename to evaluate" )
61+ flags .MarkHidden ("filename" )
5562 return cmd
5663}
5764
@@ -81,29 +88,29 @@ func runEval(ctx context.Context, dockerCli command.Cli, source string, opts eva
8188 return err
8289 }
8390
84- workers , err := c .ListWorkers (ctx )
85- if err != nil {
86- return err
87- }
91+ var p ocispecs.Platform
92+ if opts .platform != "" {
93+ parsedPlatform , err := parsePlatform (opts .platform )
94+ if err != nil {
95+ return err
96+ }
97+ p = * parsedPlatform
98+ } else {
99+ workers , err := c .ListWorkers (ctx )
100+ if err != nil {
101+ return err
102+ }
88103
89- if len (workers ) == 0 {
90- return errors .New ("no workers available in the builder" )
91- }
104+ if len (workers ) == 0 {
105+ return errors .New ("no workers available in the builder" )
106+ }
92107
93- defaultPlatform := workers [0 ].Platforms [0 ]
94- p := ocispecs.Platform {
95- Architecture : defaultPlatform .Architecture ,
96- OS : defaultPlatform .OS ,
97- Variant : defaultPlatform .Variant ,
108+ p = workers [0 ].Platforms [0 ]
98109 }
99110 metaResolver := sourcemeta .NewResolver (c )
100111 defer metaResolver .Close ()
101112
102- platform := & pb.Platform {
103- Architecture : p .Architecture ,
104- OS : p .OS ,
105- Variant : p .Variant ,
106- }
113+ platform := toPBPlatform (p )
107114 verifier := policy .SignatureVerifier (confutil .NewConfig (dockerCli ))
108115
109116 if opts .printOutput {
@@ -185,9 +192,8 @@ func runEval(ctx context.Context, dockerCli command.Cli, source string, opts eva
185192 if opts .filename == "" {
186193 return errors .New ("filename is required" )
187194 }
188- policyName := opts .filename
189- policyFile := policyName + ".rego"
190- policyData , err := os .ReadFile (policyFile )
195+ policyName , policyFile := policyFileNames (opts .filename )
196+ policyData , err := readPolicyData (policyFile , os .Stdin )
191197 if err != nil {
192198 return errors .Wrapf (err , "failed to read policy file %s" , policyFile )
193199 }
@@ -261,6 +267,20 @@ func runEval(ctx context.Context, dockerCli command.Cli, source string, opts eva
261267 }
262268}
263269
270+ func policyFileNames (filename string ) (string , string ) {
271+ if filename == "-" {
272+ return "stdin" , filename
273+ }
274+ return filename , filename + ".rego"
275+ }
276+
277+ func readPolicyData (filename string , stdin io.Reader ) ([]byte , error ) {
278+ if filename == "-" {
279+ return io .ReadAll (stdin )
280+ }
281+ return os .ReadFile (filename )
282+ }
283+
264284func selectReloadFields (fields []string , unknowns []string ) ([]string , []string ) {
265285 if len (fields ) == 0 {
266286 return nil , nil
0 commit comments