You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2020/11/17 10:46:34 UTC

[camel-k] branch master updated (d8adb7d -> 1729ac5)

This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git.


    from d8adb7d  chore(doc): Generate PDB trait documentation
     new 5e82772  Add local run command.
     new 9edff32  Factor out common code between inspect and run-local commands.
     new 197c67f  Run existing integration locally.
     new 5ea1b6e  Add class containing main function.
     new a62cdf4  Ensure Maven working directory is kept until after the integration is run.
     new 9b2d0b2  Address comments. Clean-up code.
     new 430ba1b  Add test for property-file and dependency flags for local-run.
     new 334d848  Add support for modeline options.
     new f0e11b2  Update usage.
     new 8bcff84  Remove TODO comment. Remove printing of dependencies when running locally.
     new 184b36f  Add local run command. Resolve all modeline options.
     new 1729ac5  Remove old modeline support for just dependencies from dependency resolution..

The 12 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 pkg/cmd/inspect.go                           | 279 ++----------------------
 pkg/cmd/{version.go => local.go}             |  46 ++--
 pkg/cmd/local_run.go                         | 110 ++++++++++
 pkg/cmd/local_run_test.go                    |  78 +++++++
 pkg/cmd/modeline.go                          |  54 +++--
 pkg/cmd/root.go                              |   5 +
 pkg/cmd/util.go                              |   3 +-
 pkg/cmd/util_commands.go                     |  95 +++++++++
 pkg/cmd/{inspect.go => util_dependencies.go} | 308 +++++++++++++--------------
 pkg/cmd/util_sources.go                      |  46 ++--
 10 files changed, 542 insertions(+), 482 deletions(-)
 copy pkg/cmd/{version.go => local.go} (54%)
 create mode 100644 pkg/cmd/local_run.go
 create mode 100644 pkg/cmd/local_run_test.go
 create mode 100644 pkg/cmd/util_commands.go
 copy pkg/cmd/{inspect.go => util_dependencies.go} (60%)


[camel-k] 02/12: Factor out common code between inspect and run-local commands.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 9edff327323334b9e9b14063a980ba86b8fa4b9f
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Tue Nov 3 16:38:33 2020 -0500

    Factor out common code between inspect and run-local commands.
---
 pkg/cmd/inspect.go                           | 266 +-------------------------
 pkg/cmd/local_run.go                         |  77 +++-----
 pkg/cmd/{inspect.go => util_dependencies.go} | 269 ++++++++++++---------------
 3 files changed, 140 insertions(+), 472 deletions(-)

diff --git a/pkg/cmd/inspect.go b/pkg/cmd/inspect.go
index 02eed21..e524e56 100644
--- a/pkg/cmd/inspect.go
+++ b/pkg/cmd/inspect.go
@@ -19,27 +19,11 @@ package cmd
 
 import (
 	"fmt"
-	"io/ioutil"
-	"os"
-	"path"
 	"strings"
 
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/builder/runtime"
-	"github.com/apache/camel-k/pkg/trait"
-	"github.com/apache/camel-k/pkg/util"
-	"github.com/apache/camel-k/pkg/util/camel"
-	"github.com/apache/camel-k/pkg/util/defaults"
-	"github.com/apache/camel-k/pkg/util/maven"
-	"github.com/pkg/errors"
-	"github.com/scylladb/go-set/strset"
 	"github.com/spf13/cobra"
 )
 
