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
commit e4ba473f1c6d40c9af40c4b0612d840da16c4626 Author: Tadayoshi Sato <[email protected]> AuthorDate: Fri Jul 29 17:08:32 2022 +0900 chore(cli): refactor - package utils to local & source for better encapsulation and cohesion --- .../container.go} | 28 ++++---- pkg/cmd/{local_util.go => local/local.go} | 57 ++++++++-------- .../{local_util_test.go => local/local_test.go} | 8 +-- pkg/cmd/{local_util_dirs.go => local/workdir.go} | 40 +++++------ pkg/cmd/local_build.go | 37 +++++----- pkg/cmd/local_inspect.go | 13 ++-- pkg/cmd/local_run.go | 61 ++++++++--------- pkg/cmd/modeline.go | 5 +- pkg/cmd/run.go | 12 ++-- pkg/cmd/run_help.go | 9 +-- pkg/cmd/run_test.go | 5 +- pkg/cmd/{util_content.go => source/content.go} | 24 +++++-- .../content_test.go} | 26 ++++---- pkg/cmd/{util_sources.go => source/source.go} | 78 +++++++++++----------- pkg/cmd/source/util.go | 62 +++++++++++++++++ pkg/cmd/{ => source}/util_test.go | 18 ++--- pkg/cmd/util.go | 45 ------------- 17 files changed, 282 insertions(+), 246 deletions(-) diff --git a/pkg/cmd/local_util_container.go b/pkg/cmd/local/container.go similarity index 93% rename from pkg/cmd/local_util_container.go rename to pkg/cmd/local/container.go index 109ca030d..8174176d8 100644 --- a/pkg/cmd/local_util_container.go +++ b/pkg/cmd/local/container.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package local import ( "context" @@ -35,8 +35,8 @@ import ( // Local Docker file system management functions. -// createDockerBaseWorkingDirectory creates local docker base directory. -func createDockerBaseWorkingDirectory() error { +// CreateDockerBaseWorkingDirectory creates local docker base directory. +func CreateDockerBaseWorkingDirectory() error { temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "docker-base-") if err != nil { return err @@ -48,13 +48,13 @@ func createDockerBaseWorkingDirectory() error { return nil } -// deleteDockerBaseWorkingDirectory removes directory used for computing the base dependencies. -func deleteDockerBaseWorkingDirectory() error { +// DeleteDockerBaseWorkingDirectory removes directory used for computing the base dependencies. +func DeleteDockerBaseWorkingDirectory() error { return os.RemoveAll(docker.BaseWorkingDirectory) } -// createDockerWorkingDirectory creates local docker directory. -func createDockerWorkingDirectory() error { +// CreateDockerWorkingDirectory creates local docker directory. +func CreateDockerWorkingDirectory() error { temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "docker-") if err != nil { return err @@ -66,18 +66,18 @@ func createDockerWorkingDirectory() error { return nil } -// deleteDockerWorkingDirectory removes directory used for computing the integration dependencies. -func deleteDockerWorkingDirectory() error { +// DeleteDockerWorkingDirectory removes directory used for computing the integration dependencies. +func DeleteDockerWorkingDirectory() error { return os.RemoveAll(docker.IntegrationWorkingDirectory) } -func setDockerNetworkName(networkName string) { +func SetDockerNetworkName(networkName string) { if networkName != "" { docker.NetworkName = networkName } } -func setDockerEnvVars(envVars []string) { +func SetDockerEnvVars(envVars []string) { if len(envVars) > 0 { util.CLIEnvVars = envVars } @@ -132,7 +132,7 @@ func setupDockerRegistry(containerRegistry string, image string, justBaseImage b return nil } -func createAndBuildIntegrationImage(ctx context.Context, containerRegistry string, justBaseImage bool, image string, +func CreateAndBuildIntegrationImage(ctx context.Context, containerRegistry string, justBaseImage bool, image string, propertyFiles []string, dependencies []string, routes []string, startsFromLocalFolder bool, stdout, stderr io.Writer) error { if err := setupDockerRegistry(containerRegistry, image, justBaseImage); err != nil { @@ -213,7 +213,7 @@ func buildIntegrationImage(ctx context.Context, image string, stdout, stderr io. return nil } -func runIntegrationImage(ctx context.Context, image string, stdout, stderr io.Writer) error { +func RunIntegrationImage(ctx context.Context, image string, stdout, stderr io.Writer) error { // Stop the child process before exiting dockerCtx, cancel := context.WithCancel(ctx) cs := make(chan os.Signal, 1) @@ -259,7 +259,7 @@ func getContainerIntegrationRunCommand(ctx context.Context, properties []string, docker.GetContainerPropertiesDir(), stdout, stderr, false) } -func runLocalIntegration(ctx context.Context, properties []string, dependencies []string, routes []string, +func RunLocalIntegration(ctx context.Context, properties []string, dependencies []string, routes []string, propertiesDir string, stdout, stderr io.Writer) error { cmd, err := assembleIntegrationRunCommand(ctx, properties, dependencies, routes, propertiesDir, stdout, stderr, true) diff --git a/pkg/cmd/local_util.go b/pkg/cmd/local/local.go similarity index 89% rename from pkg/cmd/local_util.go rename to pkg/cmd/local/local.go index bc51bd674..8f150ad6c 100644 --- a/pkg/cmd/local_util.go +++ b/pkg/cmd/local/local.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package local import ( "context" @@ -32,6 +32,7 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/builder" + "github.com/apache/camel-k/pkg/cmd/source" "github.com/apache/camel-k/pkg/trait" "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/camel" @@ -45,8 +46,8 @@ var acceptedDependencyTypes = []string{ "github", "gitlab", "bitbucket", "gitee", "azure", } -// 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) { +// 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 { @@ -84,15 +85,15 @@ func getTopLevelDependencies(ctx context.Context, catalog *camel.RuntimeCatalog, dependencies := strset.New() // Invoke the dependency inspector code for each source file - for _, source := range args { - data, _, _, err := loadTextContent(ctx, source, false) + for _, src := range args { + data, _, _, err := source.LoadTextContent(ctx, src, false) if err != nil { return []string{}, err } sourceSpec := v1.SourceSpec{ DataSpec: v1.DataSpec{ - Name: path.Base(source), + Name: path.Base(src), Content: data, Compression: false, }, @@ -175,24 +176,24 @@ func getRegularFilesInDir(directory string, dirnameInPath bool) ([]string, error return dirFiles, nil } -func getLocalBuildDependencies(integrationDirectory string) ([]string, error) { - locallyBuiltDependencies, err := getRegularFilesInDir(getCustomDependenciesDir(integrationDirectory), true) +func GetBuildDependencies(integrationDirectory string) ([]string, error) { + locallyBuiltDependencies, err := getRegularFilesInDir(GetCustomDependenciesDir(integrationDirectory), true) if err != nil { return nil, err } return locallyBuiltDependencies, nil } -func getLocalBuildProperties(integrationDirectory string) ([]string, error) { - locallyBuiltProperties, err := getRegularFilesInDir(getCustomPropertiesDir(integrationDirectory), true) +func GetBuildProperties(integrationDirectory string) ([]string, error) { + locallyBuiltProperties, err := getRegularFilesInDir(GetCustomPropertiesDir(integrationDirectory), true) if err != nil { return nil, err } return locallyBuiltProperties, nil } -func getLocalBuildRoutes(integrationDirectory string) ([]string, error) { - locallyBuiltRoutes, err := getRegularFilesInDir(getCustomRoutesDir(integrationDirectory), true) +func GetBuildRoutes(integrationDirectory string) ([]string, error) { + locallyBuiltRoutes, err := getRegularFilesInDir(GetCustomRoutesDir(integrationDirectory), true) if err != nil { return nil, err } @@ -236,7 +237,7 @@ func createCamelCatalog(ctx context.Context) (*camel.RuntimeCatalog, error) { return catalog, nil } -func outputDependencies(dependencies []string, format string, cmd *cobra.Command) error { +func OutputDependencies(dependencies []string, format string, cmd *cobra.Command) error { if format != "" { if err := printDependencies(format, dependencies, cmd); err != nil { return err @@ -300,8 +301,8 @@ func validateFile(file string) error { return nil } -// validateFiles ensures existence of given files. -func validateFiles(args []string) error { +// ValidateFiles ensures existence of given files. +func ValidateFiles(args []string) error { // Ensure source files exist for _, arg := range args { err := validateFile(arg) @@ -313,9 +314,9 @@ func validateFiles(args []string) error { return nil } -// validateDependencies validates list of additional dependencies i.e. makes sure +// ValidateDependencies validates list of additional dependencies i.e. makes sure // that each dependency has a valid type. -func validateDependencies(dependencies []string) error { +func ValidateDependencies(dependencies []string) error { for _, dependency := range dependencies { depType := strings.Split(dependency, ":")[0] if !util.StringSliceExists(acceptedDependencyTypes, depType) { @@ -326,7 +327,7 @@ func validateDependencies(dependencies []string) error { return nil } -func validatePropertyFiles(propertyFiles []string) error { +func ValidatePropertyFiles(propertyFiles []string) error { for _, fileName := range propertyFiles { if err := validatePropertyFile(fileName); err != nil { return err @@ -350,16 +351,16 @@ func validatePropertyFile(fileName string) error { return nil } -func updateIntegrationProperties(properties []string, propertyFiles []string, hasIntegrationDir bool) ([]string, error) { +func UpdateIntegrationProperties(properties []string, propertyFiles []string, hasIntegrationDir bool) ([]string, error) { // Create properties directory under Maven working directory. // This ensures that property files of different integrations do not clash. - if err := createLocalPropertiesDirectory(); err != nil { + if err := CreateLocalPropertiesDirectory(); err != nil { return nil, err } // Relocate properties files to this integration's property directory. relocatedPropertyFiles := []string{} - dir := getLocalPropertiesDir() + dir := GetLocalPropertiesDir() for _, propertyFile := range propertyFiles { relocatedPropertyFile := path.Join(dir, path.Base(propertyFile)) if _, err := util.CopyFile(propertyFile, relocatedPropertyFile); err != nil { @@ -428,7 +429,7 @@ func updateQuarkusDirectory() error { } // ignore error if custom dir doesn't exist - _ = copyQuarkusAppFiles(util.CustomQuarkusDirectoryName, getLocalQuarkusDir()) + _ = CopyQuarkusAppFiles(util.CustomQuarkusDirectoryName, getLocalQuarkusDir()) return nil } @@ -439,7 +440,7 @@ func updateAppDirectory() error { } // ignore error if custom dir doesn't exist - _ = copyAppFile(util.CustomAppDirectoryName, getLocalAppDir()) + _ = CopyAppFile(util.CustomAppDirectoryName, getLocalAppDir()) return nil } @@ -450,12 +451,12 @@ func updateLibDirectory() error { } // ignore error if custom dir doesn't exist - _ = copyLibFiles(util.CustomLibDirectoryName, getLocalLibDir()) + _ = CopyLibFiles(util.CustomLibDirectoryName, getLocalLibDir()) return nil } -func copyIntegrationFilesToDirectory(files []string, directory string) ([]string, error) { +func CopyIntegrationFilesToDirectory(files []string, directory string) ([]string, error) { // Create directory if one does not already exist if err := util.CreateDirectory(directory); err != nil { return nil, err @@ -474,7 +475,7 @@ func copyIntegrationFilesToDirectory(files []string, directory string) ([]string return relocatedFilesList, nil } -func copyQuarkusAppFiles(dependenciesDir string, quarkusDir string) error { +func CopyQuarkusAppFiles(dependenciesDir string, quarkusDir string) error { // Create directory if one does not already exist if err := util.CreateDirectory(quarkusDir); err != nil { return err @@ -498,7 +499,7 @@ func copyQuarkusAppFiles(dependenciesDir string, quarkusDir string) error { return nil } -func copyLibFiles(dependenciesDir string, libDir string) error { +func CopyLibFiles(dependenciesDir string, libDir string) error { // Create directory if one does not already exist if err := util.CreateDirectory(libDir); err != nil { return err @@ -520,7 +521,7 @@ func copyLibFiles(dependenciesDir string, libDir string) error { return nil } -func copyAppFile(dependenciesDir string, appDir string) error { +func CopyAppFile(dependenciesDir string, appDir string) error { // Create directory if one does not already exist if err := util.CreateDirectory(appDir); err != nil { return err diff --git a/pkg/cmd/local_util_test.go b/pkg/cmd/local/local_test.go similarity index 93% rename from pkg/cmd/local_util_test.go rename to pkg/cmd/local/local_test.go index 2f44490aa..207947241 100644 --- a/pkg/cmd/local_util_test.go +++ b/pkg/cmd/local/local_test.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package local import ( "io/ioutil" @@ -37,7 +37,7 @@ func TestValidatePropertyFiles_ShouldSucceed(t *testing.T) { assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte("key=value"), 0o400)) inputValues := []string{tmpFile1.Name()} - err = validatePropertyFiles(inputValues) + err = ValidatePropertyFiles(inputValues) assert.Nil(t, err) } @@ -53,7 +53,7 @@ func TestValidatePropertyFiles_ShouldFailNotAPropertiesFile(t *testing.T) { assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte("key=value"), 0o400)) inputValues := []string{tmpFile1.Name()} - err = validatePropertyFiles(inputValues) + err = ValidatePropertyFiles(inputValues) assert.NotNil(t, err) assert.True(t, strings.HasPrefix(err.Error(), "supported property files must have a .properties extension")) @@ -61,7 +61,7 @@ func TestValidatePropertyFiles_ShouldFailNotAPropertiesFile(t *testing.T) { func TestValidatePropertyFiles_ShouldFailNotFound(t *testing.T) { inputValues := []string{"/tmp/not-found.properties"} - err := validatePropertyFiles(inputValues) + err := ValidatePropertyFiles(inputValues) assert.NotNil(t, err) assert.True(t, strings.HasPrefix(err.Error(), "unable to access property file")) diff --git a/pkg/cmd/local_util_dirs.go b/pkg/cmd/local/workdir.go similarity index 85% rename from pkg/cmd/local_util_dirs.go rename to pkg/cmd/local/workdir.go index 7d0311d12..3ab67f5ba 100644 --- a/pkg/cmd/local_util_dirs.go +++ b/pkg/cmd/local/workdir.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package local import ( "io/ioutil" @@ -30,8 +30,8 @@ import ( // By default, a temporary folder will be used. var MavenWorkingDirectory = "" -// createMavenWorkingDirectory creates local Maven working directory. -func createMavenWorkingDirectory() error { +// CreateMavenWorkingDirectory creates local Maven working directory. +func CreateMavenWorkingDirectory() error { temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "maven-") if err != nil { return err @@ -43,8 +43,8 @@ func createMavenWorkingDirectory() error { return nil } -// deleteMavenWorkingDirectory removes local Maven working directory. -func deleteMavenWorkingDirectory() error { +// DeleteMavenWorkingDirectory removes local Maven working directory. +func DeleteMavenWorkingDirectory() error { return os.RemoveAll(MavenWorkingDirectory) } @@ -73,24 +73,24 @@ func createLocalDependenciesDirectory() error { return nil } -// getLocalPropertiesDir returns <mavenWorkingDirectory>/properties. -func getLocalPropertiesDir() string { +// GetLocalPropertiesDir returns <mavenWorkingDirectory>/properties. +func GetLocalPropertiesDir() string { return path.Join(MavenWorkingDirectory, util.DefaultPropertiesDirectoryName) } -func createLocalPropertiesDirectory() error { +func CreateLocalPropertiesDirectory() error { // Do not create a directory unless the maven directory contains a valid value. if MavenWorkingDirectory == "" { return nil } - directoryExists, err := util.DirectoryExists(getLocalPropertiesDir()) + directoryExists, err := util.DirectoryExists(GetLocalPropertiesDir()) if err != nil { return err } if !directoryExists { - err := os.MkdirAll(getLocalPropertiesDir(), 0o700) + err := os.MkdirAll(GetLocalPropertiesDir(), 0o700) if err != nil { return err } @@ -199,38 +199,38 @@ func createLocalLibDirectory() error { return nil } -func getCustomDependenciesDir(dir string) string { +func GetCustomDependenciesDir(dir string) string { return path.Join(dir, util.DefaultDependenciesDirectoryName) } -func getCustomPropertiesDir(dir string) string { +func GetCustomPropertiesDir(dir string) string { return path.Join(dir, util.DefaultPropertiesDirectoryName) } -func getCustomRoutesDir(dir string) string { +func GetCustomRoutesDir(dir string) string { return path.Join(dir, util.DefaultRoutesDirectoryName) } -func getCustomQuarkusDir(dir string) string { +func GetCustomQuarkusDir(dir string) string { parentDir := path.Dir(strings.TrimSuffix(dir, "/")) return path.Join(parentDir, util.CustomQuarkusDirectoryName) } -func getCustomLibDir(dir string) string { +func GetCustomLibDir(dir string) string { parentDir := path.Dir(strings.TrimSuffix(dir, "/")) return path.Join(parentDir, util.CustomLibDirectoryName) } -func getCustomAppDir(dir string) string { +func GetCustomAppDir(dir string) string { parentDir := path.Dir(strings.TrimSuffix(dir, "/")) return path.Join(parentDir, "app") } -func deleteLocalIntegrationDirs(dir string) error { +func DeleteLocalIntegrationDirs(dir string) error { dirs := []string{ - getCustomQuarkusDir(dir), - getCustomLibDir(dir), - getCustomAppDir(dir), + GetCustomQuarkusDir(dir), + GetCustomLibDir(dir), + GetCustomAppDir(dir), } for _, dir := range dirs { diff --git a/pkg/cmd/local_build.go b/pkg/cmd/local_build.go index cf36c9d85..6f8cbcfd0 100644 --- a/pkg/cmd/local_build.go +++ b/pkg/cmd/local_build.go @@ -23,6 +23,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/apache/camel-k/pkg/cmd/local" "github.com/apache/camel-k/pkg/util" ) @@ -139,17 +140,17 @@ func (o *localBuildCmdOptions) validateIntegrationMode(args []string) error { } // Validate integration files. - if err := validateFiles(args); err != nil { + if err := local.ValidateFiles(args); err != nil { return err } // Validate additional dependencies specified by the user. - if err := validateDependencies(o.Dependencies); err != nil { + if err := local.ValidateDependencies(o.Dependencies); err != nil { return err } // Validate properties file. - if err := validateFiles(o.PropertyFiles); err != nil { + if err := local.ValidateFiles(o.PropertyFiles); err != nil { return err } @@ -166,19 +167,19 @@ func (o *localBuildCmdOptions) init(args []string) error { if o.BaseImage || o.Image != "" { // If base image construction is enabled create a directory for it. - if err := createDockerBaseWorkingDirectory(); err != nil { + if err := local.CreateDockerBaseWorkingDirectory(); err != nil { return err } // If integration image construction is enabled, an integration image will be built. if o.Image != "" { - if err := createDockerWorkingDirectory(); err != nil { + if err := local.CreateDockerWorkingDirectory(); err != nil { return err } } } - return createMavenWorkingDirectory() + return local.CreateMavenWorkingDirectory() } func (o *localBuildCmdOptions) run(cmd *cobra.Command, args []string) error { @@ -186,7 +187,7 @@ func (o *localBuildCmdOptions) run(cmd *cobra.Command, args []string) error { routeFiles := args if !o.BaseImage { - dependencies, err := getDependencies(o.Context, args, o.Dependencies, o.MavenRepositories, true) + dependencies, err := local.GetDependencies(o.Context, args, o.Dependencies, o.MavenRepositories, true) if err != nil { return err } @@ -194,7 +195,7 @@ func (o *localBuildCmdOptions) run(cmd *cobra.Command, args []string) error { var propertyFiles []string if !o.DependenciesOnly { // Manage integration properties which may come from files or CLI - propertyFiles, err = updateIntegrationProperties(o.Properties, o.PropertyFiles, false) + propertyFiles, err = local.UpdateIntegrationProperties(o.Properties, o.PropertyFiles, false) if err != nil { return err } @@ -207,8 +208,8 @@ func (o *localBuildCmdOptions) run(cmd *cobra.Command, args []string) error { // build the integration without also building the image. A local build of the integration is // represented by all the files that define the integration: dependencies, properties, and routes. if o.IntegrationDirectory != "" { - localDependenciesDir := getCustomDependenciesDir(o.IntegrationDirectory) - dependenciesList, err = copyIntegrationFilesToDirectory(dependencies, localDependenciesDir) + localDependenciesDir := local.GetCustomDependenciesDir(o.IntegrationDirectory) + dependenciesList, err = local.CopyIntegrationFilesToDirectory(dependencies, localDependenciesDir) if err != nil { return err } @@ -218,14 +219,14 @@ func (o *localBuildCmdOptions) run(cmd *cobra.Command, args []string) error { return nil } - localPropertiesDir := getCustomPropertiesDir(o.IntegrationDirectory) - propertyFilesList, err = copyIntegrationFilesToDirectory(propertyFiles, localPropertiesDir) + localPropertiesDir := local.GetCustomPropertiesDir(o.IntegrationDirectory) + propertyFilesList, err = local.CopyIntegrationFilesToDirectory(propertyFiles, localPropertiesDir) if err != nil { return err } - localRoutesDir := getCustomRoutesDir(o.IntegrationDirectory) - routeFiles, err = copyIntegrationFilesToDirectory(args, localRoutesDir) + localRoutesDir := local.GetCustomRoutesDir(o.IntegrationDirectory) + routeFiles, err = local.CopyIntegrationFilesToDirectory(args, localRoutesDir) if err != nil { return err } @@ -240,7 +241,7 @@ func (o *localBuildCmdOptions) run(cmd *cobra.Command, args []string) error { } } - if err := createAndBuildIntegrationImage(o.Context, o.ContainerRegistry, o.BaseImage, o.Image, + if err := local.CreateAndBuildIntegrationImage(o.Context, o.ContainerRegistry, o.BaseImage, o.Image, propertyFilesList, dependenciesList, routeFiles, false, cmd.OutOrStdout(), cmd.ErrOrStderr()); err != nil { return err @@ -251,16 +252,16 @@ func (o *localBuildCmdOptions) run(cmd *cobra.Command, args []string) error { func (o *localBuildCmdOptions) deinit() error { // If base image construction is enabled delete the directory for it. - if err := deleteDockerBaseWorkingDirectory(); err != nil { + if err := local.DeleteDockerBaseWorkingDirectory(); err != nil { return err } // If integration files are provided delete the maven project folder. if !o.BaseImage { - if err := deleteDockerWorkingDirectory(); err != nil { + if err := local.DeleteDockerWorkingDirectory(); err != nil { return err } - if err := deleteMavenWorkingDirectory(); err != nil { + if err := local.DeleteMavenWorkingDirectory(); err != nil { return err } } diff --git a/pkg/cmd/local_inspect.go b/pkg/cmd/local_inspect.go index 22c6aefb9..553f36fca 100644 --- a/pkg/cmd/local_inspect.go +++ b/pkg/cmd/local_inspect.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" + "github.com/apache/camel-k/pkg/cmd/local" "github.com/spf13/cobra" ) @@ -75,11 +76,11 @@ func (o *localInspectCmdOptions) validate(args []string) error { return errors.New("no integration files have been provided") } - if err := validateFiles(args); err != nil { + if err := local.ValidateFiles(args); err != nil { return err } - if err := validateDependencies(o.Dependencies); err != nil { + if err := local.ValidateDependencies(o.Dependencies); err != nil { return err } @@ -87,16 +88,16 @@ func (o *localInspectCmdOptions) validate(args []string) error { } func (o *localInspectCmdOptions) init() error { - return createMavenWorkingDirectory() + return local.CreateMavenWorkingDirectory() } func (o *localInspectCmdOptions) run(cmd *cobra.Command, args []string) error { - dependencies, err := getDependencies(o.Context, args, o.Dependencies, o.MavenRepositories, o.AllDependencies) + dependencies, err := local.GetDependencies(o.Context, args, o.Dependencies, o.MavenRepositories, o.AllDependencies) if err != nil { return err } - if err = outputDependencies(dependencies, o.OutputFormat, cmd); err != nil { + if err = local.OutputDependencies(dependencies, o.OutputFormat, cmd); err != nil { return err } @@ -104,5 +105,5 @@ func (o *localInspectCmdOptions) run(cmd *cobra.Command, args []string) error { } func (o *localInspectCmdOptions) deinit() error { - return deleteMavenWorkingDirectory() + return local.DeleteMavenWorkingDirectory() } diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go index 467c35076..2c3ce54a7 100644 --- a/pkg/cmd/local_run.go +++ b/pkg/cmd/local_run.go @@ -23,6 +23,7 @@ import ( "os/signal" "syscall" + "github.com/apache/camel-k/pkg/cmd/local" "github.com/apache/camel-k/pkg/util" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -105,17 +106,17 @@ func (o *localRunCmdOptions) validate(args []string) error { } // Validate integration files. - if err := validateFiles(args); err != nil { + if err := local.ValidateFiles(args); err != nil { return err } // Validate additional dependencies specified by the user. - if err := validateDependencies(o.Dependencies); err != nil { + if err := local.ValidateDependencies(o.Dependencies); err != nil { return err } // Validate properties file. - if err := validatePropertyFiles(o.PropertyFiles); err != nil { + if err := local.ValidatePropertyFiles(o.PropertyFiles); err != nil { return err } @@ -132,24 +133,24 @@ func (o *localRunCmdOptions) validate(args []string) error { func (o *localRunCmdOptions) init() error { if o.Containerize { - if err := createDockerBaseWorkingDirectory(); err != nil { + if err := local.CreateDockerBaseWorkingDirectory(); err != nil { return err } - if err := createDockerWorkingDirectory(); err != nil { + if err := local.CreateDockerWorkingDirectory(); err != nil { return err } } - setDockerNetworkName(o.Network) - setDockerEnvVars(o.EnvironmentVariables) + local.SetDockerNetworkName(o.Network) + local.SetDockerEnvVars(o.EnvironmentVariables) - return createMavenWorkingDirectory() + return local.CreateMavenWorkingDirectory() } func (o *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 o.Image != "" && !o.Containerize { // Run image locally. - return runIntegrationImage(o.Context, o.Image, cmd.OutOrStdout(), cmd.ErrOrStderr()) + return local.RunIntegrationImage(o.Context, o.Image, cmd.OutOrStdout(), cmd.ErrOrStderr()) } dependencies, err := o.processDependencies(args) @@ -167,29 +168,29 @@ func (o *localRunCmdOptions) run(cmd *cobra.Command, args []string) error { if o.Containerize { // Create, build, and run the container image. - if err := createAndBuildIntegrationImage(o.Context, "", false, o.Image, + if err := local.CreateAndBuildIntegrationImage(o.Context, "", false, o.Image, propertyFiles, dependencies, routes, o.IntegrationDirectory != "", cmd.OutOrStdout(), cmd.ErrOrStderr()); err != nil { return err } - return runIntegrationImage(o.Context, o.Image, cmd.OutOrStdout(), cmd.ErrOrStderr()) + return local.RunIntegrationImage(o.Context, o.Image, cmd.OutOrStdout(), cmd.ErrOrStderr()) } // Run integration locally. - return runLocalIntegration(o.Context, propertyFiles, dependencies, routes, o.getPropertiesDir(), + return local.RunLocalIntegration(o.Context, propertyFiles, dependencies, routes, o.getPropertiesDir(), cmd.OutOrStdout(), cmd.ErrOrStderr()) } func (o *localRunCmdOptions) processDependencies(args []string) ([]string, error) { if o.IntegrationDirectory == "" { - return getDependencies(o.Context, args, o.Dependencies, o.MavenRepositories, true) + return local.GetDependencies(o.Context, args, o.Dependencies, o.MavenRepositories, true) } // Set up on the integration directory // Fetch local dependencies - dependencies, err := getLocalBuildDependencies(o.IntegrationDirectory) + dependencies, err := local.GetBuildDependencies(o.IntegrationDirectory) if err != nil { return nil, err } @@ -203,27 +204,27 @@ func (o *localRunCmdOptions) processDependencies(args []string) ([]string, error // setupDependenciesForQuarkusRun sets up resources under the integration directory for running Quarkus app. func (o *localRunCmdOptions) setupDependenciesForQuarkusRun() error { // Local dependencies directory - localDependenciesDir := getCustomDependenciesDir(o.IntegrationDirectory) + localDependenciesDir := local.GetCustomDependenciesDir(o.IntegrationDirectory) // The quarkus application files need to be at a specific location i.e.: // <integration_directory>/../quarkus/quarkus-application.dat // <integration_directory>/../quarkus/generated-bytecode.jar - localQuarkusDir := getCustomQuarkusDir(o.IntegrationDirectory) - if err := copyQuarkusAppFiles(localDependenciesDir, localQuarkusDir); err != nil { + localQuarkusDir := local.GetCustomQuarkusDir(o.IntegrationDirectory) + if err := local.CopyQuarkusAppFiles(localDependenciesDir, localQuarkusDir); err != nil { return err } // The dependency jar files need to be at a specific location i.e.: // <integration_directory>/../lib/main/*.jar - localLibDir := getCustomLibDir(o.IntegrationDirectory) - if err := copyLibFiles(localDependenciesDir, localLibDir); err != nil { + localLibDir := local.GetCustomLibDir(o.IntegrationDirectory) + if err := local.CopyLibFiles(localDependenciesDir, localLibDir); err != nil { return err } // The Camel K jar file needs to be at a specific location i.e.: // <integration_directory>/../app/camel-k-integration-X.X.X{-SNAPSHOT}.jar - localAppDir := getCustomAppDir(o.IntegrationDirectory) - if err := copyAppFile(localDependenciesDir, localAppDir); err != nil { + localAppDir := local.GetCustomAppDir(o.IntegrationDirectory) + if err := local.CopyAppFile(localDependenciesDir, localAppDir); err != nil { return err } @@ -235,14 +236,14 @@ func (o *localRunCmdOptions) processPropertyFiles() ([]string, error) { propertyFiles := o.PropertyFiles hasIntegrationDir := o.IntegrationDirectory != "" if hasIntegrationDir { - localPropertyFiles, err := getLocalBuildProperties(o.IntegrationDirectory) + localPropertyFiles, err := local.GetBuildProperties(o.IntegrationDirectory) if err != nil { return nil, err } propertyFiles = localPropertyFiles } - return updateIntegrationProperties(o.Properties, propertyFiles, hasIntegrationDir) + return local.UpdateIntegrationProperties(o.Properties, propertyFiles, hasIntegrationDir) } func (o *localRunCmdOptions) processRoutes(args []string) ([]string, error) { @@ -250,33 +251,33 @@ func (o *localRunCmdOptions) processRoutes(args []string) ([]string, error) { return args, nil } - return getLocalBuildRoutes(o.IntegrationDirectory) + return local.GetBuildRoutes(o.IntegrationDirectory) } func (o *localRunCmdOptions) getPropertiesDir() string { if o.IntegrationDirectory == "" { - return getLocalPropertiesDir() + return local.GetLocalPropertiesDir() } - return getCustomPropertiesDir(o.IntegrationDirectory) + return local.GetCustomPropertiesDir(o.IntegrationDirectory) } func (o *localRunCmdOptions) deinit() error { if o.Containerize { - if err := deleteDockerBaseWorkingDirectory(); err != nil { + if err := local.DeleteDockerBaseWorkingDirectory(); err != nil { return err } - if err := deleteDockerWorkingDirectory(); err != nil { + if err := local.DeleteDockerWorkingDirectory(); err != nil { return err } } if o.IntegrationDirectory != "" { - if err := deleteLocalIntegrationDirs(o.IntegrationDirectory); err != nil { + if err := local.DeleteLocalIntegrationDirs(o.IntegrationDirectory); err != nil { return err } } - return deleteMavenWorkingDirectory() + return local.DeleteMavenWorkingDirectory() } diff --git a/pkg/cmd/modeline.go b/pkg/cmd/modeline.go index 07e88155b..4ef02caa2 100644 --- a/pkg/cmd/modeline.go +++ b/pkg/cmd/modeline.go @@ -24,6 +24,7 @@ import ( "path/filepath" "strings" + "github.com/apache/camel-k/pkg/cmd/source" "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/modeline" "github.com/pkg/errors" @@ -194,7 +195,7 @@ func createKamelWithModelineCommand(ctx context.Context, args []string) (*cobra. func extractModelineOptions(ctx context.Context, sources []string, cmd *cobra.Command) ([]modeline.Option, error) { opts := make([]modeline.Option, 0) - resolvedSources, err := ResolveSources(ctx, sources, false, cmd) + resolvedSources, err := source.Resolve(ctx, sources, false, cmd) if err != nil { return opts, errors.Wrap(err, "failed to resolve sources") } @@ -216,7 +217,7 @@ func extractModelineOptions(ctx context.Context, sources []string, cmd *cobra.Co return opts, nil } -func extractModelineOptionsFromSource(resolvedSource Source) ([]modeline.Option, error) { +func extractModelineOptionsFromSource(resolvedSource source.Source) ([]modeline.Option, error) { ops, err := modeline.Parse(resolvedSource.Name, resolvedSource.Content) if err != nil { return ops, errors.Wrapf(err, "cannot process file %s", resolvedSource.Location) diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index e84a628e6..a3282e1f7 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -61,6 +61,8 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/client" + "github.com/apache/camel-k/pkg/cmd/local" + "github.com/apache/camel-k/pkg/cmd/source" platformutil "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/trait" "github.com/apache/camel-k/pkg/util" @@ -238,7 +240,7 @@ func (o *runCmdOptions) validateArgs(cmd *cobra.Command, args []string) error { return errors.New("run expects at least 1 argument, received 0") } - if _, err := ResolveSources(context.Background(), args, false, cmd); err != nil { + if _, err := source.Resolve(context.Background(), args, false, cmd); err != nil { return errors.Wrap(err, "One of the provided sources is not reachable") } @@ -259,7 +261,7 @@ func (o *runCmdOptions) validate() error { propertyFiles := filterBuildPropertyFiles(o.Properties) propertyFiles = append(propertyFiles, filterBuildPropertyFiles(o.BuildProperties)...) - err := validatePropertyFiles(propertyFiles) + err := local.ValidatePropertyFiles(propertyFiles) if err != nil { return err } @@ -441,7 +443,7 @@ func (o *runCmdOptions) syncIntegration(cmd *cobra.Command, c client.Client, sou files = append(files, filterFileLocation(o.OpenAPIs)...) for _, s := range files { - ok, err := isLocalAndFileExists(s) + ok, err := source.IsLocalAndFileExists(s) if err != nil { return err } @@ -578,7 +580,7 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C srcs = append(srcs, sources...) srcs = append(srcs, o.Sources...) - resolvedSources, err := ResolveSources(context.Background(), srcs, o.Compression, cmd) + resolvedSources, err := source.Resolve(context.Background(), srcs, o.Compression, cmd) if err != nil { return nil, err } @@ -801,7 +803,7 @@ func resolvePodTemplate(ctx context.Context, cmd *cobra.Command, templateSrc str // check if value is a path to the file if _, err := os.Stat(templateSrc); err == nil { - rsc, err := ResolveSources(ctx, []string{templateSrc}, false, cmd) + rsc, err := source.Resolve(ctx, []string{templateSrc}, false, cmd) if err == nil && len(rsc) > 0 { templateSrc = rsc[0].Content } diff --git a/pkg/cmd/run_help.go b/pkg/cmd/run_help.go index 1f868292d..c885e4151 100644 --- a/pkg/cmd/run_help.go +++ b/pkg/cmd/run_help.go @@ -25,6 +25,7 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/client" + "github.com/apache/camel-k/pkg/cmd/source" "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/apache/camel-k/pkg/util/resource" "github.com/magiconair/properties" @@ -48,11 +49,11 @@ func parseConfigAndGenCm(ctx context.Context, cmd *cobra.Command, c client.Clien } case resource.StorageTypeFile: // Don't allow a binary non compressed resource - rawData, contentType, err := loadRawContent(ctx, config.Name()) + rawData, contentType, err := source.LoadRawContent(ctx, config.Name()) if err != nil { return nil, err } - if config.ContentType() != resource.ContentTypeData && !enableCompression && isBinary(contentType) { + if config.ContentType() != resource.ContentTypeData && !enableCompression && source.IsBinary(contentType) { return nil, fmt.Errorf("you cannot provide a binary config, use a text file or check --resource flag instead") } resourceType := v1.ResourceTypeData @@ -85,13 +86,13 @@ func binaryOrTextResource(fileName string, data []byte, contentType string, base Type: resourceType, } - if !base64Compression && isBinary(contentType) { + if !base64Compression && source.IsBinary(contentType) { resourceSpec.RawContent = data return resourceSpec, nil } // either is a text resource or base64 compression is enabled if base64Compression { - content, err := compressToString(data) + content, err := source.CompressToString(data) if err != nil { return resourceSpec, err } diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go index d53516400..b02f37698 100644 --- a/pkg/cmd/run_test.go +++ b/pkg/cmd/run_test.go @@ -27,6 +27,7 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" traitv1 "github.com/apache/camel-k/pkg/apis/camel/v1/trait" + "github.com/apache/camel-k/pkg/cmd/source" "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/trait" "github.com/apache/camel-k/pkg/util/test" @@ -463,7 +464,7 @@ func TestRunBinaryResource(t *testing.T) { func TestRunBinaryCompressedResource(t *testing.T) { data := []byte{1, 2, 3, 4} - base64Compressed, _ := compressToString(data) + base64Compressed, _ := source.CompressToString(data) binaryResourceSpec, err := binaryOrTextResource("file.ext", data, "application/octet-stream", true, v1.ResourceTypeData, "") assert.Nil(t, err) assert.Equal(t, base64Compressed, binaryResourceSpec.Content) @@ -485,7 +486,7 @@ func TestRunTextResource(t *testing.T) { func TestRunTextCompressedResource(t *testing.T) { data := []byte("hello horld") - base64Compressed, _ := compressToString(data) + base64Compressed, _ := source.CompressToString(data) textResourceSpec, err := binaryOrTextResource("file.ext", []byte("hello horld"), "text/plain", true, v1.ResourceTypeData, "") assert.Nil(t, err) assert.Equal(t, base64Compressed, textResourceSpec.Content) diff --git a/pkg/cmd/util_content.go b/pkg/cmd/source/content.go similarity index 85% rename from pkg/cmd/util_content.go rename to pkg/cmd/source/content.go index 67e706aae..28e359fff 100644 --- a/pkg/cmd/util_content.go +++ b/pkg/cmd/source/content.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package source import ( "context" @@ -27,6 +27,7 @@ import ( "strings" "github.com/apache/camel-k/pkg/util" + "github.com/apache/camel-k/pkg/util/gzip" ) const ( @@ -36,11 +37,11 @@ const ( Kilobyte = 1 << 10 ) -func loadRawContent(ctx context.Context, source string) ([]byte, string, error) { +func LoadRawContent(ctx context.Context, source string) ([]byte, string, error) { var content []byte var err error - ok, err := isLocalAndFileExists(source) + ok, err := IsLocalAndFileExists(source) if err != nil { return nil, "", err } @@ -74,20 +75,29 @@ func loadRawContent(ctx context.Context, source string) ([]byte, string, error) return content, contentType, nil } -func isBinary(contentType string) bool { +func IsBinary(contentType string) bool { // According the http.DetectContentType method // also json and other "text" application mime types would be reported as text return !strings.HasPrefix(contentType, "text") } -func loadTextContent(ctx context.Context, source string, base64Compression bool) (string, string, bool, error) { - content, contentType, err := loadRawContent(ctx, source) +func CompressToString(content []byte) (string, error) { + bytes, err := gzip.CompressBase64(content) + if err != nil { + return "", err + } + + return string(bytes), nil +} + +func LoadTextContent(ctx context.Context, source string, base64Compression bool) (string, string, bool, error) { + content, contentType, err := LoadRawContent(ctx, source) if err != nil { return "", "", false, err } if base64Compression { - base64Compressed, err := compressToString(content) + base64Compressed, err := CompressToString(content) return base64Compressed, contentType, true, err } diff --git a/pkg/cmd/util_content_test.go b/pkg/cmd/source/content_test.go similarity index 83% rename from pkg/cmd/util_content_test.go rename to pkg/cmd/source/content_test.go index a0548c0ed..1a3a9a7b6 100644 --- a/pkg/cmd/util_content_test.go +++ b/pkg/cmd/source/content_test.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package source import ( "context" @@ -31,7 +31,7 @@ import ( ) func TestRawContentFileMissing(t *testing.T) { - _, _, err := loadRawContent(context.Background(), "dsadas") + _, _, err := LoadRawContent(context.Background(), "dsadas") assert.NotNil(t, err) } @@ -44,10 +44,10 @@ func TestRawBinaryContentType(t *testing.T) { assert.Nil(t, tmpFile.Close()) assert.Nil(t, ioutil.WriteFile(tmpFile.Name(), []byte{1, 2, 3, 4, 5, 6}, 0o400)) - data, contentType, err := loadRawContent(context.Background(), tmpFile.Name()) + data, contentType, err := LoadRawContent(context.Background(), tmpFile.Name()) assert.Nil(t, err) assert.Equal(t, []byte{1, 2, 3, 4, 5, 6}, data) - assert.True(t, isBinary(contentType)) + assert.True(t, IsBinary(contentType)) } func TestRawApplicationContentType(t *testing.T) { @@ -59,10 +59,10 @@ func TestRawApplicationContentType(t *testing.T) { assert.Nil(t, tmpFile.Close()) assert.Nil(t, ioutil.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) - data, contentType, err := loadRawContent(context.Background(), tmpFile.Name()) + data, contentType, err := LoadRawContent(context.Background(), tmpFile.Name()) assert.Nil(t, err) assert.Equal(t, `{"hello":"world"}`, string(data)) - assert.False(t, isBinary(contentType)) + assert.False(t, IsBinary(contentType)) } func TestTextContentType(t *testing.T) { @@ -74,10 +74,10 @@ func TestTextContentType(t *testing.T) { assert.Nil(t, tmpFile.Close()) assert.Nil(t, ioutil.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) - data, contentType, compressed, err := loadTextContent(context.Background(), tmpFile.Name(), false) + data, contentType, compressed, err := LoadTextContent(context.Background(), tmpFile.Name(), false) assert.Nil(t, err) assert.Equal(t, `{"hello":"world"}`, data) - assert.False(t, isBinary(contentType)) + assert.False(t, IsBinary(contentType)) assert.False(t, compressed) } @@ -90,17 +90,17 @@ func TestTextCompressed(t *testing.T) { assert.Nil(t, tmpFile.Close()) assert.Nil(t, ioutil.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) - data, contentType, compressed, err := loadTextContent(context.Background(), tmpFile.Name(), true) + data, contentType, compressed, err := LoadTextContent(context.Background(), tmpFile.Name(), true) assert.Nil(t, err) assert.NotEqual(t, `{"hello":"world"}`, data) - assert.False(t, isBinary(contentType)) + assert.False(t, IsBinary(contentType)) assert.True(t, compressed) } func TestIsBinary(t *testing.T) { - assert.True(t, isBinary("image/jpeg")) - assert.True(t, isBinary("application/zip")) - assert.False(t, isBinary("text/plain")) + assert.True(t, IsBinary("image/jpeg")) + assert.True(t, IsBinary("application/zip")) + assert.False(t, IsBinary("text/plain")) } func TestContentHttp(t *testing.T) { diff --git a/pkg/cmd/util_sources.go b/pkg/cmd/source/source.go similarity index 77% rename from pkg/cmd/util_sources.go rename to pkg/cmd/source/source.go index b15e66912..7af7f3600 100644 --- a/pkg/cmd/util_sources.go +++ b/pkg/cmd/source/source.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package source import ( "context" @@ -45,9 +45,34 @@ type Source struct { Local bool } +// newSource creates a source using the content provider function. +func newSource(location string, compress bool, loadContent func() ([]byte, error)) (Source, error) { + // strip query part from location if any + locPath := util.SubstringBefore(location, "?") + if locPath == "" { + locPath = location + } + src := Source{ + Name: path.Base(locPath), + Origin: location, + Location: location, + Compress: compress, + } + + content, err := loadContent() + if err != nil { + return Source{}, err + } + if err := src.setContent(content); err != nil { + return Source{}, err + } + + return src, nil +} + func (s *Source) setContent(content []byte) error { if s.Compress { - result, err := compressToString(content) + result, err := CompressToString(content) if err != nil { return err } @@ -60,18 +85,18 @@ func (s *Source) setContent(content []byte) error { return nil } -// ResolveSources resolves sources from a variety of locations including local and remote. -func ResolveSources(ctx context.Context, locations []string, compress bool, cmd *cobra.Command) ([]Source, error) { +// Resolve resolves sources from a variety of locations including local and remote. +func Resolve(ctx context.Context, locations []string, compress bool, cmd *cobra.Command) ([]Source, error) { sources := make([]Source, 0, len(locations)) for _, location := range locations { - ok, err := isLocalAndFileExists(location) + ok, err := IsLocalAndFileExists(location) if err != nil { return sources, err } if ok { - answer, err := resolveLocalSource(location, compress) + answer, err := resolveLocal(location, compress) if err != nil { return sources, err } @@ -85,13 +110,13 @@ func ResolveSources(ctx context.Context, locations []string, compress bool, cmd switch { case u.Scheme == gistScheme || strings.HasPrefix(location, "https://gist.github.com/"): - answer, err := resolveGistSource(ctx, location, compress, cmd, u) + answer, err := resolveGist(ctx, location, compress, cmd, u) if err != nil { return sources, err } sources = append(sources, answer...) case u.Scheme == githubScheme: - answer, err := resolveSource(location, compress, func() ([]byte, error) { + answer, err := newSource(location, compress, func() ([]byte, error) { return loadContentGitHub(ctx, u) }) if err != nil { @@ -99,7 +124,7 @@ func ResolveSources(ctx context.Context, locations []string, compress bool, cmd } sources = append(sources, answer) case u.Scheme == httpScheme || u.Scheme == httpsScheme: - answer, err := resolveSource(location, compress, func() ([]byte, error) { + answer, err := newSource(location, compress, func() ([]byte, error) { return loadContentHTTP(ctx, u) }) if err != nil { @@ -115,8 +140,8 @@ func ResolveSources(ctx context.Context, locations []string, compress bool, cmd return sources, nil } -// resolveGistSource resolves sources from a Gist. -func resolveGistSource(ctx context.Context, location string, compress bool, cmd *cobra.Command, u *url.URL) ([]Source, error) { +// resolveGist resolves sources from a Gist. +func resolveGist(ctx context.Context, location string, compress bool, cmd *cobra.Command, u *url.URL) ([]Source, error) { var hc *http.Client if token, ok := os.LookupEnv("GITHUB_TOKEN"); ok { @@ -170,15 +195,15 @@ func resolveGistSource(ctx context.Context, location string, compress bool, cmd return sources, nil } -// resolveLocalSource resolves a source from the local file system. -func resolveLocalSource(location string, compress bool) (Source, error) { +// resolveLocal resolves a source from the local file system. +func resolveLocal(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, err := resolveSource(location, compress, func() ([]byte, error) { + answer, err := newSource(location, compress, func() ([]byte, error) { return util.ReadFile(location) }) if err != nil { @@ -188,28 +213,3 @@ func resolveLocalSource(location string, compress bool) (Source, error) { return answer, nil } - -// resolveSource resolves a source using the content provider function. -func resolveSource(location string, compress bool, loadContent func() ([]byte, error)) (Source, error) { - // strip query part from location if any - locPath := util.SubstringBefore(location, "?") - if locPath == "" { - locPath = location - } - answer := Source{ - Name: path.Base(locPath), - Origin: location, - Location: location, - Compress: compress, - } - - content, err := loadContent() - if err != nil { - return Source{}, err - } - if err := answer.setContent(content); err != nil { - return Source{}, err - } - - return answer, nil -} diff --git a/pkg/cmd/source/util.go b/pkg/cmd/source/util.go new file mode 100644 index 000000000..3e2b6a787 --- /dev/null +++ b/pkg/cmd/source/util.go @@ -0,0 +1,62 @@ +/* +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 source + +import ( + "fmt" + "os" + "strings" + + "github.com/pkg/errors" +) + +const ( + // Supported source schemes. + gistScheme = "gist" + githubScheme = "github" + httpScheme = "http" + httpsScheme = "https" +) + +func IsLocalAndFileExists(uri string) (bool, error) { + if hasSupportedScheme(uri) { + // it's not a local file as it matches one of the supporting schemes + return false, nil + } + info, err := os.Stat(uri) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + // If it is a different error (ie, permission denied) we should report it back + return false, errors.Wrap(err, fmt.Sprintf("file system error while looking for %s", uri)) + } + + return !info.IsDir(), nil +} + +func hasSupportedScheme(uri string) bool { + if strings.HasPrefix(strings.ToLower(uri), gistScheme+":") || + strings.HasPrefix(strings.ToLower(uri), githubScheme+":") || + strings.HasPrefix(strings.ToLower(uri), httpScheme+":") || + strings.HasPrefix(strings.ToLower(uri), httpsScheme+":") { + return true + } + + return false +} diff --git a/pkg/cmd/util_test.go b/pkg/cmd/source/util_test.go similarity index 76% rename from pkg/cmd/util_test.go rename to pkg/cmd/source/util_test.go index 2d8734b35..53de90c9b 100644 --- a/pkg/cmd/util_test.go +++ b/pkg/cmd/source/util_test.go @@ -18,7 +18,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package source import ( "testing" @@ -27,8 +27,8 @@ import ( ) func TestCorrectFileValuesButNotFound(t *testing.T) { - value1, err1 := isLocalAndFileExists("c:\\test") - value2, err2 := isLocalAndFileExists("path/to/file") + value1, err1 := IsLocalAndFileExists("c:\\test") + value2, err2 := IsLocalAndFileExists("path/to/file") // they are all not found, but it must not panic assert.Nil(t, err1) @@ -38,17 +38,17 @@ func TestCorrectFileValuesButNotFound(t *testing.T) { } func TestPermissionDenied(t *testing.T) { - value, err := isLocalAndFileExists("/root/test") + value, err := IsLocalAndFileExists("/root/test") // must not panic because a permission error assert.NotNil(t, err) assert.False(t, value) } func TestSupportedScheme(t *testing.T) { - gistValue, err1 := isLocalAndFileExists("gist:some/gist/resource") - githubValue, err2 := isLocalAndFileExists("github:some/github/resource") - httpValue, err3 := isLocalAndFileExists("http://some/http/resource") - httpsValue, err4 := isLocalAndFileExists("https://some/https/resource") + gistValue, err1 := IsLocalAndFileExists("gist:some/gist/resource") + githubValue, err2 := IsLocalAndFileExists("github:some/github/resource") + httpValue, err3 := IsLocalAndFileExists("http://some/http/resource") + httpsValue, err4 := IsLocalAndFileExists("https://some/https/resource") assert.Nil(t, err1) assert.False(t, gistValue) @@ -61,7 +61,7 @@ func TestSupportedScheme(t *testing.T) { } func TestUnSupportedScheme(t *testing.T) { - value, err := isLocalAndFileExists("bad_scheme:some/bad/resource") + value, err := IsLocalAndFileExists("bad_scheme:some/bad/resource") // must not report an error assert.Nil(t, err) assert.False(t, value) diff --git a/pkg/cmd/util.go b/pkg/cmd/util.go index 1dd67136a..1736037f2 100644 --- a/pkg/cmd/util.go +++ b/pkg/cmd/util.go @@ -24,17 +24,14 @@ import ( "fmt" "io" "log" - "os" "reflect" "strings" "github.com/mitchellh/mapstructure" - "github.com/pkg/errors" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/client" platformutil "github.com/apache/camel-k/pkg/platform" - "github.com/apache/camel-k/pkg/util/gzip" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -46,12 +43,6 @@ import ( const ( offlineCommandLabel = "camel.apache.org/cmd.offline" - - // Supported source schemes. - gistScheme = "gist" - githubScheme = "github" - httpScheme = "http" - httpsScheme = "https" ) // DeleteIntegration --. @@ -250,42 +241,6 @@ func fieldByMapstructureTagName(target reflect.Value, tagName string) (reflect.S return reflect.StructField{}, false } -func compressToString(content []byte) (string, error) { - bytes, err := gzip.CompressBase64(content) - if err != nil { - return "", err - } - - return string(bytes), nil -} - -func isLocalAndFileExists(uri string) (bool, error) { - if hasSupportedScheme(uri) { - // it's not a local file as it matches one of the supporting schemes - return false, nil - } - info, err := os.Stat(uri) - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - // If it is a different error (ie, permission denied) we should report it back - return false, errors.Wrap(err, fmt.Sprintf("file system error while looking for %s", uri)) - } - return !info.IsDir(), nil -} - -func hasSupportedScheme(uri string) bool { - if strings.HasPrefix(strings.ToLower(uri), gistScheme+":") || - strings.HasPrefix(strings.ToLower(uri), githubScheme+":") || - strings.HasPrefix(strings.ToLower(uri), httpScheme+":") || - strings.HasPrefix(strings.ToLower(uri), httpsScheme+":") { - return true - } - - return false -} - func verifyOperatorID(ctx context.Context, client client.Client, operatorID string, out io.Writer) error { if pl, err := platformutil.LookupForPlatformName(ctx, client, operatorID); err != nil { if k8serrors.IsForbidden(err) {
