@@ -3,10 +3,12 @@ package ocm_cli
33import (
44 "context"
55 "fmt"
6+ "io"
67 "os"
78 "os/exec"
89 "strings"
910
11+ yaml2 "k8s.io/apimachinery/pkg/util/yaml"
1012 "sigs.k8s.io/yaml"
1113)
1214
@@ -46,16 +48,40 @@ func Execute(ctx context.Context, commands []string, args []string, ocmConfig st
4648 return fmt .Errorf ("error waiting for ocm command to finish: %w" , err )
4749 }
4850
49- // get exit code
50- if exitError , ok := cmd .ProcessState .Sys ().(interface { ExitStatus () int }); ok {
51- if exitCode := exitError .ExitStatus (); exitCode != 0 {
52- return fmt .Errorf ("ocm command exited with code %d" , exitCode )
53- }
51+ if cmd .ProcessState .ExitCode () != 0 {
52+ return fmt .Errorf ("ocm command exited with code %d" , cmd .ProcessState .ExitCode ())
5453 }
5554
5655 return nil
5756}
5857
58+ func ExecuteOutput (ctx context.Context , commands []string , args []string , ocmConfig string ) ([]byte , error ) {
59+ var ocmArgs []string
60+
61+ if ocmConfig != NoOcmConfig {
62+ ocmArgs = append (ocmArgs , "--config" , ocmConfig )
63+
64+ if err := verifyOCMConfig (ocmConfig ); err != nil {
65+ return nil , fmt .Errorf ("invalid OCM configuration: %w" , err )
66+ }
67+ }
68+
69+ ocmArgs = append (ocmArgs , commands ... )
70+ ocmArgs = append (ocmArgs , args ... )
71+
72+ cmd := exec .CommandContext (ctx , "ocm" , ocmArgs ... )
73+ out , err := cmd .CombinedOutput ()
74+ if err != nil {
75+ return nil , fmt .Errorf ("error executing ocm command: %w, %q" , err , out )
76+ }
77+
78+ if cmd .ProcessState .ExitCode () != 0 {
79+ return nil , fmt .Errorf ("ocm command exited with code %d: %q" , cmd .ProcessState .ExitCode (), out )
80+ }
81+
82+ return out , nil
83+ }
84+
5985// ComponentVersion represents a version of an OCM component.
6086type ComponentVersion struct {
6187 // Component is the OCM component associated with this version.
@@ -109,6 +135,11 @@ type Access struct {
109135 MediaType * string `json:"mediaType"`
110136}
111137
138+ type ComponentListEntry struct {
139+ Name string `json:"name"`
140+ Version string `json:"version"`
141+ }
142+
112143var (
113144 OCIImageResourceType = "ociImage"
114145)
@@ -143,24 +174,36 @@ func (cv *ComponentVersion) GetComponentReference(name string) (*ComponentRefere
143174 return nil , fmt .Errorf ("component reference %s not found in component version %s" , name , cv .Component .Name )
144175}
145176
146- // GetComponentVersion retrieves a component version by its reference using the OCM CLI.
147- func GetComponentVersion (ctx context.Context , componentReference string , ocmConfig string ) (* ComponentVersion , error ) {
148- var ocmArgs []string
177+ func (cv * ComponentVersion ) ListComponentVersions (ctx context.Context , ocmConfig string ) ([]string , error ) {
149178
150- if ocmConfig != NoOcmConfig {
151- ocmArgs = append (ocmArgs , "--config" , ocmConfig )
179+ out , err := ExecuteOutput (ctx , []string {"list" , "componentversion" , cv .Repository + "//" + cv .Component .Name }, []string {"--output" , "yaml" }, NoOcmConfig )
180+ if err != nil {
181+ return nil , err
182+ }
152183
153- if err := verifyOCMConfig (ocmConfig ); err != nil {
154- return nil , fmt .Errorf ("invalid OCM configuration: %w" , err )
184+ cvList := make ([]string , 0 )
185+ decoder := yaml2 .NewYAMLOrJSONDecoder (strings .NewReader (string (out )), 1024 )
186+ for {
187+ var entry ComponentListEntry
188+ err = decoder .Decode (& entry )
189+ if err == io .EOF {
190+ break
155191 }
192+ if err != nil {
193+ return nil , fmt .Errorf ("error decoding component version list: %w" , err )
194+ }
195+ cvList = append (cvList , entry .Version )
156196 }
157197
158- ocmArgs = append ( ocmArgs , "get" , "componentversion" , "--output" , "yaml" , componentReference )
198+ return cvList , nil
159199
160- cmd := exec .CommandContext (ctx , "ocm" , ocmArgs ... )
161- out , err := cmd .CombinedOutput ()
200+ }
201+
202+ // GetComponentVersion retrieves a component version by its reference using the OCM CLI.
203+ func GetComponentVersion (ctx context.Context , componentReference string , ocmConfig string ) (* ComponentVersion , error ) {
204+ out , err := ExecuteOutput (ctx , []string {"get" , "componentversion" , componentReference }, []string {"--output" , "yaml" }, ocmConfig )
162205 if err != nil {
163- return nil , fmt . Errorf ( "error executing ocm command: %w, %q" , err , out )
206+ return nil , err
164207 }
165208
166209 var cv ComponentVersion
0 commit comments