Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -222,28 +222,42 @@ private String extractPackageName(String line) {
}

private Path getDependencies(Path manifestPath) throws IOException {
// create a temp file for storing the dependency tree in
var tempFile = Files.createTempFile("TRUSTIFY_DA_graph_", null);
// the command will create the dependency tree in the temp file
String gradleCommand = gradleExecutable + " dependencies";

String[] cmdList = gradleCommand.split("\\s+");
String gradleOutput =
Operations.runProcessGetOutput(Path.of(manifestPath.getParent().toString()), cmdList);
Files.writeString(tempFile, gradleOutput);

var result =
Operations.runProcessGetFullOutput(
Path.of(manifestPath.getParent().toString()), cmdList, null);

if (result.getExitCode() != 0) {
throw new RuntimeException(
String.format(
"gradle dependencies command failed with exit code %d for manifest '%s': %s",
result.getExitCode(), manifestPath, result.getError()));
}
Comment thread
qodo-code-review[bot] marked this conversation as resolved.

Files.writeString(tempFile, result.getOutput());
return tempFile;
}

private Path getProperties(Path manifestPath) throws IOException {
Path propsTempFile = Files.createTempFile("propsfile", ".txt");
String propCmd = gradleExecutable + " properties";
String[] propCmdList = propCmd.split("\\s+");
String properties =
Operations.runProcessGetOutput(Path.of(manifestPath.getParent().toString()), propCmdList);
// Create a temporary file
Files.writeString(propsTempFile, properties);

var result =
Operations.runProcessGetFullOutput(
Path.of(manifestPath.getParent().toString()), propCmdList, null);

if (result.getExitCode() != 0) {
throw new RuntimeException(
String.format(
"gradle properties command failed with exit code %d for manifest '%s': %s",
result.getExitCode(), manifestPath, result.getError()));
}

Files.writeString(propsTempFile, result.getOutput());
return propsTempFile;
}

Expand Down Expand Up @@ -503,9 +517,12 @@ private boolean containsVersion(String line) {

private String getRoot(Path textFormatFile, Map<String, String> propertiesMap)
throws IOException {
String group = propertiesMap.get("group");
String version = propertiesMap.get("version");
String group = propertiesMap.getOrDefault("group", "unknown");
String version = propertiesMap.getOrDefault("version", "0.0.0");
String rootName = extractRootProjectValue(textFormatFile);
if (rootName == null || rootName.isEmpty()) {
rootName = "unknown";
}
return group + ':' + rootName + ':' + "jar" + ':' + version;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package io.github.guacsec.trustifyda.providers;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mockStatic;

import io.github.guacsec.trustifyda.Api;
Expand All @@ -27,7 +29,9 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.ArgumentMatcher;
Expand Down Expand Up @@ -127,9 +131,10 @@ void test_the_provideStack(String testFolder) throws IOException {
gradleProperties = new String(is.readAllBytes());
}

ArgumentMatcher<String> gradle = string -> string.equals("gradle");
ArgumentMatcher<String> dependencies = string -> string.equals("dependencies");
ArgumentMatcher<String> properties = string -> string.equals("properties");
ArgumentMatcher<String[]> containsDependencies =
cmd -> cmd != null && Arrays.asList(cmd).contains("dependencies");
ArgumentMatcher<String[]> containsProperties =
cmd -> cmd != null && Arrays.asList(cmd).contains("properties");
try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
mockedOperations.when(() -> Operations.getCustomPathOrElse("gradle")).thenReturn("gradle");
mockedOperations
Expand All @@ -138,15 +143,15 @@ void test_the_provideStack(String testFolder) throws IOException {
mockedOperations
.when(
() ->
Operations.runProcessGetOutput(
any(Path.class), argThat(gradle), argThat(dependencies)))
.thenReturn(depTree);
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsDependencies), isNull()))
.thenReturn(new Operations.ProcessExecOutput(depTree, "", 0));
mockedOperations
.when(
() ->
Operations.runProcessGetOutput(
any(Path.class), argThat(gradle), argThat(properties)))
.thenReturn(gradleProperties);
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsProperties), isNull()))
.thenReturn(new Operations.ProcessExecOutput(gradleProperties, "", 0));

// when providing stack content for our pom
var content = new GradleProvider(tmpGradleFile).provideStack();
Expand Down Expand Up @@ -231,25 +236,26 @@ void test_the_provideComponent(String testFolder) throws IOException {
}

try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
ArgumentMatcher<String> gradle = string -> string.equals("gradle");
ArgumentMatcher<String> dependencies = string -> string.equals("dependencies");
ArgumentMatcher<String> properties = string -> string.equals("properties");
ArgumentMatcher<String[]> containsDependencies =
cmd -> cmd != null && Arrays.asList(cmd).contains("dependencies");
ArgumentMatcher<String[]> containsProperties =
cmd -> cmd != null && Arrays.asList(cmd).contains("properties");
mockedOperations.when(() -> Operations.getCustomPathOrElse("gradle")).thenReturn("gradle");
mockedOperations
.when(() -> Operations.getExecutable("gradle", "--version"))
.thenReturn("gradle");
mockedOperations
.when(
() ->
Operations.runProcessGetOutput(
any(Path.class), argThat(gradle), argThat(dependencies)))
.thenReturn(depTree);
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsDependencies), isNull()))
.thenReturn(new Operations.ProcessExecOutput(depTree, "", 0));
mockedOperations
.when(
() ->
Operations.runProcessGetOutput(
any(Path.class), argThat(gradle), argThat(properties)))
.thenReturn(gradleProperties);
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsProperties), isNull()))
.thenReturn(new Operations.ProcessExecOutput(gradleProperties, "", 0));

