You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2021/08/23 12:58:06 UTC
[camel-k] 01/03: fix(cli): property priority
This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 6139abb0551c73626ca25c7faa7782714218a287
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Thu Aug 12 15:38:41 2021 +0200
fix(cli): property priority
Introduced a merge function which is in charge to merge all properties, giving priority to single declaration property options
Closes #2538
---
pkg/cmd/run.go | 57 ++++++++++++++++---------------------------
pkg/cmd/run_help.go | 36 +++++++++++++++++++++++++++
pkg/cmd/run_help_test.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
pkg/cmd/run_test.go | 35 ---------------------------
4 files changed, 120 insertions(+), 71 deletions(-)
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 5095362..8cb1ebf 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -575,34 +575,33 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C
// Deprecated: making it compatible with newer mechanism
o.Properties = append(o.Properties, "file:"+item)
}
- for _, item := range o.Properties {
- props, err := extractProperties(item)
- if err != nil {
- return nil, err
- }
- if err := addIntegrationProperties(props, &integration.Spec); err != nil {
- return nil, err
- }
+
+ props, err := mergePropertiesWithPrecedence(o.Properties)
+ if err != nil {
+ return nil, err
+ }
+ if err := addIntegrationProperties(props, &integration.Spec); err != nil {
+ return nil, err
}
+
// convert each build configuration to a builder trait property
- for _, item := range o.BuildProperties {
- props, err := extractProperties(item)
- if err != nil {
- return nil, err
- }
- for _, k := range props.Keys() {
- v, ok := props.Get(k)
- if ok {
- entry, err := property.EncodePropertyFileEntry(k, v)
- if err != nil {
- return nil, err
- }
- o.Traits = append(o.Traits, fmt.Sprintf("builder.properties=%s", entry))
- } else {
+ buildProps, err := mergePropertiesWithPrecedence(o.BuildProperties)
+ if err != nil {
+ return nil, err
+ }
+ for _, k := range buildProps.Keys() {
+ v, ok := buildProps.Get(k)
+ if ok {
+ entry, err := property.EncodePropertyFileEntry(k, v)
+ if err != nil {
return nil, err
}
+ o.Traits = append(o.Traits, fmt.Sprintf("builder.properties=%s", entry))
+ } else {
+ return nil, err
}
}
+
for _, item := range o.Configs {
if config, parseErr := ParseConfigOption(item); parseErr == nil {
if applyConfigOptionErr := ApplyConfigOption(config, &integration.Spec, c, namespace, o.Compression); applyConfigOptionErr != nil {
@@ -687,20 +686,6 @@ func addResource(resourceLocation string, integrationSpec *v1.IntegrationSpec, e
return nil
}
-// The function parse the value and if it is a file (file:/path/), it will parse as property file
-// otherwise return a single property built from the item passed as `key=value`
-func extractProperties(value string) (*properties.Properties, error) {
- if !strings.HasPrefix(value, "file:") {
- return keyValueProps(value)
- }
- // we already validated the existence of files during validate()
- return loadPropertyFile(strings.Replace(value, "file:", "", 1))
-}
-
-func keyValueProps(value string) (*properties.Properties, error) {
- return properties.Load([]byte(value), properties.UTF8)
-}
-
func (o *runCmdOptions) GetIntegrationName(sources []string) string {
name := ""
if o.IntegrationName != "" {
diff --git a/pkg/cmd/run_help.go b/pkg/cmd/run_help.go
index 55ea888..0bd45fe 100644
--- a/pkg/cmd/run_help.go
+++ b/pkg/cmd/run_help.go
@@ -27,6 +27,7 @@ import (
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/client"
"github.com/apache/camel-k/pkg/util/kubernetes"
+ "github.com/magiconair/properties"
)
var invalidPaths = []string{"/etc/camel", "/deployments/dependencies"}
@@ -277,3 +278,38 @@ func filterFileLocation(maybeFileLocations []string) []string {
}
return filteredOptions
}
+
+func mergePropertiesWithPrecedence(items []string) (*properties.Properties, error) {
+ loPrecedenceProps := properties.NewProperties()
+ hiPrecedenceProps := properties.NewProperties()
+ for _, item := range items {
+ prop, err := extractProperties(item)
+ if err != nil {
+ return nil, err
+ }
+ // We consider file props to have a lower priority versus single properties
+ if strings.HasPrefix(item, "file:") {
+ loPrecedenceProps.Merge(prop)
+ } else {
+ hiPrecedenceProps.Merge(prop)
+ }
+ }
+ // Any property contained in both collections will be merged
+ // giving precedence to the ones in hiPrecedenceProps
+ loPrecedenceProps.Merge(hiPrecedenceProps)
+ return loPrecedenceProps, nil
+}
+
+// The function parse the value and if it is a file (file:/path/), it will parse as property file
+// otherwise return a single property built from the item passed as `key=value`
+func extractProperties(value string) (*properties.Properties, error) {
+ if !strings.HasPrefix(value, "file:") {
+ return keyValueProps(value)
+ }
+ // we already validated the existence of files during validate()
+ return loadPropertyFile(strings.Replace(value, "file:", "", 1))
+}
+
+func keyValueProps(value string) (*properties.Properties, error) {
+ return properties.Load([]byte(value), properties.UTF8)
+}
diff --git a/pkg/cmd/run_help_test.go b/pkg/cmd/run_help_test.go
index a7d92bb..02f852d 100644
--- a/pkg/cmd/run_help_test.go
+++ b/pkg/cmd/run_help_test.go
@@ -18,6 +18,8 @@ limitations under the License.
package cmd
import (
+ "io/ioutil"
+ "os"
"testing"
"github.com/stretchr/testify/assert"
@@ -173,3 +175,64 @@ func TestValidateFileLocation(t *testing.T) {
assert.NotNil(t, err)
assert.Equal(t, "you cannot mount a file under /deployments/dependencies path", err.Error())
}
+
+func TestExtractProperties_SingleKeyValue(t *testing.T) {
+ correctValues := []string{"key=val", "key = val", "key= val", " key = val"}
+ for _, val := range correctValues {
+ prop, err := extractProperties(val)
+ assert.Nil(t, err)
+ value, ok := prop.Get("key")
+ assert.True(t, ok)
+ assert.Equal(t, "val", value)
+ }
+}
+
+func TestExtractProperties_FromFile(t *testing.T) {
+ var tmpFile1 *os.File
+ var err error
+ if tmpFile1, err = ioutil.TempFile("", "camel-k-*.properties"); err != nil {
+ t.Error(err)
+ }
+
+ assert.Nil(t, tmpFile1.Close())
+ assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte(`
+ key=value
+ #key2=value2
+ my.key=value
+ `), 0644))
+
+ props, err := extractProperties("file:" + tmpFile1.Name())
+ assert.Nil(t, err)
+ assert.Equal(t, 2, props.Len())
+ for _, prop := range props.Keys() {
+ value, ok := props.Get(prop)
+ assert.True(t, ok)
+ assert.Equal(t, "value", value)
+ }
+}
+
+func TestExtractPropertiesFromFileAndSingleValue(t *testing.T) {
+ var tmpFile1 *os.File
+ var err error
+ if tmpFile1, err = ioutil.TempFile("", "camel-k-*.properties"); err != nil {
+ t.Error(err)
+ }
+
+ assert.Nil(t, tmpFile1.Close())
+ assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte(`
+ key=value
+ #key2=value2
+ my.key=value
+ `), 0644))
+
+ properties := []string{"key=override", "file:" + tmpFile1.Name(), "my.key = override"}
+ props, err := mergePropertiesWithPrecedence(properties)
+ assert.Nil(t, err)
+ assert.Equal(t, 2, props.Len())
+ val, ok := props.Get("key")
+ assert.True(t, ok)
+ assert.Equal(t, "override", val)
+ val, ok = props.Get("my.key")
+ assert.True(t, ok)
+ assert.Equal(t, "override", val)
+}
diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go
index 00ca7fb..6da2bf0 100644
--- a/pkg/cmd/run_test.go
+++ b/pkg/cmd/run_test.go
@@ -565,41 +565,6 @@ func TestResolveJsonPodTemplate(t *testing.T) {
assert.Equal(t, 2, len(integrationSpec.PodTemplate.Spec.Containers))
}
-func TestExtractProperties_SingleKeyValue(t *testing.T) {
- correctValues := []string{"key=val", "key = val", "key= val", " key = val"}
- for _, val := range correctValues {
- prop, err := extractProperties(val)
- assert.Nil(t, err)
- value, ok := prop.Get("key")
- assert.True(t, ok)
- assert.Equal(t, "val", value)
- }
-}
-
-func TestExtractProperties_FromFile(t *testing.T) {
- var tmpFile1 *os.File
- var err error
- if tmpFile1, err = ioutil.TempFile("", "camel-k-*.properties"); err != nil {
- t.Error(err)
- }
-
- assert.Nil(t, tmpFile1.Close())
- assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte(`
- key=value
- #key2=value2
- my.key=value
- `), 0644))
-
- props, err := extractProperties("file:" + tmpFile1.Name())
- assert.Nil(t, err)
- assert.Equal(t, 2, props.Len())
- for _, prop := range props.Keys() {
- value, ok := props.Get(prop)
- assert.True(t, ok)
- assert.Equal(t, "value", value)
- }
-}
-
func TestFilterBuildPropertyFiles(t *testing.T) {
inputValues := []string{"file:/tmp/test", "key=val"}
outputValues := filterBuildPropertyFiles(inputValues)