@@ -19,6 +19,8 @@ import (
1919 "fmt"
2020 "os"
2121
22+ "github.com/jedib0t/go-pretty/v6/table"
23+ "github.com/muesli/reflow/wrap"
2224 "github.com/spf13/cobra"
2325 "github.com/spf13/viper"
2426 "google.golang.org/grpc"
@@ -27,6 +29,8 @@ import (
2729 schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
2830)
2931
32+ const NotSet = "[NOT SET]"
33+
3034func newAttestationAddCmd () * cobra.Command {
3135 var name , value , kind string
3236 var artifactCASConn * grpc.ClientConn
@@ -90,14 +94,21 @@ func newAttestationAddCmd() *cobra.Command {
9094 return runWithBackoffRetry (
9195 func () error {
9296 // TODO: take the material output and show render it
93- _ , err := a .Run (cmd .Context (), attestationID , name , value , kind , annotations )
97+ resp , err := a .Run (cmd .Context (), attestationID , name , value , kind , annotations )
9498 if err != nil {
9599 return err
96100 }
97101
98102 logger .Info ().Msg ("material added to attestation" )
99103
100- return nil
104+ policies , err := a .GetPolicyEvaluations (cmd .Context (), attestationID )
105+ if err != nil {
106+ return err
107+ }
108+
109+ return encodeOutput (resp , func (s * action.AttestationStatusMaterial ) error {
110+ return displayMaterialInfo (s , policies [resp .Name ])
111+ })
101112 },
102113 )
103114 },
@@ -138,3 +149,53 @@ func newAttestationAddCmd() *cobra.Command {
138149
139150 return cmd
140151}
152+
153+ // displayMaterialInfo prints the material information in a table format.
154+ func displayMaterialInfo (status * action.AttestationStatusMaterial , policyEvaluations []* action.PolicyEvaluation ) error {
155+ if status == nil {
156+ return nil
157+ }
158+
159+ mt := newTableWriter ()
160+
161+ mt .AppendRow (table.Row {"Name" , status .Material .Name })
162+ mt .AppendRow (table.Row {"Type" , status .Material .Type })
163+ mt .AppendRow (table.Row {"Required" , hBool (status .Required )})
164+
165+ if status .IsOutput {
166+ mt .AppendRow (table.Row {"Is output" , "Yes" })
167+ }
168+
169+ if status .Value != "" {
170+ v := status .Value
171+ if status .Tag != "" {
172+ v = fmt .Sprintf ("%s:%s" , v , status .Tag )
173+ }
174+ mt .AppendRow (table.Row {"Value" , wrap .String (v , 100 )})
175+ }
176+
177+ if status .Hash != "" {
178+ mt .AppendRow (table.Row {"Digest" , status .Hash })
179+ }
180+
181+ if len (status .Material .Annotations ) > 0 {
182+ mt .AppendRow (table.Row {"Annotations" , "------" })
183+ for _ , a := range status .Material .Annotations {
184+ value := a .Value
185+ if value == "" {
186+ value = NotSet
187+ }
188+ mt .AppendRow (table.Row {"" , fmt .Sprintf ("%s: %s" , a .Name , value )})
189+ }
190+ }
191+
192+ if len (policyEvaluations ) > 0 {
193+ mt .AppendRow (table.Row {"Policy evaluations" , "------" })
194+ }
195+
196+ policiesTable (policyEvaluations , mt )
197+ mt .SetStyle (table .StyleLight )
198+ mt .Style ().Options .SeparateRows = true
199+ mt .Render ()
200+ return nil
201+ }
0 commit comments