This is an automated email from the ASF dual-hosted git repository.
tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/main by this push:
new 36439e167 fix(cli): `kamel local build` doesn't support same
dependency notation
36439e167 is described below
commit 36439e167964489ad45e6348031d317f1b72003d
Author: Tadayoshi Sato <[email protected]>
AuthorDate: Wed Jul 13 14:40:54 2022 +0900
fix(cli): `kamel local build` doesn't support same dependency notation
This also fixes jitpack dependencies resolution.
Fix #2213.
---
e2e/local/files/dependency.groovy | 2 +-
e2e/local/local_build_test.go | 6 +-
e2e/local/local_run_test.go | 25 ++++++++
pkg/apis/camel/v1/integration_types_support.go | 25 +++++---
.../camel/v1/integration_types_support_test.go | 7 +++
pkg/cmd/local.go | 48 +++++++++++++---
pkg/cmd/local_build.go | 48 ++++++----------
pkg/cmd/local_build_test.go | 38 ++++++++++---
pkg/cmd/local_inspect.go | 35 ++++--------
pkg/cmd/local_inspect_test.go | 40 ++++++++++---
pkg/cmd/local_run.go | 57 +++++++------------
pkg/cmd/local_run_test.go | 66 +++++++++++-----------
pkg/cmd/{util_dependencies.go => local_util.go} | 45 ++++++---------
...til_dependencies_test.go => local_util_test.go} | 0
pkg/cmd/root.go | 5 +-
pkg/cmd/run.go | 4 +-
pkg/util/camel/camel_dependencies.go | 9 +--
17 files changed, 261 insertions(+), 199 deletions(-)
diff --git a/e2e/local/files/dependency.groovy
b/e2e/local/files/dependency.groovy
index d686acb8a..b5d56df17 100644
--- a/e2e/local/files/dependency.groovy
+++ b/e2e/local/files/dependency.groovy
@@ -1,4 +1,4 @@
-// camel-k: language=groovy dependency=camel:twitter
dependency=mvn:com.google.guava:guava:31.1-jre
dependency=github:squakez/samplejp:v1.0
+// camel-k: language=groovy dependency=camel-twitter
dependency=mvn:com.google.guava:guava:31.1-jre
dependency=github:squakez/samplejp:v1.0
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/e2e/local/local_build_test.go b/e2e/local/local_build_test.go
index ab3440b4b..2ea34f91b 100644
--- a/e2e/local/local_build_test.go
+++ b/e2e/local/local_build_test.go
@@ -195,7 +195,7 @@ func TestLocalBuildDependenciesOnly(t *testing.T) {
file := testutil.MakeTempCopy(t, "files/yaml.yaml")
dir := testutil.MakeTempDir(t)
- kamelBuild := KamelWithContext(ctx, "local", "build", file,
"--integration-directory", dir, "--dependencies-only")
+ kamelBuild := KamelWithContext(ctx, "local", "build", file,
"--integration-directory", dir, "--dependencies-only", "-d", "camel-amqp")
go func() {
err := kamelBuild.Execute()
@@ -206,6 +206,7 @@ func TestLocalBuildDependenciesOnly(t *testing.T) {
Eventually(dir+"/dependencies", TestTimeoutShort).Should(BeADirectory())
Eventually(dependency(dir, "org.apache.camel.camel-timer-%s.jar",
camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
Eventually(dependency(dir, "org.apache.camel.camel-log-%s.jar",
camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
+ Eventually(dependency(dir, "org.apache.camel.camel-amqp-%s.jar",
camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
Expect(dir + "/properties").ShouldNot(BeADirectory())
Expect(dir + "/routes/yaml.yaml").ShouldNot(BeAnExistingFile())
}
@@ -219,7 +220,7 @@ func TestLocalBuildModelineDependencies(t *testing.T) {
file := testutil.MakeTempCopy(t, "files/dependency.groovy")
dir := testutil.MakeTempDir(t)
- kamelBuild := KamelWithContext(ctx, "local", "build", file,
"--integration-directory", dir)
+ kamelBuild := KamelWithContext(ctx, "local", "build", file,
"--integration-directory", dir, "-d", "camel-amqp")
go func() {
err := kamelBuild.Execute()
@@ -229,6 +230,7 @@ func TestLocalBuildModelineDependencies(t *testing.T) {
Eventually(dir+"/dependencies", TestTimeoutShort).Should(BeADirectory())
Eventually(dependency(dir, "org.apache.camel.camel-timer-%s.jar",
camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
Eventually(dependency(dir, "org.apache.camel.camel-log-%s.jar",
camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
+ Eventually(dependency(dir, "org.apache.camel.camel-amqp-%s.jar",
camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
// camel dependency
Eventually(dependency(dir, "org.apache.camel.camel-twitter-%s.jar",
camelVersion), TestTimeoutMedium).Should(BeAnExistingFile())
// mvn dependency
diff --git a/e2e/local/local_run_test.go b/e2e/local/local_run_test.go
index e016b0119..c703e3825 100644
--- a/e2e/local/local_run_test.go
+++ b/e2e/local/local_run_test.go
@@ -60,6 +60,31 @@ func TestLocalRun(t *testing.T) {
Eventually(logScanner.IsFound("Magicstring!"),
TestTimeoutMedium).Should(BeTrue())
}
+func TestLocalRunWithDependencies(t *testing.T) {
+ RegisterTestingT(t)
+
+ ctx, cancel := context.WithCancel(TestContext)
+ defer cancel()
+ piper, pipew := io.Pipe()
+ defer pipew.Close()
+ defer piper.Close()
+
+ file := testutil.MakeTempCopy(t, "files/dependency.groovy")
+
+ kamelRun := KamelWithContext(ctx, "local", "run", file, "-d",
"camel-amqp")
+ kamelRun.SetOut(pipew)
+
+ logScanner := testutil.NewLogScanner(ctx, piper, "Magicstring!")
+
+ go func() {
+ err := kamelRun.Execute()
+ assert.NoError(t, err)
+ cancel()
+ }()
+
+ Eventually(logScanner.IsFound("Magicstring!"),
TestTimeoutMedium).Should(BeTrue())
+}
+
func TestLocalRunContainerize(t *testing.T) {
RegisterTestingT(t)
diff --git a/pkg/apis/camel/v1/integration_types_support.go
b/pkg/apis/camel/v1/integration_types_support.go
index 5b6fd9130..50316a081 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -105,14 +105,7 @@ func (in *IntegrationSpec) AddDependency(dependency
string) {
if in.Dependencies == nil {
in.Dependencies = make([]string, 0)
}
- newDep := dependency
- if strings.HasPrefix(newDep, "camel-quarkus-") {
- newDep = "camel:" + strings.TrimPrefix(dependency,
"camel-quarkus-")
- } else if strings.HasPrefix(newDep, "camel-quarkus:") {
- newDep = "camel:" + strings.TrimPrefix(dependency,
"camel-quarkus:")
- } else if strings.HasPrefix(newDep, "camel-") {
- newDep = "camel:" + strings.TrimPrefix(dependency, "camel-")
- }
+ newDep := NormalizeDependency(dependency)
for _, d := range in.Dependencies {
if d == newDep {
return
@@ -121,6 +114,22 @@ func (in *IntegrationSpec) AddDependency(dependency
string) {
in.Dependencies = append(in.Dependencies, newDep)
}
+// NormalizeDependency converts different forms of camel dependencies
+// -- `camel-xxx`, `camel-quarkus-xxx`, and `camel-quarkus:xxx` --
+// into the unified form `camel:xxx`.
+func NormalizeDependency(dependency string) string {
+ newDep := dependency
+ switch {
+ case strings.HasPrefix(newDep, "camel-quarkus-"):
+ newDep = "camel:" + strings.TrimPrefix(dependency,
"camel-quarkus-")
+ case strings.HasPrefix(newDep, "camel-quarkus:"):
+ newDep = "camel:" + strings.TrimPrefix(dependency,
"camel-quarkus:")
+ case strings.HasPrefix(newDep, "camel-"):
+ newDep = "camel:" + strings.TrimPrefix(dependency, "camel-")
+ }
+ return newDep
+}
+
// GetConfigurationProperty returns a configuration property
func (in *IntegrationSpec) GetConfigurationProperty(property string) string {
for _, confSpec := range in.Configuration {
diff --git a/pkg/apis/camel/v1/integration_types_support_test.go
b/pkg/apis/camel/v1/integration_types_support_test.go
index 6f4d4827c..7a5e81d86 100644
--- a/pkg/apis/camel/v1/integration_types_support_test.go
+++ b/pkg/apis/camel/v1/integration_types_support_test.go
@@ -74,6 +74,13 @@ func TestAddDependency(t *testing.T) {
assert.Equal(t, integration.Dependencies, []string{"file:dep"})
}
+func TestNormalizeDependency(t *testing.T) {
+ assert.Equal(t, "camel:file", NormalizeDependency("camel-file"))
+ assert.Equal(t, "camel:file", NormalizeDependency("camel:file"))
+ assert.Equal(t, "camel:file", NormalizeDependency("camel-quarkus-file"))
+ assert.Equal(t, "camel:file", NormalizeDependency("camel-quarkus:file"))
+}
+
func TestGetConfigurationProperty(t *testing.T) {
integration := IntegrationSpec{}
integration.AddConfiguration("property", "key1=value1")
diff --git a/pkg/cmd/local.go b/pkg/cmd/local.go
index cac6e51d5..1a480490f 100644
--- a/pkg/cmd/local.go
+++ b/pkg/cmd/local.go
@@ -20,25 +20,57 @@ package cmd
import (
"fmt"
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/spf13/cobra"
)
// newCmdLocal -- Add local kamel subcommand with several other subcommands of
its own.
-func newCmdLocal(rootCmdOptions *RootCmdOptions) *cobra.Command {
+func newCmdLocal(rootCmdOptions *RootCmdOptions) (*cobra.Command,
*LocalCmdOptions) {
+ options := LocalCmdOptions{
+ RootCmdOptions: rootCmdOptions,
+ }
+
cmd := cobra.Command{
- Use: "local [sub-command]",
- Short: "Perform integration actions locally.",
- Long: `Perform integration actions locally given a set of
input integration files.`,
+ Use: "local [sub-command]",
+ Short: "Perform integration actions locally.",
+ Long: `Perform integration actions locally given a
set of input integration files.`,
+ PersistentPreRunE: options.persistentPreRun,
Annotations: map[string]string{
offlineCommandLabel: "true",
},
}
- cmd.AddCommand(cmdOnly(newCmdLocalBuild(rootCmdOptions)))
- cmd.AddCommand(cmdOnly(newCmdLocalInspect(rootCmdOptions)))
- cmd.AddCommand(cmdOnly(newCmdLocalRun(rootCmdOptions)))
+ cmd.PersistentFlags().StringArrayVarP(&options.Dependencies,
"dependency", "d", nil, usageDependency)
+
+ // hidden flags for compatibility with kamel run
+ cmd.PersistentFlags().StringArrayVarP(&options.Traits, "trait", "t",
nil, "")
+ if err := cmd.PersistentFlags().MarkHidden("trait"); err != nil {
+ fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
+ }
+
+ cmd.AddCommand(cmdOnly(newCmdLocalBuild(&options)))
+ cmd.AddCommand(cmdOnly(newCmdLocalInspect(&options)))
+ cmd.AddCommand(cmdOnly(newCmdLocalRun(&options)))
+
+ return &cmd, &options
+}
+
+type LocalCmdOptions struct {
+ *RootCmdOptions
+ Dependencies []string `mapstructure:"dependencies"`
+ Traits []string `mapstructure:"traits"`
+}
+
+func (o *LocalCmdOptions) persistentPreRun(cmd *cobra.Command, args []string)
error {
+ // pre-process dependencies
+ for i, dependency := range o.Dependencies {
+ o.Dependencies[i] = v1.NormalizeDependency(dependency)
+ }
+
+ // validate traits
+ warnTraitUsages(cmd, o.Traits)
- return &cmd
+ return nil
}
func warnTraitUsages(cmd *cobra.Command, traits []string) {
diff --git a/pkg/cmd/local_build.go b/pkg/cmd/local_build.go
index 222c510de..5c0d72cd4 100644
--- a/pkg/cmd/local_build.go
+++ b/pkg/cmd/local_build.go
@@ -26,9 +26,9 @@ import (
"github.com/apache/camel-k/pkg/util"
)
-func newCmdLocalBuild(rootCmdOptions *RootCmdOptions) (*cobra.Command,
*localBuildCmdOptions) {
+func newCmdLocalBuild(localCmdOptions *LocalCmdOptions) (*cobra.Command,
*localBuildCmdOptions) {
options := localBuildCmdOptions{
- RootCmdOptions: rootCmdOptions,
+ LocalCmdOptions: localCmdOptions,
}
cmd := cobra.Command{
@@ -37,7 +37,7 @@ func newCmdLocalBuild(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *localBui
Long: `Build integration images locally for containerized
integrations.`,
PreRunE: decode(&options),
RunE: func(cmd *cobra.Command, args []string) error {
- if err := options.validate(cmd, args); err != nil {
+ if err := options.validate(args); err != nil {
return err
}
if err := options.init(args); err != nil {
@@ -64,50 +64,38 @@ func newCmdLocalBuild(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *localBui
cmd.Flags().String("integration-directory", "", "Directory to hold
local integration files.")
cmd.Flags().StringArray("property-file", nil, "Add a property file to
the integration.")
cmd.Flags().StringArrayP("property", "p", nil, "Add a Camel property to
the integration.")
- cmd.Flags().StringArrayP("dependency", "d", nil, "Add an additional
dependency")
cmd.Flags().StringArray("maven-repository", nil, "Use a maven
repository")
- // hidden flags for compatibility with kamel run
- cmd.Flags().StringArrayP("trait", "t", nil, "")
- if err := cmd.Flags().MarkHidden("trait"); err != nil {
- fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
- }
-
return &cmd, &options
}
type localBuildCmdOptions struct {
- *RootCmdOptions
- BaseImage bool `mapstructure:"base-image"`
- DependenciesOnly bool `mapstructure:"dependencies-only"`
- ContainerRegistry string `mapstructure:"container-registry"`
- Image string `mapstructure:"image"`
- IntegrationDirectory string `mapstructure:"integration-directory"`
- AdditionalDependencies []string `mapstructure:"dependencies"`
- Properties []string `mapstructure:"properties"`
- PropertyFiles []string `mapstructure:"property-files"`
- MavenRepositories []string `mapstructure:"maven-repositories"`
- Traits []string `mapstructure:"traits"`
+ *LocalCmdOptions
+ BaseImage bool `mapstructure:"base-image"`
+ DependenciesOnly bool `mapstructure:"dependencies-only"`
+ ContainerRegistry string `mapstructure:"container-registry"`
+ Image string `mapstructure:"image"`
+ IntegrationDirectory string `mapstructure:"integration-directory"`
+ Properties []string `mapstructure:"properties"`
+ PropertyFiles []string `mapstructure:"property-files"`
+ MavenRepositories []string `mapstructure:"maven-repositories"`
}
-func (command *localBuildCmdOptions) validate(cmd *cobra.Command, args
[]string) error {
+func (command *localBuildCmdOptions) validate(args []string) error {
// Validate integration files.
if len(args) > 0 {
- err := validateIntegrationFiles(args)
- if err != nil {
+ if err := validateIntegrationFiles(args); err != nil {
return err
}
}
// Validate additional dependencies specified by the user.
- err := validateAdditionalDependencies(command.AdditionalDependencies)
- if err != nil {
+ if err := validateDependencies(command.Dependencies); err != nil {
return err
}
// Validate properties file.
- err = validateFiles(command.PropertyFiles)
- if err != nil {
+ if err := validateFiles(command.PropertyFiles); err != nil {
return err
}
@@ -136,8 +124,6 @@ func (command *localBuildCmdOptions) validate(cmd
*cobra.Command, args []string)
return errors.New("to output dependencies the integration
directory flag must be set")
}
- warnTraitUsages(cmd, command.Traits)
-
return nil
}
@@ -176,7 +162,7 @@ func (command *localBuildCmdOptions) run(cmd
*cobra.Command, args []string) erro
var dependenciesList, propertyFilesList []string
routeFiles := args
if !command.BaseImage {
- dependencies, err := getDependencies(command.Context, args,
command.AdditionalDependencies, command.MavenRepositories, true)
+ dependencies, err := GetDependencies(command.Context, args,
command.Dependencies, command.MavenRepositories, true)
if err != nil {
return err
}
diff --git a/pkg/cmd/local_build_test.go b/pkg/cmd/local_build_test.go
index 8519bd1a4..5c9db5ff2 100644
--- a/pkg/cmd/local_build_test.go
+++ b/pkg/cmd/local_build_test.go
@@ -22,28 +22,52 @@ import (
"github.com/apache/camel-k/pkg/util/test"
"github.com/spf13/cobra"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func addTestLocalBuildCmd(rootCmdOptions *RootCmdOptions, rootCmd
*cobra.Command) *localBuildCmdOptions {
+ localCmd, localCmdOptions := newCmdLocal(rootCmdOptions)
+ // remove predefined sub commands
+ localCmd.RemoveCommand(localCmd.Commands()...)
// add a testing version of build Command
- localBuildCmd, localBuildCmdOptions := newCmdLocalBuild(rootCmdOptions)
+ localBuildCmd, localBuildCmdOptions := newCmdLocalBuild(localCmdOptions)
localBuildCmd.RunE = func(c *cobra.Command, args []string) error {
return nil
}
localBuildCmd.Args = test.ArbitraryArgs
- rootCmd.AddCommand(localBuildCmd)
+ localCmd.AddCommand(localBuildCmd)
+ rootCmd.AddCommand(localCmd)
return localBuildCmdOptions
}
func TestLocalBuildAcceptsTraits(t *testing.T) {
options, rootCmd := kamelTestPreAddCommandInit()
-
addTestLocalBuildCmd(options, rootCmd)
+ kamelTestPostAddCommandInit(t, rootCmd)
+
+ _, err := test.ExecuteCommand(rootCmd, "local", "build", "route.java",
+ "-t", "jolokia.enabled=true",
+ "--trait", "prometheus.enabled=true")
+
+ require.NoError(t, err)
+}
+func TestLocalBuildWithDependencies(t *testing.T) {
+ options, rootCmd := kamelTestPreAddCommandInit()
+ localBuildCmdOptions := addTestLocalBuildCmd(options, rootCmd)
kamelTestPostAddCommandInit(t, rootCmd)
- _, err := test.ExecuteCommand(rootCmd, "build", "route.java", "-t",
"jolokia.enabled=true", "--trait", "prometheus.enabled=true")
- if err != nil {
- t.Fatalf("Unexpected error: %v", err)
- }
+ _, err := test.ExecuteCommand(rootCmd, "local", "build", "route.java",
+ "-d", "camel-amqp",
+ "-d", "camel:bean",
+ "-d", "camel-quarkus-controlbus",
+ "-d", "camel-quarkus:directvm",
+ "--dependency", "mvn:test:component:1.0.0")
+
+ require.NoError(t, err)
+ assert.Len(t, localBuildCmdOptions.Dependencies, 5)
+ assert.ElementsMatch(t, localBuildCmdOptions.Dependencies, []string{
+ "camel:amqp", "camel:bean", "camel:controlbus",
"camel:directvm", "mvn:test:component:1.0.0",
+ })
}
diff --git a/pkg/cmd/local_inspect.go b/pkg/cmd/local_inspect.go
index e4e6c95cf..54fca9862 100644
--- a/pkg/cmd/local_inspect.go
+++ b/pkg/cmd/local_inspect.go
@@ -23,9 +23,9 @@ import (
"github.com/spf13/cobra"
)
-func newCmdLocalInspect(rootCmdOptions *RootCmdOptions) (*cobra.Command,
*localInspectCmdOptions) {
+func newCmdLocalInspect(localCmdOptions *LocalCmdOptions) (*cobra.Command,
*localInspectCmdOptions) {
options := localInspectCmdOptions{
- RootCmdOptions: rootCmdOptions,
+ LocalCmdOptions: localCmdOptions,
}
cmd := cobra.Command{
@@ -36,7 +36,7 @@ top level dependencies only. When --all-dependencies is
enabled, the transitive
will be generated by calling Maven and then printed in the selected output
format.`,
PreRunE: decode(&options),
RunE: func(cmd *cobra.Command, args []string) error {
- if err := options.validate(cmd, args); err != nil {
+ if err := options.validate(args); err != nil {
return err
}
if err := options.init(); err != nil {
@@ -57,41 +57,28 @@ will be generated by calling Maven and then printed in the
selected output forma
}
cmd.Flags().Bool("all-dependencies", false, "Enable computation of
transitive dependencies.")
- cmd.Flags().StringArrayP("dependency", "d", nil,
additionalDependencyUsageMessage)
cmd.Flags().StringP("output", "o", "", "Output format. One of:
json|yaml")
cmd.Flags().StringArray("maven-repository", nil, "Use a maven
repository")
- // hidden flags for compatibility with kamel run
- cmd.Flags().StringArrayP("trait", "t", nil, "")
- if err := cmd.Flags().MarkHidden("trait"); err != nil {
- fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
- }
-
return &cmd, &options
}
type localInspectCmdOptions struct {
- *RootCmdOptions
- AllDependencies bool `mapstructure:"all-dependencies"`
- OutputFormat string `mapstructure:"output"`
- AdditionalDependencies []string `mapstructure:"dependencies"`
- MavenRepositories []string `mapstructure:"maven-repositories"`
- Traits []string `mapstructure:"traits"`
+ *LocalCmdOptions
+ AllDependencies bool `mapstructure:"all-dependencies"`
+ OutputFormat string `mapstructure:"output"`
+ MavenRepositories []string `mapstructure:"maven-repositories"`
}
-func (command *localInspectCmdOptions) validate(cmd *cobra.Command, args
[]string) error {
- err := validateIntegrationFiles(args)
- if err != nil {
+func (command *localInspectCmdOptions) validate(args []string) error {
+ if err := validateIntegrationFiles(args); err != nil {
return err
}
- err = validateAdditionalDependencies(command.AdditionalDependencies)
- if err != nil {
+ if err := validateDependencies(command.Dependencies); err != nil {
return err
}
- warnTraitUsages(cmd, command.Traits)
-
return nil
}
@@ -100,7 +87,7 @@ func (command *localInspectCmdOptions) init() error {
}
func (command *localInspectCmdOptions) run(cmd *cobra.Command, args []string)
error {
- dependencies, err := getDependencies(command.Context, args,
command.AdditionalDependencies, command.MavenRepositories,
command.AllDependencies)
+ dependencies, err := GetDependencies(command.Context, args,
command.Dependencies, command.MavenRepositories, command.AllDependencies)
if err != nil {
return err
}
diff --git a/pkg/cmd/local_inspect_test.go b/pkg/cmd/local_inspect_test.go
index 993ea88b9..92fad62be 100644
--- a/pkg/cmd/local_inspect_test.go
+++ b/pkg/cmd/local_inspect_test.go
@@ -22,28 +22,52 @@ import (
"github.com/apache/camel-k/pkg/util/test"
"github.com/spf13/cobra"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func addTestLocalInspectCmd(rootCmdOptions *RootCmdOptions, rootCmd
*cobra.Command) *localInspectCmdOptions {
+ localCmd, localCmdOptions := newCmdLocal(rootCmdOptions)
+ // remove predefined sub commands
+ localCmd.RemoveCommand(localCmd.Commands()...)
// add a testing version of inspect Command
- localInspectCmd, localInspectCmdOptions :=
newCmdLocalInspect(rootCmdOptions)
+ localInspectCmd, localInspectCmdOptions :=
newCmdLocalInspect(localCmdOptions)
localInspectCmd.RunE = func(c *cobra.Command, args []string) error {
return nil
}
localInspectCmd.Args = test.ArbitraryArgs
- rootCmd.AddCommand(localInspectCmd)
+ localCmd.AddCommand(localInspectCmd)
+ rootCmd.AddCommand(localCmd)
return localInspectCmdOptions
}
func TestLocalInspectAcceptsTraits(t *testing.T) {
- options, rootCmd := kamelTestPreAddCommandInit()
+ rootOptions, rootCmd := kamelTestPreAddCommandInit()
+ addTestLocalInspectCmd(rootOptions, rootCmd)
+ kamelTestPostAddCommandInit(t, rootCmd)
+
+ _, err := test.ExecuteCommand(rootCmd, "local", "inspect", "route.java",
+ "-t", "jolokia.enabled=true",
+ "--trait", "prometheus.enabled=true")
- addTestLocalInspectCmd(options, rootCmd)
+ require.NoError(t, err)
+}
+func TestLocalInspectWithDependencies(t *testing.T) {
+ rootOptions, rootCmd := kamelTestPreAddCommandInit()
+ options := addTestLocalInspectCmd(rootOptions, rootCmd)
kamelTestPostAddCommandInit(t, rootCmd)
- _, err := test.ExecuteCommand(rootCmd, "inspect", "route.java", "-t",
"jolokia.enabled=true", "--trait", "prometheus.enabled=true")
- if err != nil {
- t.Fatalf("Unexpected error: %v", err)
- }
+ _, err := test.ExecuteCommand(rootCmd, "local", "inspect", "route.java",
+ "-d", "camel-amqp",
+ "-d", "camel:bean",
+ "-d", "camel-quarkus-controlbus",
+ "-d", "camel-quarkus:directvm",
+ "--dependency", "mvn:test:component:1.0.0")
+
+ require.NoError(t, err)
+ assert.Len(t, options.Dependencies, 5)
+ assert.ElementsMatch(t, options.Dependencies, []string{
+ "camel:amqp", "camel:bean", "camel:controlbus",
"camel:directvm", "mvn:test:component:1.0.0",
+ })
}
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 1e347608c..ec021ed0d 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -29,9 +29,9 @@ import (
"github.com/apache/camel-k/pkg/util"
)
-func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command,
*localRunCmdOptions) {
+func newCmdLocalRun(localCmdOptions *LocalCmdOptions) (*cobra.Command,
*localRunCmdOptions) {
options := localRunCmdOptions{
- RootCmdOptions: rootCmdOptions,
+ LocalCmdOptions: localCmdOptions,
}
cmd := cobra.Command{
@@ -40,7 +40,7 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *localRunCm
Long: `Run integration locally using the input integration
files.`,
PreRunE: decode(&options),
RunE: func(cmd *cobra.Command, args []string) error {
- if err := options.validate(cmd, args); err != nil {
+ if err := options.validate(args); err != nil {
return err
}
if err := options.init(); err != nil {
@@ -80,51 +80,39 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *localRunCm
cmd.Flags().StringArrayP("env", "e", nil, "Flag to specify an
environment variable [--env VARIABLE=value].")
cmd.Flags().StringArray("property-file", nil, "Add a property file to
the integration.")
cmd.Flags().StringArrayP("property", "p", nil, "Add a Camel property to
the integration.")
- cmd.Flags().StringArrayP("dependency", "d", nil,
additionalDependencyUsageMessage)
cmd.Flags().StringArray("maven-repository", nil, "Use a maven
repository")
- // hidden flags for compatibility with kamel run
- cmd.Flags().StringArrayP("trait", "t", nil, "")
- if err := cmd.Flags().MarkHidden("trait"); err != nil {
- fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
- }
-
return &cmd, &options
}
type localRunCmdOptions struct {
- *RootCmdOptions
- Containerize bool `mapstructure:"containerize"`
- Image string `mapstructure:"image"`
- Network string `mapstructure:"network"`
- IntegrationDirectory string `mapstructure:"integration-directory"`
- EnvironmentVariables []string `mapstructure:"envs"`
- PropertyFiles []string `mapstructure:"property-files"`
- Properties []string `mapstructure:"properties"`
- AdditionalDependencies []string `mapstructure:"dependencies"`
- MavenRepositories []string `mapstructure:"maven-repositories"`
- Traits []string `mapstructure:"traits"`
+ *LocalCmdOptions
+ Containerize bool `mapstructure:"containerize"`
+ Image string `mapstructure:"image"`
+ Network string `mapstructure:"network"`
+ IntegrationDirectory string `mapstructure:"integration-directory"`
+ EnvironmentVariables []string `mapstructure:"envs"`
+ PropertyFiles []string `mapstructure:"property-files"`
+ Properties []string `mapstructure:"properties"`
+ MavenRepositories []string `mapstructure:"maven-repositories"`
}
-func (command *localRunCmdOptions) validate(cmd *cobra.Command, args []string)
error {
+func (command *localRunCmdOptions) validate(args []string) error {
// Validate integration files when no image is provided and we are
// not running an already locally-built integration.
if command.Image == "" && command.IntegrationDirectory == "" {
- err := validateIntegrationFiles(args)
- if err != nil {
+ if err := validateIntegrationFiles(args); err != nil {
return err
}
}
// Validate additional dependencies specified by the user.
- err := validateAdditionalDependencies(command.AdditionalDependencies)
- if err != nil {
+ if err := validateDependencies(command.Dependencies); err != nil {
return err
}
// Validate properties file.
- err = validatePropertyFiles(command.PropertyFiles)
- if err != nil {
+ if err := validatePropertyFiles(command.PropertyFiles); err != nil {
return err
}
@@ -133,20 +121,16 @@ func (command *localRunCmdOptions) validate(cmd
*cobra.Command, args []string) e
return errors.New("containerization is active but no image name
has been provided")
}
- warnTraitUsages(cmd, command.Traits)
-
return nil
}
func (command *localRunCmdOptions) init() error {
if command.Containerize {
- err := createDockerBaseWorkingDirectory()
- if err != nil {
+ if err := createDockerBaseWorkingDirectory(); err != nil {
return err
}
- err = createDockerWorkingDirectory()
- if err != nil {
+ if err := createDockerWorkingDirectory(); err != nil {
return err
}
}
@@ -162,8 +146,7 @@ func (command *localRunCmdOptions) run(cmd *cobra.Command,
args []string) error
// If local run is provided with an image name, it will just run the
image locally and exit.
if command.Image != "" && !command.Containerize {
// Run image locally.
- err := runIntegrationImage(command.Context, command.Image,
cmd.OutOrStdout(), cmd.ErrOrStderr())
- if err != nil {
+ if err := runIntegrationImage(command.Context, command.Image,
cmd.OutOrStdout(), cmd.ErrOrStderr()); err != nil {
return err
}
@@ -209,7 +192,7 @@ func (command *localRunCmdOptions) run(cmd *cobra.Command,
args []string) error
return err
}
} else {
- computedDependencies, err := getDependencies(command.Context,
args, command.AdditionalDependencies, command.MavenRepositories, true)
+ computedDependencies, err := GetDependencies(command.Context,
args, command.Dependencies, command.MavenRepositories, true)
if err != nil {
return err
}
diff --git a/pkg/cmd/local_run_test.go b/pkg/cmd/local_run_test.go
index 1e4c08093..d6bdab05e 100644
--- a/pkg/cmd/local_run_test.go
+++ b/pkg/cmd/local_run_test.go
@@ -22,31 +22,35 @@ import (
"github.com/apache/camel-k/pkg/util/test"
"github.com/spf13/cobra"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func addTestLocalRunCmd(rootCmdOptions *RootCmdOptions, rootCmd
*cobra.Command) *localRunCmdOptions {
+ localCmd, localCmdOptions := newCmdLocal(rootCmdOptions)
+ // remove predefined sub commands
+ localCmd.RemoveCommand(localCmd.Commands()...)
// add a testing version of run Command
- localRunCmd, localRunCmdOptions := newCmdLocalRun(rootCmdOptions)
+ localRunCmd, localRunCmdOptions := newCmdLocalRun(localCmdOptions)
localRunCmd.RunE = func(c *cobra.Command, args []string) error {
return nil
}
localRunCmd.Args = test.ArbitraryArgs
- rootCmd.AddCommand(localRunCmd)
+ localCmd.AddCommand(localRunCmd)
+ rootCmd.AddCommand(localCmd)
return localRunCmdOptions
}
func TestLocalRunPropertyFileFlag(t *testing.T) {
options, rootCmd := kamelTestPreAddCommandInit()
-
localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
-
kamelTestPostAddCommandInit(t, rootCmd)
- _, err := test.ExecuteCommand(rootCmd, "run", "route.java",
"--property-file", "file1.properties", "--property-file", "file2.properties")
- if err != nil {
- t.Fatalf("Unexpected error: %v", err)
- }
+ _, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+ "--property-file", "file1.properties",
+ "--property-file", "file2.properties")
+ require.NoError(t, err)
if len(localRunCmdOptions.PropertyFiles) != 2 {
t.Fatalf("Property files expected to contain: \n %v
elements\nGot:\n %v elements\n", 2, len(localRunCmdOptions.PropertyFiles))
}
@@ -57,16 +61,14 @@ func TestLocalRunPropertyFileFlag(t *testing.T) {
func TestLocalRunPropertiesFlag(t *testing.T) {
options, rootCmd := kamelTestPreAddCommandInit()
-
localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
-
kamelTestPostAddCommandInit(t, rootCmd)
- _, err := test.ExecuteCommand(rootCmd, "run", "route.java", "-p",
"prop1=value1", "-p", "prop2=value2")
- if err != nil {
- t.Fatalf("Unexpected error: %v", err)
- }
+ _, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+ "-p", "prop1=value1",
+ "-p", "prop2=value2")
+ require.NoError(t, err)
if len(localRunCmdOptions.Properties) != 2 {
t.Fatalf("Additional dependencies expected to contain: \n %v
elements\nGot:\n %v elements\n", 2, len(localRunCmdOptions.Properties))
}
@@ -77,33 +79,31 @@ func TestLocalRunPropertiesFlag(t *testing.T) {
func TestLocalRunAdditionalDependenciesFlag(t *testing.T) {
options, rootCmd := kamelTestPreAddCommandInit()
-
localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
-
kamelTestPostAddCommandInit(t, rootCmd)
- _, err := test.ExecuteCommand(rootCmd, "run", "route.java", "-d",
"mvn:camel-component-1", "-d", "mvn:camel-component-2")
- if err != nil {
- t.Fatalf("Unexpected error: %v", err)
- }
-
- if len(localRunCmdOptions.AdditionalDependencies) != 2 {
- t.Fatalf("Additional dependencies expected to contain: \n %v
elements\nGot:\n %v elements\n", 2,
len(localRunCmdOptions.AdditionalDependencies))
- }
- if localRunCmdOptions.AdditionalDependencies[0] !=
"mvn:camel-component-1" || localRunCmdOptions.AdditionalDependencies[1] !=
"mvn:camel-component-2" {
- t.Fatalf("Additional dependencies expected to be: \n %v\nGot:\n
%v\n", "[mvn:camel-component-1, mvn:camel-component-2]",
localRunCmdOptions.AdditionalDependencies)
- }
+ _, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+ "-d", "camel-amqp",
+ "-d", "camel:bean",
+ "-d", "camel-quarkus-controlbus",
+ "-d", "camel-quarkus:directvm",
+ "--dependency", "mvn:test:component:1.0.0")
+
+ require.NoError(t, err)
+ assert.Len(t, localRunCmdOptions.Dependencies, 5)
+ assert.ElementsMatch(t, localRunCmdOptions.Dependencies, []string{
+ "camel:amqp", "camel:bean", "camel:controlbus",
"camel:directvm", "mvn:test:component:1.0.0",
+ })
}
func TestLocalRunAcceptsTraits(t *testing.T) {
options, rootCmd := kamelTestPreAddCommandInit()
-
addTestLocalRunCmd(options, rootCmd)
-
kamelTestPostAddCommandInit(t, rootCmd)
- _, err := test.ExecuteCommand(rootCmd, "run", "route.java", "-t",
"jolokia.enabled=true", "--trait", "prometheus.enabled=true")
- if err != nil {
- t.Fatalf("Unexpected error: %v", err)
- }
+ _, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+ "-t", "jolokia.enabled=true",
+ "--trait", "prometheus.enabled=true")
+
+ require.NoError(t, err)
}
diff --git a/pkg/cmd/util_dependencies.go b/pkg/cmd/local_util.go
similarity index 91%
rename from pkg/cmd/util_dependencies.go
rename to pkg/cmd/local_util.go
index e8f609d3f..c9b04feda 100644
--- a/pkg/cmd/util_dependencies.go
+++ b/pkg/cmd/local_util.go
@@ -38,13 +38,14 @@ import (
"github.com/apache/camel-k/pkg/util/maven"
)
-var acceptedDependencyTypes = []string{"bom", "camel", "camel-k",
"camel-quarkus", "mvn", "github"}
-
-var additionalDependencyUsageMessage = `Additional top-level dependencies are
specified with the format:
-<type>:<dependency-name>
-where <type> is one of {` + strings.Join(acceptedDependencyTypes, "|") + `}.`
+var acceptedDependencyTypes = []string{
+ "bom", "camel", "camel-k", "camel-quarkus", "mvn",
+ // jitpack
+ "github", "gitlab", "bitbucket", "gitee", "azure",
+}
-func getDependencies(ctx context.Context, args []string,
additionalDependencies []string, repositories []string, allDependencies bool)
([]string, error) {
+// GetDependencies resolves and gets the list of dependencies from catalog and
sources.
+func GetDependencies(ctx context.Context, args []string,
additionalDependencies []string, repositories []string, allDependencies bool)
([]string, error) {
// Fetch existing catalog or create new one if one does not already
exist
catalog, err := createCamelCatalog(ctx)
if err != nil {
@@ -109,8 +110,7 @@ func getTransitiveDependencies(ctx context.Context, catalog
*camel.RuntimeCatalo
catalog.CamelCatalogSpec.Runtime.Metadata["quarkus.version"],
)
- err := camel.ManageIntegrationDependencies(&project, dependencies,
catalog)
- if err != nil {
+ if err := camel.ManageIntegrationDependencies(&project, dependencies,
catalog); err != nil {
return nil, err
}
@@ -132,8 +132,7 @@ func getTransitiveDependencies(ctx context.Context, catalog
*camel.RuntimeCatalo
// Make maven command less verbose
mc.AdditionalArguments = append(mc.AdditionalArguments, "-q")
- err = builder.BuildQuarkusRunnerCommon(ctx, mc, project)
- if err != nil {
+ if err := builder.BuildQuarkusRunnerCommon(ctx, mc, project); err !=
nil {
return nil, err
}
@@ -293,31 +292,19 @@ func validateFiles(args []string) error {
return nil
}
-func validateAdditionalDependencies(additionalDependencies []string) error {
- // Validate list of additional dependencies i.e. make sure that each
dependency has a valid type
- for _, additionalDependency := range additionalDependencies {
- isValid := validateDependency(additionalDependency)
- if !isValid {
- return errors.New("Unexpected type for user-provided
dependency: " + additionalDependency + ". " + additionalDependencyUsageMessage)
+// validateDependencies validates list of additional dependencies i.e. makes
sure
+// that each dependency has a valid type.
+func validateDependencies(dependencies []string) error {
+ for _, dependency := range dependencies {
+ depType := strings.Split(dependency, ":")[0]
+ if !util.StringSliceExists(acceptedDependencyTypes, depType) {
+ return fmt.Errorf("dependency is not valid: %s",
dependency)
}
}
return nil
}
-func validateDependency(additionalDependency string) bool {
- dependencyComponents := strings.Split(additionalDependency, ":")
-
- TypeIsValid := false
- for _, dependencyType := range acceptedDependencyTypes {
- if dependencyType == dependencyComponents[0] {
- TypeIsValid = true
- }
- }
-
- return TypeIsValid
-}
-
func validateIntegrationFiles(args []string) error {
// If no source files have been provided there is nothing to inspect.
if len(args) == 0 {
diff --git a/pkg/cmd/util_dependencies_test.go b/pkg/cmd/local_util_test.go
similarity index 100%
rename from pkg/cmd/util_dependencies_test.go
rename to pkg/cmd/local_util_test.go
diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go
index abdde0747..c32a187e1 100644
--- a/pkg/cmd/root.go
+++ b/pkg/cmd/root.go
@@ -59,7 +59,6 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command,
error) {
ContextCancel: childCancel,
}
- var err error
cmd := kamelPreAddCommandInit(&options)
addKamelSubcommands(cmd, &options)
@@ -67,7 +66,7 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command,
error) {
return cmd, err
}
- err = kamelPostAddCommandInit(cmd)
+ err := kamelPostAddCommandInit(cmd)
return cmd, err
}
@@ -148,7 +147,7 @@ func addKamelSubcommands(cmd *cobra.Command, options
*RootCmdOptions) {
cmd.AddCommand(cmdOnly(newCmdInit(options)))
cmd.AddCommand(cmdOnly(newCmdDebug(options)))
cmd.AddCommand(cmdOnly(newCmdDump(options)))
- cmd.AddCommand(newCmdLocal(options))
+ cmd.AddCommand(cmdOnly(newCmdLocal(options)))
cmd.AddCommand(cmdOnly(newCmdBind(options)))
cmd.AddCommand(cmdOnly(newCmdPromote(options)))
cmd.AddCommand(newCmdKamelet(options))
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 27df5e167..9a02f5064 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -75,6 +75,8 @@ import (
"github.com/apache/camel-k/pkg/util/watch"
)
+const usageDependency = `A dependency that should be included, e.g., "-d
camel-mail" for a Camel component, "-d mvn:org.my:app:1.0" for a Maven
dependency or
"file://localPath[?targetPath=<path>®istry=<registry_URL>&skipChecksums=<true>&skipPOM=<true>]"
for local files (experimental)`
+
func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command,
*runCmdOptions) {
options := runCmdOptions{
RootCmdOptions: rootCmdOptions,
@@ -94,7 +96,7 @@ func newCmdRun(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *runCmdOptions)
cmd.Flags().String("name", "", "The integration name")
cmd.Flags().StringArrayP("connect", "c", nil, "A Service that the
integration should bind to, specified as
[[apigroup/]version:]kind:[namespace/]name")
- cmd.Flags().StringArrayP("dependency", "d", nil, "A dependency that
should be included, e.g., \"-d camel-mail\" for a Camel component, \"-d
mvn:org.my:app:1.0\" for a Maven dependency or
\"file://localPath[?targetPath=<path>®istry=<registry
URL>&skipChecksums=<true>&skipPOM=<true>]\" for local files (experimental)")
+ cmd.Flags().StringArrayP("dependency", "d", nil, usageDependency)
cmd.Flags().BoolP("wait", "w", false, "Wait for the integration to be
running")
cmd.Flags().StringP("kit", "k", "", "The kit used to run the
integration")
cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property
or properties file (syntax:
[my-key=my-value|file:/path/to/my-conf.properties])")
diff --git a/pkg/util/camel/camel_dependencies.go
b/pkg/util/camel/camel_dependencies.go
index ae43f9c7f..e6055f596 100644
--- a/pkg/util/camel/camel_dependencies.go
+++ b/pkg/util/camel/camel_dependencies.go
@@ -30,14 +30,9 @@ import (
)
// ManageIntegrationDependencies --.
-func ManageIntegrationDependencies(
- project *maven.Project,
- dependencies []string,
- catalog *RuntimeCatalog) error {
-
+func ManageIntegrationDependencies(project *maven.Project, dependencies
[]string, catalog *RuntimeCatalog) error {
// Add dependencies from build
- err := addDependencies(project, dependencies, catalog)
- if err != nil {
+ if err := addDependencies(project, dependencies, catalog); err != nil {
return err
}
// Add dependencies from catalog