// when providing component content for our pom
var content = new GradleProvider(tmpGradleFile).provideComponent();
Expand All @@ -261,6 +267,126 @@ void test_the_provideComponent(String testFolder) throws IOException {
}
}

@Test
void test_provideStack_throws_on_gradle_failure() throws IOException {
var tmpGradleDir = Files.createTempDirectory("TRUSTIFY_DA_test_");
var tmpGradleFile = Files.createFile(tmpGradleDir.resolve(getManifestName()));
try (var is =
getClass()
.getClassLoader()
.getResourceAsStream(
String.join(
"/", "tst_manifests", getProviderFolder(), "empty", getManifestName()))) {
Files.write(tmpGradleFile, is.readAllBytes());
}
var settingsFile = Files.createFile(tmpGradleDir.resolve(getSettingsName()));
try (var is =
getClass()
.getClassLoader()
.getResourceAsStream(
String.join(
"/", "tst_manifests", getProviderFolder(), "empty", getSettingsName()))) {
Files.write(settingsFile, is.readAllBytes());
}

String gradleErrorOutput =
"FAILURE: Build failed with an exception.\n"
+ "* What went wrong:\n"
+ "A problem occurred evaluating root project.\n"
+ "> No such property: io for class: java.lang.String\n"
+ "BUILD FAILED in 761ms\n";

ArgumentMatcher<String[]> containsDependencies =
cmd -> cmd != null && Arrays.asList(cmd).contains("dependencies");
ArgumentMatcher<String[]> containsProperties =
cmd -> cmd != null && Arrays.asList(cmd).contains("properties");
try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
mockedOperations.when(() -> Operations.getCustomPathOrElse("gradle")).thenReturn("gradle");
mockedOperations
.when(() -> Operations.getExecutable("gradle", "--version"))
.thenReturn("gradle");
mockedOperations
.when(
() ->
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsDependencies), isNull()))
.thenReturn(new Operations.ProcessExecOutput("", gradleErrorOutput, 1));
mockedOperations
.when(
() ->
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsProperties), isNull()))
.thenReturn(new Operations.ProcessExecOutput("", gradleErrorOutput, 1));

assertThatThrownBy(() -> new GradleProvider(tmpGradleFile).provideStack())
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("gradle dependencies command failed with exit code 1")
.hasMessageContaining("No such property: io for class: java.lang.String");

Files.deleteIfExists(tmpGradleFile);
}
}

@Test
void test_provideComponent_throws_on_gradle_failure() throws IOException {
var tmpGradleDir = Files.createTempDirectory("TRUSTIFY_DA_test_");
var tmpGradleFile = Files.createFile(tmpGradleDir.resolve(getManifestName()));
try (var is =
getClass()
.getClassLoader()
.getResourceAsStream(
String.join(
"/", "tst_manifests", getProviderFolder(), "empty", getManifestName()))) {
Files.write(tmpGradleFile, is.readAllBytes());
}
var settingsFile = Files.createFile(tmpGradleDir.resolve(getSettingsName()));
try (var is =
getClass()
.getClassLoader()
.getResourceAsStream(
String.join(
"/", "tst_manifests", getProviderFolder(), "empty", getSettingsName()))) {
Files.write(settingsFile, is.readAllBytes());
}

String gradleErrorOutput =
"FAILURE: Build failed with an exception.\n"
+ "* What went wrong:\n"
+ "A problem occurred evaluating root project.\n"
+ "> No such property: io for class: java.lang.String\n"
+ "BUILD FAILED in 761ms\n";

ArgumentMatcher<String[]> containsDependencies =
cmd -> cmd != null && Arrays.asList(cmd).contains("dependencies");
ArgumentMatcher<String[]> containsProperties =
cmd -> cmd != null && Arrays.asList(cmd).contains("properties");
try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
mockedOperations.when(() -> Operations.getCustomPathOrElse("gradle")).thenReturn("gradle");
mockedOperations
.when(() -> Operations.getExecutable("gradle", "--version"))
.thenReturn("gradle");
mockedOperations
.when(
() ->
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsDependencies), isNull()))
.thenReturn(new Operations.ProcessExecOutput("", gradleErrorOutput, 1));
mockedOperations
.when(
() ->
Operations.runProcessGetFullOutput(
any(Path.class), argThat(containsProperties), isNull()))
.thenReturn(new Operations.ProcessExecOutput("", gradleErrorOutput, 1));

assertThatThrownBy(() -> new GradleProvider(tmpGradleFile).provideComponent())
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("gradle dependencies command failed with exit code 1")
.hasMessageContaining("No such property: io for class: java.lang.String");

Files.deleteIfExists(tmpGradleFile);
}
}

private String dropIgnored(String s) {
return s.replaceAll("\\s+", "").replaceAll("\"timestamp\":\"[a-zA-Z0-9\\-\\:]+\",", "");
}
Expand Down
Loading