@@ -19,6 +19,8 @@ import (
19
19
"fmt"
20
20
"os"
21
21
22
+ "github.com/jedib0t/go-pretty/v6/table"
23
+ "github.com/muesli/reflow/wrap"
22
24
"github.com/spf13/cobra"
23
25
"github.com/spf13/viper"
24
26
"google.golang.org/grpc"
@@ -27,6 +29,8 @@ import (
27
29
schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
28
30
)
29
31
32
+ const NotSet = "[NOT SET]"
33
+
30
34
func newAttestationAddCmd () * cobra.Command {
31
35
var name , value , kind string
32
36
var artifactCASConn * grpc.ClientConn
@@ -90,14 +94,21 @@ func newAttestationAddCmd() *cobra.Command {
90
94
return runWithBackoffRetry (
91
95
func () error {
92
96
// 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 )
94
98
if err != nil {
95
99
return err
96
100
}
97
101
98
102
logger .Info ().Msg ("material added to attestation" )
99
103
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
+ })
101
112
},
102
113
)
103
114
},
@@ -138,3 +149,53 @@ func newAttestationAddCmd() *cobra.Command {
138
149
139
150
return cmd
140
151
}
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