pkg/util/camel/camel_dependencies.go (231 lines of code) (raw):

/* 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 camel import ( "fmt" "io" "strings" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/jitpack" "github.com/apache/camel-k/v2/pkg/util/maven" "github.com/rs/xid" ) // NormalizeDependency converts different forms of camel dependencies // -- `camel-xxx`, `camel-quarkus-xxx`, and `camel-quarkus:xxx` -- // into the unified form `camel:xxx`. func NormalizeDependency(dependency string) string { newDep := dependency switch { case strings.HasPrefix(newDep, "camel-quarkus-"): newDep = "camel:" + strings.TrimPrefix(dependency, "camel-quarkus-") case strings.HasPrefix(newDep, "camel-quarkus:"): newDep = "camel:" + strings.TrimPrefix(dependency, "camel-quarkus:") case strings.HasPrefix(newDep, "camel-k-"): newDep = "camel-k:" + strings.TrimPrefix(dependency, "camel-k-") case strings.HasPrefix(newDep, "camel-k:"): // do nothing case strings.HasPrefix(newDep, "camel-"): newDep = "camel:" + strings.TrimPrefix(dependency, "camel-") } return newDep } // ValidateDependency validates a dependency against Camel catalog. // It only shows warning and does not throw error in case the Catalog is just not complete, // and we don't want to let it stop the process. func ValidateDependency(catalog *RuntimeCatalog, dependency string, out io.Writer) { if err := ValidateDependencyE(catalog, dependency); err != nil { fmt.Fprintf(out, "Warning: %s\n", err.Error()) } switch { case strings.HasPrefix(dependency, "mvn:org.apache.camel:"): component := strings.Split(dependency, ":")[2] fmt.Fprintf(out, "Warning: do not use %s. Use %s instead\n", dependency, NormalizeDependency(component)) case strings.HasPrefix(dependency, "mvn:org.apache.camel.quarkus:"): component := strings.Split(dependency, ":")[2] fmt.Fprintf(out, "Warning: do not use %s. Use %s instead\n", dependency, NormalizeDependency(component)) } } // ValidateDependencyE validates a dependency against Camel catalog and throws error // in case it does not exist in the catalog. func ValidateDependencyE(catalog *RuntimeCatalog, dependency string) error { var artifact string switch { case strings.HasPrefix(dependency, "camel:"): artifact = strings.TrimPrefix(dependency, "camel:") case strings.HasPrefix(dependency, "camel-quarkus:"): artifact = strings.TrimPrefix(dependency, "camel-quarkus:") case strings.HasPrefix(dependency, "camel-"): artifact = dependency } if artifact == "" { return nil } if ok := catalog.IsValidArtifact(artifact); !ok { return fmt.Errorf("dependency %s not found in Camel catalog", dependency) } return nil } // ValidateDependenciesE validates dependencies against Camel catalog and throws error // in case it does not exist in the catalog. func ValidateDependenciesE(catalog *RuntimeCatalog, dependencies []string) error { for _, dependency := range dependencies { if err := ValidateDependencyE(catalog, dependency); err != nil { return err } } return nil } // ManageIntegrationDependencies sets up all the required dependencies for the given Maven project. func ManageIntegrationDependencies(project *maven.Project, dependencies []string, catalog *RuntimeCatalog) error { // Add dependencies from build if err := addDependencies(project, dependencies, catalog); err != nil { return err } // Add dependencies from catalog addDependenciesFromCatalog(project, catalog) // Post process dependencies postProcessDependencies(project, catalog) return nil } func addDependencies(project *maven.Project, dependencies []string, catalog *RuntimeCatalog) error { for _, d := range dependencies { switch { case strings.HasPrefix(d, "bom:"): if err := addBOM(project, d); err != nil { return err } case strings.HasPrefix(d, "camel:"): addCamelComponent(project, catalog, d) case strings.HasPrefix(d, "camel-k:"): addCamelKComponent(project, d) case strings.HasPrefix(d, "camel-quarkus:"): addCamelQuarkusComponent(project, d) case strings.HasPrefix(d, "mvn:"): addMavenDependency(project, d) default: if err := addJitPack(project, d); err != nil { return err } } } return nil } func addBOM(project *maven.Project, dependency string) error { gav := strings.TrimPrefix(dependency, "bom:") d, err := maven.ParseGAV(gav) if err != nil { return err } project.DependencyManagement.Dependencies = append(project.DependencyManagement.Dependencies, maven.Dependency{ GroupID: d.GroupID, ArtifactID: d.ArtifactID, Version: d.Version, Type: "pom", Scope: "import", }) return nil } func addCamelComponent(project *maven.Project, catalog *RuntimeCatalog, dependency string) { artifactID := strings.TrimPrefix(dependency, "camel:") if catalog != nil && catalog.Runtime.Provider.IsQuarkusBased() { if !strings.HasPrefix(artifactID, "camel-") { artifactID = "camel-quarkus-" + artifactID } project.AddDependencyGAV("org.apache.camel.quarkus", artifactID, "") } else { if !strings.HasPrefix(artifactID, "camel-") { artifactID = "camel-" + artifactID } project.AddDependencyGAV("org.apache.camel", artifactID, "") } } func addCamelKComponent(project *maven.Project, dependency string) { artifactID := strings.TrimPrefix(dependency, "camel-k:") if !strings.HasPrefix(artifactID, "camel-k-") { artifactID = "camel-k-" + artifactID } project.AddDependencyGAV("org.apache.camel.k", artifactID, "") } func addCamelQuarkusComponent(project *maven.Project, dependency string) { artifactID := strings.TrimPrefix(dependency, "camel-quarkus:") if !strings.HasPrefix(artifactID, "camel-quarkus-") { artifactID = "camel-quarkus-" + artifactID } project.AddDependencyGAV("org.apache.camel.quarkus", artifactID, "") } func addMavenDependency(project *maven.Project, dependency string) { gav := strings.TrimPrefix(dependency, "mvn:") project.AddEncodedDependencyGAV(gav) } func addJitPack(project *maven.Project, dependency string) error { dep := jitpack.ToDependency(dependency) if dep == nil { return fmt.Errorf("unknown dependency type: %s", dependency) } project.AddDependency(*dep) addRepo := true for _, repo := range project.Repositories { if repo.URL == jitpack.RepoURL { addRepo = false break } } if addRepo { project.Repositories = append(project.Repositories, v1.Repository{ ID: "jitpack.io-" + xid.New().String(), URL: jitpack.RepoURL, Releases: v1.RepositoryPolicy{ Enabled: true, ChecksumPolicy: "fail", }, Snapshots: v1.RepositoryPolicy{ Enabled: true, ChecksumPolicy: "fail", }, }) } return nil } func addDependenciesFromCatalog(project *maven.Project, catalog *RuntimeCatalog) { deps := make([]maven.Dependency, len(project.Dependencies)) copy(deps, project.Dependencies) for _, d := range deps { if a, ok := catalog.Artifacts[d.ArtifactID]; ok { for _, dep := range a.Dependencies { md := maven.Dependency{ GroupID: dep.GroupID, ArtifactID: dep.ArtifactID, Type: dep.Type, Classifier: dep.Classifier, } project.AddDependency(md) for _, e := range dep.Exclusions { me := maven.Exclusion{ GroupID: e.GroupID, ArtifactID: e.ArtifactID, } project.AddDependencyExclusion(md, me) } } } } } func postProcessDependencies(project *maven.Project, catalog *RuntimeCatalog) { deps := make([]maven.Dependency, len(project.Dependencies)) copy(deps, project.Dependencies) for _, d := range deps { if a, ok := catalog.Artifacts[d.ArtifactID]; ok { md := maven.Dependency{ GroupID: a.GroupID, ArtifactID: a.ArtifactID, } for _, e := range a.Exclusions { me := maven.Exclusion{ GroupID: e.GroupID, ArtifactID: e.ArtifactID, } project.AddDependencyExclusion(md, me) } } } } // SanitizeIntegrationDependencies --. func SanitizeIntegrationDependencies(dependencies []maven.Dependency) error { for i := range dependencies { dep := dependencies[i] // It may be externalized into runtime provider specific steps switch dep.GroupID { case "org.apache.camel": fallthrough case "org.apache.camel.k": fallthrough case "org.apache.camel.quarkus": // // Remove the version so we force using the one configured by the bom // dependencies[i].Version = "" } } return nil }