From 56a20f12927537e7ae8a19e62023ff080f349761 Mon Sep 17 00:00:00 2001 From: Olga Lavtar Date: Wed, 27 Mar 2024 10:53:47 -0700 Subject: [PATCH] feat: added support for gradle Signed-off-by: Olga Lavtar --- .../exhort/providers/GradleProvider.java | 4 +- .../providers/Gradle_Provider_Test.java | 32 +++-- .../expected_stack_sbom.json | 4 +- .../gradle.properties | 123 ++++++++++++++++++ 4 files changed, 149 insertions(+), 14 deletions(-) create mode 100644 src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/gradle.properties diff --git a/src/main/java/com/redhat/exhort/providers/GradleProvider.java b/src/main/java/com/redhat/exhort/providers/GradleProvider.java index ccbf4482..aa456ee0 100644 --- a/src/main/java/com/redhat/exhort/providers/GradleProvider.java +++ b/src/main/java/com/redhat/exhort/providers/GradleProvider.java @@ -69,7 +69,7 @@ private static Path getDependencies(Path manifestPath) throws IOException { String gradleCommand = gradle + " dependencies"; String[] cmdList = gradleCommand.split("\\s+"); - String gradleOutput = Operations.runProcessGetOutput(Path.of(manifestPath.getParent().toString()), cmdList, null); + String gradleOutput = Operations.runProcessGetOutput(Path.of(manifestPath.getParent().toString()), cmdList); Files.writeString(tempFile, gradleOutput); return tempFile; @@ -80,7 +80,7 @@ private Path getProperties(Path manifestPath) throws IOException { var gradle = Operations.getCustomPathOrElse("gradle"); String propCmd = gradle + " properties"; String[] propCmdList = propCmd.split("\\s+"); - String properties = Operations.runProcessGetOutput(Path.of(manifestPath.getParent().toString()), propCmdList, null); + String properties = Operations.runProcessGetOutput(Path.of(manifestPath.getParent().toString()), propCmdList); // Create a temporary file Files.writeString(propsTempFile, properties); diff --git a/src/test/java/com/redhat/exhort/providers/Gradle_Provider_Test.java b/src/test/java/com/redhat/exhort/providers/Gradle_Provider_Test.java index 366eb524..c2ac2b1a 100644 --- a/src/test/java/com/redhat/exhort/providers/Gradle_Provider_Test.java +++ b/src/test/java/com/redhat/exhort/providers/Gradle_Provider_Test.java @@ -82,10 +82,18 @@ void test_the_provideStack(String testFolder) throws IOException, InterruptedExc try (var is = getClass().getClassLoader().getResourceAsStream(String.join("/","tst_manifests", "gradle", testFolder, "depTree.txt"))) { depTree = new String(is.readAllBytes()); } + String gradleProperties; + try (var is = getClass().getClassLoader().getResourceAsStream(String.join("/","tst_manifests", "gradle", testFolder, "gradle.properties"))) { + gradleProperties = new String(is.readAllBytes()); + } - MockedStatic mockedOperations = mockStatic(Operations.class, Mockito.CALLS_REAL_METHODS); - ArgumentMatcher matchPath = path -> path == null; - mockedOperations.when(() -> Operations.runProcessGetOutput(argThat(matchPath),any(String[].class), any(String[].class))).thenReturn(depTree); + MockedStatic mockedOperations = mockStatic(Operations.class); + ArgumentMatcher gradle = string -> string.equals("gradle"); + ArgumentMatcher dependencies = string -> string.equals("dependencies"); + ArgumentMatcher properties = string -> string.equals("properties"); + mockedOperations.when(() -> Operations.getCustomPathOrElse("gradle")).thenReturn("gradle"); + mockedOperations.when(() -> Operations.runProcessGetOutput(any(Path.class), argThat(gradle),argThat(dependencies))).thenReturn(depTree); + mockedOperations.when(() -> Operations.runProcessGetOutput(any(Path.class), argThat(gradle), argThat(properties))).thenReturn(gradleProperties); // when providing stack content for our pom var content = new GradleProvider().provideStack(tmpGradleFile); @@ -117,8 +125,6 @@ void test_the_provideComponent(String testFolder) throws IOException, Interrupte @ParameterizedTest @MethodSource("testFolders") void test_the_provideComponent_With_Path(String testFolder) throws IOException, InterruptedException { - System.setProperty("EXHORT_GRADLE_PATH", "/opt/homebrew/bin/gradle"); - // create temp file hosting our sut build.gradle var tmpGradleDir = Files.createTempDirectory("exhort_test_"); var tmpGradleFile = Files.createFile(tmpGradleDir.resolve("build.gradle")); @@ -144,11 +150,18 @@ void test_the_provideComponent_With_Path(String testFolder) throws IOException, try (var is = getClass().getClassLoader().getResourceAsStream(String.join("/","tst_manifests", "gradle", testFolder, "depTree.txt"))) { depTree = new String(is.readAllBytes()); } + String gradleProperties; + try (var is = getClass().getClassLoader().getResourceAsStream(String.join("/","tst_manifests", "gradle", testFolder, "gradle.properties"))) { + gradleProperties = new String(is.readAllBytes()); + } - MockedStatic mockedOperations = mockStatic(Operations.class, Mockito.CALLS_REAL_METHODS); - ArgumentMatcher matchPath = path -> path == null; - mockedOperations.when(() -> Operations.runProcessGetOutput(argThat(matchPath),any(String[].class), any(String[].class))).thenReturn(depTree); - + MockedStatic mockedOperations = mockStatic(Operations.class); + ArgumentMatcher gradle = string -> string.equals("gradle"); + ArgumentMatcher dependencies = string -> string.equals("dependencies"); + ArgumentMatcher properties = string -> string.equals("properties"); + mockedOperations.when(() -> Operations.getCustomPathOrElse("gradle")).thenReturn("gradle"); + mockedOperations.when(() -> Operations.runProcessGetOutput(any(Path.class), argThat(gradle),argThat(dependencies))).thenReturn(depTree); + mockedOperations.when(() -> Operations.runProcessGetOutput(any(Path.class), argThat(gradle), argThat(properties))).thenReturn(gradleProperties); // when providing component content for our pom var content = new GradleProvider().provideComponent(tmpGradleFile); @@ -159,7 +172,6 @@ void test_the_provideComponent_With_Path(String testFolder) throws IOException, assertThat(content.type).isEqualTo(Api.CYCLONEDX_MEDIA_TYPE); assertThat(dropIgnored(new String(content.buffer))) .isEqualTo(dropIgnored(expectedSbom)); - } private String dropIgnored(String s) { diff --git a/src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/expected_stack_sbom.json b/src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/expected_stack_sbom.json index 59e9ebf8..5fc93527 100644 --- a/src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/expected_stack_sbom.json +++ b/src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/expected_stack_sbom.json @@ -3,7 +3,7 @@ "specVersion" : "1.4", "version" : 1, "metadata" : { - "timestamp" : "2024-02-28T19:37:19Z", + "timestamp" : "2024-03-27T16:58:19Z", "component" : { "group" : "org.acme.dbaas", "name" : "postgresql-orm-quarkus", @@ -2637,4 +2637,4 @@ "dependsOn" : [ ] } ] -} +} \ No newline at end of file diff --git a/src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/gradle.properties b/src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/gradle.properties new file mode 100644 index 00000000..bb8009fb --- /dev/null +++ b/src/test/resources/tst_manifests/gradle/deps_with_no_ignore_common_paths/gradle.properties @@ -0,0 +1,123 @@ + +> Task :properties + +------------------------------------------------------------ +Root project 'postgresql-orm-quarkus' - postgresql-orm-quarkus +------------------------------------------------------------ + +allprojects: [root project 'postgresql-orm-quarkus'] +ant: org.gradle.api.internal.project.DefaultAntBuilder@35380f02 +antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@3891bb0a +archivesBaseName: postgresql-orm-quarkus +artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@30efd286 +asDynamicObject: DynamicObject for root project 'postgresql-orm-quarkus' +autoTargetJvmDisabled: false +base: extension 'base' +baseClassLoaderScope: org.gradle.api.internal.initialization.MutableClassLoaderScope@27204a61 +buildDir: /Users/olgalavtar/repos/gradle-postgresql-vulnerability-example/build +buildFile: /Users/olgalavtar/repos/gradle-postgresql-vulnerability-example/build.gradle +buildPath: : +buildScriptSource: org.gradle.groovy.scripts.TextResourceScriptSource@52950198 +buildTreePath: : +buildscript: org.gradle.api.internal.initialization.DefaultScriptHandler_Decorated@6769a92b +childProjects: {} +childProjectsUnchecked: {} +class: class org.gradle.api.internal.project.DefaultProject_Decorated +classLoaderScope: org.gradle.api.internal.initialization.MutableClassLoaderScope@295c2ca2 +clean: task ':clean' +compileJava: task ':compileJava' +compileTestJava: task ':compileTestJava' +components: SoftwareComponent container +configurationActions: org.gradle.configuration.project.DefaultProjectConfigurationActionContainer@c8a08aa +configurationTargetIdentifier: org.gradle.configuration.ConfigurationTargetIdentifier$1@76e95162 +configurations: configuration container +convention: org.gradle.internal.extensibility.DefaultConvention@5c639e65 +crossProjectModelAccess: org.gradle.api.internal.project.DefaultCrossProjectModelAccess@14129077 +defaultArtifacts: extension 'defaultArtifacts' +defaultTasks: [] +deferredProjectConfiguration: org.gradle.api.internal.project.DeferredProjectConfiguration@48810507 +dependencies: org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler_Decorated@745f2f34 +dependencyFactory: org.gradle.api.internal.artifacts.DefaultDependencyFactory@348f176c +dependencyLocking: org.gradle.internal.locking.DefaultDependencyLockingHandler_Decorated@349eb8a2 +dependencyMetaDataProvider: org.gradle.internal.service.scopes.ProjectScopeServices$ProjectBackedModuleMetaDataProvider@74772a0b +depth: 0 +description: postgresql-orm-quarkus +detachedState: false +displayName: root project 'postgresql-orm-quarkus' +distsDirName: distributions +distsDirectory: extension 'base' property 'distsDirectory' +docsDir: /Users/olgalavtar/repos/gradle-postgresql-vulnerability-example/build/docs +docsDirName: docs +ext: org.gradle.internal.extensibility.DefaultExtraPropertiesExtension@795c8d3e +extensions: org.gradle.internal.extensibility.DefaultConvention@5c639e65 +fileOperations: org.gradle.api.internal.file.DefaultFileOperations@35a4c10e +fileResolver: org.gradle.api.internal.file.BaseDirFileResolver@743e24b0 +gradle: build 'postgresql-orm-quarkus' +group: org.acme.dbaas +identityPath: : +inheritedScope: org.gradle.internal.extensibility.ExtensibleDynamicObject$InheritedDynamicObject@39d47f4e +internalStatus: property(java.lang.Object, fixed(class java.lang.String, integration)) +java: extension 'java' +javaToolchains: extension 'javaToolchains' +javadoc: task ':javadoc' +layout: org.gradle.api.internal.file.DefaultProjectLayout@37433907 +libs: extension 'libs' +libsDirName: libs +libsDirectory: extension 'base' property 'libsDirectory' +listenerBuildOperationDecorator: org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator@32dd90fb +logger: org.gradle.internal.logging.slf4j.OutputEventListenerBackedLogger@2eba049a +logging: org.gradle.internal.logging.services.DefaultLoggingManager@28e9b7e1 +model: root project 'postgresql-orm-quarkus' +modelIdentityDisplayName: null +modelRegistry: org.gradle.model.internal.registry.DefaultModelRegistry@6d515753 +name: postgresql-orm-quarkus +normalization: org.gradle.normalization.internal.DefaultInputNormalizationHandler_Decorated@4374c0ff +objects: org.gradle.api.internal.model.DefaultObjectFactory@1df0da22 +owner: root project 'postgresql-orm-quarkus' +parent: null +parentIdentifier: null +path: : +pluginContext: false +pluginManager: org.gradle.api.internal.plugins.DefaultPluginManager_Decorated@78c320c2 +plugins: [org.gradle.api.plugins.HelpTasksPlugin$Inject@6de134c8, org.gradle.buildinit.plugins.BuildInitPlugin$Inject@22ccce5c, org.gradle.buildinit.plugins.WrapperPlugin$Inject@1d80c735, org.gradle.language.base.plugins.LifecycleBasePlugin$Inject@1ba74c0b, org.gradle.api.plugins.BasePlugin$Inject@25cdcf74, org.gradle.api.plugins.JvmEcosystemPlugin$Inject@47dce553, org.gradle.api.plugins.ReportingBasePlugin$Inject@632023, org.gradle.api.plugins.JvmToolchainsPlugin$Inject@7370cff8, org.gradle.api.plugins.JavaBasePlugin$Inject@6391f2b, org.gradle.testing.base.plugins.TestSuiteBasePlugin$Inject@66add8f2, org.gradle.api.plugins.JvmTestSuitePlugin$Inject@5ce50d92, org.gradle.api.plugins.JavaPlugin$Inject@7219c38b, org.gradle.api.plugins.JavaLibraryPlugin$Inject@95bbf32, org.gradle.api.publish.plugins.PublishingPlugin$Inject@1c2d2718, org.gradle.api.publish.maven.plugins.MavenPublishPlugin$Inject@6ccee335] +processOperations: org.gradle.process.internal.DefaultExecActionFactory$DecoratingExecActionFactory@1f4f1b46 +project: root project 'postgresql-orm-quarkus' +projectConfigurator: org.gradle.api.internal.project.BuildOperationCrossProjectConfigurator@7ad94368 +projectDir: /Users/olgalavtar/repos/gradle-postgresql-vulnerability-example +projectEvaluationBroadcaster: ProjectEvaluationListener broadcast +projectEvaluator: org.gradle.configuration.project.LifecycleProjectEvaluator@61e3a7db +projectPath: : +properties: {...} +providers: org.gradle.api.internal.provider.DefaultProviderFactory_Decorated@c75e15 +publishing: extension 'publishing' +reporting: extension 'reporting' +repositories: repository container +resources: org.gradle.api.internal.resources.DefaultResourceHandler@67b5f060 +rootDir: /Users/olgalavtar/repos/gradle-postgresql-vulnerability-example +rootProject: root project 'postgresql-orm-quarkus' +rootScript: false +script: false +scriptHandlerFactory: org.gradle.api.internal.initialization.DefaultScriptHandlerFactory@57c73dfd +scriptPluginFactory: org.gradle.configuration.ScriptPluginFactorySelector@2b6685a1 +serviceRegistryFactory: org.gradle.internal.service.scopes.BuildScopeServiceRegistryFactory@11eb512e +services: ProjectScopeServices +sourceCompatibility: 11 +sourceSets: SourceSet container +standardOutputCapture: org.gradle.internal.logging.services.DefaultLoggingManager@28e9b7e1 +state: project state 'EXECUTED' +status: integration +subprojects: [] +targetCompatibility: 11 +taskDependencyFactory: org.gradle.api.internal.tasks.DefaultTaskDependencyFactory@59159583 +taskThatOwnsThisObject: null +tasks: task set +testReportDir: /Users/olgalavtar/repos/gradle-postgresql-vulnerability-example/build/reports/tests +testReportDirName: tests +testResultsDir: /Users/olgalavtar/repos/gradle-postgresql-vulnerability-example/build/test-results +testResultsDirName: test-results +testing: extension 'testing' +version: 1.0.0-SNAPSHOT +versionCatalogs: extension 'versionCatalogs' + +BUILD SUCCESSFUL in 468ms +1 actionable task: 1 executed