-var acceptedDependencyTypes = []string{"bom", "camel", "camel-k", "camel-quarkus", "mvn", "github"}
-
-const defaultDependenciesDirectoryName = "dependencies"
-
 func newCmdInspect(rootCmdOptions *RootCmdOptions) (*cobra.Command, *inspectCmdOptions) {
 	options := inspectCmdOptions{
 		RootCmdOptions: rootCmdOptions,
@@ -84,261 +68,21 @@ type inspectCmdOptions struct {
 }
 
 func (command *inspectCmdOptions) validate(args []string) error {
-	// If no source files have been provided there is nothing to inspect.
-	if len(args) == 0 {
-		return errors.New("no integration files have been provided, nothing to inspect")
-	}
-
-	// Ensure source files exist.
-	for _, arg := range args {
-		// fmt.Printf("Validating file: %v\n", arg)
-		fileExists, err := util.FileExists(arg)
-
-		// Report any error.
-		if err != nil {
-			return err
-		}
-
-		// Signal file not found.
-		if !fileExists {
-			return errors.New("input file " + arg + " file does not exist")
-		}
-	}
-
-	// Validate list of additional dependencies i.e. make sure that each dependency has
-	// a valid type.
-	if command.AdditionalDependencies != nil {
-		for _, additionalDependency := range command.AdditionalDependencies {
-			dependencyComponents := strings.Split(additionalDependency, ":")
-
-			TypeIsValid := false
-			for _, dependencyType := range acceptedDependencyTypes {
-				if dependencyType == dependencyComponents[0] {
-					TypeIsValid = true
-				}
-			}
-
-			if !TypeIsValid {
-				return errors.New("Unexpected type for user-provided dependency: " + additionalDependency + ", check command usage for valid format.")
-			}
-
-		}
-	}
-
-	return nil
+	return validateIntegrationForDependencies(args, command.AdditionalDependencies)
 }
 
 func (command *inspectCmdOptions) run(args []string) error {
-	// Fetch existing catalog or create new one if one does not already exist.
-	catalog, err := createCamelCatalog()
-
-	// Get top-level dependencies, this is the default behavior when no other options are provided.
-	// Do not output these options when transitive options are enbled.
-	dependencies, err := getTopLevelDependencies(catalog, command.OutputFormat, args, !command.AllDependencies)
-	if err != nil {
-		return err
-	}
-
-	// Add additional user-provided dependencies.
-	if command.AdditionalDependencies != nil {
-		for _, additionalDependency := range command.AdditionalDependencies {
-			dependencies = append(dependencies, additionalDependency)
-		}
-	}
-
-	// Top level dependencies are printed out.
-	if command.AllDependencies {
-		// If --all-dependencies flag is set, move all transitive dependencies in the --dependencies-directory.
-		err = getTransitiveDependencies(catalog, dependencies, command)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func getTopLevelDependencies(catalog *camel.RuntimeCatalog, format string, args []string, printDependencies bool) ([]string, error) {
-	// List of top-level dependencies.
-	dependencies := strset.New()
-
-	// Invoke the dependency inspector code for each source file.
-	for _, source := range args {
-		data, _, err := loadContent(source, false, false)
-		if err != nil {
-			return []string{}, err
-		}
-
-		sourceSpec := v1.SourceSpec{
-			DataSpec: v1.DataSpec{
-				Name:        path.Base(source),
-				Content:     data,
-				Compression: false,
-			},
-		}
-
-		// Extract list of top-level dependencies.
-		dependencies.Merge(trait.AddSourceDependencies(sourceSpec, catalog))
-	}
-
-	if printDependencies {
-		err := outputDependencies(dependencies.List(), format)
-		if err != nil {
-			return []string{}, err
-		}
-	}
-
-	return dependencies.List(), nil
-}
-
-func generateCatalog() (*camel.RuntimeCatalog, error) {
-	// A Camel catalog is requiref for this operatio.
-	settings := ""
-	mvn := v1.MavenSpec{
-		LocalRepository: "",
-	}
-	runtime := v1.RuntimeSpec{
-		Version:  defaults.DefaultRuntimeVersion,
-		Provider: v1.RuntimeProviderQuarkus,
-	}
-	providerDependencies := []maven.Dependency{}
-	catalog, err := camel.GenerateCatalogCommon(settings, mvn, runtime, providerDependencies)
-	if err != nil {
-		return nil, err
-	}
-
-	return catalog, nil
-}
-
-func getTransitiveDependencies(
-	catalog *camel.RuntimeCatalog,
-	dependencies []string,
-	command *inspectCmdOptions) error {
-
-	mvn := v1.MavenSpec{
-		LocalRepository: "",
-	}
-
-	// Create Maven project.
-	project := runtime.GenerateQuarkusProjectCommon(
-		catalog.CamelCatalogSpec.Runtime.Metadata["camel-quarkus.version"],
-		defaults.DefaultRuntimeVersion, catalog.CamelCatalogSpec.Runtime.Metadata["quarkus.version"])
-
-	// Inject dependencies into Maven project.
-	err := camel.ManageIntegrationDependencies(&project, dependencies, catalog)
-	if err != nil {
-		return err
-	}
-
-	// Create local Maven context.
-	temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "maven-")
+	// Fetch dependencies.
+	dependencies, err := getDependencies(args, command.AdditionalDependencies, command.AllDependencies)
 	if err != nil {
 		return err
 	}
 
-	// Maven local context to be used for generating the transitive dependencies.
-	mc := maven.NewContext(temporaryDirectory, project)
-	mc.LocalRepository = mvn.LocalRepository
-	mc.Timeout = mvn.GetTimeout().Duration
-
-	// Make maven command less verbose.
-	mc.AdditionalArguments = append(mc.AdditionalArguments, "-q")
-
-	err = runtime.BuildQuarkusRunnerCommon(mc)
+	// Print dependencies.
+	err = outputDependencies(dependencies, command.OutputFormat)
 	if err != nil {
 		return err
 	}
 
-	// Compute dependencies.
-	content, err := runtime.ComputeQuarkusDependenciesCommon(mc, catalog.Runtime.Version)
-	if err != nil {
-		return err
-	}
-
-	// Compose artifacts list.
-	artifacts := []v1.Artifact{}
-	artifacts, err = runtime.ProcessQuarkusTransitiveDependencies(mc, content)
-	if err != nil {
-		return err
-	}
-
-	// Dump dependencies in the dependencies directory and construct the list of dependencies.
-	transitiveDependencies := []string{}
-	for _, entry := range artifacts {
-		transitiveDependencies = append(transitiveDependencies, entry.Location)
-	}
-
-	// Remove directory used for computing the dependencies.
-	defer os.RemoveAll(temporaryDirectory)
-
-	// Output transitive dependencies only if requested via the output format flag.
-	err = outputDependencies(transitiveDependencies, command.OutputFormat)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func outputDependencies(dependencies []string, format string) error {
-	if format != "" {
-		err := printDependencies(format, dependencies)
-		if err != nil {
-			return err
-		}
-	} else {
-		// Print output in text form.
-		for _, dep := range dependencies {
-			fmt.Printf("%v\n", dep)
-		}
-	}
-
 	return nil
 }
-
-func printDependencies(format string, dependecies []string) error {
-	switch format {
-	case "yaml":
-		data, err := util.DependenciesToYAML(dependecies)
-		if err != nil {
-			return err
-		}
-		fmt.Print(string(data))
-	case "json":
-		data, err := util.DependenciesToJSON(dependecies)
-		if err != nil {
-			return err
-		}
-		fmt.Print(string(data))
-	default:
-		return errors.New("unknown output format: " + format)
-	}
-	return nil
-}
-
-func getWorkingDirectory() (string, error) {
-	currentDirectory, err := os.Getwd()
-	if err != nil {
-		return "", err
-	}
-
-	return currentDirectory, nil
-}
-
-func createCamelCatalog() (*camel.RuntimeCatalog, error) {
-	// Attempt to reuse existing Camel catalog if one is present.
-	catalog, err := camel.DefaultCatalog()
-	if err != nil {
-		return nil, err
-	}
-
-	// Generate catalog if one was not found.
-	if catalog == nil {
-		catalog, err = generateCatalog()
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return catalog, nil
-}
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 70af154..8a0bdb2 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -18,15 +18,9 @@ limitations under the License.
 package cmd
 
 import (
-	"errors"
 	"fmt"
-	"path"
+	"strings"
 
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/trait"
-	"github.com/apache/camel-k/pkg/util"
-	"github.com/apache/camel-k/pkg/util/camel"
-	"github.com/scylladb/go-set/strset"
 	"github.com/spf13/cobra"
 )
 
@@ -55,76 +49,47 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 		},
 	}
 
-	cmd.Flags().StringP("properties", "p", "", "Output format. One of: json|yaml")
+	cmd.Flags().StringArrayP("properties-file", "p", nil, "File containing the integration properties.")
+	cmd.Flags().StringArrayP("dependency", "d", nil, `Additional top-level dependency with the format:
+<type>:<dependency-name>
+where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
 
 	return &cmd, &options
 }
 
 type localRunCmdOptions struct {
 	*RootCmdOptions
-	Properties string `mapstructure:"properties"`
+	PropertiesFiles        []string `mapstructure:"properties"`
+	AdditionalDependencies []string `mapstructure:"dependencies"`
 }
 
 func (command *localRunCmdOptions) validate(args []string) error {
-	// If no source files have been provided there is nothing to inspect.
-	if len(args) == 0 {
-		return errors.New("no integration files have been provided, nothing to inspect")
+	// Validate additional dependencies specified by the user.
+	err := validateIntegrationForDependencies(args, command.AdditionalDependencies)
+	if err != nil {
+		return err
 	}
 
-	// Ensure source files exist.
-	for _, arg := range args {
-		// fmt.Printf("Validating file: %v\n", arg)
-		fileExists, err := util.FileExists(arg)
-
-		// Report any error.
-		if err != nil {
-			return err
-		}
-
-		// Signal file not found.
-		if !fileExists {
-			return errors.New("input file " + arg + " file does not exist")
-		}
+	// Validate properties file.
+	err = validateFiles(command.PropertiesFiles)
+	if err != nil {
+		return nil
 	}
 
 	return nil
 }
 
 func (command *localRunCmdOptions) run(args []string) error {
-	// Attempt to reuse existing Camel catalog if one is present.
-	catalog, err := camel.MainCatalog()
+	// Fetch dependencies.
+	dependencies, err := getDependencies(args, command.AdditionalDependencies, true)
 	if err != nil {
 		return err
 	}
 
-	// Generate catalog if one was not found.
-	if catalog == nil {
-		catalog, err = generateCatalog()
-		if err != nil {
-			return err
-		}
-	}
-
-	// List of top-level dependencies.
-	dependencies := strset.New()
-
-	// Invoke the dependency inspector code for each source file.
-	for _, source := range args {
-		data, _, err := loadContent(source, false, false)
-		if err != nil {
-			return err
-		}
-
-		sourceSpec := v1.SourceSpec{
-			DataSpec: v1.DataSpec{
-				Name:        path.Base(source),
-				Content:     data,
-				Compression: false,
-			},
-		}
-
-		// Extract list of top-level dependencies.
-		dependencies.Merge(trait.AddSourceDependencies(sourceSpec, catalog))
+	// Print dependencies.
+	err = outputDependencies(dependencies, "")
+	if err != nil {
+		return err
 	}
 
 	return nil
diff --git a/pkg/cmd/inspect.go b/pkg/cmd/util_dependencies.go
similarity index 64%
copy from pkg/cmd/inspect.go
copy to pkg/cmd/util_dependencies.go
index 02eed21..49d0d07 100644
--- a/pkg/cmd/inspect.go
+++ b/pkg/cmd/util_dependencies.go
@@ -33,132 +33,41 @@ import (
 	"github.com/apache/camel-k/pkg/util/maven"
 	"github.com/pkg/errors"
 	"github.com/scylladb/go-set/strset"
-	"github.com/spf13/cobra"
 )
 
 var acceptedDependencyTypes = []string{"bom", "camel", "camel-k", "camel-quarkus", "mvn", "github"}
 
 const defaultDependenciesDirectoryName = "dependencies"
 
-func newCmdInspect(rootCmdOptions *RootCmdOptions) (*cobra.Command, *inspectCmdOptions) {
-	options := inspectCmdOptions{
-		RootCmdOptions: rootCmdOptions,
-	}
-
-	cmd := cobra.Command{
-		Use:   "inspect [files to inspect]",
-		Short: "Generate dependencies list given integration files.",
-		Long: `Output dependencies for a list of integration files. By default this command returns the
-top level dependencies only. When --all-dependencies is enabled, the transitive dependencies
-will be generated by calling Maven and then printed in the selected output format.`,
-		PreRunE: decode(&options),
-		RunE: func(_ *cobra.Command, args []string) error {
-			if err := options.validate(args); err != nil {
-				return err
-			}
-			if err := options.run(args); err != nil {
-				fmt.Println(err.Error())
-			}
-
-			return nil
-		},
-		Annotations: map[string]string{
-			offlineCommandLabel: "true",
-		},
-	}
-
-	cmd.Flags().Bool("all-dependencies", false, "Compute transitive dependencies and move them to directory pointed to by the --dependencies-directory flag.")
-	cmd.Flags().StringArrayP("dependency", "d", nil, `Additional top-level dependency with the format:
-<type>:<dependency-name>
-where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
-	cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml")
-
-	return &cmd, &options
-}
-
-type inspectCmdOptions struct {
-	*RootCmdOptions
-	AllDependencies        bool     `mapstructure:"all-dependencies"`
-	OutputFormat           string   `mapstructure:"output"`
-	AdditionalDependencies []string `mapstructure:"dependencies"`
-}
-
-func (command *inspectCmdOptions) validate(args []string) error {
-	// If no source files have been provided there is nothing to inspect.
-	if len(args) == 0 {
-		return errors.New("no integration files have been provided, nothing to inspect")
-	}
-
-	// Ensure source files exist.
-	for _, arg := range args {
-		// fmt.Printf("Validating file: %v\n", arg)
-		fileExists, err := util.FileExists(arg)
-
-		// Report any error.
-		if err != nil {
-			return err
-		}
-
-		// Signal file not found.
-		if !fileExists {
-			return errors.New("input file " + arg + " file does not exist")
-		}
-	}
-
-	// Validate list of additional dependencies i.e. make sure that each dependency has
-	// a valid type.
-	if command.AdditionalDependencies != nil {
-		for _, additionalDependency := range command.AdditionalDependencies {
-			dependencyComponents := strings.Split(additionalDependency, ":")
-
-			TypeIsValid := false
-			for _, dependencyType := range acceptedDependencyTypes {
-				if dependencyType == dependencyComponents[0] {
-					TypeIsValid = true
-				}
-			}
-
-			if !TypeIsValid {
-				return errors.New("Unexpected type for user-provided dependency: " + additionalDependency + ", check command usage for valid format.")
-			}
-
-		}
-	}
-
-	return nil
-}
-
-func (command *inspectCmdOptions) run(args []string) error {
+func getDependencies(args []string, additionalDependencies []string, allDependencies bool) ([]string, error) {
 	// Fetch existing catalog or create new one if one does not already exist.
 	catalog, err := createCamelCatalog()
 
-	// Get top-level dependencies, this is the default behavior when no other options are provided.
-	// Do not output these options when transitive options are enbled.
-	dependencies, err := getTopLevelDependencies(catalog, command.OutputFormat, args, !command.AllDependencies)
+	// Get top-level dependencies.
+	dependencies, err := getTopLevelDependencies(catalog, args)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	// Add additional user-provided dependencies.
-	if command.AdditionalDependencies != nil {
-		for _, additionalDependency := range command.AdditionalDependencies {
+	if additionalDependencies != nil {
+		for _, additionalDependency := range additionalDependencies {
 			dependencies = append(dependencies, additionalDependency)
 		}
 	}
 
-	// Top level dependencies are printed out.
-	if command.AllDependencies {
-		// If --all-dependencies flag is set, move all transitive dependencies in the --dependencies-directory.
-		err = getTransitiveDependencies(catalog, dependencies, command)
+	// Compute transitive dependencies.
+	if allDependencies {
+		dependencies, err = getTransitiveDependencies(catalog, dependencies)
 		if err != nil {
-			return err
+			return nil, err
 		}
 	}
 
-	return nil
+	return dependencies, nil
 }
 
-func getTopLevelDependencies(catalog *camel.RuntimeCatalog, format string, args []string, printDependencies bool) ([]string, error) {
+func getTopLevelDependencies(catalog *camel.RuntimeCatalog, args []string) ([]string, error) {
 	// List of top-level dependencies.
 	dependencies := strset.New()
 
@@ -181,39 +90,12 @@ func getTopLevelDependencies(catalog *camel.RuntimeCatalog, format string, args
 		dependencies.Merge(trait.AddSourceDependencies(sourceSpec, catalog))
 	}
 
-	if printDependencies {
-		err := outputDependencies(dependencies.List(), format)
-		if err != nil {
-			return []string{}, err
-		}
-	}
-
 	return dependencies.List(), nil
 }
 
-func generateCatalog() (*camel.RuntimeCatalog, error) {
-	// A Camel catalog is requiref for this operatio.
-	settings := ""
-	mvn := v1.MavenSpec{
-		LocalRepository: "",
-	}
-	runtime := v1.RuntimeSpec{
-		Version:  defaults.DefaultRuntimeVersion,
-		Provider: v1.RuntimeProviderQuarkus,
-	}
-	providerDependencies := []maven.Dependency{}
-	catalog, err := camel.GenerateCatalogCommon(settings, mvn, runtime, providerDependencies)
-	if err != nil {
-		return nil, err
-	}
-
-	return catalog, nil
-}
-
 func getTransitiveDependencies(
 	catalog *camel.RuntimeCatalog,
-	dependencies []string,
-	command *inspectCmdOptions) error {
+	dependencies []string) ([]string, error) {
 
 	mvn := v1.MavenSpec{
 		LocalRepository: "",
@@ -227,13 +109,13 @@ func getTransitiveDependencies(
 	// Inject dependencies into Maven project.
 	err := camel.ManageIntegrationDependencies(&project, dependencies, catalog)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	// Create local Maven context.
 	temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "maven-")
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	// Maven local context to be used for generating the transitive dependencies.
@@ -246,20 +128,20 @@ func getTransitiveDependencies(
 
 	err = runtime.BuildQuarkusRunnerCommon(mc)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	// Compute dependencies.
 	content, err := runtime.ComputeQuarkusDependenciesCommon(mc, catalog.Runtime.Version)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	// Compose artifacts list.
 	artifacts := []v1.Artifact{}
 	artifacts, err = runtime.ProcessQuarkusTransitiveDependencies(mc, content)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	// Dump dependencies in the dependencies directory and construct the list of dependencies.
@@ -271,13 +153,44 @@ func getTransitiveDependencies(
 	// Remove directory used for computing the dependencies.
 	defer os.RemoveAll(temporaryDirectory)
 
-	// Output transitive dependencies only if requested via the output format flag.
-	err = outputDependencies(transitiveDependencies, command.OutputFormat)
+	return transitiveDependencies, nil
+}
+
+func generateCatalog() (*camel.RuntimeCatalog, error) {
+	// A Camel catalog is requiref for this operatio.
+	settings := ""
+	mvn := v1.MavenSpec{
+		LocalRepository: "",
+	}
+	runtime := v1.RuntimeSpec{
+		Version:  defaults.DefaultRuntimeVersion,
+		Provider: v1.RuntimeProviderQuarkus,
+	}
+	providerDependencies := []maven.Dependency{}
+	catalog, err := camel.GenerateCatalogCommon(settings, mvn, runtime, providerDependencies)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
-	return nil
+	return catalog, nil
+}
+
+func createCamelCatalog() (*camel.RuntimeCatalog, error) {
+	// Attempt to reuse existing Camel catalog if one is present.
+	catalog, err := camel.DefaultCatalog()
+	if err != nil {
+		return nil, err
+	}
+
+	// Generate catalog if one was not found.
+	if catalog == nil {
+		catalog, err = generateCatalog()
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	return catalog, nil
 }
 
 func outputDependencies(dependencies []string, format string) error {
@@ -316,29 +229,75 @@ func printDependencies(format string, dependecies []string) error {
 	return nil
 }
 
-func getWorkingDirectory() (string, error) {
-	currentDirectory, err := os.Getwd()
+func validateFile(file string) error {
+	fileExists, err := util.FileExists(file)
+
+	// Report any error.
 	if err != nil {
-		return "", err
+		return err
 	}
 
-	return currentDirectory, nil
+	// Signal file not found.
+	if !fileExists {
+		return errors.New("File " + file + " file does not exist")
+	}
+
+	return nil
 }
 
-func createCamelCatalog() (*camel.RuntimeCatalog, error) {
-	// Attempt to reuse existing Camel catalog if one is present.
-	catalog, err := camel.DefaultCatalog()
-	if err != nil {
-		return nil, err
+func validateFiles(args []string) error {
+	// Ensure source files exist.
+	for _, arg := range args {
+		err := validateFile(arg)
+		if err != nil {
+			return nil
+		}
 	}
 
-	// Generate catalog if one was not found.
-	if catalog == nil {
-		catalog, err = generateCatalog()
-		if err != nil {
-			return nil, err
+	return nil
+}
+
+func validateAdditionalDependencies(additionalDependencies []string) error {
+	// Validate list of additional dependencies i.e. make sure that each dependency has
+	// a valid type.
+	if additionalDependencies != nil {
+		for _, additionalDependency := range additionalDependencies {
+			dependencyComponents := strings.Split(additionalDependency, ":")
+
+			TypeIsValid := false
+			for _, dependencyType := range acceptedDependencyTypes {
+				if dependencyType == dependencyComponents[0] {
+					TypeIsValid = true
+				}
+			}
+
+			if !TypeIsValid {
+				return errors.New("Unexpected type for user-provided dependency: " + additionalDependency + ", check command usage for valid format.")
+			}
+
 		}
 	}
 
-	return catalog, nil
+	return nil
+}
+
+func validateIntegrationForDependencies(args []string, additionalDependencies []string) error {
+	// If no source files have been provided there is nothing to inspect.
+	if len(args) == 0 {
+		return errors.New("no integration files have been provided")
+	}
+
+	// Validate integration files.
+	err := validateFiles(args)
+	if err != nil {
+		return nil
+	}
+
+	// Validate additional dependencies specified by the user.
+	err = validateAdditionalDependencies(additionalDependencies)
+	if err != nil {
+		return err
+	}
+
+	return nil
 }


[camel-k] 11/12: Add local run command. Resolve all modeline options.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 184b36fd1d186d52f97b65b81e7b9a6de84effaf
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Fri Nov 13 13:03:55 2020 -0500

    Add local run command. Resolve all modeline options.
---
 pkg/cmd/local.go          | 55 +++++++++++++++++++++++++++++++++++++++++++++++
 pkg/cmd/local_run.go      |  2 +-
 pkg/cmd/local_run_test.go | 12 ++++++-----
 pkg/cmd/modeline.go       | 12 ++++++++---
 pkg/cmd/root.go           |  6 +++++-
 pkg/cmd/util.go           |  3 ++-
 6 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/pkg/cmd/local.go b/pkg/cmd/local.go
new file mode 100644
index 0000000..89b7740
--- /dev/null
+++ b/pkg/cmd/local.go
@@ -0,0 +1,55 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"github.com/pkg/errors"
+	"github.com/spf13/cobra"
+)
+
+// NewCmdLocal -- Add local kamel subcommand with several other subcommands of its own.
+func newCmdLocal(rootCmdOptions *RootCmdOptions) *cobra.Command {
+	cmd := cobra.Command{
+		Use:   "local [sub-command]",
+		Short: "Perform integration actions locally.",
+		Long:  `Perform integration actions locally given a set of input integration files.`,
+		Annotations: map[string]string{
+			offlineCommandLabel: "true",
+		},
+	}
+
+	return &cmd
+}
+
+func addLocalSubCommands(cmd *cobra.Command, options *RootCmdOptions) error {
+	var localCmd *cobra.Command
+	for _, c := range cmd.Commands() {
+		if c.Name() == "local" {
+			localCmd = c
+			break
+		}
+	}
+
+	if localCmd == nil {
+		return errors.New("could not find any configured local command")
+	}
+
+	localCmd.AddCommand(cmdOnly(newCmdLocalRun(options)))
+
+	return nil
+}
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 4a68877..f2b86f4 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -30,7 +30,7 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 	}
 
 	cmd := cobra.Command{
-		Use:     "local-run [integration files]",
+		Use:     "run [integration files]",
 		Short:   "Run integration locally.",
 		Long:    `Run integration locally using the input integration files.`,
 		PreRunE: decode(&options),
diff --git a/pkg/cmd/local_run_test.go b/pkg/cmd/local_run_test.go
index 2858021..72f84f2 100644
--- a/pkg/cmd/local_run_test.go
+++ b/pkg/cmd/local_run_test.go
@@ -24,14 +24,16 @@ import (
 	"github.com/spf13/cobra"
 )
 
-func addTestLocalRunCmd(options *RootCmdOptions, rootCmd *cobra.Command) *localRunCmdOptions {
+func addTestLocalRunCmd(rootCmdOptions *RootCmdOptions, rootCmd *cobra.Command) *localRunCmdOptions {
 	//add a testing version of run Command
-	localRunCmd, localRunCmdOptions := newCmdLocalRun(options)
+	localCmd := newCmdLocal(rootCmdOptions)
+	localRunCmd, localRunCmdOptions := newCmdLocalRun(rootCmdOptions)
 	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
 }
 
@@ -42,7 +44,7 @@ func TestLocalRunPropertyFileFlag(t *testing.T) {
 
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "local-run", "route.java", "--property-file", "file1.properties", "--property-file", "file2.properties")
+	_, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java", "--property-file", "file1.properties", "--property-file", "file2.properties")
 	if err != nil {
 		t.Fatalf("Unexpected error: %v", err)
 	}
@@ -62,7 +64,7 @@ func TestLocalRunAdditionalDependenciesFlag(t *testing.T) {
 
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "local-run", "route.java", "-d", "mvn:camel-component-1", "-d", "mvn:camel-component-2")
+	_, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java", "-d", "mvn:camel-component-1", "-d", "mvn:camel-component-2")
 	if err != nil {
 		t.Fatalf("Unexpected error: %v", err)
 	}
diff --git a/pkg/cmd/modeline.go b/pkg/cmd/modeline.go
index b232110..9e3331f 100644
--- a/pkg/cmd/modeline.go
+++ b/pkg/cmd/modeline.go
@@ -31,6 +31,7 @@ import (
 
 const (
 	runCmdName        = "run"
+	localCmdName      = "local"
 	runCmdSourcesArgs = "source"
 )
 
@@ -98,9 +99,14 @@ func createKamelWithModelineCommand(ctx context.Context, args []string) (*cobra.
 
 	fg := target.Flags()
 
-	additionalSources, err := fg.GetStringArray(runCmdSourcesArgs)
-	if err != nil {
-		return nil, nil, err
+	// Only the run command has source flag (for now). Remove condition when
+	// local run also supports source.
+	additionalSources := make([]string, 0)
+	if target.Name() == runCmdName && target.Parent().Name() != localCmdName {
+		additionalSources, err = fg.GetStringArray(runCmdSourcesArgs)
+		if err != nil {
+			return nil, nil, err
+		}
 	}
 
 	files := make([]string, 0, len(fg.Args())+len(additionalSources))
diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go
index eba43c2..c56d369 100644
--- a/pkg/cmd/root.go
+++ b/pkg/cmd/root.go
@@ -61,6 +61,10 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) {
 		return cmd, err
 	}
 
+	if err := addLocalSubCommands(cmd, &options); err != nil {
+		return cmd, err
+	}
+
 	err = kamelPostAddCommandInit(cmd)
 
 	return cmd, err
@@ -139,7 +143,7 @@ func addKamelSubcommands(cmd *cobra.Command, options *RootCmdOptions) {
 	cmd.AddCommand(cmdOnly(newCmdInit(options)))
 	cmd.AddCommand(cmdOnly(newCmdDebug(options)))
 	cmd.AddCommand(cmdOnly(newCmdInspect(options)))
-	cmd.AddCommand(cmdOnly(newCmdLocalRun(options)))
+	cmd.AddCommand(newCmdLocal(options))
 }
 
 func addHelpSubCommands(cmd *cobra.Command, options *RootCmdOptions) error {
diff --git a/pkg/cmd/util.go b/pkg/cmd/util.go
index 8d5ac14..3e364a6 100644
--- a/pkg/cmd/util.go
+++ b/pkg/cmd/util.go
@@ -24,11 +24,12 @@ import (
 	"encoding/csv"
 	"encoding/json"
 	"fmt"
-	"github.com/apache/camel-k/pkg/util/gzip"
 	"log"
 	"reflect"
 	"strings"
 
+	"github.com/apache/camel-k/pkg/util/gzip"
+
 	"github.com/mitchellh/mapstructure"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"


[camel-k] 07/12: Add test for property-file and dependency flags for local-run.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 430ba1b6d9eced7ae2be9f3550bcc4753b7c3e28
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Tue Nov 10 16:41:15 2020 -0500

    Add test for property-file and dependency flags for local-run.
---
 pkg/cmd/local_run.go      |  6 ++--
 pkg/cmd/local_run_test.go | 76 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 5959a8e..654ffce 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -65,7 +65,7 @@ where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
 
 type localRunCmdOptions struct {
 	*RootCmdOptions
-	PropertiesFiles        []string `mapstructure:"property-files"`
+	PropertyFiles          []string `mapstructure:"property-files"`
 	AdditionalDependencies []string `mapstructure:"dependencies"`
 }
 
@@ -77,7 +77,7 @@ func (command *localRunCmdOptions) validate(args []string) error {
 	}
 
 	// Validate properties file.
-	err = validateFiles(command.PropertiesFiles)
+	err = validateFiles(command.PropertyFiles)
 	if err != nil {
 		return nil
 	}
@@ -103,7 +103,7 @@ func (command *localRunCmdOptions) run(args []string) error {
 	}
 
 	// Run the integration locally.
-	err = RunLocalIntegration(command.PropertiesFiles, dependencies, args)
+	err = RunLocalIntegration(command.PropertyFiles, dependencies, args)
 	if err != nil {
 		return nil
 	}
diff --git a/pkg/cmd/local_run_test.go b/pkg/cmd/local_run_test.go
new file mode 100644
index 0000000..2858021
--- /dev/null
+++ b/pkg/cmd/local_run_test.go
@@ -0,0 +1,76 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"testing"
+
+	"github.com/apache/camel-k/pkg/util/test"
+	"github.com/spf13/cobra"
+)
+
+func addTestLocalRunCmd(options *RootCmdOptions, rootCmd *cobra.Command) *localRunCmdOptions {
+	//add a testing version of run Command
+	localRunCmd, localRunCmdOptions := newCmdLocalRun(options)
+	localRunCmd.RunE = func(c *cobra.Command, args []string) error {
+		return nil
+	}
+	localRunCmd.Args = test.ArbitraryArgs
+	rootCmd.AddCommand(localRunCmd)
+	return localRunCmdOptions
+}
+
+func TestLocalRunPropertyFileFlag(t *testing.T) {
+	options, rootCmd := kamelTestPreAddCommandInit()
+
+	localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
+
+	kamelTestPostAddCommandInit(t, rootCmd)
+
+	_, err := test.ExecuteCommand(rootCmd, "local-run", "route.java", "--property-file", "file1.properties", "--property-file", "file2.properties")
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", 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))
+	}
+	if localRunCmdOptions.PropertyFiles[0] != "file1.properties" || localRunCmdOptions.PropertyFiles[1] != "file2.properties" {
+		t.Fatalf("Property files expected to be: \n %v\nGot:\n %v\n", "[file1.properties, file2.properties]", localRunCmdOptions.PropertyFiles)
+	}
+}
+
+func TestLocalRunAdditionalDependenciesFlag(t *testing.T) {
+	options, rootCmd := kamelTestPreAddCommandInit()
+
+	localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
+
+	kamelTestPostAddCommandInit(t, rootCmd)
+
+	_, err := test.ExecuteCommand(rootCmd, "local-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)
+	}
+}


[camel-k] 03/12: Run existing integration locally.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 197c67f58fc63699ab2fbf3e92bde49adb78d365
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Wed Nov 4 17:50:34 2020 -0500

    Run existing integration locally.
---
 pkg/cmd/local_run.go     | 18 ++++++++-
 pkg/cmd/util_commands.go | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 8a0bdb2..a76daa3 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -49,7 +49,7 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 		},
 	}
 
-	cmd.Flags().StringArrayP("properties-file", "p", nil, "File containing the integration properties.")
+	cmd.Flags().StringArrayP("properties-file", "p", nil, "File containing integration properties.")
 	cmd.Flags().StringArrayP("dependency", "d", nil, `Additional top-level dependency with the format:
 <type>:<dependency-name>
 where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
@@ -59,11 +59,19 @@ where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
 
 type localRunCmdOptions struct {
 	*RootCmdOptions
-	PropertiesFiles        []string `mapstructure:"properties"`
+	PropertiesFiles        []string `mapstructure:"properties-files"`
 	AdditionalDependencies []string `mapstructure:"dependencies"`
 }
 
 func (command *localRunCmdOptions) validate(args []string) error {
+	for _, additionalDependency := range command.AdditionalDependencies {
+		fmt.Printf("Dep: %v\n", additionalDependency)
+	}
+
+	for _, prop := range command.PropertiesFiles {
+		fmt.Printf("Prop: %v\n", prop)
+	}
+
 	// Validate additional dependencies specified by the user.
 	err := validateIntegrationForDependencies(args, command.AdditionalDependencies)
 	if err != nil {
@@ -92,5 +100,11 @@ func (command *localRunCmdOptions) run(args []string) error {
 		return err
 	}
 
+	// Run the integration locally.
+	err = RunLocalIntegration(command.PropertiesFiles, dependencies, args)
+	if err != nil {
+		return nil
+	}
+
 	return nil
 }
diff --git a/pkg/cmd/util_commands.go b/pkg/cmd/util_commands.go
new file mode 100644
index 0000000..36ae564
--- /dev/null
+++ b/pkg/cmd/util_commands.go
@@ -0,0 +1,97 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"os/exec"
+	"path"
+	"strings"
+)
+
+var (
+	ctx9, cancel9 = context.WithCancel(context.Background()) // preemptive: kill subprocess
+	ctx, cancel   = context.WithCancel(ctx9)                 // cooperative: wait for subprocess
+)
+
+func formatRoutes(files []string) []string {
+	routes := []string{}
+	for _, route := range files {
+		// Split route path.
+		a := strings.Split(route, ".")
+
+		// Extract extension.
+		extension := a[len(a)-1]
+
+		// Add file if extension is supported.
+		routes = append(routes, "file:"+route+"?language="+extension)
+	}
+
+	return routes
+}
+
+func confDirectories(properties []string) []string {
+	confDirs := []string{}
+
+	for _, propertiesPath := range properties {
+		confDirs = append(confDirs, path.Dir(propertiesPath))
+	}
+
+	return confDirs
+}
+
+func assembleClasspatchArgValue(properties []string, dependencies []string, routes []string) string {
+	classpathContents := []string{}
+	classpathContents = append(classpathContents, properties...)
+	classpathContents = append(classpathContents, routes...)
+	classpathContents = append(classpathContents, dependencies...)
+	return strings.Join(classpathContents, ":")
+}
+
+// RunLocalIntegration --
+func RunLocalIntegration(properties []string, dependencies []string, routes []string) error {
+	// Create classpath value.
+	classpathValue := assembleClasspatchArgValue(properties, dependencies, routes)
+
+	// Create java command that runs the integration.
+	javaCmd := "java"
+
+	// Create java command arguments.
+	args := make([]string, 0)
+	args = append(args, "-cp")
+	args = append(args, classpathValue)
+	args = append(args, "org.apache.camel.k.main.Application")
+
+	cmd := exec.CommandContext(ctx, javaCmd, args...)
+	cmd.Stderr = os.Stderr
+	cmd.Stdout = os.Stdout
+	// cmd.Dir = ctx.Path
+
+	// TODO: for debug purposes, remove when done.
+	fmt.Printf("executing: %s", strings.Join(cmd.Args, " "))
+
+	// Add directory where the properties file resides.
+	os.Setenv("CAMEL_K_CONF_D", strings.Join(confDirectories(properties), ","))
+
+	// Add files to the command line under the CAMEL_K_ROUTES flag.
+	os.Setenv("CAMEL_K_ROUTES", strings.Join(formatRoutes(routes), ","))
+
+	return cmd.Run()
+}


[camel-k] 01/12: Add local run command.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 5e827721eb9e166fa92c511988549f7a43e3e955
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Tue Nov 3 10:29:00 2020 -0500

    Add local run command.
---
 pkg/cmd/inspect.go   |   2 +-
 pkg/cmd/local_run.go | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++
 pkg/cmd/root.go      |   1 +
 3 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/pkg/cmd/inspect.go b/pkg/cmd/inspect.go
index 1c2cbf4..02eed21 100644
--- a/pkg/cmd/inspect.go
+++ b/pkg/cmd/inspect.go
@@ -18,7 +18,6 @@ limitations under the License.
 package cmd
 
 import (
-	"errors"
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -32,6 +31,7 @@ import (
 	"github.com/apache/camel-k/pkg/util/camel"
 	"github.com/apache/camel-k/pkg/util/defaults"
 	"github.com/apache/camel-k/pkg/util/maven"
+	"github.com/pkg/errors"
 	"github.com/scylladb/go-set/strset"
 	"github.com/spf13/cobra"
 )
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
new file mode 100644
index 0000000..70af154
--- /dev/null
+++ b/pkg/cmd/local_run.go
@@ -0,0 +1,131 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"errors"
+	"fmt"
+	"path"
+
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/trait"
+	"github.com/apache/camel-k/pkg/util"
+	"github.com/apache/camel-k/pkg/util/camel"
+	"github.com/scylladb/go-set/strset"
+	"github.com/spf13/cobra"
+)
+
+func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCmdOptions) {
+	options := localRunCmdOptions{
+		RootCmdOptions: rootCmdOptions,
+	}
+
+	cmd := cobra.Command{
+		Use:     "local-run [files to inspect]",
+		Short:   "Run a Camel integration locally.",
+		Long:    `Run a Camel integration locally using existing integration files.`,
+		PreRunE: decode(&options),
+		RunE: func(_ *cobra.Command, args []string) error {
+			if err := options.validate(args); err != nil {
+				return err
+			}
+			if err := options.run(args); err != nil {
+				fmt.Println(err.Error())
+			}
+
+			return nil
+		},
+		Annotations: map[string]string{
+			offlineCommandLabel: "true",
+		},
+	}
+
+	cmd.Flags().StringP("properties", "p", "", "Output format. One of: json|yaml")
+
+	return &cmd, &options
+}
+
+type localRunCmdOptions struct {
+	*RootCmdOptions
+	Properties string `mapstructure:"properties"`
+}
+
+func (command *localRunCmdOptions) validate(args []string) error {
+	// If no source files have been provided there is nothing to inspect.
+	if len(args) == 0 {
+		return errors.New("no integration files have been provided, nothing to inspect")
+	}
+
+	// Ensure source files exist.
+	for _, arg := range args {
+		// fmt.Printf("Validating file: %v\n", arg)
+		fileExists, err := util.FileExists(arg)
+
+		// Report any error.
+		if err != nil {
+			return err
+		}
+
+		// Signal file not found.
+		if !fileExists {
+			return errors.New("input file " + arg + " file does not exist")
+		}
+	}
+
+	return nil
+}
+
+func (command *localRunCmdOptions) run(args []string) error {
+	// Attempt to reuse existing Camel catalog if one is present.
+	catalog, err := camel.MainCatalog()
+	if err != nil {
+		return err
+	}
+
+	// Generate catalog if one was not found.
+	if catalog == nil {
+		catalog, err = generateCatalog()
+		if err != nil {
+			return err
+		}
+	}
+
+	// List of top-level dependencies.
+	dependencies := strset.New()
+
+	// Invoke the dependency inspector code for each source file.
+	for _, source := range args {
+		data, _, err := loadContent(source, false, false)
+		if err != nil {
+			return err
+		}
+
+		sourceSpec := v1.SourceSpec{
+			DataSpec: v1.DataSpec{
+				Name:        path.Base(source),
+				Content:     data,
+				Compression: false,
+			},
+		}
+
+		// Extract list of top-level dependencies.
+		dependencies.Merge(trait.AddSourceDependencies(sourceSpec, catalog))
+	}
+
+	return nil
+}
diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go
index 2899a30..eba43c2 100644
--- a/pkg/cmd/root.go
+++ b/pkg/cmd/root.go
@@ -139,6 +139,7 @@ func addKamelSubcommands(cmd *cobra.Command, options *RootCmdOptions) {
 	cmd.AddCommand(cmdOnly(newCmdInit(options)))
 	cmd.AddCommand(cmdOnly(newCmdDebug(options)))
 	cmd.AddCommand(cmdOnly(newCmdInspect(options)))
+	cmd.AddCommand(cmdOnly(newCmdLocalRun(options)))
 }
 
 func addHelpSubCommands(cmd *cobra.Command, options *RootCmdOptions) error {


[camel-k] 09/12: Update usage.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit f0e11b25c94b06f96256447f0332e5c2460b1ec6
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Wed Nov 11 14:43:19 2020 -0500

    Update usage.
---
 pkg/cmd/inspect.go | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/pkg/cmd/inspect.go b/pkg/cmd/inspect.go
index 9967cfd..40c0dc1 100644
--- a/pkg/cmd/inspect.go
+++ b/pkg/cmd/inspect.go
@@ -19,7 +19,6 @@ package cmd
 
 import (
 	"fmt"
-	"strings"
 
 	"github.com/spf13/cobra"
 )
@@ -58,9 +57,7 @@ will be generated by calling Maven and then printed in the selected output forma
 	}
 
 	cmd.Flags().Bool("all-dependencies", false, "Compute transitive dependencies and move them to directory pointed to by the --dependencies-directory flag.")
-	cmd.Flags().StringArrayP("dependency", "d", nil, `Additional top-level dependency with the format:
-<type>:<dependency-name>
-where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
+	cmd.Flags().StringArrayP("dependency", "d", nil, additionalDependencyUsageMessage)
 	cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml")
 
 	return &cmd, &options


[camel-k] 05/12: Ensure Maven working directory is kept until after the integration is run.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit a62cdf4627e58e9cd8a8e354648104bc0c177947
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Tue Nov 10 12:52:47 2020 -0500

    Ensure Maven working directory is kept until after the integration is run.
---
 pkg/builder/runtime/quarkus.go |  9 +++++++++
 pkg/cmd/inspect.go             | 14 ++++++++++++++
 pkg/cmd/local_run.go           | 14 ++++++++++++++
 pkg/cmd/util_dependencies.go   | 35 +++++++++++++++++++++++++----------
 4 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/pkg/builder/runtime/quarkus.go b/pkg/builder/runtime/quarkus.go
index a98faba..dbc3e33 100644
--- a/pkg/builder/runtime/quarkus.go
+++ b/pkg/builder/runtime/quarkus.go
@@ -259,5 +259,14 @@ func ProcessQuarkusTransitiveDependencies(mc maven.Context, content []byte) ([]v
 		Checksum: "sha1:" + runnerChecksum,
 	})
 
+	// currentpath, errr := os.Getwd()
+	// if errr != nil {
+	// 	return nil, errr
+	// }
+	// _, err = util.CopyFile(path.Join(mc.Path, "target", runner), path.Join(currentpath, runner))
+	// if err != nil {
+	// 	return nil, err
+	// }
+
 	return artifacts, nil
 }
diff --git a/pkg/cmd/inspect.go b/pkg/cmd/inspect.go
index e524e56..9967cfd 100644
--- a/pkg/cmd/inspect.go
+++ b/pkg/cmd/inspect.go
@@ -40,9 +40,15 @@ will be generated by calling Maven and then printed in the selected output forma
 			if err := options.validate(args); err != nil {
 				return err
 			}
+			if err := options.init(); err != nil {
+				return err
+			}
 			if err := options.run(args); err != nil {
 				fmt.Println(err.Error())
 			}
+			if err := options.deinit(); err != nil {
+				return err
+			}
 
 			return nil
 		},
@@ -71,6 +77,10 @@ func (command *inspectCmdOptions) validate(args []string) error {
 	return validateIntegrationForDependencies(args, command.AdditionalDependencies)
 }
 
+func (command *inspectCmdOptions) init() error {
+	return createMavenWorkingDirectory()
+}
+
 func (command *inspectCmdOptions) run(args []string) error {
 	// Fetch dependencies.
 	dependencies, err := getDependencies(args, command.AdditionalDependencies, command.AllDependencies)
@@ -86,3 +96,7 @@ func (command *inspectCmdOptions) run(args []string) error {
 
 	return nil
 }
+
+func (command *inspectCmdOptions) deinit() error {
+	return deleteMavenWorkingDirectory()
+}
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index a76daa3..2031e52 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -38,9 +38,15 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 			if err := options.validate(args); err != nil {
 				return err
 			}
+			if err := options.init(); err != nil {
+				return err
+			}
 			if err := options.run(args); err != nil {
 				fmt.Println(err.Error())
 			}
+			if err := options.deinit(); err != nil {
+				return err
+			}
 
 			return nil
 		},
@@ -87,6 +93,10 @@ func (command *localRunCmdOptions) validate(args []string) error {
 	return nil
 }
 
+func (command *localRunCmdOptions) init() error {
+	return createMavenWorkingDirectory()
+}
+
 func (command *localRunCmdOptions) run(args []string) error {
 	// Fetch dependencies.
 	dependencies, err := getDependencies(args, command.AdditionalDependencies, true)
@@ -108,3 +118,7 @@ func (command *localRunCmdOptions) run(args []string) error {
 
 	return nil
 }
+
+func (command *localRunCmdOptions) deinit() error {
+	return deleteMavenWorkingDirectory()
+}
diff --git a/pkg/cmd/util_dependencies.go b/pkg/cmd/util_dependencies.go
index 49d0d07..cd29a3e 100644
--- a/pkg/cmd/util_dependencies.go
+++ b/pkg/cmd/util_dependencies.go
@@ -35,6 +35,10 @@ import (
 	"github.com/scylladb/go-set/strset"
 )
 
+// Directory used by Maven for an invocation of the kamel local command.
+// By default a temporary folder will be used.
+var mavenWorkingDirectory string = ""
+
 var acceptedDependencyTypes = []string{"bom", "camel", "camel-k", "camel-quarkus", "mvn", "github"}
 
 const defaultDependenciesDirectoryName = "dependencies"
@@ -112,14 +116,8 @@ func getTransitiveDependencies(
 		return nil, err
 	}
 
-	// Create local Maven context.
-	temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "maven-")
-	if err != nil {
-		return nil, err
-	}
-
 	// Maven local context to be used for generating the transitive dependencies.
-	mc := maven.NewContext(temporaryDirectory, project)
+	mc := maven.NewContext(mavenWorkingDirectory, project)
 	mc.LocalRepository = mvn.LocalRepository
 	mc.Timeout = mvn.GetTimeout().Duration
 
@@ -150,9 +148,6 @@ func getTransitiveDependencies(
 		transitiveDependencies = append(transitiveDependencies, entry.Location)
 	}
 
-	// Remove directory used for computing the dependencies.
-	defer os.RemoveAll(temporaryDirectory)
-
 	return transitiveDependencies, nil
 }
 
@@ -301,3 +296,23 @@ func validateIntegrationForDependencies(args []string, additionalDependencies []
 
 	return nil
 }
+
+func createMavenWorkingDirectory() error {
+	// Create local Maven context.
+	temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "maven-")
+	if err != nil {
+		return err
+	}
+
+	// Set the Maven directory to the default value.
+	mavenWorkingDirectory = temporaryDirectory
+
+	return nil
+}
+
+func deleteMavenWorkingDirectory() error {
+	// Remove directory used for computing the dependencies.
+	defer os.RemoveAll(mavenWorkingDirectory)
+
+	return nil
+}


[camel-k] 06/12: Address comments. Clean-up code.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 9b2d0b229a778f03a3613be3de63222f0f89dae5
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Tue Nov 10 16:05:28 2020 -0500

    Address comments. Clean-up code.
---
 pkg/builder/runtime/quarkus.go |  9 ---------
 pkg/cmd/local_run.go           | 18 +++++-------------
 pkg/cmd/util_commands.go       |  4 ++--
 3 files changed, 7 insertions(+), 24 deletions(-)

diff --git a/pkg/builder/runtime/quarkus.go b/pkg/builder/runtime/quarkus.go
index dbc3e33..a98faba 100644
--- a/pkg/builder/runtime/quarkus.go
+++ b/pkg/builder/runtime/quarkus.go
@@ -259,14 +259,5 @@ func ProcessQuarkusTransitiveDependencies(mc maven.Context, content []byte) ([]v
 		Checksum: "sha1:" + runnerChecksum,
 	})
 
-	// currentpath, errr := os.Getwd()
-	// if errr != nil {
-	// 	return nil, errr
-	// }
-	// _, err = util.CopyFile(path.Join(mc.Path, "target", runner), path.Join(currentpath, runner))
-	// if err != nil {
-	// 	return nil, err
-	// }
-
 	return artifacts, nil
 }
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 2031e52..5959a8e 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -30,9 +30,9 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 	}
 
 	cmd := cobra.Command{
-		Use:     "local-run [files to inspect]",
-		Short:   "Run a Camel integration locally.",
-		Long:    `Run a Camel integration locally using existing integration files.`,
+		Use:     "local-run [integration files]",
+		Short:   "Run integration locally.",
+		Long:    `Run integration locally using the input integration files.`,
 		PreRunE: decode(&options),
 		RunE: func(_ *cobra.Command, args []string) error {
 			if err := options.validate(args); err != nil {
@@ -55,7 +55,7 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 		},
 	}
 
-	cmd.Flags().StringArrayP("properties-file", "p", nil, "File containing integration properties.")
+	cmd.Flags().StringArray("property-file", nil, "Add a property file to the integration.")
 	cmd.Flags().StringArrayP("dependency", "d", nil, `Additional top-level dependency with the format:
 <type>:<dependency-name>
 where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
@@ -65,19 +65,11 @@ where <type> is one of {`+strings.Join(acceptedDependencyTypes, "|")+`}.`)
 
 type localRunCmdOptions struct {
 	*RootCmdOptions
-	PropertiesFiles        []string `mapstructure:"properties-files"`
+	PropertiesFiles        []string `mapstructure:"property-files"`
 	AdditionalDependencies []string `mapstructure:"dependencies"`
 }
 
 func (command *localRunCmdOptions) validate(args []string) error {
-	for _, additionalDependency := range command.AdditionalDependencies {
-		fmt.Printf("Dep: %v\n", additionalDependency)
-	}
-
-	for _, prop := range command.PropertiesFiles {
-		fmt.Printf("Prop: %v\n", prop)
-	}
-
 	// Validate additional dependencies specified by the user.
 	err := validateIntegrationForDependencies(args, command.AdditionalDependencies)
 	if err != nil {
diff --git a/pkg/cmd/util_commands.go b/pkg/cmd/util_commands.go
index 213ea6b..5ec0a34 100644
--- a/pkg/cmd/util_commands.go
+++ b/pkg/cmd/util_commands.go
@@ -88,10 +88,10 @@ func RunLocalIntegration(properties []string, dependencies []string, routes []st
 	fmt.Printf("executing: %s", strings.Join(cmd.Args, " "))
 
 	// Add directory where the properties file resides.
-	os.Setenv("CAMEL_K_CONF_D", strings.Join(confDirectories(properties), ","))
+	cmd.Env = append(cmd.Env, "CAMEL_K_CONF_D="+strings.Join(confDirectories(properties), ","))
 
 	// Add files to the command line under the CAMEL_K_ROUTES flag.
-	os.Setenv("CAMEL_K_ROUTES", strings.Join(formatRoutes(routes), ","))
+	cmd.Env = append(cmd.Env, "CAMEL_K_ROUTES="+strings.Join(formatRoutes(routes), ","))
 
 	return cmd.Run()
 }


[camel-k] 10/12: Remove TODO comment. Remove printing of dependencies when running locally.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 8bcff84a76e96f3fa98e3b32e82c180335b00f44
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Fri Nov 13 12:08:54 2020 -0500

    Remove TODO comment. Remove printing of dependencies when running locally.
---
 pkg/cmd/local_run.go     | 6 ------
 pkg/cmd/util_commands.go | 2 --
 2 files changed, 8 deletions(-)

diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 654ffce..4a68877 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -96,12 +96,6 @@ func (command *localRunCmdOptions) run(args []string) error {
 		return err
 	}
 
-	// Print dependencies.
-	err = outputDependencies(dependencies, "")
-	if err != nil {
-		return err
-	}
-
 	// Run the integration locally.
 	err = RunLocalIntegration(command.PropertyFiles, dependencies, args)
 	if err != nil {
diff --git a/pkg/cmd/util_commands.go b/pkg/cmd/util_commands.go
index 5ec0a34..b44243a 100644
--- a/pkg/cmd/util_commands.go
+++ b/pkg/cmd/util_commands.go
@@ -82,9 +82,7 @@ func RunLocalIntegration(properties []string, dependencies []string, routes []st
 	cmd := exec.CommandContext(ctx, javaCmd, args...)
 	cmd.Stderr = os.Stderr
 	cmd.Stdout = os.Stdout
-	// cmd.Dir = ctx.Path
 
-	// TODO: for debug purposes, remove when done.
 	fmt.Printf("executing: %s", strings.Join(cmd.Args, " "))
 
 	// Add directory where the properties file resides.


[camel-k] 04/12: Add class containing main function.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 5ea1b6e5183d6d24b584b6cd54df5e05b1fe5365
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Tue Nov 10 10:50:38 2020 -0500

    Add class containing main function.
---
 pkg/cmd/util_commands.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/cmd/util_commands.go b/pkg/cmd/util_commands.go
index 36ae564..213ea6b 100644
--- a/pkg/cmd/util_commands.go
+++ b/pkg/cmd/util_commands.go
@@ -77,7 +77,7 @@ func RunLocalIntegration(properties []string, dependencies []string, routes []st
 	args := make([]string, 0)
 	args = append(args, "-cp")
 	args = append(args, classpathValue)
-	args = append(args, "org.apache.camel.k.main.Application")
+	args = append(args, "io.quarkus.runner.GeneratedMain")
 
 	cmd := exec.CommandContext(ctx, javaCmd, args...)
 	cmd.Stderr = os.Stderr


[camel-k] 12/12: Remove old modeline support for just dependencies from dependency resolution..

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 1729ac5daa73f8bc20f4556053ffbc34be4f027a
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Fri Nov 13 13:14:10 2020 -0500

    Remove old modeline support for just dependencies from dependency resolution..
---
 pkg/cmd/modeline.go          |  5 ++---
 pkg/cmd/util_dependencies.go | 25 -------------------------
 2 files changed, 2 insertions(+), 28 deletions(-)

diff --git a/pkg/cmd/modeline.go b/pkg/cmd/modeline.go
index 9e3331f..6a3f0c1 100644
--- a/pkg/cmd/modeline.go
+++ b/pkg/cmd/modeline.go
@@ -161,7 +161,7 @@ func extractModelineOptions(ctx context.Context, sources []string) ([]modeline.O
 	}
 
 	for _, resolvedSource := range resolvedSources {
-		ops, err := ExtractModelineOptionsFromSource(resolvedSource)
+		ops, err := extractModelineOptionsFromSource(resolvedSource)
 		if err != nil {
 			return opts, err
 		}
@@ -172,8 +172,7 @@ func extractModelineOptions(ctx context.Context, sources []string) ([]modeline.O
 	return opts, nil
 }
 
-// ExtractModelineOptionsFromSource --
-func ExtractModelineOptionsFromSource(resolvedSource Source) ([]modeline.Option, error) {
+func extractModelineOptionsFromSource(resolvedSource Source) ([]modeline.Option, error) {
 	ops, err := modeline.Parse(resolvedSource.Location, resolvedSource.Content)
 	if err != nil {
 		return ops, errors.Wrapf(err, "cannot process file %s", resolvedSource.Location)
diff --git a/pkg/cmd/util_dependencies.go b/pkg/cmd/util_dependencies.go
index e21ca89..30722a7 100644
--- a/pkg/cmd/util_dependencies.go
+++ b/pkg/cmd/util_dependencies.go
@@ -96,31 +96,6 @@ func getTopLevelDependencies(catalog *camel.RuntimeCatalog, args []string) ([]st
 
 		// Extract list of top-level dependencies.
 		dependencies.Merge(trait.AddSourceDependencies(sourceSpec, catalog))
-
-		// Extract modeline dependencies from file and add them to the list of
-		// top-level dependencies.
-		resolvedSource, err := ResolveLocalSource(source, false)
-		if err != nil {
-			return []string{}, err
-		}
-
-		opts, err := ExtractModelineOptionsFromSource(resolvedSource)
-		if err != nil {
-			return []string{}, err
-		}
-
-		for _, o := range opts {
-			if o.Name == "dependency" {
-				// Make sure dependency is valid.
-				isValid := validateDependency(o.Value)
-				if !isValid {
-					return []string{}, errors.New("Unexpected type for modeline dependency: " + o.Value + ". " + additionalDependencyUsageMessage)
-				}
-
-				// Only valid modeline dependencies are added to the top level dependencies list.
-				dependencies.Add(o.Value)
-			}
-		}
 	}
 
 	return dependencies.List(), nil


[camel-k] 08/12: Add support for modeline options.

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 334d848d86464c5c230a745f05670d0fcb46adf9
Author: Doru Bercea <gh...@ibm.com>
AuthorDate: Wed Nov 11 14:32:58 2020 -0500

    Add support for modeline options.
---
 pkg/cmd/modeline.go          | 43 +++++++++++++++++++++-------------
 pkg/cmd/util_dependencies.go | 55 +++++++++++++++++++++++++++++++++++---------
 pkg/cmd/util_sources.go      | 46 +++++++++++++++++++++---------------
 3 files changed, 99 insertions(+), 45 deletions(-)

diff --git a/pkg/cmd/modeline.go b/pkg/cmd/modeline.go
index 4eab57a..b232110 100644
--- a/pkg/cmd/modeline.go
+++ b/pkg/cmd/modeline.go
@@ -155,27 +155,38 @@ func extractModelineOptions(ctx context.Context, sources []string) ([]modeline.O
 	}
 
 	for _, resolvedSource := range resolvedSources {
-		ops, err := modeline.Parse(resolvedSource.Location, resolvedSource.Content)
+		ops, err := ExtractModelineOptionsFromSource(resolvedSource)
 		if err != nil {
-			return opts, errors.Wrapf(err, "cannot process file %s", resolvedSource.Location)
+			return opts, err
 		}
-		for i, o := range ops {
-			if disallowedOptions[o.Name] {
-				return opts, fmt.Errorf("option %q is disallowed in modeline", o.Name)
-			}
 
-			if fileOptions[o.Name] && resolvedSource.Local {
-				baseDir := filepath.Dir(resolvedSource.Origin)
-				refPath := o.Value
-				if !filepath.IsAbs(refPath) {
-					full := path.Join(baseDir, refPath)
-					o.Value = full
-					ops[i] = o
-				}
-			}
-		}
 		opts = append(opts, ops...)
 	}
 
 	return opts, nil
 }
+
+// ExtractModelineOptionsFromSource --
+func ExtractModelineOptionsFromSource(resolvedSource Source) ([]modeline.Option, error) {
+	ops, err := modeline.Parse(resolvedSource.Location, resolvedSource.Content)
+	if err != nil {
+		return ops, errors.Wrapf(err, "cannot process file %s", resolvedSource.Location)
+	}
+	for i, o := range ops {
+		if disallowedOptions[o.Name] {
+			return ops, fmt.Errorf("option %q is disallowed in modeline", o.Name)
+		}
+
+		if fileOptions[o.Name] && resolvedSource.Local {
+			baseDir := filepath.Dir(resolvedSource.Origin)
+			refPath := o.Value
+			if !filepath.IsAbs(refPath) {
+				full := path.Join(baseDir, refPath)
+				o.Value = full
+				ops[i] = o
+			}
+		}
+	}
+
+	return ops, nil
+}
diff --git a/pkg/cmd/util_dependencies.go b/pkg/cmd/util_dependencies.go
index cd29a3e..e21ca89 100644
--- a/pkg/cmd/util_dependencies.go
+++ b/pkg/cmd/util_dependencies.go
@@ -41,6 +41,10 @@ var mavenWorkingDirectory string = ""
 
 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, "|") + `}.`
+
 const defaultDependenciesDirectoryName = "dependencies"
 
 func getDependencies(args []string, additionalDependencies []string, allDependencies bool) ([]string, error) {
@@ -92,6 +96,31 @@ func getTopLevelDependencies(catalog *camel.RuntimeCatalog, args []string) ([]st
 
 		// Extract list of top-level dependencies.
 		dependencies.Merge(trait.AddSourceDependencies(sourceSpec, catalog))
+
+		// Extract modeline dependencies from file and add them to the list of
+		// top-level dependencies.
+		resolvedSource, err := ResolveLocalSource(source, false)
+		if err != nil {
+			return []string{}, err
+		}
+
+		opts, err := ExtractModelineOptionsFromSource(resolvedSource)
+		if err != nil {
+			return []string{}, err
+		}
+
+		for _, o := range opts {
+			if o.Name == "dependency" {
+				// Make sure dependency is valid.
+				isValid := validateDependency(o.Value)
+				if !isValid {
+					return []string{}, errors.New("Unexpected type for modeline dependency: " + o.Value + ". " + additionalDependencyUsageMessage)
+				}
+
+				// Only valid modeline dependencies are added to the top level dependencies list.
+				dependencies.Add(o.Value)
+			}
+		}
 	}
 
 	return dependencies.List(), nil
@@ -257,23 +286,27 @@ func validateAdditionalDependencies(additionalDependencies []string) error {
 	// a valid type.
 	if additionalDependencies != nil {
 		for _, additionalDependency := range additionalDependencies {
-			dependencyComponents := strings.Split(additionalDependency, ":")
-
-			TypeIsValid := false
-			for _, dependencyType := range acceptedDependencyTypes {
-				if dependencyType == dependencyComponents[0] {
-					TypeIsValid = true
-				}
+			isValid := validateDependency(additionalDependency)
+			if !isValid {
+				return errors.New("Unexpected type for user-provided dependency: " + additionalDependency + ". " + additionalDependencyUsageMessage)
 			}
+		}
+	}
 
-			if !TypeIsValid {
-				return errors.New("Unexpected type for user-provided dependency: " + additionalDependency + ", check command usage for valid format.")
-			}
+	return nil
+}
 
+func validateDependency(additionalDependency string) bool {
+	dependencyComponents := strings.Split(additionalDependency, ":")
+
+	TypeIsValid := false
+	for _, dependencyType := range acceptedDependencyTypes {
+		if dependencyType == dependencyComponents[0] {
+			TypeIsValid = true
 		}
 	}
 
-	return nil
+	return TypeIsValid
 }
 
 func validateIntegrationForDependencies(args []string, additionalDependencies []string) error {
diff --git a/pkg/cmd/util_sources.go b/pkg/cmd/util_sources.go
index af218f0..50a0838 100644
--- a/pkg/cmd/util_sources.go
+++ b/pkg/cmd/util_sources.go
@@ -66,27 +66,10 @@ func ResolveSources(ctx context.Context, locations []string, compress bool) ([]S
 
 	for _, location := range locations {
 		if isLocal(location) {
-			if _, err := os.Stat(location); err != nil && os.IsNotExist(err) {
-				return sources, errors.Wrapf(err, "file %s does not exist", location)
-			} else if err != nil {
-				return sources, errors.Wrapf(err, "error while accessing file %s", location)
-			}
-
-			answer := Source{
-				Name:     path.Base(location),
-				Origin:   location,
-				Location: location,
-				Compress: compress,
-				Local:    true,
-			}
-
-			content, err := ioutil.ReadFile(location)
+			answer, err := ResolveLocalSource(location, compress)
 			if err != nil {
 				return sources, err
 			}
-			if err := answer.setContent(content); err != nil {
-				return sources, err
-			}
 
 			sources = append(sources, answer)
 		} else {
@@ -199,3 +182,30 @@ func ResolveSources(ctx context.Context, locations []string, compress bool) ([]S
 
 	return sources, nil
 }
+
+// ResolveLocalSource --
+func ResolveLocalSource(location string, compress bool) (Source, error) {
+	if _, err := os.Stat(location); err != nil && os.IsNotExist(err) {
+		return Source{}, errors.Wrapf(err, "file %s does not exist", location)
+	} else if err != nil {
+		return Source{}, errors.Wrapf(err, "error while accessing file %s", location)
+	}
+
+	answer := Source{
+		Name:     path.Base(location),
+		Origin:   location,
+		Location: location,
+		Compress: compress,
+		Local:    true,
+	}
+
+	content, err := ioutil.ReadFile(location)
+	if err != nil {
+		return Source{}, err
+	}
+	if err := answer.setContent(content); err != nil {
+		return Source{}, err
+	}
+
+	return answer, nil
+}