diff --git a/detectable/src/main/java/com/synopsys/integration/detectable/detectables/go/gomod/GoModCliExtractor.java b/detectable/src/main/java/com/synopsys/integration/detectable/detectables/go/gomod/GoModCliExtractor.java index b86e4332c9..9afb47f5ae 100644 --- a/detectable/src/main/java/com/synopsys/integration/detectable/detectables/go/gomod/GoModCliExtractor.java +++ b/detectable/src/main/java/com/synopsys/integration/detectable/detectables/go/gomod/GoModCliExtractor.java @@ -23,8 +23,15 @@ package com.synopsys.integration.detectable.detectables.go.gomod; import java.io.File; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.synopsys.integration.blackduck.service.BlackDuckServicesFactory; import com.synopsys.integration.detectable.Extraction; import com.synopsys.integration.detectable.detectable.codelocation.CodeLocation; import com.synopsys.integration.detectable.detectable.exception.DetectableException; @@ -35,6 +42,9 @@ public class GoModCliExtractor { private final ExecutableRunner executableRunner; private final GoModGraphParser goModGraphParser; + private final Gson gson = BlackDuckServicesFactory.createDefaultGsonBuilder().setPrettyPrinting().setLenient().create(); + private final Map replacementData = new HashMap<>(); + private final static String PATHS = "paths"; public GoModCliExtractor(final ExecutableRunner executableRunner, final GoModGraphParser goModGraphParser) { this.executableRunner = executableRunner; @@ -44,7 +54,8 @@ public GoModCliExtractor(final ExecutableRunner executableRunner, final GoModGra public Extraction extract(final File directory, final File goExe) { try { final List listOutput = execute(directory, goExe, "Querying go for the list of modules failed: ", "list", "-m"); - final List modGraphOutput = execute(directory, goExe, "Querying for the go mod graph failed:", "mod", "graph"); + final List listUJsonOutput = execute(directory, goExe, "Querying for the go mod graph failed:", "list", "-m", "-u", "-json", "all"); + final List modGraphOutput = modGraphOutputWithReplacements(directory, goExe, listUJsonOutput); final List codeLocations = goModGraphParser.parseListAndGoModGraph(listOutput, modGraphOutput); return new Extraction.Builder().success(codeLocations).build();//no project info - hoping git can help with that. } catch (final Exception e) { @@ -61,4 +72,48 @@ private List execute(final File directory, final File goExe, final Strin throw new DetectableException(failureMessage + output.getReturnCode()); } } + + private List modGraphOutputWithReplacements(File directory, File goExe, List listUJsonOutput) throws ExecutableRunnerException, DetectableException { + final List modGraphOutput = execute(directory, goExe, "Querying for the go mod graph failed:", "mod", "graph"); + String jsonString = convertOutputToJsonString(listUJsonOutput); + JsonObject json = gson.fromJson(jsonString, JsonObject.class); + + for (final JsonElement jsonElement : json.getAsJsonArray(PATHS)) { + JsonObject jsonObject = jsonElement.getAsJsonObject(); + JsonObject replace = jsonObject.getAsJsonObject("Replace"); + if (replace != null) { + String path = jsonObject.get("Path").getAsString(); + String originalVersion = jsonObject.get("Version").getAsString(); + String replaceVersion = replace.get("Version").getAsString(); + replacementData.put(String.format("%s@%s", path, originalVersion), String.format("%s@%s", path, replaceVersion)); + } + } + + for (String line : modGraphOutput) { + for (String original : replacementData.keySet()) { + if (line.contains("ocsql@v0.1.5")) { + System.out.println(""); + } + String newLine = line.replace(original, replacementData.get(original)); + int indexOfLine = modGraphOutput.indexOf(line); + modGraphOutput.set(indexOfLine, newLine); + } + } + return modGraphOutput; + } + + private String convertOutputToJsonString(List listUJsonOutput) { + // go list -u -json does not provide data in a format that can be consumed by gson + Collections.replaceAll(listUJsonOutput, "}", "},"); + String goModGraphAsString = String.join(System.lineSeparator(), listUJsonOutput); + int lastCloseBrace = goModGraphAsString.lastIndexOf("},"); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(String.format("{%n %s: [%n", PATHS)); + stringBuilder.append(goModGraphAsString.substring(0, lastCloseBrace)); + stringBuilder.append("}"); + stringBuilder.append(goModGraphAsString.substring(lastCloseBrace + 2)); + stringBuilder.append("\n] \n}"); + + return stringBuilder.toString(); + } } diff --git a/detectable/src/test/java/com/synopsys/integration/detectable/detectables/go/functional/GoModDetectableTest.java b/detectable/src/test/java/com/synopsys/integration/detectable/detectables/go/functional/GoModDetectableTest.java index 8f306eee52..0d6945a8ab 100644 --- a/detectable/src/test/java/com/synopsys/integration/detectable/detectables/go/functional/GoModDetectableTest.java +++ b/detectable/src/test/java/com/synopsys/integration/detectable/detectables/go/functional/GoModDetectableTest.java @@ -33,6 +33,24 @@ protected void setup() throws IOException { ); addExecutableOutput(goListOutput, "go", "list", "-m"); + ExecutableOutput goListUJsonOutput = createStandardOutput( + "{", + "\t\"Path\": \"github.com/codegangsta/negroni\",", + "\t\"Version\": \"v1.0.0\"", + "}", + "", + "{", + "\t\"Path\": \"github.com/sirupsen/logrus\",", + "\t\"Version\": \"v1.1.1\"", + "}", + "", + "{", + "\t\"Path\": \"github.com/davecgh/go-spew\",", + "\t\"Version\": \"v1.1.1\"", + "}" + ); + addExecutableOutput(goListUJsonOutput, "go", "list", "-m", "-u", "-json", "all"); + ExecutableOutput goModGraphOutput = createStandardOutput( "github.com/gomods/athens github.com/codegangsta/negroni@v1.0.0", "github.com/gomods/athens github.com/sirupsen/logrus@v1.1.1",