Skip to content

Commit

Permalink
Adds flag to add paramValues
Browse files Browse the repository at this point in the history
This commit enables the option to pass custom/required parameters
via CLI while creating the build or buildRun.
  • Loading branch information
apoorvajagtap committed Aug 26, 2024
1 parent 5fb30ef commit 39d8e69
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 0 deletions.
1 change: 1 addition & 0 deletions pkg/shp/flags/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func BuildSpecFromFlags(flags *pflag.FlagSet) *buildv1alpha1.BuildSpec {
imageFlags(flags, "output", &spec.Output)
timeoutFlags(flags, spec.Timeout)
envFlags(flags, &spec.Env)
paramValueFlag(flags, &spec.ParamValues)
imageLabelsFlags(flags, spec.Output.Labels)
imageAnnotationsFlags(flags, spec.Output.Annotations)
buildRetentionFlags(flags, spec.Retention)
Expand Down
1 change: 1 addition & 0 deletions pkg/shp/flags/buildrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func BuildRunSpecFromFlags(flags *pflag.FlagSet) *buildv1alpha1.BuildRunSpec {
timeoutFlags(flags, spec.Timeout)
imageFlags(flags, "output", spec.Output)
envFlags(flags, &spec.Env)
paramValueFlag(flags, &spec.ParamValues)
imageLabelsFlags(flags, spec.Output.Labels)
imageAnnotationsFlags(flags, spec.Output.Annotations)
buildRunRetentionFlags(flags, spec.Retention)
Expand Down
12 changes: 12 additions & 0 deletions pkg/shp/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const (
OutputInsecureFlag = "output-insecure"
// OutputCredentialsSecretFlag command-line flag.
OutputCredentialsSecretFlag = "output-credentials-secret" // #nosec G101
// ParameterValueFlag command-line flag.
ParamValueFlag = "param-value"
// ServiceAccountNameFlag command-line flag.
ServiceAccountNameFlag = "sa-name"
// ServiceAccountGenerateFlag command-line flag.
Expand Down Expand Up @@ -212,6 +214,16 @@ func envFlags(flags *pflag.FlagSet, envs *[]corev1.EnvVar) {
)
}

// parameterValueFlag registers flags for adding BuildSpec.ParamValues
func paramValueFlag(flags *pflag.FlagSet, paramValue *[]buildv1alpha1.ParamValue) {
flags.VarP(
NewParamArrayValue(paramValue),
ParamValueFlag,
"",
"set of key-value pairs to pass as parameters to the buildStrategy",
)
}

// imageLabelsFlags registers flags for output image labels.
func imageLabelsFlags(flags *pflag.FlagSet, labels map[string]string) {
flags.VarP(
Expand Down
50 changes: 50 additions & 0 deletions pkg/shp/flags/param_value.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package flags

import (
"fmt"

buildv1alpha1 "github.com/shipwright-io/build/pkg/apis/build/v1alpha1"
)

// ParamArrayValue implements pflag.Value interface, in order to store ParamValue key-value
// pairs used on Shipwright's BuildSpec.
type ParamArrayValue struct {
params *[]buildv1alpha1.ParamValue // pointer to the slice of ParamValue
}

// String prints out the string representation of the slice of EnvVar objects.
func (p *ParamArrayValue) String() string {
slice := []string{}
for _, e := range *p.params {
slice = append(slice, fmt.Sprintf("%s=%v", e.Name, e.Value))
}
csv, _ := writeAsCSV(slice)
return fmt.Sprintf("[%s]", csv)
}

// Set receives a key-value entry separated by equal sign ("=").
func (p *ParamArrayValue) Set(value string) error {
k, v, err := splitKeyValue(value)
if err != nil {
return err
}
for _, e := range *p.params {
if k == e.Name {
return fmt.Errorf("environment variable '%s' is already set", k)
}
}
*p.params = append(*p.params, buildv1alpha1.ParamValue{Name: k, SingleValue: &buildv1alpha1.SingleValue{Value: &v}})
return nil
}

// Type analogous to the pflag "stringArray" type, where each flag entry will be tranlated to a
// single array (slice) entry, therefore the comma (",") is accepted as part of the value, as any
// other special character.
func (p *ParamArrayValue) Type() string {
return "stringArray"
}

// NewCoreEnvVarArrayValue instantiate a ParamValSliceValue sharing the EnvVar pointer.
func NewParamArrayValue(params *[]buildv1alpha1.ParamValue) *ParamArrayValue {
return &ParamArrayValue{params: params}
}
60 changes: 60 additions & 0 deletions pkg/shp/flags/param_value_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package flags

import (
"errors"
"testing"

"github.com/onsi/gomega"
buildv1alpha1 "github.com/shipwright-io/build/pkg/apis/build/v1alpha1"
)

func TestNewParamArrayValue(t *testing.T) {
g := gomega.NewWithT(t)

testCases := map[string]struct {
paramPassed string
paramKey string
paramValue string
expectedErr error
}{
"simpleKeyValPair": {
paramPassed: "dockerfile=Dockerfile",
paramKey: "dockerfile",
paramValue: "Dockerfile",
expectedErr: nil,
},
"specialCharKeyValPair": {
paramPassed: "b=cd=e",
paramKey: "b",
paramValue: "cd=e",
expectedErr: nil,
},
"noEquals": {
paramPassed: "bc",
expectedErr: errors.New("informed value 'bc' is not in key=value format"),
},
"withSpaceVal": {
paramPassed: "b=c d",
paramKey: "b",
paramValue: "c d",
expectedErr: nil,
},
}
for tName, tCase := range testCases {
paramVal := tCase.paramValue
t.Run(tName, func(_ *testing.T) {
buildSpec := buildv1alpha1.BuildSpec{}
buildParamVal := NewParamArrayValue(&buildSpec.ParamValues)

err := buildParamVal.Set(tCase.paramPassed)
if tCase.expectedErr != nil {
g.Expect(err).To(gomega.Equal(tCase.expectedErr))
return
}
g.Expect(err).To(gomega.BeNil())

g.Expect(buildSpec.ParamValues[0].Name).To(gomega.Equal(tCase.paramKey))
g.Expect(buildSpec.ParamValues[0].Value).To(gomega.Equal(&paramVal))
})
}
}

0 comments on commit 39d8e69

Please sign in to comment.