diff --git a/pom.xml b/pom.xml index c95010b7c..58d2de546 100644 --- a/pom.xml +++ b/pom.xml @@ -120,6 +120,11 @@ maven-model 3.9.9 + + dev.gradleplugins + gradle-api + 7.6 + org.tomlj tomlj diff --git a/src/main/java/com/ibm/usecases/scanning/processmanager/ScanProcessManager.java b/src/main/java/com/ibm/usecases/scanning/processmanager/ScanProcessManager.java index 8ac04ddf7..d3656e39e 100644 --- a/src/main/java/com/ibm/usecases/scanning/processmanager/ScanProcessManager.java +++ b/src/main/java/com/ibm/usecases/scanning/processmanager/ScanProcessManager.java @@ -59,9 +59,10 @@ import com.ibm.usecases.scanning.services.indexing.JavaIndexService; import com.ibm.usecases.scanning.services.indexing.ProjectModule; import com.ibm.usecases.scanning.services.indexing.PythonIndexService; -import com.ibm.usecases.scanning.services.pkg.JavaPackageFinderService; -import com.ibm.usecases.scanning.services.pkg.PythonPackageFinderService; +import com.ibm.usecases.scanning.services.pkg.GradlePackageFinderService; +import com.ibm.usecases.scanning.services.pkg.MavenPackageFinderService; import com.ibm.usecases.scanning.services.pkg.SetupPackageFinderService; +import com.ibm.usecases.scanning.services.pkg.TomlPackageFinderService; import com.ibm.usecases.scanning.services.scan.ScanResultDTO; import com.ibm.usecases.scanning.services.scan.java.JavaScannerService; import com.ibm.usecases.scanning.services.scan.python.PythonScannerService; @@ -224,13 +225,13 @@ private void handleSetPackageFolderCommand(@Nonnull IdentifyPackageFolderCommand final PackageURL purl = optionalPackageURL.get(); Optional packagePath = Optional.empty(); - // java if (purl.getType().equals("maven")) { - packagePath = new JavaPackageFinderService(dir).findPackage(purl); - // TODO: find gradle package - // python + packagePath = new MavenPackageFinderService(dir).findPackage(purl); + if (packagePath.isEmpty()) { + packagePath = new GradlePackageFinderService(dir).findPackage(purl); + } } else if (purl.getType().equals("pypi")) { - packagePath = new PythonPackageFinderService(dir).findPackage(purl); + packagePath = new TomlPackageFinderService(dir).findPackage(purl); if (packagePath.isEmpty()) { packagePath = new SetupPackageFinderService(dir).findPackage(purl); } diff --git a/src/main/java/com/ibm/usecases/scanning/services/pkg/GradlePackageFinderService.java b/src/main/java/com/ibm/usecases/scanning/services/pkg/GradlePackageFinderService.java new file mode 100644 index 000000000..8d6f0d5fd --- /dev/null +++ b/src/main/java/com/ibm/usecases/scanning/services/pkg/GradlePackageFinderService.java @@ -0,0 +1,67 @@ +/* + * CBOMkit + * Copyright (C) 2025 IBM + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ibm.usecases.scanning.services.pkg; + +import jakarta.annotation.Nonnull; +import java.io.File; +import java.nio.file.Path; +import java.util.Optional; +import org.gradle.api.Project; +import org.gradle.api.publish.PublishingExtension; +import org.gradle.api.publish.maven.MavenPublication; +import org.gradle.tooling.GradleConnector; +import org.gradle.tooling.ProjectConnection; + +public class GradlePackageFinderService extends PackageFinderService { + public GradlePackageFinderService(@Nonnull File rootFile) throws IllegalArgumentException { + super(rootFile); + } + + @Override + public boolean isBuildFile(@Nonnull Path file) { + return file.endsWith("build.gradle") || file.endsWith("build.gradle.kts"); + } + + @Override + public Optional getPackageName(@Nonnull Path buildFile) throws Exception { + try (ProjectConnection connection = + GradleConnector.newConnector() + .forProjectDirectory(buildFile.toFile().getParentFile()) + .connect()) { + + Project project = connection.getModel(Project.class); + PublishingExtension publishing = + project.getExtensions().findByType(PublishingExtension.class); + + if (publishing != null) { + String projectName = + publishing.getPublications().withType(MavenPublication.class).stream() + .findFirst() + .map(MavenPublication::getArtifactId) + .orElse(project.getName()); + return Optional.ofNullable(projectName); + } + + return Optional.ofNullable(project.getName()); + } catch (RuntimeException rte) { + throw new Exception(rte); + } + } +} diff --git a/src/main/java/com/ibm/usecases/scanning/services/pkg/JavaPackageFinderService.java b/src/main/java/com/ibm/usecases/scanning/services/pkg/MavenPackageFinderService.java similarity index 73% rename from src/main/java/com/ibm/usecases/scanning/services/pkg/JavaPackageFinderService.java rename to src/main/java/com/ibm/usecases/scanning/services/pkg/MavenPackageFinderService.java index db09ece93..f9006e66e 100644 --- a/src/main/java/com/ibm/usecases/scanning/services/pkg/JavaPackageFinderService.java +++ b/src/main/java/com/ibm/usecases/scanning/services/pkg/MavenPackageFinderService.java @@ -22,17 +22,15 @@ import jakarta.annotation.Nonnull; import java.io.File; import java.io.FileReader; -import java.io.IOException; import java.nio.file.Path; import java.util.Optional; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -public class JavaPackageFinderService extends PackageFinderService { +public class MavenPackageFinderService extends PackageFinderService { @Nonnull private final MavenXpp3Reader reader; - public JavaPackageFinderService(@Nonnull File rootFile) throws IllegalArgumentException { + public MavenPackageFinderService(@Nonnull File rootFile) throws IllegalArgumentException { super(rootFile); this.reader = new MavenXpp3Reader(); } @@ -43,12 +41,8 @@ public boolean isBuildFile(@Nonnull Path file) { } @Override - public Optional getPackageName(@Nonnull Path buildFile) { - try { - final Model model = reader.read(new FileReader(buildFile.toFile())); - return Optional.ofNullable(model.getArtifactId()); - } catch (IOException | XmlPullParserException e) { - return Optional.empty(); - } + public Optional getPackageName(@Nonnull Path buildFile) throws Exception { + final Model model = reader.read(new FileReader(buildFile.toFile())); + return Optional.ofNullable(model.getArtifactId()); } } diff --git a/src/main/java/com/ibm/usecases/scanning/services/pkg/PackageFinderService.java b/src/main/java/com/ibm/usecases/scanning/services/pkg/PackageFinderService.java index 58f1993b7..12792ead1 100644 --- a/src/main/java/com/ibm/usecases/scanning/services/pkg/PackageFinderService.java +++ b/src/main/java/com/ibm/usecases/scanning/services/pkg/PackageFinderService.java @@ -22,7 +22,6 @@ import com.github.packageurl.PackageURL; import jakarta.annotation.Nonnull; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -46,7 +45,7 @@ protected PackageFinderService(@Nonnull File rootFile) throws IllegalArgumentExc @Nonnull public Optional findPackage(@Nonnull PackageURL purl) { - LOGGER.info("Trying to find package folder for purl {} in gir repository", purl); + LOGGER.info("Searching package folder for purl {}", purl); try (Stream walk = Files.walk(this.root)) { final List poms = walk.filter(p -> !Files.isDirectory(p)).filter(this::isBuildFile).toList(); @@ -67,15 +66,13 @@ public Optional findPackage(@Nonnull PackageURL purl) { pkgPath.equals(Paths.get("")) ? "" : pkgPath); return Optional.of(pkgPath); } - } catch (IOException e) { - LOGGER.warn("Package folder not found"); - return Optional.empty(); + } catch (Exception e) { + LOGGER.error("Failed to find package folder: " + e.getLocalizedMessage()); } - LOGGER.warn("Package folder not found"); return Optional.empty(); } public abstract boolean isBuildFile(@Nonnull Path file); - public abstract Optional getPackageName(@Nonnull Path buildFile); + public abstract Optional getPackageName(@Nonnull Path buildFile) throws Exception; } diff --git a/src/main/java/com/ibm/usecases/scanning/services/pkg/SetupPackageFinderService.java b/src/main/java/com/ibm/usecases/scanning/services/pkg/SetupPackageFinderService.java index e45e54711..bc0e76897 100644 --- a/src/main/java/com/ibm/usecases/scanning/services/pkg/SetupPackageFinderService.java +++ b/src/main/java/com/ibm/usecases/scanning/services/pkg/SetupPackageFinderService.java @@ -54,7 +54,7 @@ public Optional getPackageName(@Nonnull Path buildFile) { } @Nonnull - private Optional findPackageNameUsingRegex(@Nonnull Path buildFile) { + private Optional findPackageNameUsingRegex(@Nonnull Path buildFile) throws Exception { try (BufferedReader reader = new BufferedReader(new FileReader(buildFile.toFile()))) { final Pattern pattern = Pattern.compile("name\\s*=\\s*['\"]([^'\"]*)['\"]"); String line; @@ -65,8 +65,6 @@ private Optional findPackageNameUsingRegex(@Nonnull Path buildFile) { return Optional.ofNullable(matcher.group(1)); } } - } catch (Exception e) { - return Optional.empty(); } return Optional.empty(); } diff --git a/src/main/java/com/ibm/usecases/scanning/services/pkg/PythonPackageFinderService.java b/src/main/java/com/ibm/usecases/scanning/services/pkg/TomlPackageFinderService.java similarity index 75% rename from src/main/java/com/ibm/usecases/scanning/services/pkg/PythonPackageFinderService.java rename to src/main/java/com/ibm/usecases/scanning/services/pkg/TomlPackageFinderService.java index b74cc5183..7e5068392 100644 --- a/src/main/java/com/ibm/usecases/scanning/services/pkg/PythonPackageFinderService.java +++ b/src/main/java/com/ibm/usecases/scanning/services/pkg/TomlPackageFinderService.java @@ -21,15 +21,14 @@ import jakarta.annotation.Nonnull; import java.io.File; -import java.io.IOException; import java.nio.file.Path; import java.util.Optional; import org.tomlj.Toml; import org.tomlj.TomlParseResult; -public class PythonPackageFinderService extends PackageFinderService { +public class TomlPackageFinderService extends PackageFinderService { - public PythonPackageFinderService(@Nonnull File rootFile) throws IllegalArgumentException { + public TomlPackageFinderService(@Nonnull File rootFile) throws IllegalArgumentException { super(rootFile); } @@ -39,12 +38,8 @@ public boolean isBuildFile(@Nonnull Path file) { } @Override - public Optional getPackageName(@Nonnull Path buildFile) { - try { - TomlParseResult result = Toml.parse(buildFile); - return Optional.ofNullable(result.getString(("project.name"))); - } catch (IOException e) { - return Optional.empty(); - } + public Optional getPackageName(@Nonnull Path buildFile) throws Exception { + TomlParseResult result = Toml.parse(buildFile); + return Optional.ofNullable(result.getString("project.name")); } }