From ba9dc630f07dae1e1b5e4ecb2d9e951149da273f Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Fri, 12 Apr 2024 12:01:44 +0200 Subject: [PATCH 01/17] Configure JDK for use with gradle Signed-off-by: Juan Manuel Leflet Estrada --- .../pkg/java_external_provider/service_client.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/external-providers/java-external-provider/pkg/java_external_provider/service_client.go b/external-providers/java-external-provider/pkg/java_external_provider/service_client.go index 1749b7cb..3f557e11 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/service_client.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/service_client.go @@ -205,6 +205,8 @@ func (p *javaServiceClient) initialization(ctx context.Context) { params.ExtendedClientCapilities = map[string]interface{}{ "classFileContentsSupport": true, } + // See https://github.com/eclipse-jdtls/eclipse.jdt.ls/blob/1a3dd9323756113bf39cfab82746d57a2fd19474/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java + // TODO: what if no wrapper? params.InitializationOptions = map[string]interface{}{ "bundles": absBundles, "workspaceFolders": []string{fmt.Sprintf("file://%v", absLocation)}, @@ -221,6 +223,13 @@ func (p *javaServiceClient) initialization(ctx context.Context) { "maven": map[string]interface{}{ "downloadSources": downloadSources, }, + "import": map[string]interface{}{ + "gradle": map[string]interface{}{ + "java": map[string]interface{}{ + "home": "/usr/lib/jvm/java-1.8.0-openjdk", + }, + }, + }, }, }, } From fe91718b64f7e9a6d96ce09c0eac782a7a3a6c0f Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Fri, 26 Apr 2024 11:43:55 +0200 Subject: [PATCH 02/17] Add support for fetching dependencies with Gradle Signed-off-by: Juan Manuel Leflet Estrada --- .../pkg/java_external_provider/dependency.go | 210 ++++++++++++++++ .../java_external_provider/dependency_test.go | 235 ++++++++++++++++++ 2 files changed, 445 insertions(+) diff --git a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go index d980e85e..33af1e74 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "io" "io/fs" @@ -36,6 +37,21 @@ const ( baseDepKey = "baseDep" ) +const ( + maven = "maven" + gradle = "gradle" +) + +func (p *javaServiceClient) getBuildTool() string { + bf := "" + if bf = p.findPom(); bf != "" { + return maven + } else if bf = p.findGradleBuild(); bf != "" { + return gradle + } + return "" +} + // TODO implement this for real func (p *javaServiceClient) findPom() string { var depPath string @@ -51,10 +67,41 @@ func (p *javaServiceClient) findPom() string { if err != nil { return "" } + if _, err := os.Stat(f); errors.Is(err, os.ErrNotExist) { + return "" + } return f } +func (p *javaServiceClient) findGradleBuild() string { + // TODO: naive? + if p.config.Location != "" { + f, err := filepath.Abs(filepath.Join(p.config.Location, "build.gradle")) + if err != nil { + return "" + } + return f + } + return "" +} + func (p *javaServiceClient) GetDependencies(ctx context.Context) (map[uri.URI][]*provider.Dep, error) { + if p.getBuildTool() == gradle { + p.log.V(2).Info("gradle found - retrieving dependencies") + m := map[uri.URI][]*provider.Dep{} + deps, err := p.getDependenciesForGradle(ctx) + for f, ds := range deps { + deps := []*provider.Dep{} + for _, dep := range ds { + d := dep.Dep + deps = append(deps, &d) + deps = append(deps, provider.ConvertDagItemsToList(dep.AddedDeps)...) + } + m[f] = deps + } + return m, err + } + p.depsMutex.RLock() val := p.depsCache p.depsMutex.RUnlock() @@ -226,6 +273,17 @@ func pomCoordinate(value *string) string { } func (p *javaServiceClient) GetDependenciesDAG(ctx context.Context) (map[uri.URI][]provider.DepDAGItem, error) { + switch p.getBuildTool() { + case maven: + return p.getDependenciesForMaven(ctx) + case gradle: + return p.getDependenciesForGradle(ctx) + default: + return nil, fmt.Errorf("no build tool found") + } +} + +func (p *javaServiceClient) getDependenciesForMaven(ctx context.Context) (map[uri.URI][]provider.DepDAGItem, error) { localRepoPath := getMavenLocalRepoPath(p.mvnSettingsFile) path := p.findPom() @@ -274,6 +332,158 @@ func (p *javaServiceClient) GetDependenciesDAG(ctx context.Context) (map[uri.URI return m, nil } +// getDependenciesForGradle invokes the Gradle wrapper to get the dependency tree and returns all project dependencies +// TODO: what if no wrapper? +func (p *javaServiceClient) getDependenciesForGradle(ctx context.Context) (map[uri.URI][]provider.DepDAGItem, error) { + subprojects, err := p.getGradleSubprojects() + if err != nil { + return nil, err + } + + // command syntax: ./gradlew subproject1:dependencies subproject2:dependencies ... + args := []string{} + if len(subprojects) > 0 { + for _, sp := range subprojects { + args = append(args, fmt.Sprintf("%s:dependencies", sp)) + } + } else { + args = append(args, "dependencies") + } + + // get the graph output + cmd := exec.Command("./gradlew", args...) + cmd.Dir = p.config.Location + output, err := cmd.CombinedOutput() + if err != nil { + return nil, err + } + + lines := strings.Split(string(output), "\n") + deps := p.parseGradleDependencyOutput(lines) + + // TODO: do we need to separate by submodule somehow? + + path := p.findGradleBuild() + file := uri.File(path) + m := map[uri.URI][]provider.DepDAGItem{} + m[file] = deps + + // TODO: need error? + return m, nil +} + +func (p *javaServiceClient) getGradleSubprojects() ([]string, error) { + args := []string{ + "projects", + } + + // Ideally we'd want to set this in gradle.properties, or as a -Dorg.gradle.java.home arg, + // but it doesn't seem to work in older Gradle versions. This should only affect child processes in any case. + err := os.Setenv("JAVA_HOME", os.Getenv("JAVA8_HOME")) + if err != nil { + return nil, err + } + + exe := filepath.Join(p.config.Location, "gradlew") + cmd := exec.Command(exe, args...) + cmd.Dir = p.config.Location + output, err := cmd.CombinedOutput() + if err != nil { + return nil, err + } + + beginRegex := regexp.MustCompile(`Root project`) + endRegex := regexp.MustCompile(`To see a list of`) + npRegex := regexp.MustCompile(`No sub-projects`) + pRegex := regexp.MustCompile(`.*- Project '(.*)'`) + + subprojects := []string{} + + gather := false + lines := strings.Split(string(output), "\n") + for _, line := range lines { + if npRegex.Find([]byte(line)) != nil { + return []string{}, nil + } + if beginRegex.Find([]byte(line)) != nil { + gather = true + continue + } + if gather { + if endRegex.Find([]byte(line)) != nil { + return subprojects, nil + } + + if p := pRegex.FindStringSubmatch(line); p != nil { + subprojects = append(subprojects, p[1]) + } + } + } + + return subprojects, fmt.Errorf("error parsing gradle dependency output") +} + +// parseGradleDependencyOutput converts the relevant lines from the dependency output into actual dependencies +// See https://regex101.com/r/9Gp7dW/1 for context +func (p *javaServiceClient) parseGradleDependencyOutput(lines []string) []provider.DepDAGItem { + deps := []provider.DepDAGItem{} + + treeDepRegex := regexp.MustCompile(`^([| ]+)?[+\\]--- (.*)`) + + // map of to + // this is so that children can be added to their respective parents + lastFoundWithDepth := make(map[int]*provider.DepDAGItem) + + for _, line := range lines { + match := treeDepRegex.FindStringSubmatch(line) + if match != nil { + dep := parseGradleDependencyString(match[2]) + if reflect.DeepEqual(dep, provider.DepDAGItem{}) { // ignore empty dependency + continue + } else if match[1] != "" { // transitive dependency + dep.Dep.Indirect = true + depth := len(match[1]) / 5 // get the level of anidation of the dependency within the tree + parent := lastFoundWithDepth[depth-1] // find its parent + parent.AddedDeps = append(parent.AddedDeps, dep) // add child to parent + lastFoundWithDepth[depth] = &parent.AddedDeps[len(parent.AddedDeps)-1] // update last found with given depth + } else { // root level (direct) dependency + deps = append(deps, dep) // add root dependency to result list + lastFoundWithDepth[0] = &deps[len(deps)-1] + continue + } + } + } + + return deps +} + +// parseGradleDependencyString parses the lines of the gradle dependency output, for instance: +// org.codehaus.groovy:groovy:3.0.21 +// org.codehaus.groovy:groovy:3.+ -> 3.0.21 +// com.codevineyard:hello-world:{strictly 1.0.1} -> 1.0.1 +// :simple-jar (n) +func parseGradleDependencyString(s string) provider.DepDAGItem { + // (*) - dependencies omitted (listed previously) + // (n) - Not resolved (configuration is not meant to be resolved) + if strings.HasSuffix(s, "(n)") || strings.HasSuffix(s, "(*)") { + return provider.DepDAGItem{} + } + + depRegex := regexp.MustCompile(`(.+):(.+):((.*) -> )?(.*)`) + libRegex := regexp.MustCompile(`:(.*)`) + + dep := provider.Dep{} + match := depRegex.FindStringSubmatch(s) + if match != nil { + dep.Name = match[1] + "." + match[2] + dep.Version = match[5] + } else if match = libRegex.FindStringSubmatch(s); match != nil { + dep.Name = match[1] + } + + return provider.DepDAGItem{Dep: dep, AddedDeps: []provider.DepDAGItem{}} +} + // extractSubmoduleTrees creates an array of lines for each submodule tree found in the mvn dependency:tree output func extractSubmoduleTrees(lines []string) [][]string { submoduleTrees := [][]string{} diff --git a/external-providers/java-external-provider/pkg/java_external_provider/dependency_test.go b/external-providers/java-external-provider/pkg/java_external_provider/dependency_test.go index d605f319..33957093 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/dependency_test.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/dependency_test.go @@ -560,3 +560,238 @@ func Test_parseMavenDepLines(t *testing.T) { }) } } + +func Test_parseGradleDependencyOutput(t *testing.T) { + gradleOutput := ` +Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details + +> Task :dependencies + +------------------------------------------------------------ +Root project +------------------------------------------------------------ + +annotationProcessor - Annotation processors and their dependencies for source set 'main'. +No dependencies + +api - API dependencies for source set 'main'. (n) +No dependencies + +apiElements - API elements for main. (n) +No dependencies + +archives - Configuration for archive artifacts. (n) +No dependencies + +compileClasspath - Compile classpath for source set 'main'. ++--- org.codehaus.groovy:groovy:3.+ -> 3.0.21 ++--- org.codehaus.groovy:groovy-json:3.+ -> 3.0.21 +| \--- org.codehaus.groovy:groovy:3.0.21 ++--- com.codevineyard:hello-world:{strictly 1.0.1} -> 1.0.1 +\--- :simple-jar + +testRuntimeOnly - Runtime only dependencies for source set 'test'. (n) +No dependencies + +(*) - dependencies omitted (listed previously) + +(n) - Not resolved (configuration is not meant to be resolved) + +A web-based, searchable dependency report is available by adding the --scan option. + +BUILD SUCCESSFUL in 4s +1 actionable task: 1 executed +` + + lines := strings.Split(gradleOutput, "\n") + + p := javaServiceClient{ + log: testr.New(t), + depToLabels: map[string]*depLabelItem{}, + config: provider.InitConfig{ + ProviderSpecificConfig: map[string]interface{}{ + "excludePackages": []string{}, + }, + }, + } + + wantedDeps := []provider.DepDAGItem{ + { + Dep: provider.Dep{ + Name: "org.codehaus.groovy.groovy", + Version: "3.0.21", + Indirect: false, + }, + }, + { + Dep: provider.Dep{ + Name: "org.codehaus.groovy.groovy-json", + Version: "3.0.21", + Indirect: false, + }, + AddedDeps: []provider.DepDAGItem{ + { + Dep: provider.Dep{ + Name: "org.codehaus.groovy.groovy", + Version: "3.0.21", + Indirect: true, + }, + }, + }, + }, + { + Dep: provider.Dep{ + Name: "com.codevineyard.hello-world", + Version: "1.0.1", + Indirect: false, + }, + }, + { + Dep: provider.Dep{ + Name: "simple-jar", + Indirect: false, + }, + }, + } + + deps := p.parseGradleDependencyOutput(lines) + + if len(deps) != len(wantedDeps) { + t.Errorf("different number of dependencies found") + } + + for i := 0; i < len(deps); i++ { + dep := deps[i] + wantedDep := wantedDeps[i] + if dep.Dep.Name != wantedDep.Dep.Name { + t.Errorf("wanted name: %s, found name: %s", wantedDep.Dep.Name, dep.Dep.Name) + } + if dep.Dep.Version != wantedDep.Dep.Version { + t.Errorf("wanted version: %s, found version: %s", wantedDep.Dep.Version, dep.Dep.Version) + } + if len(dep.AddedDeps) != len(wantedDep.AddedDeps) { + t.Errorf("wanted %d child deps, found %d for dep %s", len(wantedDep.AddedDeps), len(dep.AddedDeps), dep.Dep.Name) + } + + } + +} + +func Test_parseGradleDependencyOutput_withTwoLevelsOfNesting(t *testing.T) { + gradleOutput := ` +Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details + +> Task :dependencies + +------------------------------------------------------------ +Root project +------------------------------------------------------------ + +annotationProcessor - Annotation processors and their dependencies for source set 'main'. +No dependencies + +api - API dependencies for source set 'main'. (n) +No dependencies + +apiElements - API elements for main. (n) +No dependencies + +archives - Configuration for archive artifacts. (n) +No dependencies + +compileClasspath - Compile classpath for source set 'main'. ++--- net.sourceforge.pmd:pmd-java:5.6.1 + +--- net.sourceforge.pmd:pmd-core:5.6.1 + | \--- com.google.code.gson:gson:2.5 + \--- net.sourceforge.saxon:saxon:9.1.0.8 ++--- org.apache.logging.log4j:log4j-api:2.9.1 + +testRuntimeOnly - Runtime only dependencies for source set 'test'. (n) +No dependencies + +(*) - dependencies omitted (listed previously) + +(n) - Not resolved (configuration is not meant to be resolved) + +A web-based, searchable dependency report is available by adding the --scan option. + +BUILD SUCCESSFUL in 4s +1 actionable task: 1 executed +` + + lines := strings.Split(gradleOutput, "\n") + + p := javaServiceClient{ + log: testr.New(t), + depToLabels: map[string]*depLabelItem{}, + config: provider.InitConfig{ + ProviderSpecificConfig: map[string]interface{}{ + "excludePackages": []string{}, + }, + }, + } + + wantedDeps := []provider.DepDAGItem{ + { + Dep: provider.Dep{ + Name: "net.sourceforge.pmd.pmd-java", + Version: "5.6.1", + Indirect: false, + }, + AddedDeps: []provider.DepDAGItem{ + { + Dep: provider.Dep{ + Name: "net.sourceforge.pmd.pmd-core", + Version: "5.6.1", + Indirect: true, + }, + AddedDeps: []provider.DepDAGItem{ + { + Dep: provider.Dep{ + Name: "com.google.code.gson.gson", + Version: "2.5", + Indirect: true, + }, + }, + }, + }, + { + Dep: provider.Dep{ + Name: "net.sourceforge.saxon.saxon", + Version: "9.1.0.8", + Indirect: true, + }, + }, + }, + }, + { + Dep: provider.Dep{ + Name: "org.apache.logging.log4j.log4j-api", + Version: "2.9.1", + Indirect: false, + }, + }, + } + + deps := p.parseGradleDependencyOutput(lines) + + if len(deps) != len(wantedDeps) { + t.Errorf("different number of dependencies found") + } + + for i := 0; i < len(deps); i++ { + dep := deps[i] + wantedDep := wantedDeps[i] + if dep.Dep.Name != wantedDep.Dep.Name { + t.Errorf("wanted name: %s, found name: %s", wantedDep.Dep.Name, dep.Dep.Name) + } + if dep.Dep.Version != wantedDep.Dep.Version { + t.Errorf("wanted version: %s, found version: %s", wantedDep.Dep.Version, dep.Dep.Version) + } + if len(dep.AddedDeps) != len(wantedDep.AddedDeps) { + t.Errorf("wanted %d child deps, found %d for dep %s", len(wantedDep.AddedDeps), len(dep.AddedDeps), dep.Dep.Name) + } + + } + +} From b251b4fb4075e6cbf7034884322f995f4e95df3b Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Tue, 30 Apr 2024 15:08:04 +0200 Subject: [PATCH 03/17] Add example project, fix path Signed-off-by: Juan Manuel Leflet Estrada --- demo-output.yaml | 5 + .../gradle-multi-project-example/.gitignore | 105 ++++++++ .../gradle-multi-project-example/LICENSE | 21 ++ .../gradle-multi-project-example/Procfile | 2 + .../gradle-multi-project-example/README.md | 53 ++++ .../gradle-multi-project-example/build.gradle | 47 ++++ .../codequality/checkstyle.xml | 238 ++++++++++++++++++ .../gradle/check.gradle | 15 ++ .../gradle/heroku/clean.gradle | 5 + .../gradle/heroku/stage.gradle | 8 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54727 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../gradle-multi-project-example/gradlew | 172 +++++++++++++ .../gradle-multi-project-example/gradlew.bat | 84 +++++++ .../settings.gradle | 4 + .../template-core/build.gradle | 10 + .../java/io/jeffchao/template/core/Core.java | 8 + .../io/jeffchao/template/core/CoreTest.java | 16 ++ .../template-server/build.gradle | 10 + .../io/jeffchao/template/server/Server.java | 32 +++ .../jeffchao/template/server/ServerTest.java | 16 ++ .../java-external-provider/go.mod | 6 +- .../pkg/java_external_provider/dependency.go | 11 +- 23 files changed, 870 insertions(+), 4 deletions(-) create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/.gitignore create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/LICENSE create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/Procfile create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/README.md create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/build.gradle create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/codequality/checkstyle.xml create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/check.gradle create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/clean.gradle create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/stage.gradle create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/wrapper/gradle-wrapper.jar create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/wrapper/gradle-wrapper.properties create mode 100755 external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew.bat create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/build.gradle create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/main/java/io/jeffchao/template/core/Core.java create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/test/java/io/jeffchao/template/core/CoreTest.java create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/build.gradle create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java create mode 100644 external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/test/java/io/jeffchao/template/server/ServerTest.java diff --git a/demo-output.yaml b/demo-output.yaml index c04b5877..138b0179 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -381,6 +381,11 @@ description: "" category: potential incidents: + - uri: file:///examples/gradle-multi-project-example/build.gradle + message: dependency junit.junit with 4.12 is bad and you should feel bad for using it + variables: + name: junit.junit + version: "4.12" - uri: file:///examples/java/pom.xml message: dependency io.fabric8.kubernetes-client with 6.0.0 is bad and you should feel bad for using it codeSnip: "26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8\n41 kubernetes-client-api\n42 6.0.0\n43 \n44 \n45 javax\n46 javaee-api" diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/.gitignore b/external-providers/java-external-provider/examples/gradle-multi-project-example/.gitignore new file mode 100644 index 00000000..0c740ded --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/.gitignore @@ -0,0 +1,105 @@ +### Intellij+iml ### +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### Intellij+iml Patch ### +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +.idea/ + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### macOS ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Gradle ### +.gradle +**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/LICENSE b/external-providers/java-external-provider/examples/gradle-multi-project-example/LICENSE new file mode 100644 index 00000000..25408ddc --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [author] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/Procfile b/external-providers/java-external-provider/examples/gradle-multi-project-example/Procfile new file mode 100644 index 00000000..40dc36e6 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/Procfile @@ -0,0 +1,2 @@ +web: java -jar build/libs/template-server-all.jar +worker: java -jar build/libs/template-core-all.jar diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/README.md b/external-providers/java-external-provider/examples/gradle-multi-project-example/README.md new file mode 100644 index 00000000..64e41321 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/README.md @@ -0,0 +1,53 @@ +# gradle-multi-project-example + +Basic gradle template with subprojects, deployable to Heroku as separate dyno processes. + +## What's included? + +1. Gradle Plugins + - application plugin + - shadowjar plugin +2. Code Style + - checkstyle + - findbugs + - pmd +3. General Libraries + - guava + - junit + - mockito + - log4j2 via slf4j +4. Multi-Project Gradle Setup + - see: [settings.gradle](settings.gradle) +5. Heroku Deployment + - see: [Procfile](Procfile), [stage.gradle](gradle/heroku/stage.gradle) + +## Development + +### Building + +``` +$ ./gradlew clean build +``` + +### Testing + +``` +$ ./gradlew clean test +``` + +### Building Deployment Artifacts + +``` +$ ./gradlew clean stage +``` + +### Running + +Use the Gradle [application plugin](https://docs.gradle.org/current/userguide/application_plugin.html). +However, `./gradlew run` will run applications in lexicographical order. +Instead, explicitly specify which subproject to run: + +``` +$ ./gradlew template-core:run +$ ./gradlew template-server:run +``` diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/build.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/build.gradle new file mode 100644 index 00000000..d81723d2 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/build.gradle @@ -0,0 +1,47 @@ +apply plugin: 'idea' + +ext { + log4jVersion = '2.9.1' +} + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.1' + } +} + +allprojects { + repositories { + mavenLocal() + mavenCentral() // maven { url: 'http://jcenter.bintray.com' } + } +} + +apply from: file('gradle/check.gradle') +apply from: file('gradle/heroku/clean.gradle') + +subprojects { + apply plugin: 'com.github.johnrengelman.shadow' + apply plugin: 'java' + + group = "io.jeffchao.${rootProject.name}" + + dependencies { + implementation 'com.google.guava:guava:23.0' + + testImplementation 'junit:junit:4.12' + + compile "org.apache.logging.log4j:log4j-api:$log4jVersion" + compile "org.apache.logging.log4j:log4j-core:$log4jVersion" + compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion" + + testCompile 'org.mockito:mockito-core:2.11.0' + + } + + apply from: file("$rootProject.projectDir/gradle/heroku/stage.gradle") + +} \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/codequality/checkstyle.xml b/external-providers/java-external-provider/examples/gradle-multi-project-example/codequality/checkstyle.xml new file mode 100644 index 00000000..2d6336e9 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/codequality/checkstyle.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/check.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/check.gradle new file mode 100644 index 00000000..19af4208 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/check.gradle @@ -0,0 +1,15 @@ +subprojects { + apply plugin: 'checkstyle' + checkstyle { + ignoreFailures = true + configFile = rootProject.file('codequality/checkstyle.xml') + toolVersion = '8.4' + } + + apply plugin: 'findbugs' + findbugs { + ignoreFailures = true + } + + apply plugin: 'pmd' +} diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/clean.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/clean.gradle new file mode 100644 index 00000000..67329835 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/clean.gradle @@ -0,0 +1,5 @@ +apply plugin: 'base' + +clean.doLast { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/stage.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/stage.gradle new file mode 100644 index 00000000..819e4e83 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/heroku/stage.gradle @@ -0,0 +1,8 @@ +task stage(dependsOn: ['clean', 'shadowJar']) + +task copyToLib(type: Copy) { + from "$buildDir/libs" + into "$rootProject.buildDir/libs" +} +copyToLib.dependsOn(shadowJar) +stage.dependsOn(copyToLib) \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/wrapper/gradle-wrapper.jar b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..27768f1bbac3ce2d055b20d521f12da78d331e8e GIT binary patch literal 54727 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

i| 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 literal 0 HcmV?d00001 diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/wrapper/gradle-wrapper.properties b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..7e4921d3 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Nov 01 15:30:19 PDT 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-all.zip diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew new file mode 100755 index 00000000..cccdd3d5 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew.bat b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew.bat new file mode 100644 index 00000000..e95643d6 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle new file mode 100644 index 00000000..ace373a1 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle @@ -0,0 +1,4 @@ +rootProject.name = 'basic-gradle-template' + +include 'template-core' +include 'template-server' diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/build.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/build.gradle new file mode 100644 index 00000000..7fb7ee66 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/build.gradle @@ -0,0 +1,10 @@ +apply plugin: 'application' + +mainClassName = 'io.jeffchao.template.core.Core' + +dependencies { +} + +run.doFirst { + // Environment variables go here. +} \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/main/java/io/jeffchao/template/core/Core.java b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/main/java/io/jeffchao/template/core/Core.java new file mode 100644 index 00000000..b430f2b1 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/main/java/io/jeffchao/template/core/Core.java @@ -0,0 +1,8 @@ +package io.jeffchao.template.core; + +public class Core { + + public static void main(String[] args) { + System.out.println("hello, template!"); + } +} \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/test/java/io/jeffchao/template/core/CoreTest.java b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/test/java/io/jeffchao/template/core/CoreTest.java new file mode 100644 index 00000000..d88ab5a1 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-core/src/test/java/io/jeffchao/template/core/CoreTest.java @@ -0,0 +1,16 @@ +package io.jeffchao.template.core; + +import org.junit.After; +import org.junit.Before; + + +public class CoreTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } +} \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/build.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/build.gradle new file mode 100644 index 00000000..47600b02 --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/build.gradle @@ -0,0 +1,10 @@ +apply plugin: 'application' + +mainClassName = 'io.jeffchao.template.server.Server' + +dependencies { +} + +run.doFirst { + // Environment variables go here. +} diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java new file mode 100644 index 00000000..cc6d373d --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java @@ -0,0 +1,32 @@ +package io.jeffchao.template.server; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public class Server { + + public static void main(String[] args) throws IOException { + String portString = System.getenv("PORT"); + int port = portString == null ? 8080 : Integer.valueOf(portString); + HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); + server.createContext("/", new MyHandler()); + server.setExecutor(null); // creates a default executor + server.start(); + } + + static class MyHandler implements HttpHandler { + @Override + public void handle(HttpExchange t) throws IOException { + String response = "Hello from Gradle!"; + t.sendResponseHeaders(200, response.length()); + OutputStream os = t.getResponseBody(); + os.write(response.getBytes()); + os.close(); + } + } +} \ No newline at end of file diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/test/java/io/jeffchao/template/server/ServerTest.java b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/test/java/io/jeffchao/template/server/ServerTest.java new file mode 100644 index 00000000..6f63c10e --- /dev/null +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/template-server/src/test/java/io/jeffchao/template/server/ServerTest.java @@ -0,0 +1,16 @@ +package io.jeffchao.template.server; + +import org.junit.After; +import org.junit.Before; + + +public class ServerTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } +} \ No newline at end of file diff --git a/external-providers/java-external-provider/go.mod b/external-providers/java-external-provider/go.mod index 19bbba6e..be927d8d 100644 --- a/external-providers/java-external-provider/go.mod +++ b/external-providers/java-external-provider/go.mod @@ -6,14 +6,16 @@ require ( github.com/go-logr/logr v1.4.1 github.com/konveyor/analyzer-lsp v0.4.0-alpha.1.0.20240520232004-8af6f5c84a59 github.com/swaggest/openapi-go v0.2.50 - github.com/vifraa/gopom v1.0.0 go.lsp.dev/uri v0.3.0 go.opentelemetry.io/otel v1.11.2 google.golang.org/grpc v1.62.1 // indirect gopkg.in/yaml.v2 v2.4.0 ) -require github.com/sirupsen/logrus v1.9.0 +require ( + github.com/sirupsen/logrus v1.9.0 + github.com/vifraa/gopom v1.0.0 +) require ( github.com/golang-jwt/jwt/v5 v5.2.1 // indirect diff --git a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go index 33af1e74..1a2c9833 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go @@ -351,7 +351,11 @@ func (p *javaServiceClient) getDependenciesForGradle(ctx context.Context) (map[u } // get the graph output - cmd := exec.Command("./gradlew", args...) + exe, err := filepath.Abs(filepath.Join(p.config.Location, "gradlew")) + if err != nil { + return nil, fmt.Errorf("error calculating gradle wrapper path") + } + cmd := exec.Command(exe, args...) cmd.Dir = p.config.Location output, err := cmd.CombinedOutput() if err != nil { @@ -384,7 +388,10 @@ func (p *javaServiceClient) getGradleSubprojects() ([]string, error) { return nil, err } - exe := filepath.Join(p.config.Location, "gradlew") + exe, err := filepath.Abs(filepath.Join(p.config.Location, "gradlew")) + if err != nil { + return nil, fmt.Errorf("error calculating gradle wrapper path") + } cmd := exec.Command(exe, args...) cmd.Dir = p.config.Location output, err := cmd.CombinedOutput() From 9f2d6f1e67e7ad319327da75254fc838bc5c2f7b Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 2 May 2024 11:47:22 +0200 Subject: [PATCH 04/17] Add check for gradle wrapper Signed-off-by: Juan Manuel Leflet Estrada --- .../pkg/java_external_provider/dependency.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go index 1a2c9833..a5969c82 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go @@ -333,7 +333,6 @@ func (p *javaServiceClient) getDependenciesForMaven(ctx context.Context) (map[ur } // getDependenciesForGradle invokes the Gradle wrapper to get the dependency tree and returns all project dependencies -// TODO: what if no wrapper? func (p *javaServiceClient) getDependenciesForGradle(ctx context.Context) (map[uri.URI][]provider.DepDAGItem, error) { subprojects, err := p.getGradleSubprojects() if err != nil { @@ -355,6 +354,9 @@ func (p *javaServiceClient) getDependenciesForGradle(ctx context.Context) (map[u if err != nil { return nil, fmt.Errorf("error calculating gradle wrapper path") } + if _, err = os.Stat(exe); errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("a gradle wrapper must be present in the project") + } cmd := exec.Command(exe, args...) cmd.Dir = p.config.Location output, err := cmd.CombinedOutput() @@ -392,6 +394,9 @@ func (p *javaServiceClient) getGradleSubprojects() ([]string, error) { if err != nil { return nil, fmt.Errorf("error calculating gradle wrapper path") } + if _, err = os.Stat(exe); errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("a gradle wrapper must be present in the project") + } cmd := exec.Command(exe, args...) cmd.Dir = p.config.Location output, err := cmd.CombinedOutput() From 24459cd76596705f1961459842bf00e1a8f39a13 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Mon, 20 May 2024 17:11:40 +0200 Subject: [PATCH 05/17] Fix tests paths Signed-off-by: Juan Manuel Leflet Estrada --- .../pkg/java_external_provider/dependency.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go index a5969c82..15b061c3 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go @@ -74,9 +74,13 @@ func (p *javaServiceClient) findPom() string { } func (p *javaServiceClient) findGradleBuild() string { - // TODO: naive? if p.config.Location != "" { - f, err := filepath.Abs(filepath.Join(p.config.Location, "build.gradle")) + path := filepath.Join(p.config.Location, "build.gradle") + _, err := os.Stat(path) + if err != nil { + return "" + } + f, err := filepath.Abs(path) if err != nil { return "" } From 0337d07aba394c5a619733382d72b55837938666 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Tue, 21 May 2024 09:50:18 +0200 Subject: [PATCH 06/17] Add demo output Signed-off-by: Juan Manuel Leflet Estrada --- demo-output.yaml | 43 ++++++++++--------------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/demo-output.yaml b/demo-output.yaml index 138b0179..b3d8f59f 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -381,22 +381,13 @@ description: "" category: potential incidents: - - uri: file:///examples/gradle-multi-project-example/build.gradle - message: dependency junit.junit with 4.12 is bad and you should feel bad for using it - variables: - name: junit.junit - version: "4.12" - uri: file:///examples/java/pom.xml message: dependency io.fabric8.kubernetes-client with 6.0.0 is bad and you should feel bad for using it - codeSnip: "26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8\n41 kubernetes-client-api\n42 6.0.0\n43 \n44 \n45 javax\n46 javaee-api" - lineNumber: 35 variables: name: io.fabric8.kubernetes-client version: 6.0.0 - uri: file:///examples/java/pom.xml message: dependency junit.junit with 4.11 is bad and you should feel bad for using it - codeSnip: "20 \n21 UTF-8\n22 1.7\n23 1.7\n24 7.0\n25 \n26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8" - lineNumber: 29 variables: name: junit.junit version: "4.11" @@ -508,29 +499,6 @@ incidents: - uri: file:///examples/java/pom.xml message: If you migrate your application to JBoss EAP 7.3, or later, and want to ensure its Maven building, running or testing works as expected, use instead the Jakarta EE dependency with groupId `com.sun.activation` - codeSnip: |- - 36 kubernetes-client - 37 6.0.0 - 38 - 39 - 40 io.fabric8 - 41 kubernetes-client-api - 42 6.0.0 - 43 - 44 - 45 javax - 46 javaee-api - 47 ${javaee-api.version} - 48 provided - 49 - 50 - 51 - 52 io.netty - 53 netty-transport-native-epoll - 54 4.1.76.Final - 55 linux-x86_64 - 56 runtime - lineNumber: 45 variables: name: javax.activation.activation version: "1.1" @@ -564,6 +532,16 @@ lineNumber: 6 variables: file: file:///examples/python/file_a.py + python-sample-rule-003: + description: "" + category: potential + incidents: + - uri: file:///examples/python/main.py + message: python sample rule 003 + codeSnip: "19 # Create an instance of the API class\n20 api_instance = kubernetes.client.ApiextensionsV1Api(api_client)\n21 body = kubernetes.client.V1CustomResourceDefinition() # V1CustomResourceDefinition | \n22 pretty = 'pretty_example' # str | If 'true', then the output is pretty printed. (optional)\n23 dry_run = 'dry_run_example' # str | When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed (optional)\n24 field_manager = 'field_manager_example' # str | fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. (optional)\n25 field_validation = 'field_validation_example' # str | fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. (optional)\n26 \n27 try:\n28 api_response = api_instance.create_custom_resource_definition(body, pretty=pretty, dry_run=dry_run, field_manager=field_manager, field_validation=field_validation)\n29 pprint(api_response)\n30 except ApiException as e:\n31 print(\"Exception when calling ApiextensionsV1Api->create_custom_resource_definition: %s\\n\" % e)\n" + lineNumber: 28 + variables: + file: file:///examples/python/main.py singleton-sessionbean-00001: description: "" category: potential @@ -885,4 +863,3 @@ unmatched: - file-002 - lang-ref-002 - - python-sample-rule-003 From 96603e97058d337a1a4f30675cba214ca25fb834 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Tue, 21 May 2024 13:20:32 +0200 Subject: [PATCH 07/17] Modify test result files Signed-off-by: Juan Manuel Leflet Estrada --- demo-output.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/demo-output.yaml b/demo-output.yaml index b3d8f59f..5f4df66e 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -383,11 +383,15 @@ incidents: - uri: file:///examples/java/pom.xml message: dependency io.fabric8.kubernetes-client with 6.0.0 is bad and you should feel bad for using it + codeSnip: "26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8\n41 kubernetes-client-api\n42 6.0.0\n43 \n44 \n45 javax\n46 javaee-api" + lineNumber: 35 variables: name: io.fabric8.kubernetes-client version: 6.0.0 - uri: file:///examples/java/pom.xml message: dependency junit.junit with 4.11 is bad and you should feel bad for using it + codeSnip: "20 \n21 UTF-8\n22 1.7\n23 1.7\n24 7.0\n25 \n26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8" + lineNumber: 29 variables: name: junit.junit version: "4.11" @@ -499,6 +503,29 @@ incidents: - uri: file:///examples/java/pom.xml message: If you migrate your application to JBoss EAP 7.3, or later, and want to ensure its Maven building, running or testing works as expected, use instead the Jakarta EE dependency with groupId `com.sun.activation` + codeSnip: |- + 36 kubernetes-client + 37 6.0.0 + 38 + 39 + 40 io.fabric8 + 41 kubernetes-client-api + 42 6.0.0 + 43 + 44 + 45 javax + 46 javaee-api + 47 ${javaee-api.version} + 48 provided + 49 + 50 + 51 + 52 io.netty + 53 netty-transport-native-epoll + 54 4.1.76.Final + 55 linux-x86_64 + 56 runtime + lineNumber: 45 variables: name: javax.activation.activation version: "1.1" From 31fb8ada2c0bd807b97dfead839d6f571c689209 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Tue, 30 Apr 2024 15:08:04 +0200 Subject: [PATCH 08/17] Add example project, fix path Signed-off-by: Juan Manuel Leflet Estrada --- demo-dep-output.yaml | 137 +++++++++++++++++- demo-output.yaml | 5 + .../java-external-provider/go.sum | 8 +- .../pkg/java_external_provider/dependency.go | 1 + 4 files changed, 142 insertions(+), 9 deletions(-) diff --git a/demo-dep-output.yaml b/demo-dep-output.yaml index 7cbd4b12..3a9702ce 100644 --- a/demo-dep-output.yaml +++ b/demo-dep-output.yaml @@ -171,11 +171,6 @@ labels: - konveyor.io/dep-source=downloadable - konveyor.io/language=go - - name: go - version: "1.18" - labels: - - konveyor.io/dep-source=downloadable - - konveyor.io/language=go - name: go.etcd.io/etcd/client/pkg/v3 version: v3.5.1 labels: @@ -1494,6 +1489,138 @@ - konveyor.io/dep-source=open-source - konveyor.io/language=java prefix: file:///root/.m2/repository/org/yaml/snakeyaml/1.28 +- fileURI: file:///analyzer-lsp/examples/gradle-multi-project-example/build.gradle + provider: java + dependencies: + - name: antlr.antlr + version: 2.7.7 + indirect: true + - name: com.apple.AppleJavaExtensions + version: "1.4" + indirect: true + - name: com.beust.jcommander + version: "1.48" + indirect: true + - name: com.google.code.findbugs.bcel-findbugs + version: "6.0" + indirect: true + - name: com.google.code.findbugs.findbugs + version: 3.0.1 + - name: com.google.code.findbugs.jFormatString + version: 2.0.1 + indirect: true + - name: com.google.code.findbugs.jsr305 + version: 1.3.9 + indirect: true + - name: com.google.code.findbugs.jsr305 + version: 2.0.1 + indirect: true + - name: com.google.code.gson.gson + version: "2.5" + indirect: true + - name: com.google.errorprone.error_prone_annotations + version: 2.0.18 + indirect: true + - name: com.google.guava.guava + version: "23.0" + - name: com.google.guava.guava + version: 23.2-jre + indirect: true + - name: com.google.j2objc.j2objc-annotations + version: "1.1" + indirect: true + - name: com.puppycrawl.tools.checkstyle + version: "8.4" + - name: commons-beanutils.commons-beanutils + version: 1.9.3 + indirect: true + - name: commons-cli.commons-cli + version: "1.4" + indirect: true + - name: commons-collections.commons-collections + version: 3.2.2 + indirect: true + - name: commons-io.commons-io + version: "2.4" + indirect: true + - name: commons-lang.commons-lang + version: "2.6" + indirect: true + - name: dom4j.dom4j + version: 1.6.1 + indirect: true + - name: jaxen.jaxen + version: 1.1.6 + indirect: true + - name: junit.junit + version: "4.12" + - name: net.bytebuddy.byte-buddy + version: 1.7.4 + indirect: true + - name: net.bytebuddy.byte-buddy-agent + version: 1.7.4 + indirect: true + - name: net.java.dev.javacc.javacc + version: "5.0" + indirect: true + - name: net.jcip.jcip-annotations + version: "1.0" + indirect: true + - name: net.sf.saxon.Saxon-HE + version: 9.8.0-5 + indirect: true + - name: net.sourceforge.pmd.pmd-core + version: 5.6.1 + indirect: true + - name: net.sourceforge.pmd.pmd-java + version: 5.6.1 + - name: net.sourceforge.saxon.saxon + version: 9.1.0.8 + indirect: true + - name: org.antlr.antlr4-runtime + version: "4.7" + indirect: true + - name: org.apache.commons.commons-lang3 + version: "3.4" + indirect: true + - name: org.apache.logging.log4j.log4j-api + version: 2.9.1 + - name: org.apache.logging.log4j.log4j-core + version: 2.9.1 + - name: org.apache.logging.log4j.log4j-slf4j-impl + version: 2.9.1 + - name: org.codehaus.mojo.animal-sniffer-annotations + version: "1.14" + indirect: true + - name: org.hamcrest.hamcrest-core + version: "1.3" + indirect: true + - name: org.mockito.mockito-core + version: 2.11.0 + - name: org.objenesis.objenesis + version: "2.6" + indirect: true + - name: org.ow2.asm.asm + version: 5.0.2 + indirect: true + - name: org.ow2.asm.asm + version: 5.0.4 + indirect: true + - name: org.ow2.asm.asm-commons + version: 5.0.2 + indirect: true + - name: org.ow2.asm.asm-debug-all + version: 5.0.2 + indirect: true + - name: org.ow2.asm.asm-tree + version: 5.0.2 + indirect: true + - name: org.slf4j.slf4j-api + version: 1.7.25 + indirect: true + - name: xml-apis.xml-apis + version: 1.0.b2 + indirect: true - fileURI: file:///analyzer-lsp/examples/inclusion-tests/pom.xml provider: java dependencies: [] diff --git a/demo-output.yaml b/demo-output.yaml index 5f4df66e..8f031276 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -381,6 +381,11 @@ description: "" category: potential incidents: + - uri: file:///examples/gradle-multi-project-example/build.gradle + message: dependency junit.junit with 4.12 is bad and you should feel bad for using it + variables: + name: junit.junit + version: "4.12" - uri: file:///examples/java/pom.xml message: dependency io.fabric8.kubernetes-client with 6.0.0 is bad and you should feel bad for using it codeSnip: "26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8\n41 kubernetes-client-api\n42 6.0.0\n43 \n44 \n45 javax\n46 javaee-api" diff --git a/external-providers/java-external-provider/go.sum b/external-providers/java-external-provider/go.sum index 27274d0c..09f14578 100644 --- a/external-providers/java-external-provider/go.sum +++ b/external-providers/java-external-provider/go.sum @@ -72,10 +72,10 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002 h1:V7Da7qt0MkY3noVANIMVBk28nOnijADeOR3i5Hcvpj4= google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go index 15b061c3..d1b8989c 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go @@ -337,6 +337,7 @@ func (p *javaServiceClient) getDependenciesForMaven(ctx context.Context) (map[ur } // getDependenciesForGradle invokes the Gradle wrapper to get the dependency tree and returns all project dependencies +// TODO: what if no wrapper? func (p *javaServiceClient) getDependenciesForGradle(ctx context.Context) (map[uri.URI][]provider.DepDAGItem, error) { subprojects, err := p.getGradleSubprojects() if err != nil { From 261089212e600626d4759a7819673a7cb299659b Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Mon, 20 May 2024 15:41:18 +0200 Subject: [PATCH 09/17] Support sources download Signed-off-by: Juan Manuel Leflet Estrada --- Dockerfile | 2 +- debug.Dockerfile | 69 ++++ debug/debug.Dockerfile | 38 +- demo-dep-output.yaml | 353 ++++++------------ demo-output.yaml | 32 -- demo.Dockerfile | 2 +- examples/golang/go.sum | 1 + .../java-external-provider/Dockerfile | 12 +- .../java-external-provider/go.mod | 6 +- .../java-external-provider/go.sum | 4 + .../pkg/java_external_provider/dependency.go | 6 +- .../pkg/java_external_provider/filter.go | 53 ++- .../pkg/java_external_provider/provider.go | 240 +++++++++++- .../java_external_provider/service_client.go | 5 +- .../pkg/java_external_provider/util.go | 33 +- provider_container_settings.json | 10 + 16 files changed, 538 insertions(+), 328 deletions(-) create mode 100644 debug.Dockerfile diff --git a/Dockerfile b/Dockerfile index 8bfaa2de..43ef3d1a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ RUN wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_B FROM jaegertracing/all-in-one:latest AS jaeger-builder -FROM quay.io/konveyor/jdtls-server-base +FROM bundle RUN microdnf install gcc-c++ python-devel python3-devel -y RUN python3 -m ensurepip --upgrade diff --git a/debug.Dockerfile b/debug.Dockerfile new file mode 100644 index 00000000..d9b20346 --- /dev/null +++ b/debug.Dockerfile @@ -0,0 +1,69 @@ +FROM golang:1.19 as builder +WORKDIR /analyzer-lsp + +COPY cmd /analyzer-lsp/cmd +COPY engine /analyzer-lsp/engine +COPY event /analyzer-lsp/event +COPY output /analyzer-lsp/output +COPY jsonrpc2 /analyzer-lsp/jsonrpc2 +COPY jsonrpc2_v2 /analyzer-lsp/jsonrpc2_v2 +COPY lsp /analyzer-lsp/lsp +COPY parser /analyzer-lsp/parser +COPY provider /analyzer-lsp/provider +COPY tracing /analyzer-lsp/tracing +COPY external-providers /analyzer-lsp/external-providers +COPY go.mod /analyzer-lsp/go.mod +COPY go.sum /analyzer-lsp/go.sum +COPY Makefile /analyzer-lsp/Makefile + +RUN go install github.com/go-delve/delve/cmd/dlv@latest + +RUN go build -gcflags="all=-N -l" -o konveyor-analyzer ./cmd/analyzer/main.go +RUN go build -gcflags="all=-N -l" -o konveyor-analyzer-dep ./cmd/dep/main.go +RUN cd external-providers/generic-external-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o generic-external-provider main.go +RUN cd external-providers/golang-dependency-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o golang-dependency-provider main.go +RUN cd external-providers/yq-external-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o yq-external-provider main.go +RUN cd external-providers/java-external-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o java-external-provider main.go + + +FROM registry.access.redhat.com/ubi9/ubi-minimal:latest as yq-builder +RUN microdnf install -y wget tar xz gzip && \ + microdnf clean all +ARG TARGETARCH +ARG YQ_VERSION="v4.40.5" +ARG YQ_BINARY="yq_linux_${TARGETARCH}" +RUN wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_BINARY}.tar.gz" -O - | tar xz && \ + mv ${YQ_BINARY} /usr/bin/yq + +FROM jaegertracing/all-in-one:latest AS jaeger-builder + +FROM quay.io/konveyor/jdtls-server-base + +RUN microdnf install gcc-c++ python-devel python3-devel -y +RUN python3 -m ensurepip --upgrade +RUN python3 -m pip install 'python-lsp-server>=1.8.2' + +ENV NODEJS_VERSION=18 +RUN echo -e "[nodejs]\nname=nodejs\nstream=${NODEJS_VERSION}\nprofiles=\nstate=enabled\n" > /etc/dnf/modules.d/nodejs.module +RUN microdnf install nodejs -y +RUN npm install -g typescript-language-server typescript + +COPY --from=jaeger-builder /go/bin/all-in-one-linux /usr/local/bin/all-in-one-linux +COPY --from=yq-builder /usr/bin/yq /usr/local/bin/yq +COPY --from=builder /analyzer-lsp/konveyor-analyzer /usr/local/bin/konveyor-analyzer +COPY --from=builder /analyzer-lsp/konveyor-analyzer-dep /usr/local/bin/konveyor-analyzer-dep +COPY --from=builder /analyzer-lsp/external-providers/generic-external-provider/generic-external-provider /usr/local/bin/generic-external-provider +COPY --from=builder /analyzer-lsp/external-providers/yq-external-provider/yq-external-provider /usr/local/bin/yq-external-provider +COPY --from=builder /analyzer-lsp/external-providers/golang-dependency-provider/golang-dependency-provider /usr/local/bin/golang-dependency-provider +COPY --from=builder /analyzer-lsp/external-providers/java-external-provider/java-external-provider /usr/local/bin/java-external-provider + +COPY --from=builder /go/bin/dlv / + +COPY provider_container_settings.json /analyzer-lsp/provider_settings.json + +WORKDIR /analyzer-lsp + +EXPOSE 16686 40000 + +ENTRYPOINT ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec"] +CMD ["/usr/local/bin/konveyor-analyzer"] diff --git a/debug/debug.Dockerfile b/debug/debug.Dockerfile index 0870c3d7..169c2735 100644 --- a/debug/debug.Dockerfile +++ b/debug/debug.Dockerfile @@ -1,22 +1,32 @@ FROM golang:1.19 as builder WORKDIR /analyzer-lsp -COPY ../cmd /analyzer-lsp/cmd -COPY ../engine /analyzer-lsp/engine -COPY ../output /analyzer-lsp/output -COPY ../jsonrpc2 /analyzer-lsp/jsonrpc2 -COPY ../lsp /analyzer-lsp/lsp -COPY ../parser /analyzer-lsp/parser -COPY ../provider /analyzer-lsp/provider -COPY ../tracing /analyzer-lsp/tracing -COPY ../external-providers /analyzer-lsp/external-providers -COPY ../go.mod /analyzer-lsp/go.mod -COPY ../go.sum /analyzer-lsp/go.sum -COPY ../Makefile /analyzer-lsp/Makefile - -# Install delve (go debugger) +COPY ../cmd /analyzer-lsp/cmd +COPY ../engine /analyzer-lsp/engine +COPY ../event /analyzer-lsp/event +COPY ../output /analyzer-lsp/output +COPY ../jsonrpc2 /analyzer-lsp/jsonrpc2 +COPY ../jsonrpc2_v2 /analyzer-lsp/jsonrpc2_v2 +COPY ../lsp /analyzer-lsp/lsp +COPY ../parser /analyzer-lsp/parser +COPY ../provider /analyzer-lsp/provider +COPY ../tracing /analyzer-lsp/tracing +COPY ../external-providers /analyzer-lsp/external-providers +COPY ../go.mod /analyzer-lsp/go.mod +COPY ../go.sum /analyzer-lsp/go.sum +COPY ../Makefile /analyzer-lsp/Makefile + RUN go install github.com/go-delve/delve/cmd/dlv@latest +FROM registry.access.redhat.com/ubi9/ubi-minimal:latest as yq-builder +RUN microdnf install -y wget tar xz gzip && \ + microdnf clean all +ARG TARGETARCH +ARG YQ_VERSION="v4.40.5" +ARG YQ_BINARY="yq_linux_${TARGETARCH}" +RUN wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_BINARY}.tar.gz" -O - | tar xz && \ + mv ${YQ_BINARY} /usr/bin/yq + RUN go build -gcflags="all=-N -l" -o konveyor-analyzer ./cmd/analyzer/main.go RUN go build -gcflags="all=-N -l" -o konveyor-analyzer-dep ./cmd/dep/main.go RUN cd external-providers/generic-external-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go build -gcflags="all=-N -l" -o generic-external-provider main.go diff --git a/demo-dep-output.yaml b/demo-dep-output.yaml index 3a9702ce..dedbdc4e 100644 --- a/demo-dep-output.yaml +++ b/demo-dep-output.yaml @@ -333,7 +333,7 @@ version: 2.7.7 type: compile indirect: true - resolvedIdentifier: 52f15b99911ab8b8bc8744675f5cf1994a626fb8 + resolvedIdentifier: 83cd2cd674a217ade95a4bb83a8a14f351f48bd0 extras: artifactId: antlr baseDep: @@ -352,7 +352,7 @@ - name: ch.qos.logback.logback-classic version: 1.1.7 type: compile - resolvedIdentifier: 044c01db0f7d7aac366fb952a89c10251ed86f44 + resolvedIdentifier: 9865cf6994f9ff13fce0bf93f2054ef6c65bb462 extras: artifactId: logback-classic groupId: ch.qos.logback @@ -365,7 +365,7 @@ version: 1.1.7 type: compile indirect: true - resolvedIdentifier: 6d1bdb1e28c56a8f989366b339f0f62545696e6d + resolvedIdentifier: 7873092d39ef741575ca91378a6a21c388363ac8 extras: artifactId: logback-core baseDep: @@ -385,7 +385,7 @@ version: 1.5.1 type: compile indirect: true - resolvedIdentifier: d5d564526c142037daead331ee5278c088777858 + resolvedIdentifier: 3fe0bed568c62df5e89f4f174c101eab25345b6c extras: artifactId: classmate baseDep: @@ -405,7 +405,7 @@ version: 2.12.3 type: compile indirect: true - resolvedIdentifier: 87859f29ceebfab7a873c3b4f4b89c9a594b2842 + resolvedIdentifier: 7275513412694a1aafd08c0287f48469fa0e6e17 extras: artifactId: jackson-annotations baseDep: @@ -424,7 +424,7 @@ - name: com.fasterxml.jackson.core.jackson-core version: 2.12.3 type: compile - resolvedIdentifier: ef6abf067337134089d074f411306a51f11a4d62 + resolvedIdentifier: deb23fe2a7f2b773e18ced2b50d4acc1df8fa366 extras: artifactId: jackson-core groupId: com.fasterxml.jackson.core @@ -436,7 +436,7 @@ - name: com.fasterxml.jackson.core.jackson-databind version: 2.12.3 type: compile - resolvedIdentifier: 2b186d9cc73cfb9272171357d17f0979eac44889 + resolvedIdentifier: d6153f8fc60c479ab0f9efb35c034526436a4953 extras: artifactId: jackson-databind groupId: com.fasterxml.jackson.core @@ -449,7 +449,7 @@ version: 2.12.3 type: runtime indirect: true - resolvedIdentifier: db7822a553c167e95bdda25d0d6db44bd3abf847 + resolvedIdentifier: f69c636438dcf19c49960c1fe8901320ab85f989 extras: artifactId: jackson-datatype-jsr310 baseDep: @@ -468,7 +468,7 @@ - name: com.oracle.database.jdbc.ojdbc8 version: 21.1.0.0 type: compile - resolvedIdentifier: dea0cca54c29d3e44167cd80839692b325ae2daf + resolvedIdentifier: 50044485aea10afd7defeee8109c5195b4d3cae2 extras: artifactId: ojdbc8 groupId: com.oracle.database.jdbc @@ -481,7 +481,7 @@ version: 3.0.7 type: compile indirect: true - resolvedIdentifier: 8eb4c6b0e9b0a1fadf53fce8b3fc8415b00469ef + resolvedIdentifier: c197c86ceec7318b1284bffb49b54226ca774003 extras: artifactId: istack-commons-runtime baseDep: @@ -501,7 +501,7 @@ version: 1.2.15 type: compile indirect: true - resolvedIdentifier: 945cf1f4467c72add88309fb05cdf5e340b569f9 + resolvedIdentifier: bb7b7ec0379982b97c62cd17465cb6d9155f68e8 extras: artifactId: FastInfoset baseDep: @@ -520,7 +520,7 @@ - name: io.konveyor.demo.config-utils version: 1.0.0 type: compile - resolvedIdentifier: 4010193B2F96CC7B7056C4CD51C3188FBBBC86E0 + resolvedIdentifier: FE4FE11AAEE77BE10035218537FBF4B2E6EF1D9F extras: artifactId: config-utils groupId: io.konveyor.demo @@ -533,7 +533,7 @@ version: 1.7.0 type: compile indirect: true - resolvedIdentifier: fd50ef746ed294d4e064c0cd3a14ca08543d139c + resolvedIdentifier: bc7dc1605f2099dc3c39156b7f62ac889f54fb67 extras: artifactId: micrometer-core baseDep: @@ -553,7 +553,7 @@ version: 1.3.5 type: compile indirect: true - resolvedIdentifier: beb7649988a22ea30a17fcaeba8584323e86df74 + resolvedIdentifier: 59eb84ee0d616332ff44aba065f3888cf002cd2d extras: artifactId: jakarta.annotation-api baseDep: @@ -573,7 +573,7 @@ version: 2.0.2 type: compile indirect: true - resolvedIdentifier: fc029778f5494ed05e5833f8bdb57e36dbda38aa + resolvedIdentifier: 5eacc6522521f7eacb081f95cee1e231648461e7 extras: artifactId: jakarta.validation-api baseDep: @@ -593,7 +593,7 @@ version: 1.2.0 type: compile indirect: true - resolvedIdentifier: 1aa9ef58e50ba6868b2e955d61fcd73be5b4cea5 + resolvedIdentifier: 85262acf3ca9816f9537ca47d5adeabaead7cb16 extras: artifactId: javax.activation-api baseDep: @@ -613,7 +613,7 @@ version: "2.2" type: compile indirect: true - resolvedIdentifier: ac7080de51fc0596317c15e12ed441f7c0a84d09 + resolvedIdentifier: 25665ac8c0b62f50e6488173233239120fc52c96 extras: artifactId: javax.persistence-api baseDep: @@ -633,7 +633,7 @@ version: 2.3.1 type: compile indirect: true - resolvedIdentifier: c42c51ae84892b73ef7de5351188908e673f5c69 + resolvedIdentifier: 8531ad5ac454cc2deb9d4d32c40c4d7451939b5d extras: artifactId: jaxb-api baseDep: @@ -653,7 +653,7 @@ version: 1.10.22 type: compile indirect: true - resolvedIdentifier: 14de25cfee49cd27ae19153674bbb34c04c45d52 + resolvedIdentifier: ef45d7e2cd1c600d279704f492ed5ce2ceb6cdb5 extras: artifactId: byte-buddy baseDep: @@ -673,7 +673,7 @@ version: 2.14.1 type: compile indirect: true - resolvedIdentifier: 9199a73770616b1ca0b00f576db3231aaab4876a + resolvedIdentifier: cd8858fbbde69f46bce8db1152c18a43328aae78 extras: artifactId: log4j-api baseDep: @@ -693,7 +693,7 @@ version: 2.14.1 type: compile indirect: true - resolvedIdentifier: 4638502177d694ad6f429a122e32f84ceba7db41 + resolvedIdentifier: ce8a86a3f50a4304749828ce68e7478cafbc8039 extras: artifactId: log4j-to-slf4j baseDep: @@ -712,7 +712,7 @@ - name: org.apache.tomcat.tomcat-jdbc version: 9.0.46 type: runtime - resolvedIdentifier: c3b975aba8359ecf35f6fca175c2e843a1d3c107 + resolvedIdentifier: 385cb6cb1f6b26c881cd5c1c6ade5f180712ffdc extras: artifactId: tomcat-jdbc groupId: org.apache.tomcat @@ -725,7 +725,7 @@ version: 9.0.46 type: runtime indirect: true - resolvedIdentifier: 1596051131c8426ebf744e0effed0e0005c87d57 + resolvedIdentifier: 409b519751e104eab51b4347a0d27bf86a4f3bb1 extras: artifactId: tomcat-juli baseDep: @@ -744,7 +744,7 @@ - name: org.apache.tomcat.tomcat-servlet-api version: 9.0.46 type: provided - resolvedIdentifier: 1f5ec6292bbca9e6c35172044b5fee0b0a97ef24 + resolvedIdentifier: 8e8a27a3456b71b1da2c8adc902ade71bc91fcb4 extras: artifactId: tomcat-servlet-api groupId: org.apache.tomcat @@ -757,7 +757,7 @@ version: 1.9.6 type: compile indirect: true - resolvedIdentifier: 2c4216b8c0f62edf69ec5cdd68619ba2aac5a4a1 + resolvedIdentifier: 1651849d48659e5703adc2599e694bf67b8c3fc4 extras: artifactId: aspectjrt baseDep: @@ -777,7 +777,7 @@ version: 3.5.0 type: runtime indirect: true - resolvedIdentifier: 408a4451ff5bdef60400a49657867db100ea0f83 + resolvedIdentifier: 2f50520c8abea66fbd8d26e481d3aef5c673b510 extras: artifactId: checker-qual baseDep: @@ -797,7 +797,7 @@ version: 2.1.3 type: compile indirect: true - resolvedIdentifier: 012854caa63db09d82bf973bc37d7226aaaef463 + resolvedIdentifier: a75914155a9f5808963170ec20653668a2ffd2fd extras: artifactId: dom4j baseDep: @@ -817,7 +817,7 @@ version: 2.3.1 type: compile indirect: true - resolvedIdentifier: 1856da23a80b9b1374d925d6dcb4a21db2144204 + resolvedIdentifier: dd6dda9da676a54c5b36ca2806ff95ee017d8738 extras: artifactId: jaxb-runtime baseDep: @@ -837,7 +837,7 @@ version: 2.3.1 type: compile indirect: true - resolvedIdentifier: c78aa440484eab1a6e2104e4fe69d0945a3cb3da + resolvedIdentifier: a09d2c48d3285f206fafbffe0e50619284e92126 extras: artifactId: txw2 baseDep: @@ -857,7 +857,7 @@ version: 2.1.12 type: compile indirect: true - resolvedIdentifier: 9797702ee3e52e4be6bfbbc9fd20ac5447e7a541 + resolvedIdentifier: 6eb7552156e0d517ae80cc2247be1427c8d90452 extras: artifactId: HdrHistogram baseDep: @@ -877,7 +877,7 @@ version: 5.1.2.Final type: compile indirect: true - resolvedIdentifier: 573f22ce360cd7a8bcc0dae4deecbe4e8861007d + resolvedIdentifier: e59ffdbc6ad09eeb33507b39ffcf287679a498c8 extras: artifactId: hibernate-commons-annotations baseDep: @@ -897,7 +897,7 @@ version: 5.4.32.Final type: compile indirect: true - resolvedIdentifier: 5be381f7b6f3d4f17ce746e4ff54f4b8cdce40e4 + resolvedIdentifier: 99a5e10bf455337014c190e141ec631e9ff71663 extras: artifactId: hibernate-core baseDep: @@ -916,7 +916,7 @@ - name: org.hibernate.hibernate-entitymanager version: 5.4.32.Final type: compile - resolvedIdentifier: b315696800e16d33bfb297d66f87a792caa3facc + resolvedIdentifier: 3f60db4097732960ec792c033dbb7c34f1b9e328 extras: artifactId: hibernate-entitymanager groupId: org.hibernate @@ -928,7 +928,7 @@ - name: org.hibernate.validator.hibernate-validator version: 6.2.0.Final type: compile - resolvedIdentifier: 7f1beda5229a0c99a175603c18b3c66da44f966e + resolvedIdentifier: d6b0760dfffbf379cedd02f715ff4c9a2e215921 extras: artifactId: hibernate-validator groupId: org.hibernate.validator @@ -941,7 +941,7 @@ version: 3.27.0-GA type: compile indirect: true - resolvedIdentifier: 0b7565662bc91e9648aab437135f32beb040ac15 + resolvedIdentifier: f63e6aa899e15eca8fdaa402a79af4c417252213 extras: artifactId: javassist baseDep: @@ -961,7 +961,7 @@ version: 2.2.3.Final type: compile indirect: true - resolvedIdentifier: c70053a1326428ec641be311ccf5551a8ec76a63 + resolvedIdentifier: d3865101f0666b63586683bd811d754517f331ab extras: artifactId: jandex baseDep: @@ -981,7 +981,7 @@ version: 3.4.1.Final type: compile indirect: true - resolvedIdentifier: 9d82f8eea1b5ed484775517d7588e320f9f7797a + resolvedIdentifier: 40fd4d696c55793e996d1ff3c475833f836c2498 extras: artifactId: jboss-logging baseDep: @@ -1001,7 +1001,7 @@ version: 1.1.1.Final type: compile indirect: true - resolvedIdentifier: 90823b310c573492696ad7e299b694ca2e70b4c1 + resolvedIdentifier: a8485cab9484dda36e9a8c319e76b5cc18797b58 extras: artifactId: jboss-transaction-api_1.2_spec baseDep: @@ -1021,7 +1021,7 @@ version: "1.8" type: compile indirect: true - resolvedIdentifier: cc7022b896125220e51f46fa50f4b68e564ffec1 + resolvedIdentifier: 8cc35f73da321c29973191f2cf143d29d26a1df7 extras: artifactId: stax-ex baseDep: @@ -1041,7 +1041,7 @@ version: 2.0.3 type: runtime indirect: true - resolvedIdentifier: 5baec26b6f9e5b17fdd200fc20af85eead4287c4 + resolvedIdentifier: 769c0b82cb2421c8256300e907298a9410a2a3d3 extras: artifactId: LatencyUtils baseDep: @@ -1060,7 +1060,7 @@ - name: org.postgresql.postgresql version: 42.2.23 type: compile - resolvedIdentifier: cc8565ec39dbfee32c2c87f125162fe8a3010c28 + resolvedIdentifier: 9cb217a3d5b640567ed7c6e8c11f389613c81c4d extras: artifactId: postgresql groupId: org.postgresql @@ -1073,7 +1073,7 @@ version: 1.7.30 type: compile indirect: true - resolvedIdentifier: f09448bdaeee63bc0644abae571b2d17c83d16c1 + resolvedIdentifier: d58bebff8cbf70ff52b59208586095f467656c30 extras: artifactId: jul-to-slf4j baseDep: @@ -1093,7 +1093,7 @@ version: 1.7.26 type: compile indirect: true - resolvedIdentifier: 4d3419a58d77c07f49185aaa556a787d50508d27 + resolvedIdentifier: 77100a62c2e6f04b53977b9f541044d7d722693d extras: artifactId: slf4j-api baseDep: @@ -1113,7 +1113,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: 48a6c425a45395e1ccfd99fd815c92d069040e43 + resolvedIdentifier: b07513e04ad906ea69ef84293a123cdb83828f06 extras: artifactId: spring-boot baseDep: @@ -1133,7 +1133,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: ee202daac01b6399b857d187cfdbf6d97d6adc8f + resolvedIdentifier: e0ac75f1a183f8e6a319a8b03bad1c45d40a2761 extras: artifactId: spring-boot-actuator baseDep: @@ -1153,7 +1153,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: c527193b5cc67f7534c27860171e44187746aaf5 + resolvedIdentifier: 41956882243e86f8260f649ebdd96597a2ff52a9 extras: artifactId: spring-boot-actuator-autoconfigure baseDep: @@ -1173,7 +1173,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: da542216009c858c2e8b32cb595578acc19d2df3 + resolvedIdentifier: 64c7bbc941c70895621ed613f38dc66b73ea9341 extras: artifactId: spring-boot-autoconfigure baseDep: @@ -1193,7 +1193,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: 391cbf83221ae09c1c0a471b25ab3221dfe46ef1 + resolvedIdentifier: a910887c01efcc7d12f3f89a7604d436f26eeb90 extras: artifactId: spring-boot-starter baseDep: @@ -1212,7 +1212,7 @@ - name: org.springframework.boot.spring-boot-starter-actuator version: 2.5.0 type: compile - resolvedIdentifier: 76dd6dea415751e05491337b7ff22bd08ae70c7e + resolvedIdentifier: 8fc47befa38bdaa2f2b8f421d8532f03005e2851 extras: artifactId: spring-boot-starter-actuator groupId: org.springframework.boot @@ -1225,7 +1225,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: 60f06908ef3b39d8c8780898e749c4c846fabb84 + resolvedIdentifier: 22401482ba1c5a1dcd3d33e47295779211b913d8 extras: artifactId: spring-boot-starter-logging baseDep: @@ -1245,7 +1245,7 @@ version: 2.5.1 type: compile indirect: true - resolvedIdentifier: bceeabb4ef399ba7ff8511f2931e1924a41cc921 + resolvedIdentifier: c950ca1a05e928e9fb75420b4ac07713428e9969 extras: artifactId: spring-data-commons baseDep: @@ -1264,7 +1264,7 @@ - name: org.springframework.data.spring-data-jpa version: 2.5.1 type: compile - resolvedIdentifier: 461ebcc9fc00dca10a754b0e96583ce7d281d312 + resolvedIdentifier: 881f7ae140f424b3bdb1b0c27a61b93e0bee9fa5 extras: artifactId: spring-data-jpa groupId: org.springframework.data @@ -1277,7 +1277,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 0bf1d9d12108b8ab2d9d71d5fd5fee02d3ee5bde + resolvedIdentifier: b86edd2455f8c4399068c999beb9ea2a9e7f2047 extras: artifactId: spring-aop baseDep: @@ -1297,7 +1297,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 654397f55cd4a4734f8b76282e98c88884d0367a + resolvedIdentifier: 8b1eacd7aaa12f7d173a2f0836d28bd0c1b098fe extras: artifactId: spring-beans baseDep: @@ -1317,7 +1317,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 67e3176098c81702c76d20977deec8101b3faf8c + resolvedIdentifier: 330b3957efdcdebe3550b8e2c5d45a4c25496626 extras: artifactId: spring-context baseDep: @@ -1337,7 +1337,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 44ce199d05bb1ce9682621cd18953ea307485fc1 + resolvedIdentifier: 4aad1b62bd347a806fe693c9d67b376a3ad8151c extras: artifactId: spring-core baseDep: @@ -1357,7 +1357,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 30bd0b3e802e5ba4e4d9fc68e57cc0e755ba9f9f + resolvedIdentifier: 13351fce0a604957cd6a41478ebb54a953a0245e extras: artifactId: spring-expression baseDep: @@ -1377,7 +1377,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: e1e7c14c73ae5fc616bb941ce8c1e7e62736cadf + resolvedIdentifier: ccd8bde38bad689737295fa220e1c70680676d72 extras: artifactId: spring-jcl baseDep: @@ -1396,7 +1396,7 @@ - name: org.springframework.spring-jdbc version: 5.3.7 type: compile - resolvedIdentifier: a4f87a03116ecde96213642141eb95da05022f51 + resolvedIdentifier: 5caf72035a9b8a3a09ef82322cd2497aedddc487 extras: artifactId: spring-jdbc groupId: org.springframework @@ -1409,7 +1409,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: cc6911f3194cb77d493aa626c661789926027446 + resolvedIdentifier: f1892fe7a6671348d6546facbd40159b7e6f64a2 extras: artifactId: spring-orm baseDep: @@ -1429,7 +1429,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: c6df78e1d9b50b7063e4a196127d75ee9321f68b + resolvedIdentifier: 98be572c2bf3bd08724363b0bba71bcef59c4739 extras: artifactId: spring-tx baseDep: @@ -1448,7 +1448,7 @@ - name: org.springframework.spring-web version: 5.3.7 type: compile - resolvedIdentifier: d9f78e0b045d90dc862cd4a39294a468b3cc6ba9 + resolvedIdentifier: 49e6a8f45e77f14ef16f82c0413254ef493b785f extras: artifactId: spring-web groupId: org.springframework @@ -1460,7 +1460,7 @@ - name: org.springframework.spring-webmvc version: 5.3.7 type: compile - resolvedIdentifier: d0f042bff56bb90beabc6ed5d062fb87c69e652a + resolvedIdentifier: 8437c7a572177a34607abdaef2f6b8088488f5c0 extras: artifactId: spring-webmvc groupId: org.springframework @@ -1473,7 +1473,7 @@ version: "1.28" type: compile indirect: true - resolvedIdentifier: 3e38757e3eaf549cccd9bbdfa74b2930c177b8af + resolvedIdentifier: 7cae037c3014350c923776548e71c9feb7a69259 extras: artifactId: snakeyaml baseDep: @@ -1489,141 +1489,6 @@ - konveyor.io/dep-source=open-source - konveyor.io/language=java prefix: file:///root/.m2/repository/org/yaml/snakeyaml/1.28 -- fileURI: file:///analyzer-lsp/examples/gradle-multi-project-example/build.gradle - provider: java - dependencies: - - name: antlr.antlr - version: 2.7.7 - indirect: true - - name: com.apple.AppleJavaExtensions - version: "1.4" - indirect: true - - name: com.beust.jcommander - version: "1.48" - indirect: true - - name: com.google.code.findbugs.bcel-findbugs - version: "6.0" - indirect: true - - name: com.google.code.findbugs.findbugs - version: 3.0.1 - - name: com.google.code.findbugs.jFormatString - version: 2.0.1 - indirect: true - - name: com.google.code.findbugs.jsr305 - version: 1.3.9 - indirect: true - - name: com.google.code.findbugs.jsr305 - version: 2.0.1 - indirect: true - - name: com.google.code.gson.gson - version: "2.5" - indirect: true - - name: com.google.errorprone.error_prone_annotations - version: 2.0.18 - indirect: true - - name: com.google.guava.guava - version: "23.0" - - name: com.google.guava.guava - version: 23.2-jre - indirect: true - - name: com.google.j2objc.j2objc-annotations - version: "1.1" - indirect: true - - name: com.puppycrawl.tools.checkstyle - version: "8.4" - - name: commons-beanutils.commons-beanutils - version: 1.9.3 - indirect: true - - name: commons-cli.commons-cli - version: "1.4" - indirect: true - - name: commons-collections.commons-collections - version: 3.2.2 - indirect: true - - name: commons-io.commons-io - version: "2.4" - indirect: true - - name: commons-lang.commons-lang - version: "2.6" - indirect: true - - name: dom4j.dom4j - version: 1.6.1 - indirect: true - - name: jaxen.jaxen - version: 1.1.6 - indirect: true - - name: junit.junit - version: "4.12" - - name: net.bytebuddy.byte-buddy - version: 1.7.4 - indirect: true - - name: net.bytebuddy.byte-buddy-agent - version: 1.7.4 - indirect: true - - name: net.java.dev.javacc.javacc - version: "5.0" - indirect: true - - name: net.jcip.jcip-annotations - version: "1.0" - indirect: true - - name: net.sf.saxon.Saxon-HE - version: 9.8.0-5 - indirect: true - - name: net.sourceforge.pmd.pmd-core - version: 5.6.1 - indirect: true - - name: net.sourceforge.pmd.pmd-java - version: 5.6.1 - - name: net.sourceforge.saxon.saxon - version: 9.1.0.8 - indirect: true - - name: org.antlr.antlr4-runtime - version: "4.7" - indirect: true - - name: org.apache.commons.commons-lang3 - version: "3.4" - indirect: true - - name: org.apache.logging.log4j.log4j-api - version: 2.9.1 - - name: org.apache.logging.log4j.log4j-core - version: 2.9.1 - - name: org.apache.logging.log4j.log4j-slf4j-impl - version: 2.9.1 - - name: org.codehaus.mojo.animal-sniffer-annotations - version: "1.14" - indirect: true - - name: org.hamcrest.hamcrest-core - version: "1.3" - indirect: true - - name: org.mockito.mockito-core - version: 2.11.0 - - name: org.objenesis.objenesis - version: "2.6" - indirect: true - - name: org.ow2.asm.asm - version: 5.0.2 - indirect: true - - name: org.ow2.asm.asm - version: 5.0.4 - indirect: true - - name: org.ow2.asm.asm-commons - version: 5.0.2 - indirect: true - - name: org.ow2.asm.asm-debug-all - version: 5.0.2 - indirect: true - - name: org.ow2.asm.asm-tree - version: 5.0.2 - indirect: true - - name: org.slf4j.slf4j-api - version: 1.7.25 - indirect: true - - name: xml-apis.xml-apis - version: 1.0.b2 - indirect: true -- fileURI: file:///analyzer-lsp/examples/inclusion-tests/pom.xml - provider: java - dependencies: [] - fileURI: file:///analyzer-lsp/examples/java/pom.xml provider: java dependencies: @@ -1631,7 +1496,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: 717e3012ee74008533d4e92946ccf49060e84e78 + resolvedIdentifier: 7198b3aac15285a49e218e08441c5f70af00fc51 extras: artifactId: jackson-annotations baseDep: @@ -1651,7 +1516,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: 1a9b0ebfcda0063950c35f42c7fdce9a34e8b782 + resolvedIdentifier: a27014716e4421684416e5fa83d896ddb87002da extras: artifactId: jackson-core baseDep: @@ -1671,7 +1536,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: 2c0ce6eb612e33616edb250542d0fda62524f717 + resolvedIdentifier: 56deb9ea2c93a7a556b3afbedd616d342963464e extras: artifactId: jackson-databind baseDep: @@ -1691,7 +1556,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: 79e3dbba4729d503ce3eef93f68caddf213b678d + resolvedIdentifier: 9363ded5441b1fee62d5be0604035690ca759a2a extras: artifactId: jackson-dataformat-yaml baseDep: @@ -1711,7 +1576,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: b22a52de24b5bd7bcf210f02bd2e75ae1c4a740d + resolvedIdentifier: ad2f4c61aeb9e2a8bb5e4a3ed782cfddec52d972 extras: artifactId: jackson-datatype-jsr310 baseDep: @@ -1731,7 +1596,7 @@ version: 3.12.12 type: runtime indirect: true - resolvedIdentifier: 705a7df4584707ae40db2fb903f921755510567f + resolvedIdentifier: d952189f6abb148ff72aab246aa8c28cf99b469f extras: artifactId: logging-interceptor baseDep: @@ -1751,7 +1616,7 @@ version: 3.12.12 type: runtime indirect: true - resolvedIdentifier: 90c81c59b2eb943ddbe58bc717e3e75bccd518c2 + resolvedIdentifier: d3e1ce1d2b3119adf270b2d00d947beb03fe3321 extras: artifactId: okhttp baseDep: @@ -1771,7 +1636,7 @@ version: 1.15.0 type: runtime indirect: true - resolvedIdentifier: 87f1520a39a954a9aa185c7fe8f144fa7d597690 + resolvedIdentifier: bc28b5a964c8f5721eb58ee3f3c47a9bcbf4f4d8 extras: artifactId: okio baseDep: @@ -1791,7 +1656,7 @@ version: 1.5.0 type: provided indirect: true - resolvedIdentifier: 2143163e070fcd301fbf7b3246ca4854caaabacc + resolvedIdentifier: ec2410fdf7e0a3022e7c2a2e6241039d1abc1e98 extras: artifactId: javax.mail baseDep: @@ -1810,7 +1675,7 @@ - name: io.fabric8.kubernetes-client version: 6.0.0 type: compile - resolvedIdentifier: 738af0538ca0399331e1d5477edc74b19a43d912 + resolvedIdentifier: d0831d44e12313df8989fc1d4a9c90452f08858e extras: artifactId: kubernetes-client groupId: io.fabric8 @@ -1822,7 +1687,7 @@ - name: io.fabric8.kubernetes-client-api version: 6.0.0 type: compile - resolvedIdentifier: fb7ecaa7697fc3ba4157ab7250c542032b6f3b0f + resolvedIdentifier: 3f54cdb10f54b413fe4b8a0d4d044d33174bd271 extras: artifactId: kubernetes-client-api groupId: io.fabric8 @@ -1835,7 +1700,7 @@ version: 6.0.0 type: runtime indirect: true - resolvedIdentifier: b06ddc26ab91382d2ed02ae6c16f3108a12bef04 + resolvedIdentifier: 70690b98acb07a809c55d15d7cf45f53ec1026e1 extras: artifactId: kubernetes-httpclient-okhttp baseDep: @@ -1855,7 +1720,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: dcbf5acf8815378769490abee2170d54ac73732b + resolvedIdentifier: 9e3b0d4caa3d033fa0f71c71d8a535a748b280ba extras: artifactId: kubernetes-model-admissionregistration baseDep: @@ -1875,7 +1740,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: b053ca57ddd50936e1cfe8e5790b77dd76393944 + resolvedIdentifier: eac63b8dec80e96c4356c91ed0a332415efcb75e extras: artifactId: kubernetes-model-apiextensions baseDep: @@ -1895,7 +1760,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: f23c0d497dd0a99f35a06bdd0a04dd8a4ec92dd2 + resolvedIdentifier: 4dbda6401058a5fd3a4c6be88fc1bf4f99296c4f extras: artifactId: kubernetes-model-apps baseDep: @@ -1915,7 +1780,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 1d6c9585a5c33cfb19cc0ac3a27bc17b2c7e4922 + resolvedIdentifier: b353e45133fbc80791d676b16203ec94c0958b7d extras: artifactId: kubernetes-model-autoscaling baseDep: @@ -1935,7 +1800,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 32e9e912473abdbc8c70484db3ba733bdc4772f0 + resolvedIdentifier: 9f14cbfc75d172fa81f3f6ad793bdd45a2decaec extras: artifactId: kubernetes-model-batch baseDep: @@ -1955,7 +1820,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: aef58e6d3ecff8ab73e92a6a0908159e2956eb91 + resolvedIdentifier: 33f5a3f386cddda55003e1616303ab924fcd3ca5 extras: artifactId: kubernetes-model-certificates baseDep: @@ -1975,7 +1840,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 5451f267796cd342bf5ce2306657eae6319e95fa + resolvedIdentifier: 7d45968cf6b9902e37d5d542f42ee2daed203e3d extras: artifactId: kubernetes-model-common baseDep: @@ -1995,7 +1860,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: b2e8564f0426ba14c96421c9bd611a47431d9618 + resolvedIdentifier: cd454532158351d8ff37616dc33749ca2a85c8d1 extras: artifactId: kubernetes-model-coordination baseDep: @@ -2015,7 +1880,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 9dec469abc198daac6d9260fb432e711dc005655 + resolvedIdentifier: 73469e4a7baec7600455d7f4a121c6680e80bf35 extras: artifactId: kubernetes-model-core baseDep: @@ -2035,7 +1900,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: b10bf58ec0ef527e8d5854b209f45917aa64e667 + resolvedIdentifier: 246ad448a1868b3c601394e21350a9602adef24c extras: artifactId: kubernetes-model-discovery baseDep: @@ -2055,7 +1920,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: ea54163696f03b5827d7dcf47a753b638a886b25 + resolvedIdentifier: 204c2c78a4a8e0b5f5ebc1b788c9f22a8c1b14ab extras: artifactId: kubernetes-model-events baseDep: @@ -2075,7 +1940,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 22f366518f18974400a50a9b18d69d4481b97e2a + resolvedIdentifier: 60c9e43f1f34ab9c145798471926c07e13e45ecf extras: artifactId: kubernetes-model-extensions baseDep: @@ -2095,7 +1960,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: a8cce874a1b32d283431966643fdfaa148ede743 + resolvedIdentifier: 3b01d9eab7e7d7c9d46d8828202bff78fbdaa7d9 extras: artifactId: kubernetes-model-flowcontrol baseDep: @@ -2115,7 +1980,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 7406edacfddc43e81fdca5f6b58f9cffcfd6208a + resolvedIdentifier: 1a400f8f7915bd2a68fa075605768d762aaad4cb extras: artifactId: kubernetes-model-metrics baseDep: @@ -2135,7 +2000,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 5abd2eb6209f3c8f27be9d9361f02609a51d8e4a + resolvedIdentifier: c87e11bebb26bb48660765b42a68f9577336b799 extras: artifactId: kubernetes-model-networking baseDep: @@ -2155,7 +2020,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 29b29db3b39c5240b5eda0e6b2ef42e0254be90b + resolvedIdentifier: 972706f6dffa518e11c94647cf47e188db6115f6 extras: artifactId: kubernetes-model-node baseDep: @@ -2175,7 +2040,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 2a846f217bd879ecee71c03615c2b714630dca4b + resolvedIdentifier: 15b3011eb5ff48b9fc2bd8bcc4db697ca9ec30e4 extras: artifactId: kubernetes-model-policy baseDep: @@ -2195,7 +2060,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 4d218bb7b4b1f6c76d8cfe4ef136813b73973833 + resolvedIdentifier: 03ad461761d775ff9c252d2b26a4977d22dd0f3a extras: artifactId: kubernetes-model-rbac baseDep: @@ -2215,7 +2080,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 4cca28ace5b98318415d7ffd75f707820d19bf20 + resolvedIdentifier: a5fae7294f5c39fb9d7cffb7280b55ca458c9128 extras: artifactId: kubernetes-model-scheduling baseDep: @@ -2235,7 +2100,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: e944960ca3f380afaa39366f37145c5bb617e6ec + resolvedIdentifier: 6ffa61f9021d07a4a9d785e83a513955a3c48073 extras: artifactId: kubernetes-model-storageclass baseDep: @@ -2255,7 +2120,7 @@ version: 0.3.0 type: compile indirect: true - resolvedIdentifier: 1385fb99630e407ae2821c9a16ccff56c879cdc9 + resolvedIdentifier: d3ebf0f291297649b4c8dc3ecc81d2eddedc100d extras: artifactId: zjsonpatch baseDep: @@ -2274,7 +2139,7 @@ - name: io.netty.netty-buffer version: 4.1.76.Final type: runtime - resolvedIdentifier: 453d1177e8b3194ef1111ad72d6d5a245c888975 + resolvedIdentifier: 231f5042a5050773eb22a918e84daff3f00892f2 extras: artifactId: netty-buffer groupId: io.netty @@ -2286,7 +2151,7 @@ - name: io.netty.netty-common version: 4.1.76.Final type: runtime - resolvedIdentifier: 40049284125ae2450120801fe3df7f605ce29ee1 + resolvedIdentifier: 38d0b500f098dc89497b6e608d7427186f533cf0 extras: artifactId: netty-common groupId: io.netty @@ -2299,7 +2164,7 @@ version: 4.1.76.Final type: runtime indirect: true - resolvedIdentifier: afc436aa5f9368bd10e1653a6531dfda0883fa5f + resolvedIdentifier: e0b225a33772cb7bba73dc296cccefa6826ab8cc extras: artifactId: netty-resolver baseDep: @@ -2318,7 +2183,7 @@ - name: io.netty.netty-transport version: 4.1.76.Final type: runtime - resolvedIdentifier: fb77aebb06acd640d8dc2c50dcc531c59c7e1696 + resolvedIdentifier: f01d2f935005b6fdb2fedc23114d2ae717749c36 extras: artifactId: netty-transport groupId: io.netty @@ -2330,7 +2195,7 @@ - name: io.netty.netty-transport-classes-epoll version: 4.1.76.Final type: runtime - resolvedIdentifier: e7b89664fddac0b494a8d3492ac532ccf8ed7c06 + resolvedIdentifier: 921b92a76116674218af3dc4bbf43d73884e4146 extras: artifactId: netty-transport-classes-epoll groupId: io.netty @@ -2355,7 +2220,7 @@ - name: io.netty.netty-transport-native-unix-common version: 4.1.76.Final type: runtime - resolvedIdentifier: 9c1755c00652bd1d568c49bae7c6da56f5dabac6 + resolvedIdentifier: d5ed8c4be9680203c53f7ed788225c12c4d87ee0 extras: artifactId: netty-transport-native-unix-common groupId: io.netty @@ -2368,7 +2233,7 @@ version: "1.1" type: provided indirect: true - resolvedIdentifier: fd9dd0faa8f03f3ce0dc4eec22e57e818d8b9897 + resolvedIdentifier: e6cb541461c2834bdea3eb920f1884d1eb508b50 extras: artifactId: activation baseDep: @@ -2387,7 +2252,7 @@ - name: javax.javaee-api version: "7.0" type: provided - resolvedIdentifier: e54c73cdc03722ed6c66d02cf27d10970ca0cec1 + resolvedIdentifier: 51399f902cc27a808122edcbebfaa1ad989954ba extras: artifactId: javaee-api groupId: javax @@ -2399,7 +2264,7 @@ - name: junit.junit version: "4.11" type: test - resolvedIdentifier: cddf7490ffe839978cf5d6c944c01f2a8cb70a49 + resolvedIdentifier: 4e031bb61df09069aeb2bffb4019e7a5034a4ee0 extras: artifactId: junit groupId: junit @@ -2412,7 +2277,7 @@ version: "1.3" type: test indirect: true - resolvedIdentifier: 872e413497b906e7c9fa85ccc96046c5d1ef7ece + resolvedIdentifier: 42a25dc3219429f0e5d060061f71acb49bf010a0 extras: artifactId: hamcrest-core baseDep: @@ -2432,7 +2297,7 @@ version: 1.7.36 type: compile indirect: true - resolvedIdentifier: 749f6995b1d6591a417ca4fd19cdbddabae16fd1 + resolvedIdentifier: 6c62681a2f655b49963a5983b8b0950a6120ae14 extras: artifactId: slf4j-api baseDep: @@ -2452,7 +2317,7 @@ version: "1.30" type: compile indirect: true - resolvedIdentifier: 767ab0a7a346f60dad0acebe318e335a5d27fe55 + resolvedIdentifier: 8fde7fe2586328ac3c68db92045e1c8759125000 extras: artifactId: snakeyaml baseDep: diff --git a/demo-output.yaml b/demo-output.yaml index 8f031276..b3d8f59f 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -381,22 +381,13 @@ description: "" category: potential incidents: - - uri: file:///examples/gradle-multi-project-example/build.gradle - message: dependency junit.junit with 4.12 is bad and you should feel bad for using it - variables: - name: junit.junit - version: "4.12" - uri: file:///examples/java/pom.xml message: dependency io.fabric8.kubernetes-client with 6.0.0 is bad and you should feel bad for using it - codeSnip: "26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8\n41 kubernetes-client-api\n42 6.0.0\n43 \n44 \n45 javax\n46 javaee-api" - lineNumber: 35 variables: name: io.fabric8.kubernetes-client version: 6.0.0 - uri: file:///examples/java/pom.xml message: dependency junit.junit with 4.11 is bad and you should feel bad for using it - codeSnip: "20 \n21 UTF-8\n22 1.7\n23 1.7\n24 7.0\n25 \n26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8" - lineNumber: 29 variables: name: junit.junit version: "4.11" @@ -508,29 +499,6 @@ incidents: - uri: file:///examples/java/pom.xml message: If you migrate your application to JBoss EAP 7.3, or later, and want to ensure its Maven building, running or testing works as expected, use instead the Jakarta EE dependency with groupId `com.sun.activation` - codeSnip: |- - 36 kubernetes-client - 37 6.0.0 - 38 - 39 - 40 io.fabric8 - 41 kubernetes-client-api - 42 6.0.0 - 43 - 44 - 45 javax - 46 javaee-api - 47 ${javaee-api.version} - 48 provided - 49 - 50 - 51 - 52 io.netty - 53 netty-transport-native-epoll - 54 4.1.76.Final - 55 linux-x86_64 - 56 runtime - lineNumber: 45 variables: name: javax.activation.activation version: "1.1" diff --git a/demo.Dockerfile b/demo.Dockerfile index ee8a7050..53fcdaf1 100644 --- a/demo.Dockerfile +++ b/demo.Dockerfile @@ -1,4 +1,4 @@ -FROM quay.io/konveyor/analyzer-lsp +FROM analyzer WORKDIR /analyzer-lsp diff --git a/examples/golang/go.sum b/examples/golang/go.sum index 16ccc8cf..b5a4d86b 100644 --- a/examples/golang/go.sum +++ b/examples/golang/go.sum @@ -125,6 +125,7 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= diff --git a/external-providers/java-external-provider/Dockerfile b/external-providers/java-external-provider/Dockerfile index e2661f72..2e2a5b19 100644 --- a/external-providers/java-external-provider/Dockerfile +++ b/external-providers/java-external-provider/Dockerfile @@ -14,12 +14,16 @@ COPY external-providers/java-external-provider/pkg/ pkg/ RUN go mod edit -replace=github.com/konveyor/analyzer-lsp=/analyzer-lsp && go mod tidy -RUN go build -a -o java-external-provider main.go +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags="all=-N -l" -a -o java-external-provider main.go -FROM quay.io/konveyor/jdtls-server-base +RUN go install github.com/go-delve/delve/cmd/dlv@latest + +FROM bundle COPY --from=builder /java-provider/java-external-provider /usr/local/bin/java-external-provider +COPY --from=builder /go/bin/dlv /usr/local/bin/dlv -EXPOSE 14651 +EXPOSE 14651 40000 -ENTRYPOINT ["java-external-provider", "--port", "14651"] +ENTRYPOINT ["/usr/local/bin/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec"] +CMD ["--", "/usr/local/bin/java-external-provider", "--port", "14651"] diff --git a/external-providers/java-external-provider/go.mod b/external-providers/java-external-provider/go.mod index be927d8d..8229d63f 100644 --- a/external-providers/java-external-provider/go.mod +++ b/external-providers/java-external-provider/go.mod @@ -36,8 +36,10 @@ require ( go.opentelemetry.io/otel/exporters/jaeger v1.11.2 // indirect go.opentelemetry.io/otel/sdk v1.11.2 // indirect go.opentelemetry.io/otel/trace v1.11.2 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002 // indirect ) + +replace github.com/konveyor/analyzer-lsp => ../../ diff --git a/external-providers/java-external-provider/go.sum b/external-providers/java-external-provider/go.sum index 09f14578..5ed222b1 100644 --- a/external-providers/java-external-provider/go.sum +++ b/external-providers/java-external-provider/go.sum @@ -66,16 +66,20 @@ go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZ go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002 h1:V7Da7qt0MkY3noVANIMVBk28nOnijADeOR3i5Hcvpj4= google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go index d1b8989c..4171036b 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/dependency.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/dependency.go @@ -42,7 +42,7 @@ const ( gradle = "gradle" ) -func (p *javaServiceClient) getBuildTool() string { +func (p *javaServiceClient) GetBuildTool() string { bf := "" if bf = p.findPom(); bf != "" { return maven @@ -90,7 +90,7 @@ func (p *javaServiceClient) findGradleBuild() string { } func (p *javaServiceClient) GetDependencies(ctx context.Context) (map[uri.URI][]*provider.Dep, error) { - if p.getBuildTool() == gradle { + if p.GetBuildTool() == gradle { p.log.V(2).Info("gradle found - retrieving dependencies") m := map[uri.URI][]*provider.Dep{} deps, err := p.getDependenciesForGradle(ctx) @@ -277,7 +277,7 @@ func pomCoordinate(value *string) string { } func (p *javaServiceClient) GetDependenciesDAG(ctx context.Context) (map[uri.URI][]provider.DepDAGItem, error) { - switch p.getBuildTool() { + switch p.GetBuildTool() { case maven: return p.getDependenciesForMaven(ctx) case gradle: diff --git a/external-providers/java-external-provider/pkg/java_external_provider/filter.go b/external-providers/java-external-provider/pkg/java_external_provider/filter.go index fd6d85b0..3e33d14d 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/filter.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/filter.go @@ -263,7 +263,7 @@ func (p *javaServiceClient) getURI(refURI string) (string, uri.URI, error) { var jarPath string if sourceRange { - // If there is a source range, we know we know there is a sources jar + // If there is a source range, we know there is a sources jar jarName := filepath.Base(u.Path) s := strings.TrimSuffix(jarName, ".jar") s = fmt.Sprintf("%v-sources.jar", s) @@ -272,26 +272,61 @@ func (p *javaServiceClient) getURI(refURI string) (string, uri.URI, error) { jarName := filepath.Base(u.Path) jarPath = filepath.Join(filepath.Dir(u.Path), jarName) } - path := filepath.Join(strings.Split(strings.TrimSuffix(packageName, ".class"), ".")...) + + path := filepath.Join(strings.Split(strings.TrimSuffix(packageName, ".class"), ".")...) // path: org/apache/logging/log4j/core/appender/FileManager javaFileName := fmt.Sprintf("%s.java", filepath.Base(path)) if i := strings.Index(javaFileName, "$"); i > 0 { javaFileName = fmt.Sprintf("%v.java", javaFileName[0:i]) } - javaFileAbsolutePath := filepath.Join(filepath.Dir(jarPath), filepath.Dir(path), javaFileName) + javaFileAbsolutePath := "" + if p.GetBuildTool() == maven { + javaFileAbsolutePath = filepath.Join(filepath.Dir(jarPath), filepath.Dir(path), javaFileName) - // attempt to decompile when directory for the expected java file doesn't exist - // if directory exists, assume .java file is present within, this avoids decompiling every Jar - if _, err := os.Stat(filepath.Dir(javaFileAbsolutePath)); err != nil { - cmd := exec.Command("jar", "xf", filepath.Base(jarPath)) - cmd.Dir = filepath.Dir(jarPath) - err := cmd.Run() + // attempt to decompile when directory for the expected java file doesn't exist + // if directory exists, assume .java file is present within, this avoids decompiling every Jar + if _, err := os.Stat(filepath.Dir(javaFileAbsolutePath)); err != nil { + cmd := exec.Command("jar", "xf", filepath.Base(jarPath)) + cmd.Dir = filepath.Dir(jarPath) + err := cmd.Run() + if err != nil { + fmt.Printf("\n java error%v", err) + return "", "", err + } + } + } else if p.GetBuildTool() == gradle { + sourcesFile := "" + jarFile := filepath.Base(jarPath) + walker := func(path string, d os.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("found error traversing files: %w", err) + } + if !d.IsDir() && d.Name() == jarFile { + sourcesFile = path + if err != nil { + return fmt.Errorf("found error traversing files: %w", err) + } + return nil + } + return nil + } + root := filepath.Join(jarPath, "..", "..") + err := filepath.WalkDir(root, walker) + if err != nil { + return "", "", err + } + javaFileAbsolutePath = filepath.Join(filepath.Dir(sourcesFile), filepath.Dir(path), javaFileName) + + cmd := exec.Command("jar", "xf", filepath.Base(sourcesFile)) + cmd.Dir = filepath.Dir(sourcesFile) + err = cmd.Run() if err != nil { fmt.Printf("\n java error%v", err) return "", "", err } } + ui := uri.New(javaFileAbsolutePath) file, err := os.Open(ui.Filename()) defer file.Close() diff --git a/external-providers/java-external-provider/pkg/java_external_provider/provider.go b/external-providers/java-external-provider/pkg/java_external_provider/provider.go index 1bedb85b..b6bbe975 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/provider.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/provider.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "io" "os" @@ -234,16 +235,6 @@ func (p *javaProvider) Init(ctx context.Context, log logr.Logger, config provide isBinary = true } - if mode == provider.FullAnalysisMode { - // we attempt to decompile JARs of dependencies that don't have a sources JAR attached - // we need to do this for jdtls to correctly recognize source attachment for dep - err := resolveSourcesJars(ctx, log, config.Location, mavenSettingsFile) - if err != nil { - // TODO (pgaikwad): should we ignore this failure? - log.Error(err, "failed to resolve sources jar for location", "location", config.Location) - } - } - // handle proxy settings for k, v := range config.Proxy.ToEnvVars() { os.Setenv(k, v) @@ -311,6 +302,25 @@ func (p *javaProvider) Init(ctx context.Context, log logr.Logger, config provide includedPaths: provider.GetIncludedPathsFromConfig(config, false), } + if mode == provider.FullAnalysisMode { + // we attempt to decompile JARs of dependencies that don't have a sources JAR attached + // we need to do this for jdtls to correctly recognize source attachment for dep + switch svcClient.GetBuildTool() { + case maven: + err := resolveSourcesJarsForMaven(ctx, log, config.Location, mavenSettingsFile) + if err != nil { + // TODO (pgaikwad): should we ignore this failure? + log.Error(err, "failed to resolve maven sources jar for location", "location", config.Location) + } + case gradle: + err = resolveSourcesJarsForGradle(ctx, log, config.Location, mavenSettingsFile, &svcClient) + if err != nil { + log.Error(err, "failed to resolve gradle sources jar for location", "location", config.Location) + } + } + + } + svcClient.initialization(ctx) err = svcClient.depInit() if err != nil { @@ -319,6 +329,168 @@ func (p *javaProvider) Init(ctx context.Context, log logr.Logger, config provide return &svcClient, returnErr } +func resolveSourcesJarsForGradle(ctx context.Context, log logr.Logger, location string, mvnSettings string, svc *javaServiceClient) error { + ctx, span := tracing.StartNewSpan(ctx, "resolve-sources") + defer span.End() + + log.V(5).Info("resolving dependency sources for gradle") + + gb := svc.findGradleBuild() + if gb == "" { + return fmt.Errorf("could not find gradle build file for project") + } + + // create a temporary build file to append the task for downloading sources + taskgb := filepath.Join(filepath.Dir(gb), "tmp.gradle") + err := CopyFile(gb, taskgb) + if err != nil { + return fmt.Errorf("error copying file %s to %s", gb, taskgb) + } + defer os.Remove(taskgb) + + // append downloader task + taskfile := "/root/.gradle/task.gradle" + err = AppendToFile(taskfile, taskgb) + if err != nil { + return fmt.Errorf("error appending file %s to %s", taskfile, taskgb) + } + + tmpgbname := filepath.Join(location, "toberenamed.gradle") + err = os.Rename(gb, tmpgbname) + if err != nil { + return fmt.Errorf("error renaming file %s to %s", gb, "toberenamed.gradle") + } + defer os.Rename(tmpgbname, gb) + + err = os.Rename(taskgb, gb) + if err != nil { + return fmt.Errorf("error renaming file %s to %s", gb, "toberenamed.gradle") + } + defer os.Remove(gb) + + // run gradle wrapper with tmp build file + exe, err := filepath.Abs(filepath.Join(svc.config.Location, "gradlew")) + if err != nil { + return fmt.Errorf("error calculating gradle wrapper path") + } + if _, err = os.Stat(exe); errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("a gradle wrapper must be present in the project") + } + + // gradle must run with java 8 (see compatibility matrix) + java8home := os.Getenv("JAVA8_HOME") + if java8home == "" { + return fmt.Errorf("") + } + + args := []string{ + "konveyorDownloadSources", + } + cmd := exec.CommandContext(ctx, exe, args...) + cmd.Env = append(cmd.Env, fmt.Sprintf("JAVA_HOME=%s", java8home)) + cmd.Dir = location + output, err := cmd.CombinedOutput() + if err != nil { + return err + } + + log.V(8).WithValues("output", output).Info("got gradle output") + + // TODO: what if all sources available + reader := bytes.NewReader(output) + unresolvedSources, err := parseUnresolvedSourcesForGradle(reader) + if err != nil { + return err + } + + fmt.Printf("%d", len(unresolvedSources)) + + decompileJobs := []decompileJob{} + if len(unresolvedSources) > 1 { + // Gradle cache dir structure changes over time - we need to find where the actual dependencies are stored + cache, err := findGradleCache(unresolvedSources[0].GroupId) + if err != nil { + return err + } + + for _, artifact := range unresolvedSources { + log.V(5).WithValues("artifact", artifact).Info("sources for artifact not found, decompiling...") + + artifactDir := filepath.Join(cache, artifact.GroupId, artifact.ArtifactId) + jarName := fmt.Sprintf("%s-%s.jar", artifact.ArtifactId, artifact.Version) + artifactPath, err := findGradleArtifact(artifactDir, jarName) + if err != nil { + return err + } + decompileJobs = append(decompileJobs, decompileJob{ + artifact: artifact, + inputPath: artifactPath, + outputPath: filepath.Join(filepath.Dir(artifactPath), "decompiled", jarName), + }) + } + err = decompile(ctx, log, alwaysDecompileFilter(true), 10, decompileJobs, "") + if err != nil { + return err + } + // move decompiled files to base location of the jar + for _, decompileJob := range decompileJobs { + jarName := strings.TrimSuffix(filepath.Base(decompileJob.inputPath), ".jar") + err = moveFile(decompileJob.outputPath, + filepath.Join(filepath.Dir(decompileJob.inputPath), + fmt.Sprintf("%s-sources.jar", jarName))) + if err != nil { + log.V(5).Error(err, "failed to move decompiled file", "file", decompileJob.outputPath) + } + } + + } + return nil +} + +// findGradleCache looks for the folder within the Gradle cache where the actual dependencies are stored +// by walking the cache directory looking for a directory equal to the given sample group id +func findGradleCache(sampleGroupId string) (string, error) { + // TODO(jmle): atm taking for granted that the cache is going to be here + root := "/root/.gradle/caches" + cache := "" + walker := func(path string, d os.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("found error looking for cache directory: %w", err) + } + if d.IsDir() && d.Name() == sampleGroupId { + cache = path + return filepath.SkipAll + } + return nil + } + err := filepath.WalkDir(root, walker) + if err != nil { + return "", err + } + cache = filepath.Dir(cache) // return the parent of the found directory + return cache, nil +} + +// findGradleArtifact looks for a given artifact jar within the given root dir +func findGradleArtifact(root string, artifactId string) (string, error) { + artifactPath := "" + walker := func(path string, d os.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("found error looking for artifact: %w", err) + } + if !d.IsDir() && d.Name() == artifactId { + artifactPath = path + return filepath.SkipAll + } + return nil + } + err := filepath.WalkDir(root, walker) + if err != nil { + return "", err + } + return artifactPath, nil +} + // GetLocation given a dep, attempts to find line number, caches the line number for a given dep func (j *javaProvider) GetLocation(ctx context.Context, dep konveyor.Dep, file string) (engine.Location, error) { location := engine.Location{StartPosition: engine.Position{}, EndPosition: engine.Position{}} @@ -385,9 +557,9 @@ func (j *javaProvider) GetLocation(ctx context.Context, dep konveyor.Dep, file s return location, nil } -// resolveSourcesJars for a given source code location, runs maven to find +// resolveSourcesJarsForMaven for a given source code location, runs maven to find // deps that don't have sources attached and decompiles them -func resolveSourcesJars(ctx context.Context, log logr.Logger, location, mavenSettings string) error { +func resolveSourcesJarsForMaven(ctx context.Context, log logr.Logger, location, mavenSettings string) error { // TODO (pgaikwad): when we move to external provider, inherit context from parent ctx, span := tracing.StartNewSpan(ctx, "resolve-sources") defer span.End() @@ -455,6 +627,50 @@ func resolveSourcesJars(ctx context.Context, log logr.Logger, location, mavenSet return nil } +// parseUnresolvedSources takes the output from the download sources gradle task and returns the artifacts whose sources +// could not be found. Sample gradle output: +// Found 0 sources for :simple-jar: +// Found 1 sources for com.codevineyard:hello-world:1.0.1 +// Found 1 sources for org.codehaus.groovy:groovy:3.0.21 +func parseUnresolvedSourcesForGradle(output io.Reader) ([]javaArtifact, error) { + unresolvedSources := []javaArtifact{} + unresolvedRegex := regexp.MustCompile(`Found 0 sources for (.*)`) + artifactRegex := regexp.MustCompile(`(.+):(.+):(.+)|:(.+):`) + + scanner := bufio.NewScanner(output) + for scanner.Scan() { + line := scanner.Text() + + if match := unresolvedRegex.FindStringSubmatch(line); len(match) != 0 { + gav := artifactRegex.FindStringSubmatch(match[1]) + if gav[4] != "" { // internal library, unknown group/version + artifact := javaArtifact{ + ArtifactId: match[4], + } + unresolvedSources = append(unresolvedSources, artifact) + } else { // external dependency + artifact := javaArtifact{ + GroupId: gav[1], + ArtifactId: gav[2], + Version: gav[3], + } + unresolvedSources = append(unresolvedSources, artifact) + } + } + } + + // dedup artifacts + result := []javaArtifact{} + for _, artifact := range unresolvedSources { + if contains(result, artifact) { + continue + } + result = append(result, artifact) + } + + return result, scanner.Err() +} + // parseUnresolvedSources takes the output from the go-offline maven plugin and returns the artifacts whose sources // could not be found. func parseUnresolvedSources(output io.Reader) ([]javaArtifact, error) { diff --git a/external-providers/java-external-provider/pkg/java_external_provider/service_client.go b/external-providers/java-external-provider/pkg/java_external_provider/service_client.go index 3f557e11..ccb83704 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/service_client.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/service_client.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "os" "os/exec" "path/filepath" "regexp" @@ -206,7 +207,7 @@ func (p *javaServiceClient) initialization(ctx context.Context) { "classFileContentsSupport": true, } // See https://github.com/eclipse-jdtls/eclipse.jdt.ls/blob/1a3dd9323756113bf39cfab82746d57a2fd19474/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java - // TODO: what if no wrapper? + java8home := os.Getenv("JAVA8_HOME") params.InitializationOptions = map[string]interface{}{ "bundles": absBundles, "workspaceFolders": []string{fmt.Sprintf("file://%v", absLocation)}, @@ -226,7 +227,7 @@ func (p *javaServiceClient) initialization(ctx context.Context) { "import": map[string]interface{}{ "gradle": map[string]interface{}{ "java": map[string]interface{}{ - "home": "/usr/lib/jvm/java-1.8.0-openjdk", + "home": java8home, }, }, }, diff --git a/external-providers/java-external-provider/pkg/java_external_provider/util.go b/external-providers/java-external-provider/pkg/java_external_provider/util.go index d8bb0f75..1952e824 100644 --- a/external-providers/java-external-provider/pkg/java_external_provider/util.go +++ b/external-providers/java-external-provider/pkg/java_external_provider/util.go @@ -131,9 +131,11 @@ func decompile(ctx context.Context, log logr.Logger, filter decompileFilter, wor "failed to create directories for decompiled file", "path", outputPathDir) continue } + // multiple java versions may be installed - chose $JAVA_HOME one + java := filepath.Join(os.Getenv("JAVA_HOME"), "bin", "java") // -mpm (max processing method) is required to keep decomp time low cmd := exec.CommandContext( - jobCtx, "java", "-jar", "/bin/fernflower.jar", "-mpm=30", job.inputPath, outputPathDir) + jobCtx, java, "-jar", "/bin/fernflower.jar", "-mpm=30", job.inputPath, outputPathDir) err := cmd.Run() if err != nil { log.V(5).Error(err, "failed to decompile file", "file", job.inputPath, job.outputPath) @@ -385,7 +387,7 @@ func explode(ctx context.Context, log logr.Logger, archivePath, projectPath stri artifactPath := filepath.Join(strings.Split(dep.ArtifactId, ".")...) destPath := filepath.Join(m2Repo, groupPath, artifactPath, dep.Version, filepath.Base(filePath)) - if err := copyFile(filePath, destPath); err != nil { + if err := CopyFile(filePath, destPath); err != nil { log.V(8).Error(err, "failed copying jar to m2 local repo") } else { log.V(8).Info("copied jar file", "src", filePath, "dest", destPath) @@ -433,7 +435,7 @@ func createJavaProject(ctx context.Context, dir string, dependencies []javaArtif } func moveFile(srcPath string, destPath string) error { - err := copyFile(srcPath, destPath) + err := CopyFile(srcPath, destPath) if err != nil { return err } @@ -444,7 +446,7 @@ func moveFile(srcPath string, destPath string) error { return nil } -func copyFile(srcPath string, destPath string) error { +func CopyFile(srcPath string, destPath string) error { if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil { return err } @@ -465,6 +467,29 @@ func copyFile(srcPath string, destPath string) error { return nil } +func AppendToFile(src string, dst string) error { + // Read the contents of the source file + content, err := os.ReadFile(src) + if err != nil { + return fmt.Errorf("error reading source file: %s", err) + } + + // Open the destination file in append mode + destFile, err := os.OpenFile(dst, os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return fmt.Errorf("error opening destination file: %s", err) + } + defer destFile.Close() + + // Append the content to the destination file + _, err = destFile.Write(content) + if err != nil { + return fmt.Errorf("error apending to destination file: %s", err) + } + + return nil +} + // toDependency returns javaArtifact constructed for a jar func toDependency(ctx context.Context, jarFile string) (javaArtifact, error) { // attempt to lookup java artifact in maven diff --git a/provider_container_settings.json b/provider_container_settings.json index 169a3b09..c8e9bea5 100644 --- a/provider_container_settings.json +++ b/provider_container_settings.json @@ -101,6 +101,16 @@ "bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar" }, "analysisMode": "source-only" + }, + { + "location": "examples/gradle-multi-project-example", + "providerSpecificConfig": { + "lspServerName": "java", + "lspServerPath": "/jdtls/bin/jdtls", + "depOpenSourceLabelsFile": "/usr/local/etc/maven.default.index", + "bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar" + }, + "analysisMode": "source-only" } ] }, From 3d4c931a64e86ab12f8a2ac21d91a3a79e1e5786 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 23 May 2024 12:40:01 +0200 Subject: [PATCH 10/17] Add test rule and results Signed-off-by: Juan Manuel Leflet Estrada --- demo-dep-output.yaml | 355 ++++++++++++++++++++++++++++++------------- demo-output.yaml | 76 ++++++--- rule-example.yaml | 10 +- 3 files changed, 313 insertions(+), 128 deletions(-) diff --git a/demo-dep-output.yaml b/demo-dep-output.yaml index dedbdc4e..c96fa8bb 100644 --- a/demo-dep-output.yaml +++ b/demo-dep-output.yaml @@ -171,6 +171,11 @@ labels: - konveyor.io/dep-source=downloadable - konveyor.io/language=go + - name: go + version: "1.18" + labels: + - konveyor.io/dep-source=downloadable + - konveyor.io/language=go - name: go.etcd.io/etcd/client/pkg/v3 version: v3.5.1 labels: @@ -333,7 +338,7 @@ version: 2.7.7 type: compile indirect: true - resolvedIdentifier: 83cd2cd674a217ade95a4bb83a8a14f351f48bd0 + resolvedIdentifier: 52f15b99911ab8b8bc8744675f5cf1994a626fb8 extras: artifactId: antlr baseDep: @@ -352,7 +357,7 @@ - name: ch.qos.logback.logback-classic version: 1.1.7 type: compile - resolvedIdentifier: 9865cf6994f9ff13fce0bf93f2054ef6c65bb462 + resolvedIdentifier: 044c01db0f7d7aac366fb952a89c10251ed86f44 extras: artifactId: logback-classic groupId: ch.qos.logback @@ -365,7 +370,7 @@ version: 1.1.7 type: compile indirect: true - resolvedIdentifier: 7873092d39ef741575ca91378a6a21c388363ac8 + resolvedIdentifier: 6d1bdb1e28c56a8f989366b339f0f62545696e6d extras: artifactId: logback-core baseDep: @@ -385,7 +390,7 @@ version: 1.5.1 type: compile indirect: true - resolvedIdentifier: 3fe0bed568c62df5e89f4f174c101eab25345b6c + resolvedIdentifier: d5d564526c142037daead331ee5278c088777858 extras: artifactId: classmate baseDep: @@ -405,7 +410,7 @@ version: 2.12.3 type: compile indirect: true - resolvedIdentifier: 7275513412694a1aafd08c0287f48469fa0e6e17 + resolvedIdentifier: 87859f29ceebfab7a873c3b4f4b89c9a594b2842 extras: artifactId: jackson-annotations baseDep: @@ -424,7 +429,7 @@ - name: com.fasterxml.jackson.core.jackson-core version: 2.12.3 type: compile - resolvedIdentifier: deb23fe2a7f2b773e18ced2b50d4acc1df8fa366 + resolvedIdentifier: ef6abf067337134089d074f411306a51f11a4d62 extras: artifactId: jackson-core groupId: com.fasterxml.jackson.core @@ -436,7 +441,7 @@ - name: com.fasterxml.jackson.core.jackson-databind version: 2.12.3 type: compile - resolvedIdentifier: d6153f8fc60c479ab0f9efb35c034526436a4953 + resolvedIdentifier: 2b186d9cc73cfb9272171357d17f0979eac44889 extras: artifactId: jackson-databind groupId: com.fasterxml.jackson.core @@ -449,7 +454,7 @@ version: 2.12.3 type: runtime indirect: true - resolvedIdentifier: f69c636438dcf19c49960c1fe8901320ab85f989 + resolvedIdentifier: db7822a553c167e95bdda25d0d6db44bd3abf847 extras: artifactId: jackson-datatype-jsr310 baseDep: @@ -468,7 +473,7 @@ - name: com.oracle.database.jdbc.ojdbc8 version: 21.1.0.0 type: compile - resolvedIdentifier: 50044485aea10afd7defeee8109c5195b4d3cae2 + resolvedIdentifier: dea0cca54c29d3e44167cd80839692b325ae2daf extras: artifactId: ojdbc8 groupId: com.oracle.database.jdbc @@ -481,7 +486,7 @@ version: 3.0.7 type: compile indirect: true - resolvedIdentifier: c197c86ceec7318b1284bffb49b54226ca774003 + resolvedIdentifier: 8eb4c6b0e9b0a1fadf53fce8b3fc8415b00469ef extras: artifactId: istack-commons-runtime baseDep: @@ -501,7 +506,7 @@ version: 1.2.15 type: compile indirect: true - resolvedIdentifier: bb7b7ec0379982b97c62cd17465cb6d9155f68e8 + resolvedIdentifier: 945cf1f4467c72add88309fb05cdf5e340b569f9 extras: artifactId: FastInfoset baseDep: @@ -520,7 +525,7 @@ - name: io.konveyor.demo.config-utils version: 1.0.0 type: compile - resolvedIdentifier: FE4FE11AAEE77BE10035218537FBF4B2E6EF1D9F + resolvedIdentifier: 4010193B2F96CC7B7056C4CD51C3188FBBBC86E0 extras: artifactId: config-utils groupId: io.konveyor.demo @@ -533,7 +538,7 @@ version: 1.7.0 type: compile indirect: true - resolvedIdentifier: bc7dc1605f2099dc3c39156b7f62ac889f54fb67 + resolvedIdentifier: fd50ef746ed294d4e064c0cd3a14ca08543d139c extras: artifactId: micrometer-core baseDep: @@ -553,7 +558,7 @@ version: 1.3.5 type: compile indirect: true - resolvedIdentifier: 59eb84ee0d616332ff44aba065f3888cf002cd2d + resolvedIdentifier: beb7649988a22ea30a17fcaeba8584323e86df74 extras: artifactId: jakarta.annotation-api baseDep: @@ -573,7 +578,7 @@ version: 2.0.2 type: compile indirect: true - resolvedIdentifier: 5eacc6522521f7eacb081f95cee1e231648461e7 + resolvedIdentifier: fc029778f5494ed05e5833f8bdb57e36dbda38aa extras: artifactId: jakarta.validation-api baseDep: @@ -593,7 +598,7 @@ version: 1.2.0 type: compile indirect: true - resolvedIdentifier: 85262acf3ca9816f9537ca47d5adeabaead7cb16 + resolvedIdentifier: 1aa9ef58e50ba6868b2e955d61fcd73be5b4cea5 extras: artifactId: javax.activation-api baseDep: @@ -613,7 +618,7 @@ version: "2.2" type: compile indirect: true - resolvedIdentifier: 25665ac8c0b62f50e6488173233239120fc52c96 + resolvedIdentifier: ac7080de51fc0596317c15e12ed441f7c0a84d09 extras: artifactId: javax.persistence-api baseDep: @@ -633,7 +638,7 @@ version: 2.3.1 type: compile indirect: true - resolvedIdentifier: 8531ad5ac454cc2deb9d4d32c40c4d7451939b5d + resolvedIdentifier: c42c51ae84892b73ef7de5351188908e673f5c69 extras: artifactId: jaxb-api baseDep: @@ -653,7 +658,7 @@ version: 1.10.22 type: compile indirect: true - resolvedIdentifier: ef45d7e2cd1c600d279704f492ed5ce2ceb6cdb5 + resolvedIdentifier: 14de25cfee49cd27ae19153674bbb34c04c45d52 extras: artifactId: byte-buddy baseDep: @@ -673,7 +678,7 @@ version: 2.14.1 type: compile indirect: true - resolvedIdentifier: cd8858fbbde69f46bce8db1152c18a43328aae78 + resolvedIdentifier: 9199a73770616b1ca0b00f576db3231aaab4876a extras: artifactId: log4j-api baseDep: @@ -693,7 +698,7 @@ version: 2.14.1 type: compile indirect: true - resolvedIdentifier: ce8a86a3f50a4304749828ce68e7478cafbc8039 + resolvedIdentifier: 4638502177d694ad6f429a122e32f84ceba7db41 extras: artifactId: log4j-to-slf4j baseDep: @@ -712,7 +717,7 @@ - name: org.apache.tomcat.tomcat-jdbc version: 9.0.46 type: runtime - resolvedIdentifier: 385cb6cb1f6b26c881cd5c1c6ade5f180712ffdc + resolvedIdentifier: c3b975aba8359ecf35f6fca175c2e843a1d3c107 extras: artifactId: tomcat-jdbc groupId: org.apache.tomcat @@ -725,7 +730,7 @@ version: 9.0.46 type: runtime indirect: true - resolvedIdentifier: 409b519751e104eab51b4347a0d27bf86a4f3bb1 + resolvedIdentifier: 1596051131c8426ebf744e0effed0e0005c87d57 extras: artifactId: tomcat-juli baseDep: @@ -744,7 +749,7 @@ - name: org.apache.tomcat.tomcat-servlet-api version: 9.0.46 type: provided - resolvedIdentifier: 8e8a27a3456b71b1da2c8adc902ade71bc91fcb4 + resolvedIdentifier: 1f5ec6292bbca9e6c35172044b5fee0b0a97ef24 extras: artifactId: tomcat-servlet-api groupId: org.apache.tomcat @@ -757,7 +762,7 @@ version: 1.9.6 type: compile indirect: true - resolvedIdentifier: 1651849d48659e5703adc2599e694bf67b8c3fc4 + resolvedIdentifier: 2c4216b8c0f62edf69ec5cdd68619ba2aac5a4a1 extras: artifactId: aspectjrt baseDep: @@ -777,7 +782,7 @@ version: 3.5.0 type: runtime indirect: true - resolvedIdentifier: 2f50520c8abea66fbd8d26e481d3aef5c673b510 + resolvedIdentifier: 408a4451ff5bdef60400a49657867db100ea0f83 extras: artifactId: checker-qual baseDep: @@ -797,7 +802,7 @@ version: 2.1.3 type: compile indirect: true - resolvedIdentifier: a75914155a9f5808963170ec20653668a2ffd2fd + resolvedIdentifier: 012854caa63db09d82bf973bc37d7226aaaef463 extras: artifactId: dom4j baseDep: @@ -817,7 +822,7 @@ version: 2.3.1 type: compile indirect: true - resolvedIdentifier: dd6dda9da676a54c5b36ca2806ff95ee017d8738 + resolvedIdentifier: 1856da23a80b9b1374d925d6dcb4a21db2144204 extras: artifactId: jaxb-runtime baseDep: @@ -837,7 +842,7 @@ version: 2.3.1 type: compile indirect: true - resolvedIdentifier: a09d2c48d3285f206fafbffe0e50619284e92126 + resolvedIdentifier: c78aa440484eab1a6e2104e4fe69d0945a3cb3da extras: artifactId: txw2 baseDep: @@ -857,7 +862,7 @@ version: 2.1.12 type: compile indirect: true - resolvedIdentifier: 6eb7552156e0d517ae80cc2247be1427c8d90452 + resolvedIdentifier: 9797702ee3e52e4be6bfbbc9fd20ac5447e7a541 extras: artifactId: HdrHistogram baseDep: @@ -877,7 +882,7 @@ version: 5.1.2.Final type: compile indirect: true - resolvedIdentifier: e59ffdbc6ad09eeb33507b39ffcf287679a498c8 + resolvedIdentifier: 573f22ce360cd7a8bcc0dae4deecbe4e8861007d extras: artifactId: hibernate-commons-annotations baseDep: @@ -897,7 +902,7 @@ version: 5.4.32.Final type: compile indirect: true - resolvedIdentifier: 99a5e10bf455337014c190e141ec631e9ff71663 + resolvedIdentifier: 5be381f7b6f3d4f17ce746e4ff54f4b8cdce40e4 extras: artifactId: hibernate-core baseDep: @@ -916,7 +921,7 @@ - name: org.hibernate.hibernate-entitymanager version: 5.4.32.Final type: compile - resolvedIdentifier: 3f60db4097732960ec792c033dbb7c34f1b9e328 + resolvedIdentifier: b315696800e16d33bfb297d66f87a792caa3facc extras: artifactId: hibernate-entitymanager groupId: org.hibernate @@ -928,7 +933,7 @@ - name: org.hibernate.validator.hibernate-validator version: 6.2.0.Final type: compile - resolvedIdentifier: d6b0760dfffbf379cedd02f715ff4c9a2e215921 + resolvedIdentifier: 7f1beda5229a0c99a175603c18b3c66da44f966e extras: artifactId: hibernate-validator groupId: org.hibernate.validator @@ -941,7 +946,7 @@ version: 3.27.0-GA type: compile indirect: true - resolvedIdentifier: f63e6aa899e15eca8fdaa402a79af4c417252213 + resolvedIdentifier: 0b7565662bc91e9648aab437135f32beb040ac15 extras: artifactId: javassist baseDep: @@ -961,7 +966,7 @@ version: 2.2.3.Final type: compile indirect: true - resolvedIdentifier: d3865101f0666b63586683bd811d754517f331ab + resolvedIdentifier: c70053a1326428ec641be311ccf5551a8ec76a63 extras: artifactId: jandex baseDep: @@ -981,7 +986,7 @@ version: 3.4.1.Final type: compile indirect: true - resolvedIdentifier: 40fd4d696c55793e996d1ff3c475833f836c2498 + resolvedIdentifier: 9d82f8eea1b5ed484775517d7588e320f9f7797a extras: artifactId: jboss-logging baseDep: @@ -1001,7 +1006,7 @@ version: 1.1.1.Final type: compile indirect: true - resolvedIdentifier: a8485cab9484dda36e9a8c319e76b5cc18797b58 + resolvedIdentifier: 90823b310c573492696ad7e299b694ca2e70b4c1 extras: artifactId: jboss-transaction-api_1.2_spec baseDep: @@ -1021,7 +1026,7 @@ version: "1.8" type: compile indirect: true - resolvedIdentifier: 8cc35f73da321c29973191f2cf143d29d26a1df7 + resolvedIdentifier: cc7022b896125220e51f46fa50f4b68e564ffec1 extras: artifactId: stax-ex baseDep: @@ -1041,7 +1046,7 @@ version: 2.0.3 type: runtime indirect: true - resolvedIdentifier: 769c0b82cb2421c8256300e907298a9410a2a3d3 + resolvedIdentifier: 5baec26b6f9e5b17fdd200fc20af85eead4287c4 extras: artifactId: LatencyUtils baseDep: @@ -1060,7 +1065,7 @@ - name: org.postgresql.postgresql version: 42.2.23 type: compile - resolvedIdentifier: 9cb217a3d5b640567ed7c6e8c11f389613c81c4d + resolvedIdentifier: cc8565ec39dbfee32c2c87f125162fe8a3010c28 extras: artifactId: postgresql groupId: org.postgresql @@ -1073,7 +1078,7 @@ version: 1.7.30 type: compile indirect: true - resolvedIdentifier: d58bebff8cbf70ff52b59208586095f467656c30 + resolvedIdentifier: f09448bdaeee63bc0644abae571b2d17c83d16c1 extras: artifactId: jul-to-slf4j baseDep: @@ -1093,7 +1098,7 @@ version: 1.7.26 type: compile indirect: true - resolvedIdentifier: 77100a62c2e6f04b53977b9f541044d7d722693d + resolvedIdentifier: 4d3419a58d77c07f49185aaa556a787d50508d27 extras: artifactId: slf4j-api baseDep: @@ -1113,7 +1118,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: b07513e04ad906ea69ef84293a123cdb83828f06 + resolvedIdentifier: 48a6c425a45395e1ccfd99fd815c92d069040e43 extras: artifactId: spring-boot baseDep: @@ -1133,7 +1138,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: e0ac75f1a183f8e6a319a8b03bad1c45d40a2761 + resolvedIdentifier: ee202daac01b6399b857d187cfdbf6d97d6adc8f extras: artifactId: spring-boot-actuator baseDep: @@ -1153,7 +1158,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: 41956882243e86f8260f649ebdd96597a2ff52a9 + resolvedIdentifier: c527193b5cc67f7534c27860171e44187746aaf5 extras: artifactId: spring-boot-actuator-autoconfigure baseDep: @@ -1173,7 +1178,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: 64c7bbc941c70895621ed613f38dc66b73ea9341 + resolvedIdentifier: da542216009c858c2e8b32cb595578acc19d2df3 extras: artifactId: spring-boot-autoconfigure baseDep: @@ -1193,7 +1198,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: a910887c01efcc7d12f3f89a7604d436f26eeb90 + resolvedIdentifier: 391cbf83221ae09c1c0a471b25ab3221dfe46ef1 extras: artifactId: spring-boot-starter baseDep: @@ -1212,7 +1217,7 @@ - name: org.springframework.boot.spring-boot-starter-actuator version: 2.5.0 type: compile - resolvedIdentifier: 8fc47befa38bdaa2f2b8f421d8532f03005e2851 + resolvedIdentifier: 76dd6dea415751e05491337b7ff22bd08ae70c7e extras: artifactId: spring-boot-starter-actuator groupId: org.springframework.boot @@ -1225,7 +1230,7 @@ version: 2.5.0 type: compile indirect: true - resolvedIdentifier: 22401482ba1c5a1dcd3d33e47295779211b913d8 + resolvedIdentifier: 60f06908ef3b39d8c8780898e749c4c846fabb84 extras: artifactId: spring-boot-starter-logging baseDep: @@ -1245,7 +1250,7 @@ version: 2.5.1 type: compile indirect: true - resolvedIdentifier: c950ca1a05e928e9fb75420b4ac07713428e9969 + resolvedIdentifier: bceeabb4ef399ba7ff8511f2931e1924a41cc921 extras: artifactId: spring-data-commons baseDep: @@ -1264,7 +1269,7 @@ - name: org.springframework.data.spring-data-jpa version: 2.5.1 type: compile - resolvedIdentifier: 881f7ae140f424b3bdb1b0c27a61b93e0bee9fa5 + resolvedIdentifier: 461ebcc9fc00dca10a754b0e96583ce7d281d312 extras: artifactId: spring-data-jpa groupId: org.springframework.data @@ -1277,7 +1282,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: b86edd2455f8c4399068c999beb9ea2a9e7f2047 + resolvedIdentifier: 0bf1d9d12108b8ab2d9d71d5fd5fee02d3ee5bde extras: artifactId: spring-aop baseDep: @@ -1297,7 +1302,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 8b1eacd7aaa12f7d173a2f0836d28bd0c1b098fe + resolvedIdentifier: 654397f55cd4a4734f8b76282e98c88884d0367a extras: artifactId: spring-beans baseDep: @@ -1317,7 +1322,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 330b3957efdcdebe3550b8e2c5d45a4c25496626 + resolvedIdentifier: 67e3176098c81702c76d20977deec8101b3faf8c extras: artifactId: spring-context baseDep: @@ -1337,7 +1342,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 4aad1b62bd347a806fe693c9d67b376a3ad8151c + resolvedIdentifier: 44ce199d05bb1ce9682621cd18953ea307485fc1 extras: artifactId: spring-core baseDep: @@ -1357,7 +1362,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 13351fce0a604957cd6a41478ebb54a953a0245e + resolvedIdentifier: 30bd0b3e802e5ba4e4d9fc68e57cc0e755ba9f9f extras: artifactId: spring-expression baseDep: @@ -1377,7 +1382,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: ccd8bde38bad689737295fa220e1c70680676d72 + resolvedIdentifier: e1e7c14c73ae5fc616bb941ce8c1e7e62736cadf extras: artifactId: spring-jcl baseDep: @@ -1396,7 +1401,7 @@ - name: org.springframework.spring-jdbc version: 5.3.7 type: compile - resolvedIdentifier: 5caf72035a9b8a3a09ef82322cd2497aedddc487 + resolvedIdentifier: a4f87a03116ecde96213642141eb95da05022f51 extras: artifactId: spring-jdbc groupId: org.springframework @@ -1409,7 +1414,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: f1892fe7a6671348d6546facbd40159b7e6f64a2 + resolvedIdentifier: cc6911f3194cb77d493aa626c661789926027446 extras: artifactId: spring-orm baseDep: @@ -1429,7 +1434,7 @@ version: 5.3.7 type: compile indirect: true - resolvedIdentifier: 98be572c2bf3bd08724363b0bba71bcef59c4739 + resolvedIdentifier: c6df78e1d9b50b7063e4a196127d75ee9321f68b extras: artifactId: spring-tx baseDep: @@ -1448,7 +1453,7 @@ - name: org.springframework.spring-web version: 5.3.7 type: compile - resolvedIdentifier: 49e6a8f45e77f14ef16f82c0413254ef493b785f + resolvedIdentifier: d9f78e0b045d90dc862cd4a39294a468b3cc6ba9 extras: artifactId: spring-web groupId: org.springframework @@ -1460,7 +1465,7 @@ - name: org.springframework.spring-webmvc version: 5.3.7 type: compile - resolvedIdentifier: 8437c7a572177a34607abdaef2f6b8088488f5c0 + resolvedIdentifier: d0f042bff56bb90beabc6ed5d062fb87c69e652a extras: artifactId: spring-webmvc groupId: org.springframework @@ -1473,7 +1478,7 @@ version: "1.28" type: compile indirect: true - resolvedIdentifier: 7cae037c3014350c923776548e71c9feb7a69259 + resolvedIdentifier: 3e38757e3eaf549cccd9bbdfa74b2930c177b8af extras: artifactId: snakeyaml baseDep: @@ -1489,6 +1494,138 @@ - konveyor.io/dep-source=open-source - konveyor.io/language=java prefix: file:///root/.m2/repository/org/yaml/snakeyaml/1.28 +- fileURI: file:///analyzer-lsp/examples/gradle-multi-project-example/build.gradle + provider: java + dependencies: + - name: antlr.antlr + version: 2.7.7 + indirect: true + - name: com.apple.AppleJavaExtensions + version: "1.4" + indirect: true + - name: com.beust.jcommander + version: "1.48" + indirect: true + - name: com.google.code.findbugs.bcel-findbugs + version: "6.0" + indirect: true + - name: com.google.code.findbugs.findbugs + version: 3.0.1 + - name: com.google.code.findbugs.jFormatString + version: 2.0.1 + indirect: true + - name: com.google.code.findbugs.jsr305 + version: 1.3.9 + indirect: true + - name: com.google.code.findbugs.jsr305 + version: 2.0.1 + indirect: true + - name: com.google.code.gson.gson + version: "2.5" + indirect: true + - name: com.google.errorprone.error_prone_annotations + version: 2.0.18 + indirect: true + - name: com.google.guava.guava + version: "23.0" + - name: com.google.guava.guava + version: 23.2-jre + indirect: true + - name: com.google.j2objc.j2objc-annotations + version: "1.1" + indirect: true + - name: com.puppycrawl.tools.checkstyle + version: "8.4" + - name: commons-beanutils.commons-beanutils + version: 1.9.3 + indirect: true + - name: commons-cli.commons-cli + version: "1.4" + indirect: true + - name: commons-collections.commons-collections + version: 3.2.2 + indirect: true + - name: commons-io.commons-io + version: "2.4" + indirect: true + - name: commons-lang.commons-lang + version: "2.6" + indirect: true + - name: dom4j.dom4j + version: 1.6.1 + indirect: true + - name: jaxen.jaxen + version: 1.1.6 + indirect: true + - name: junit.junit + version: "4.12" + - name: net.bytebuddy.byte-buddy + version: 1.7.4 + indirect: true + - name: net.bytebuddy.byte-buddy-agent + version: 1.7.4 + indirect: true + - name: net.java.dev.javacc.javacc + version: "5.0" + indirect: true + - name: net.jcip.jcip-annotations + version: "1.0" + indirect: true + - name: net.sf.saxon.Saxon-HE + version: 9.8.0-5 + indirect: true + - name: net.sourceforge.pmd.pmd-core + version: 5.6.1 + indirect: true + - name: net.sourceforge.pmd.pmd-java + version: 5.6.1 + - name: net.sourceforge.saxon.saxon + version: 9.1.0.8 + indirect: true + - name: org.antlr.antlr4-runtime + version: "4.7" + indirect: true + - name: org.apache.commons.commons-lang3 + version: "3.4" + indirect: true + - name: org.apache.logging.log4j.log4j-api + version: 2.9.1 + - name: org.apache.logging.log4j.log4j-core + version: 2.9.1 + - name: org.apache.logging.log4j.log4j-slf4j-impl + version: 2.9.1 + - name: org.codehaus.mojo.animal-sniffer-annotations + version: "1.14" + indirect: true + - name: org.hamcrest.hamcrest-core + version: "1.3" + indirect: true + - name: org.mockito.mockito-core + version: 2.11.0 + - name: org.objenesis.objenesis + version: "2.6" + indirect: true + - name: org.ow2.asm.asm + version: 5.0.2 + indirect: true + - name: org.ow2.asm.asm + version: 5.0.4 + indirect: true + - name: org.ow2.asm.asm-commons + version: 5.0.2 + indirect: true + - name: org.ow2.asm.asm-debug-all + version: 5.0.2 + indirect: true + - name: org.ow2.asm.asm-tree + version: 5.0.2 + indirect: true + - name: org.slf4j.slf4j-api + version: 1.7.25 + indirect: true + - name: xml-apis.xml-apis + version: 1.0.b2 + indirect: true - fileURI: file:///analyzer-lsp/examples/java/pom.xml provider: java dependencies: @@ -1496,7 +1633,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: 7198b3aac15285a49e218e08441c5f70af00fc51 + resolvedIdentifier: 717e3012ee74008533d4e92946ccf49060e84e78 extras: artifactId: jackson-annotations baseDep: @@ -1516,7 +1653,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: a27014716e4421684416e5fa83d896ddb87002da + resolvedIdentifier: 1a9b0ebfcda0063950c35f42c7fdce9a34e8b782 extras: artifactId: jackson-core baseDep: @@ -1536,7 +1673,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: 56deb9ea2c93a7a556b3afbedd616d342963464e + resolvedIdentifier: 2c0ce6eb612e33616edb250542d0fda62524f717 extras: artifactId: jackson-databind baseDep: @@ -1556,7 +1693,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: 9363ded5441b1fee62d5be0604035690ca759a2a + resolvedIdentifier: 79e3dbba4729d503ce3eef93f68caddf213b678d extras: artifactId: jackson-dataformat-yaml baseDep: @@ -1576,7 +1713,7 @@ version: 2.13.3 type: compile indirect: true - resolvedIdentifier: ad2f4c61aeb9e2a8bb5e4a3ed782cfddec52d972 + resolvedIdentifier: b22a52de24b5bd7bcf210f02bd2e75ae1c4a740d extras: artifactId: jackson-datatype-jsr310 baseDep: @@ -1596,7 +1733,7 @@ version: 3.12.12 type: runtime indirect: true - resolvedIdentifier: d952189f6abb148ff72aab246aa8c28cf99b469f + resolvedIdentifier: 705a7df4584707ae40db2fb903f921755510567f extras: artifactId: logging-interceptor baseDep: @@ -1616,7 +1753,7 @@ version: 3.12.12 type: runtime indirect: true - resolvedIdentifier: d3e1ce1d2b3119adf270b2d00d947beb03fe3321 + resolvedIdentifier: 90c81c59b2eb943ddbe58bc717e3e75bccd518c2 extras: artifactId: okhttp baseDep: @@ -1636,7 +1773,7 @@ version: 1.15.0 type: runtime indirect: true - resolvedIdentifier: bc28b5a964c8f5721eb58ee3f3c47a9bcbf4f4d8 + resolvedIdentifier: 87f1520a39a954a9aa185c7fe8f144fa7d597690 extras: artifactId: okio baseDep: @@ -1656,7 +1793,7 @@ version: 1.5.0 type: provided indirect: true - resolvedIdentifier: ec2410fdf7e0a3022e7c2a2e6241039d1abc1e98 + resolvedIdentifier: 2143163e070fcd301fbf7b3246ca4854caaabacc extras: artifactId: javax.mail baseDep: @@ -1675,7 +1812,7 @@ - name: io.fabric8.kubernetes-client version: 6.0.0 type: compile - resolvedIdentifier: d0831d44e12313df8989fc1d4a9c90452f08858e + resolvedIdentifier: 738af0538ca0399331e1d5477edc74b19a43d912 extras: artifactId: kubernetes-client groupId: io.fabric8 @@ -1687,7 +1824,7 @@ - name: io.fabric8.kubernetes-client-api version: 6.0.0 type: compile - resolvedIdentifier: 3f54cdb10f54b413fe4b8a0d4d044d33174bd271 + resolvedIdentifier: fb7ecaa7697fc3ba4157ab7250c542032b6f3b0f extras: artifactId: kubernetes-client-api groupId: io.fabric8 @@ -1700,7 +1837,7 @@ version: 6.0.0 type: runtime indirect: true - resolvedIdentifier: 70690b98acb07a809c55d15d7cf45f53ec1026e1 + resolvedIdentifier: b06ddc26ab91382d2ed02ae6c16f3108a12bef04 extras: artifactId: kubernetes-httpclient-okhttp baseDep: @@ -1720,7 +1857,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 9e3b0d4caa3d033fa0f71c71d8a535a748b280ba + resolvedIdentifier: dcbf5acf8815378769490abee2170d54ac73732b extras: artifactId: kubernetes-model-admissionregistration baseDep: @@ -1740,7 +1877,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: eac63b8dec80e96c4356c91ed0a332415efcb75e + resolvedIdentifier: b053ca57ddd50936e1cfe8e5790b77dd76393944 extras: artifactId: kubernetes-model-apiextensions baseDep: @@ -1760,7 +1897,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 4dbda6401058a5fd3a4c6be88fc1bf4f99296c4f + resolvedIdentifier: f23c0d497dd0a99f35a06bdd0a04dd8a4ec92dd2 extras: artifactId: kubernetes-model-apps baseDep: @@ -1780,7 +1917,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: b353e45133fbc80791d676b16203ec94c0958b7d + resolvedIdentifier: 1d6c9585a5c33cfb19cc0ac3a27bc17b2c7e4922 extras: artifactId: kubernetes-model-autoscaling baseDep: @@ -1800,7 +1937,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 9f14cbfc75d172fa81f3f6ad793bdd45a2decaec + resolvedIdentifier: 32e9e912473abdbc8c70484db3ba733bdc4772f0 extras: artifactId: kubernetes-model-batch baseDep: @@ -1820,7 +1957,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 33f5a3f386cddda55003e1616303ab924fcd3ca5 + resolvedIdentifier: aef58e6d3ecff8ab73e92a6a0908159e2956eb91 extras: artifactId: kubernetes-model-certificates baseDep: @@ -1840,7 +1977,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 7d45968cf6b9902e37d5d542f42ee2daed203e3d + resolvedIdentifier: 5451f267796cd342bf5ce2306657eae6319e95fa extras: artifactId: kubernetes-model-common baseDep: @@ -1860,7 +1997,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: cd454532158351d8ff37616dc33749ca2a85c8d1 + resolvedIdentifier: b2e8564f0426ba14c96421c9bd611a47431d9618 extras: artifactId: kubernetes-model-coordination baseDep: @@ -1880,7 +2017,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 73469e4a7baec7600455d7f4a121c6680e80bf35 + resolvedIdentifier: 9dec469abc198daac6d9260fb432e711dc005655 extras: artifactId: kubernetes-model-core baseDep: @@ -1900,7 +2037,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 246ad448a1868b3c601394e21350a9602adef24c + resolvedIdentifier: b10bf58ec0ef527e8d5854b209f45917aa64e667 extras: artifactId: kubernetes-model-discovery baseDep: @@ -1920,7 +2057,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 204c2c78a4a8e0b5f5ebc1b788c9f22a8c1b14ab + resolvedIdentifier: ea54163696f03b5827d7dcf47a753b638a886b25 extras: artifactId: kubernetes-model-events baseDep: @@ -1940,7 +2077,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 60c9e43f1f34ab9c145798471926c07e13e45ecf + resolvedIdentifier: 22f366518f18974400a50a9b18d69d4481b97e2a extras: artifactId: kubernetes-model-extensions baseDep: @@ -1960,7 +2097,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 3b01d9eab7e7d7c9d46d8828202bff78fbdaa7d9 + resolvedIdentifier: a8cce874a1b32d283431966643fdfaa148ede743 extras: artifactId: kubernetes-model-flowcontrol baseDep: @@ -1980,7 +2117,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 1a400f8f7915bd2a68fa075605768d762aaad4cb + resolvedIdentifier: 7406edacfddc43e81fdca5f6b58f9cffcfd6208a extras: artifactId: kubernetes-model-metrics baseDep: @@ -2000,7 +2137,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: c87e11bebb26bb48660765b42a68f9577336b799 + resolvedIdentifier: 5abd2eb6209f3c8f27be9d9361f02609a51d8e4a extras: artifactId: kubernetes-model-networking baseDep: @@ -2020,7 +2157,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 972706f6dffa518e11c94647cf47e188db6115f6 + resolvedIdentifier: 29b29db3b39c5240b5eda0e6b2ef42e0254be90b extras: artifactId: kubernetes-model-node baseDep: @@ -2040,7 +2177,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 15b3011eb5ff48b9fc2bd8bcc4db697ca9ec30e4 + resolvedIdentifier: 2a846f217bd879ecee71c03615c2b714630dca4b extras: artifactId: kubernetes-model-policy baseDep: @@ -2060,7 +2197,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 03ad461761d775ff9c252d2b26a4977d22dd0f3a + resolvedIdentifier: 4d218bb7b4b1f6c76d8cfe4ef136813b73973833 extras: artifactId: kubernetes-model-rbac baseDep: @@ -2080,7 +2217,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: a5fae7294f5c39fb9d7cffb7280b55ca458c9128 + resolvedIdentifier: 4cca28ace5b98318415d7ffd75f707820d19bf20 extras: artifactId: kubernetes-model-scheduling baseDep: @@ -2100,7 +2237,7 @@ version: 6.0.0 type: compile indirect: true - resolvedIdentifier: 6ffa61f9021d07a4a9d785e83a513955a3c48073 + resolvedIdentifier: e944960ca3f380afaa39366f37145c5bb617e6ec extras: artifactId: kubernetes-model-storageclass baseDep: @@ -2120,7 +2257,7 @@ version: 0.3.0 type: compile indirect: true - resolvedIdentifier: d3ebf0f291297649b4c8dc3ecc81d2eddedc100d + resolvedIdentifier: 1385fb99630e407ae2821c9a16ccff56c879cdc9 extras: artifactId: zjsonpatch baseDep: @@ -2139,7 +2276,7 @@ - name: io.netty.netty-buffer version: 4.1.76.Final type: runtime - resolvedIdentifier: 231f5042a5050773eb22a918e84daff3f00892f2 + resolvedIdentifier: 453d1177e8b3194ef1111ad72d6d5a245c888975 extras: artifactId: netty-buffer groupId: io.netty @@ -2151,7 +2288,7 @@ - name: io.netty.netty-common version: 4.1.76.Final type: runtime - resolvedIdentifier: 38d0b500f098dc89497b6e608d7427186f533cf0 + resolvedIdentifier: 40049284125ae2450120801fe3df7f605ce29ee1 extras: artifactId: netty-common groupId: io.netty @@ -2164,7 +2301,7 @@ version: 4.1.76.Final type: runtime indirect: true - resolvedIdentifier: e0b225a33772cb7bba73dc296cccefa6826ab8cc + resolvedIdentifier: afc436aa5f9368bd10e1653a6531dfda0883fa5f extras: artifactId: netty-resolver baseDep: @@ -2183,7 +2320,7 @@ - name: io.netty.netty-transport version: 4.1.76.Final type: runtime - resolvedIdentifier: f01d2f935005b6fdb2fedc23114d2ae717749c36 + resolvedIdentifier: fb77aebb06acd640d8dc2c50dcc531c59c7e1696 extras: artifactId: netty-transport groupId: io.netty @@ -2195,7 +2332,7 @@ - name: io.netty.netty-transport-classes-epoll version: 4.1.76.Final type: runtime - resolvedIdentifier: 921b92a76116674218af3dc4bbf43d73884e4146 + resolvedIdentifier: e7b89664fddac0b494a8d3492ac532ccf8ed7c06 extras: artifactId: netty-transport-classes-epoll groupId: io.netty @@ -2220,7 +2357,7 @@ - name: io.netty.netty-transport-native-unix-common version: 4.1.76.Final type: runtime - resolvedIdentifier: d5ed8c4be9680203c53f7ed788225c12c4d87ee0 + resolvedIdentifier: 9c1755c00652bd1d568c49bae7c6da56f5dabac6 extras: artifactId: netty-transport-native-unix-common groupId: io.netty @@ -2233,7 +2370,7 @@ version: "1.1" type: provided indirect: true - resolvedIdentifier: e6cb541461c2834bdea3eb920f1884d1eb508b50 + resolvedIdentifier: fd9dd0faa8f03f3ce0dc4eec22e57e818d8b9897 extras: artifactId: activation baseDep: @@ -2252,7 +2389,7 @@ - name: javax.javaee-api version: "7.0" type: provided - resolvedIdentifier: 51399f902cc27a808122edcbebfaa1ad989954ba + resolvedIdentifier: e54c73cdc03722ed6c66d02cf27d10970ca0cec1 extras: artifactId: javaee-api groupId: javax @@ -2264,7 +2401,7 @@ - name: junit.junit version: "4.11" type: test - resolvedIdentifier: 4e031bb61df09069aeb2bffb4019e7a5034a4ee0 + resolvedIdentifier: cddf7490ffe839978cf5d6c944c01f2a8cb70a49 extras: artifactId: junit groupId: junit @@ -2277,7 +2414,7 @@ version: "1.3" type: test indirect: true - resolvedIdentifier: 42a25dc3219429f0e5d060061f71acb49bf010a0 + resolvedIdentifier: 872e413497b906e7c9fa85ccc96046c5d1ef7ece extras: artifactId: hamcrest-core baseDep: @@ -2297,7 +2434,7 @@ version: 1.7.36 type: compile indirect: true - resolvedIdentifier: 6c62681a2f655b49963a5983b8b0950a6120ae14 + resolvedIdentifier: 749f6995b1d6591a417ca4fd19cdbddabae16fd1 extras: artifactId: slf4j-api baseDep: @@ -2317,7 +2454,7 @@ version: "1.30" type: compile indirect: true - resolvedIdentifier: 8fde7fe2586328ac3c68db92045e1c8759125000 + resolvedIdentifier: 767ab0a7a346f60dad0acebe318e335a5d27fe55 extras: artifactId: snakeyaml baseDep: diff --git a/demo-output.yaml b/demo-output.yaml index b3d8f59f..59decc61 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -354,6 +354,30 @@ variables: name: sigs.k8s.io/structured-merge-diff/v4 version: v4.2.1 + java-gradle-project: + description: | + This rule looks for a class only present in the gradle project + category: mandatory + incidents: + - uri: file:///examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java + message: Only incidents in gradle project should appear + codeSnip: " 1 package io.jeffchao.template.server;\n 2 \n 3 import java.io.IOException;\n 4 import java.io.OutputStream;\n 5 import java.net.InetSocketAddress;\n 6 \n 7 import com.sun.net.httpserver.HttpExchange;\n 8 import com.sun.net.httpserver.HttpHandler;\n 9 import com.sun.net.httpserver.HttpServer;\n10 \n11 public class Server {\n12 \n13 public static void main(String[] args) throws IOException {\n14 String portString = System.getenv(\"PORT\");\n15 int port = portString == null ? 8080 : Integer.valueOf(portString);\n16 HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);\n17 server.createContext(\"/\", new MyHandler());" + lineNumber: 7 + variables: + file: file:///examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java + kind: Module + name: com.sun.net.httpserver.HttpExchange + package: io.jeffchao.template.server + - uri: file:///examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java + message: Only incidents in gradle project should appear + codeSnip: "14 String portString = System.getenv(\"PORT\");\n15 int port = portString == null ? 8080 : Integer.valueOf(portString);\n16 HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);\n17 server.createContext(\"/\", new MyHandler());\n18 server.setExecutor(null); // creates a default executor\n19 server.start();\n20 }\n21 \n22 static class MyHandler implements HttpHandler {\n23 @Override\n24 public void handle(HttpExchange t) throws IOException {\n25 String response = \"Hello from Gradle!\";\n26 t.sendResponseHeaders(200, response.length());\n27 OutputStream os = t.getResponseBody();\n28 os.write(response.getBytes());\n29 os.close();\n30 }\n31 }\n32 }\n" + lineNumber: 24 + variables: + file: file:///examples/gradle-multi-project-example/template-server/src/main/java/io/jeffchao/template/server/Server.java + kind: Method + name: handle + package: io.jeffchao.template.server + effort: 3 java-inclusion-test: description: "This rule tests includedPaths config of the java provider. There should be two instances of this issue in the example app. \nWe are filtering one of them using includedPaths in provider config.\n" category: mandatory @@ -381,13 +405,24 @@ description: "" category: potential incidents: + - uri: file:///examples/gradle-multi-project-example/build.gradle + message: dependency junit.junit with 4.12 is bad and you should feel bad for using it + codeSnip: " 1 apply plugin: 'idea'\n 2 \n 3 ext {\n 4 log4jVersion = '2.9.1'\n 5 }\n 6 \n 7 buildscript {\n 8 repositories {\n 9 jcenter()\n10 }\n11 dependencies {" + lineNumber: 0 + variables: + name: junit.junit + version: "4.12" - uri: file:///examples/java/pom.xml message: dependency io.fabric8.kubernetes-client with 6.0.0 is bad and you should feel bad for using it + codeSnip: "26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8\n41 kubernetes-client-api\n42 6.0.0\n43 \n44 \n45 javax\n46 javaee-api" + lineNumber: 35 variables: name: io.fabric8.kubernetes-client version: 6.0.0 - uri: file:///examples/java/pom.xml message: dependency junit.junit with 4.11 is bad and you should feel bad for using it + codeSnip: "20 \n21 UTF-8\n22 1.7\n23 1.7\n24 7.0\n25 \n26 \n27 \n28 \n29 junit\n30 junit\n31 4.11\n32 test\n33 \n34 \n35 io.fabric8\n36 kubernetes-client\n37 6.0.0\n38 \n39 \n40 io.fabric8" + lineNumber: 29 variables: name: junit.junit version: "4.11" @@ -499,6 +534,29 @@ incidents: - uri: file:///examples/java/pom.xml message: If you migrate your application to JBoss EAP 7.3, or later, and want to ensure its Maven building, running or testing works as expected, use instead the Jakarta EE dependency with groupId `com.sun.activation` + codeSnip: |- + 36 kubernetes-client + 37 6.0.0 + 38 + 39 + 40 io.fabric8 + 41 kubernetes-client-api + 42 6.0.0 + 43 + 44 + 45 javax + 46 javaee-api + 47 ${javaee-api.version} + 48 provided + 49 + 50 + 51 + 52 io.netty + 53 netty-transport-native-epoll + 54 4.1.76.Final + 55 linux-x86_64 + 56 runtime + lineNumber: 45 variables: name: javax.activation.activation version: "1.1" @@ -555,15 +613,6 @@ kind: Class name: Singleton package: com.example.apps - - uri: file:///examples/java/example/src/main/java/com/example/apps/Bean.java - message: condition entries should evaluate out of order - codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n" - lineNumber: 7 - variables: - file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java - kind: Class - name: Bean - package: com.example.apps singleton-sessionbean-00002: description: "" category: potential @@ -577,15 +626,6 @@ kind: Class name: Singleton package: com.example.apps - - uri: file:///examples/java/example/src/main/java/com/example/apps/Bean.java - message: condition entries should evaluate in order - codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n" - lineNumber: 7 - variables: - file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java - kind: Class - name: Bean - package: com.example.apps tech-tag-001: description: "" category: potential diff --git a/rule-example.yaml b/rule-example.yaml index 4d614909..929d10ff 100644 --- a/rule-example.yaml +++ b/rule-example.yaml @@ -291,4 +291,12 @@ pattern: inclusion-test.xml - builtin.filecontent: pattern: "" - \ No newline at end of file +- category: mandatory + description: | + This rule looks for a class only present in the gradle project + effort: 3 + message: Only incidents in gradle project should appear + ruleID: java-gradle-project + when: + java.referenced: + pattern: com.sun.net.httpserver.HttpExchange From 83241a731319f81df3133af8331951489dbacfb3 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 23 May 2024 12:59:23 +0200 Subject: [PATCH 11/17] Fix dockerfiles Signed-off-by: Juan Manuel Leflet Estrada --- Dockerfile | 2 +- external-providers/java-external-provider/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 43ef3d1a..78ee77c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ RUN wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_B FROM jaegertracing/all-in-one:latest AS jaeger-builder -FROM bundle +FROM quay.io/konveyor/jdtls-server-base:latest RUN microdnf install gcc-c++ python-devel python3-devel -y RUN python3 -m ensurepip --upgrade diff --git a/external-providers/java-external-provider/Dockerfile b/external-providers/java-external-provider/Dockerfile index 2e2a5b19..9bc9ccc4 100644 --- a/external-providers/java-external-provider/Dockerfile +++ b/external-providers/java-external-provider/Dockerfile @@ -18,7 +18,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags="all=-N -l" -a -o ja RUN go install github.com/go-delve/delve/cmd/dlv@latest -FROM bundle +FROM quay.io/konveyor/jdtls-server-base:latest COPY --from=builder /java-provider/java-external-provider /usr/local/bin/java-external-provider COPY --from=builder /go/bin/dlv /usr/local/bin/dlv From f2c6ea31beeb4a87e6cd5c4f63cb64d26c99aa28 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 23 May 2024 13:50:43 +0200 Subject: [PATCH 12/17] Remove latest from bundle Signed-off-by: Juan Manuel Leflet Estrada --- Dockerfile | 2 +- external-providers/java-external-provider/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 78ee77c3..8bfaa2de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ RUN wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_B FROM jaegertracing/all-in-one:latest AS jaeger-builder -FROM quay.io/konveyor/jdtls-server-base:latest +FROM quay.io/konveyor/jdtls-server-base RUN microdnf install gcc-c++ python-devel python3-devel -y RUN python3 -m ensurepip --upgrade diff --git a/external-providers/java-external-provider/Dockerfile b/external-providers/java-external-provider/Dockerfile index 9bc9ccc4..51637cbb 100644 --- a/external-providers/java-external-provider/Dockerfile +++ b/external-providers/java-external-provider/Dockerfile @@ -18,7 +18,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags="all=-N -l" -a -o ja RUN go install github.com/go-delve/delve/cmd/dlv@latest -FROM quay.io/konveyor/jdtls-server-base:latest +FROM quay.io/konveyor/jdtls-server-base COPY --from=builder /java-provider/java-external-provider /usr/local/bin/java-external-provider COPY --from=builder /go/bin/dlv /usr/local/bin/dlv From 7fc2e1de67249109714ed375ac6f7a7006fb62b4 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 23 May 2024 14:11:14 +0200 Subject: [PATCH 13/17] Fix demo dockerfile Signed-off-by: Juan Manuel Leflet Estrada --- demo.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo.Dockerfile b/demo.Dockerfile index 53fcdaf1..ee8a7050 100644 --- a/demo.Dockerfile +++ b/demo.Dockerfile @@ -1,4 +1,4 @@ -FROM analyzer +FROM quay.io/konveyor/analyzer-lsp WORKDIR /analyzer-lsp From 159bd2a9004ebf9c571cf9bc48d62c82876f6ba2 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 23 May 2024 14:34:37 +0200 Subject: [PATCH 14/17] Remove debug.Dockerfile Signed-off-by: Juan Manuel Leflet Estrada --- debug.Dockerfile | 69 ------------------------------------------------ 1 file changed, 69 deletions(-) delete mode 100644 debug.Dockerfile diff --git a/debug.Dockerfile b/debug.Dockerfile deleted file mode 100644 index d9b20346..00000000 --- a/debug.Dockerfile +++ /dev/null @@ -1,69 +0,0 @@ -FROM golang:1.19 as builder -WORKDIR /analyzer-lsp - -COPY cmd /analyzer-lsp/cmd -COPY engine /analyzer-lsp/engine -COPY event /analyzer-lsp/event -COPY output /analyzer-lsp/output -COPY jsonrpc2 /analyzer-lsp/jsonrpc2 -COPY jsonrpc2_v2 /analyzer-lsp/jsonrpc2_v2 -COPY lsp /analyzer-lsp/lsp -COPY parser /analyzer-lsp/parser -COPY provider /analyzer-lsp/provider -COPY tracing /analyzer-lsp/tracing -COPY external-providers /analyzer-lsp/external-providers -COPY go.mod /analyzer-lsp/go.mod -COPY go.sum /analyzer-lsp/go.sum -COPY Makefile /analyzer-lsp/Makefile - -RUN go install github.com/go-delve/delve/cmd/dlv@latest - -RUN go build -gcflags="all=-N -l" -o konveyor-analyzer ./cmd/analyzer/main.go -RUN go build -gcflags="all=-N -l" -o konveyor-analyzer-dep ./cmd/dep/main.go -RUN cd external-providers/generic-external-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o generic-external-provider main.go -RUN cd external-providers/golang-dependency-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o golang-dependency-provider main.go -RUN cd external-providers/yq-external-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o yq-external-provider main.go -RUN cd external-providers/java-external-provider && go mod edit -replace=github.com/konveyor/analyzer-lsp=../../ && go mod tidy && go build -gcflags="all=-N -l" -o java-external-provider main.go - - -FROM registry.access.redhat.com/ubi9/ubi-minimal:latest as yq-builder -RUN microdnf install -y wget tar xz gzip && \ - microdnf clean all -ARG TARGETARCH -ARG YQ_VERSION="v4.40.5" -ARG YQ_BINARY="yq_linux_${TARGETARCH}" -RUN wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_BINARY}.tar.gz" -O - | tar xz && \ - mv ${YQ_BINARY} /usr/bin/yq - -FROM jaegertracing/all-in-one:latest AS jaeger-builder - -FROM quay.io/konveyor/jdtls-server-base - -RUN microdnf install gcc-c++ python-devel python3-devel -y -RUN python3 -m ensurepip --upgrade -RUN python3 -m pip install 'python-lsp-server>=1.8.2' - -ENV NODEJS_VERSION=18 -RUN echo -e "[nodejs]\nname=nodejs\nstream=${NODEJS_VERSION}\nprofiles=\nstate=enabled\n" > /etc/dnf/modules.d/nodejs.module -RUN microdnf install nodejs -y -RUN npm install -g typescript-language-server typescript - -COPY --from=jaeger-builder /go/bin/all-in-one-linux /usr/local/bin/all-in-one-linux -COPY --from=yq-builder /usr/bin/yq /usr/local/bin/yq -COPY --from=builder /analyzer-lsp/konveyor-analyzer /usr/local/bin/konveyor-analyzer -COPY --from=builder /analyzer-lsp/konveyor-analyzer-dep /usr/local/bin/konveyor-analyzer-dep -COPY --from=builder /analyzer-lsp/external-providers/generic-external-provider/generic-external-provider /usr/local/bin/generic-external-provider -COPY --from=builder /analyzer-lsp/external-providers/yq-external-provider/yq-external-provider /usr/local/bin/yq-external-provider -COPY --from=builder /analyzer-lsp/external-providers/golang-dependency-provider/golang-dependency-provider /usr/local/bin/golang-dependency-provider -COPY --from=builder /analyzer-lsp/external-providers/java-external-provider/java-external-provider /usr/local/bin/java-external-provider - -COPY --from=builder /go/bin/dlv / - -COPY provider_container_settings.json /analyzer-lsp/provider_settings.json - -WORKDIR /analyzer-lsp - -EXPOSE 16686 40000 - -ENTRYPOINT ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec"] -CMD ["/usr/local/bin/konveyor-analyzer"] From 688c8360fedb051a0016a6a2bdb05d3b478f5db8 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Thu, 23 May 2024 14:36:24 +0200 Subject: [PATCH 15/17] Fix java provider dockerfile Signed-off-by: Juan Manuel Leflet Estrada --- external-providers/java-external-provider/Dockerfile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/external-providers/java-external-provider/Dockerfile b/external-providers/java-external-provider/Dockerfile index 51637cbb..a9b27b51 100644 --- a/external-providers/java-external-provider/Dockerfile +++ b/external-providers/java-external-provider/Dockerfile @@ -14,16 +14,12 @@ COPY external-providers/java-external-provider/pkg/ pkg/ RUN go mod edit -replace=github.com/konveyor/analyzer-lsp=/analyzer-lsp && go mod tidy -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags="all=-N -l" -a -o java-external-provider main.go - -RUN go install github.com/go-delve/delve/cmd/dlv@latest +RUN go build -a -o java-external-provider main.go FROM quay.io/konveyor/jdtls-server-base COPY --from=builder /java-provider/java-external-provider /usr/local/bin/java-external-provider -COPY --from=builder /go/bin/dlv /usr/local/bin/dlv -EXPOSE 14651 40000 +EXPOSE 14651 -ENTRYPOINT ["/usr/local/bin/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec"] -CMD ["--", "/usr/local/bin/java-external-provider", "--port", "14651"] +ENTRYPOINT ["java-external-provider", "--port", "14651"] \ No newline at end of file From dd4435230fd88884afcb21c737c6b9e4db070f99 Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Mon, 27 May 2024 16:47:00 +0200 Subject: [PATCH 16/17] Change example gradle project name Signed-off-by: Juan Manuel Leflet Estrada --- .../examples/gradle-multi-project-example/settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle b/external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle index ace373a1..9c10890a 100644 --- a/external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle +++ b/external-providers/java-external-provider/examples/gradle-multi-project-example/settings.gradle @@ -1,4 +1,4 @@ -rootProject.name = 'basic-gradle-template' +rootProject.name = 'gradle-multi-project-example' include 'template-core' include 'template-server' From 422a5fafd4135f55165b207616c16497dbe1cafa Mon Sep 17 00:00:00 2001 From: Juan Manuel Leflet Estrada Date: Fri, 31 May 2024 09:59:32 +0200 Subject: [PATCH 17/17] Fix gradle tests Signed-off-by: Juan Manuel Leflet Estrada --- demo-dep-output.yaml | 3 +++ demo-output.yaml | 29 +++++++++++++++++++---------- provider_container_settings.json | 2 +- provider_local_external_images.json | 10 ++++++++++ provider_pod_local_settings.json | 10 ++++++++++ 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/demo-dep-output.yaml b/demo-dep-output.yaml index c96fa8bb..656f10dd 100644 --- a/demo-dep-output.yaml +++ b/demo-dep-output.yaml @@ -1626,6 +1626,9 @@ - name: xml-apis.xml-apis version: 1.0.b2 indirect: true +- fileURI: file:///analyzer-lsp/examples/inclusion-tests/pom.xml + provider: java + dependencies: [] - fileURI: file:///analyzer-lsp/examples/java/pom.xml provider: java dependencies: diff --git a/demo-output.yaml b/demo-output.yaml index 59decc61..80c1a0db 100644 --- a/demo-output.yaml +++ b/demo-output.yaml @@ -590,16 +590,6 @@ lineNumber: 6 variables: file: file:///examples/python/file_a.py - python-sample-rule-003: - description: "" - category: potential - incidents: - - uri: file:///examples/python/main.py - message: python sample rule 003 - codeSnip: "19 # Create an instance of the API class\n20 api_instance = kubernetes.client.ApiextensionsV1Api(api_client)\n21 body = kubernetes.client.V1CustomResourceDefinition() # V1CustomResourceDefinition | \n22 pretty = 'pretty_example' # str | If 'true', then the output is pretty printed. (optional)\n23 dry_run = 'dry_run_example' # str | When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed (optional)\n24 field_manager = 'field_manager_example' # str | fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. (optional)\n25 field_validation = 'field_validation_example' # str | fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. (optional)\n26 \n27 try:\n28 api_response = api_instance.create_custom_resource_definition(body, pretty=pretty, dry_run=dry_run, field_manager=field_manager, field_validation=field_validation)\n29 pprint(api_response)\n30 except ApiException as e:\n31 print(\"Exception when calling ApiextensionsV1Api->create_custom_resource_definition: %s\\n\" % e)\n" - lineNumber: 28 - variables: - file: file:///examples/python/main.py singleton-sessionbean-00001: description: "" category: potential @@ -613,6 +603,15 @@ kind: Class name: Singleton package: com.example.apps + - uri: file:///examples/java/example/src/main/java/com/example/apps/Bean.java + message: condition entries should evaluate out of order + codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n" + lineNumber: 7 + variables: + file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java + kind: Class + name: Bean + package: com.example.apps singleton-sessionbean-00002: description: "" category: potential @@ -626,6 +625,15 @@ kind: Class name: Singleton package: com.example.apps + - uri: file:///examples/java/example/src/main/java/com/example/apps/Bean.java + message: condition entries should evaluate in order + codeSnip: " 1 package com.example.apps;\n 2 \n 3 import javax.ejb.SessionBean;\n 4 import javax.ejb.Singleton;\n 5 \n 6 @Singleton\n 7 public abstract class Bean implements SessionBean {\n 8 \n 9 }\n" + lineNumber: 7 + variables: + file: file:///examples/java/example/src/main/java/com/example/apps/Bean.java + kind: Class + name: Bean + package: com.example.apps tech-tag-001: description: "" category: potential @@ -903,3 +911,4 @@ unmatched: - file-002 - lang-ref-002 + - python-sample-rule-003 diff --git a/provider_container_settings.json b/provider_container_settings.json index c8e9bea5..56c63780 100644 --- a/provider_container_settings.json +++ b/provider_container_settings.json @@ -103,7 +103,7 @@ "analysisMode": "source-only" }, { - "location": "examples/gradle-multi-project-example", + "location": "/analyzer-lsp/examples/gradle-multi-project-example", "providerSpecificConfig": { "lspServerName": "java", "lspServerPath": "/jdtls/bin/jdtls", diff --git a/provider_local_external_images.json b/provider_local_external_images.json index e21c2f92..92a5129c 100644 --- a/provider_local_external_images.json +++ b/provider_local_external_images.json @@ -101,6 +101,16 @@ "bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar" }, "analysisMode": "source-only" + }, + { + "location": "examples/gradle-multi-project-example", + "providerSpecificConfig": { + "lspServerName": "java", + "lspServerPath": "/jdtls/bin/jdtls", + "depOpenSourceLabelsFile": "/usr/local/etc/maven.default.index", + "bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar" + }, + "analysisMode": "source-only" } ] }, diff --git a/provider_pod_local_settings.json b/provider_pod_local_settings.json index d62198a4..141257da 100644 --- a/provider_pod_local_settings.json +++ b/provider_pod_local_settings.json @@ -101,6 +101,16 @@ "bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar" }, "analysisMode": "source-only" + }, + { + "location": "/analyzer-lsp/examples/gradle-multi-project-example", + "providerSpecificConfig": { + "lspServerName": "java", + "lspServerPath": "/jdtls/bin/jdtls", + "depOpenSourceLabelsFile": "/usr/local/etc/maven.default.index", + "bundles": "/jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/java-analyzer-bundle.core-1.0.0-SNAPSHOT.jar" + }, + "analysisMode": "source-only" } ] },