| 
 | 1 | +package ocm_cli  | 
 | 2 | + | 
 | 3 | +import (  | 
 | 4 | +	"context"  | 
 | 5 | +	"fmt"  | 
 | 6 | +	"gopkg.in/yaml.v3"  | 
 | 7 | +	"os"  | 
 | 8 | +	"os/exec"  | 
 | 9 | +)  | 
 | 10 | + | 
 | 11 | +const (  | 
 | 12 | +	// NoOcmConfig is a constant to indicate that no OCM configuration file is being provided.  | 
 | 13 | +	NoOcmConfig = ""  | 
 | 14 | +)  | 
 | 15 | + | 
 | 16 | +// Execute runs the specified OCM command with the provided arguments and configuration.  | 
 | 17 | +// It captures the command's output and errors, and returns an error if the command fails.  | 
 | 18 | +// The `commands` parameter is a slice of strings representing the OCM command and its subcommands.  | 
 | 19 | +// The `args` parameter is a slice of strings representing the arguments to the command.  | 
 | 20 | +// The `ocmConfig` parameter is a string representing the path to the OCM configuration file. Passing `NoOcmConfig` indicates that no configuration file should be used.  | 
 | 21 | +func Execute(ctx context.Context, commands []string, args []string, ocmConfig string) error {  | 
 | 22 | +	var flags []string  | 
 | 23 | + | 
 | 24 | +	flags = append(flags, commands...)  | 
 | 25 | +	flags = append(flags, args...)  | 
 | 26 | + | 
 | 27 | +	if ocmConfig != NoOcmConfig {  | 
 | 28 | +		flags = append(flags, "--config", ocmConfig)  | 
 | 29 | +	}  | 
 | 30 | + | 
 | 31 | +	cmd := exec.CommandContext(ctx, "ocm", flags...)  | 
 | 32 | +	cmd.Stdout = os.Stdout  | 
 | 33 | +	cmd.Stderr = os.Stderr  | 
 | 34 | + | 
 | 35 | +	if err := cmd.Start(); err != nil {  | 
 | 36 | +		return fmt.Errorf("error starting ocm command: %w", err)  | 
 | 37 | +	}  | 
 | 38 | + | 
 | 39 | +	if err := cmd.Wait(); err != nil {  | 
 | 40 | +		return fmt.Errorf("error waiting for ocm command to finish: %w", err)  | 
 | 41 | +	}  | 
 | 42 | + | 
 | 43 | +	return nil  | 
 | 44 | +}  | 
 | 45 | + | 
 | 46 | +// ComponentVersion represents a version of an OCM component.  | 
 | 47 | +type ComponentVersion struct {  | 
 | 48 | +	// Component is the OCM component associated with this version.  | 
 | 49 | +	Component Component `json:"component"`  | 
 | 50 | +}  | 
 | 51 | + | 
 | 52 | +// Component represents an OCM component with its name, version, references to other components, and resources.  | 
 | 53 | +type Component struct {  | 
 | 54 | +	// Name is the name of the component.  | 
 | 55 | +	Name string `yaml:"name"`  | 
 | 56 | +	// Version is the version of the component.  | 
 | 57 | +	Version string `yaml:"version"`  | 
 | 58 | +	// ComponentReferences is a list of references to other components that this component depends on.  | 
 | 59 | +	ComponentReferences []ComponentReference `yaml:"componentReferences"`  | 
 | 60 | +	// Resources is a list of resources associated with this component, including their names, versions, types, and access information.  | 
 | 61 | +	Resources []Resource `yaml:"resources"`  | 
 | 62 | +}  | 
 | 63 | + | 
 | 64 | +// ComponentReference represents a reference to another component, including its name, version, and the name of the component it refers to.  | 
 | 65 | +type ComponentReference struct {  | 
 | 66 | +	// Name is the name of the component reference.  | 
 | 67 | +	Name string `yaml:"name"`  | 
 | 68 | +	// Version is the version of the component reference.  | 
 | 69 | +	Version string `yaml:"version"`  | 
 | 70 | +	// ComponentName is the name of the component that this reference points to.  | 
 | 71 | +	ComponentName string `yaml:"componentName"`  | 
 | 72 | +}  | 
 | 73 | + | 
 | 74 | +// Resource represents a resource associated with a component, including its name, version, type, and access information.  | 
 | 75 | +type Resource struct {  | 
 | 76 | +	// Name is the name of the resource.  | 
 | 77 | +	Name string `yaml:"name"`  | 
 | 78 | +	// Version is the version of the resource.  | 
 | 79 | +	Version string `yaml:"version"`  | 
 | 80 | +	// Type is the content type of the resource.  | 
 | 81 | +	Type string `yaml:"type"`  | 
 | 82 | +	// Access contains the information on how to access the resource.  | 
 | 83 | +	Access Access `yaml:"access"`  | 
 | 84 | +}  | 
 | 85 | + | 
 | 86 | +// Access represents the access information for a resource, including the type of access.  | 
 | 87 | +type Access struct {  | 
 | 88 | +	// Type is the content type of access to the resource.  | 
 | 89 | +	Type string `yaml:"type"`  | 
 | 90 | +	// ImageReference is the reference to the image if the Type is "ociArtifact".  | 
 | 91 | +	ImageReference string `yaml:"imageReference"`  | 
 | 92 | +}  | 
 | 93 | + | 
 | 94 | +// GetResource retrieves a resource by its name from the component version.  | 
 | 95 | +func (cv *ComponentVersion) GetResource(name string) (*Resource, error) {  | 
 | 96 | +	for _, resource := range cv.Component.Resources {  | 
 | 97 | +		if resource.Name == name {  | 
 | 98 | +			return &resource, nil  | 
 | 99 | +		}  | 
 | 100 | +	}  | 
 | 101 | +	return nil, fmt.Errorf("resource %s not found in component version %s", name, cv.Component.Name)  | 
 | 102 | +}  | 
 | 103 | + | 
 | 104 | +// GetComponentReference retrieves a component reference by its name from the component version.  | 
 | 105 | +func (cv *ComponentVersion) GetComponentReference(name string) (*ComponentReference, error) {  | 
 | 106 | +	for _, ref := range cv.Component.ComponentReferences {  | 
 | 107 | +		if ref.Name == name {  | 
 | 108 | +			return &ref, nil  | 
 | 109 | +		}  | 
 | 110 | +	}  | 
 | 111 | +	return nil, fmt.Errorf("component reference %s not found in component version %s", name, cv.Component.Name)  | 
 | 112 | +}  | 
 | 113 | + | 
 | 114 | +// GetComponentVersion retrieves a component version by its reference using the OCM CLI.  | 
 | 115 | +func GetComponentVersion(ctx context.Context, componentReference string, ocmConfig string) (*ComponentVersion, error) {  | 
 | 116 | +	flags := []string{  | 
 | 117 | +		"get",  | 
 | 118 | +		"componentversion",  | 
 | 119 | +		"--output", "yaml",  | 
 | 120 | +		componentReference,  | 
 | 121 | +	}  | 
 | 122 | + | 
 | 123 | +	if ocmConfig != NoOcmConfig {  | 
 | 124 | +		flags = append(flags, "--config", ocmConfig)  | 
 | 125 | +	}  | 
 | 126 | + | 
 | 127 | +	cmd := exec.CommandContext(ctx, "ocm", flags...)  | 
 | 128 | +	out, err := cmd.CombinedOutput()  | 
 | 129 | +	if err != nil {  | 
 | 130 | +		return nil, fmt.Errorf("error executing ocm command: %w", err)  | 
 | 131 | +	}  | 
 | 132 | + | 
 | 133 | +	var cv ComponentVersion  | 
 | 134 | +	err = yaml.Unmarshal(out, &cv)  | 
 | 135 | +	if err != nil {  | 
 | 136 | +		return nil, fmt.Errorf("error unmarshalling component version: %w", err)  | 
 | 137 | +	}  | 
 | 138 | + | 
 | 139 | +	return &cv, nil  | 
 | 140 | +}  | 
0 commit comments