Skip to content

Commit

Permalink
Allow skip VCS stamping in Go (#689)
Browse files Browse the repository at this point in the history
  • Loading branch information
yahavi authored Dec 29, 2022
1 parent 4230186 commit 8ae1132
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,14 @@ public void modTidy(boolean verbose, boolean ignoreErrors) throws IOException {
*
* @param verbose - True if should print the results to the log
* @param ignoreErrors - True if errors should be ignored
* @param dontBuildVcs - Skip VCS stamping - can be used only on Go >= 1.18
* @throws IOException - in case of any I/O error.
*/
public CommandResults getUsedModules(boolean verbose, boolean ignoreErrors) throws IOException {
public CommandResults getUsedModules(boolean verbose, boolean ignoreErrors, boolean dontBuildVcs) throws IOException {
List<String> argsList = new ArrayList<>(GO_LIST_USED_MODULES_CMD);
if (dontBuildVcs) {
argsList.add(1, "-buildvcs=false");
}
if (ignoreErrors) {
argsList.add(1, "-e");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,25 @@ public class GoDependencyTree {
/**
* Create Go dependency tree of actually used dependencies.
*
* @param goDriver - Go driver
* @param logger - The logger
* @param verbose - verbose logging
* @param goDriver - Go driver
* @param logger - The logger
* @param verbose - verbose logging
* @param dontBuildVcs - Skip VCS stamping - can be used only on Go >= 1.18
* @return Go dependency tree
* @throws IOException in case of any I/O error.
*/
public static DependencyTree createDependencyTree(GoDriver goDriver, Log logger, boolean verbose) throws IOException {
public static DependencyTree createDependencyTree(GoDriver goDriver, Log logger, boolean verbose, boolean dontBuildVcs) throws IOException {
// Run go mod graph.
CommandResults goGraphResult = goDriver.modGraph(verbose);
String[] dependenciesGraph = goGraphResult.getRes().split("\\r?\\n");

// Run go list -f "{{with .Module}}{{.Path}} {{.Version}}{{end}}" all
CommandResults usedModulesResults;
try {
usedModulesResults = goDriver.getUsedModules(false, false);
usedModulesResults = goDriver.getUsedModules(false, false, dontBuildVcs);
} catch (IOException e) {
// Errors occurred during running "go list". Run again and this time ignore errors.
usedModulesResults = goDriver.getUsedModules(false, true);
usedModulesResults = goDriver.getUsedModules(false, true, dontBuildVcs);
logger.warn("Errors occurred during building the Go dependency tree. The dependency tree may be incomplete:" +
System.lineSeparator() + ExceptionUtils.getRootCauseMessage(e));
}
Expand Down Expand Up @@ -65,7 +66,7 @@ public static DependencyTree createDependencyTree(GoDriver goDriver, Log logger,
* @param usedDependencies - Results of "go list -f "{{with .Module}}{{.Path}} {{.Version}}{{end}}" all"
* @param dependenciesMap - Dependencies parent to children map results
*/
private static void populateDependenciesMap(String[] dependenciesGraph, Set<String> usedDependencies, Map<String, List<String>> dependenciesMap) {
static void populateDependenciesMap(String[] dependenciesGraph, Set<String> usedDependencies, Map<String, List<String>> dependenciesMap) {
for (String entry : dependenciesGraph) {
if (StringUtils.isAllBlank(entry)) {
continue;
Expand All @@ -88,8 +89,8 @@ private static void populateDependenciesMap(String[] dependenciesGraph, Set<Stri
* @param allDependencies - Dependency to children map
* @param logger - The logger
*/
private static void populateDependencyTree(DependencyTree currNode, String currNameVersionString,
Map<String, List<String>> allDependencies, Log logger) {
static void populateDependencyTree(DependencyTree currNode, String currNameVersionString,
Map<String, List<String>> allDependencies, Log logger) {
if (currNode.hasLoop(logger)) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ private void setResolverAsGoProxy(ArtifactoryManager artifactoryClient) throws E
private void populateModuleAndDeps() throws Exception {
backupModAndSumFiles();
try {
DependencyTree dependencyTree = createDependencyTree(goDriver, logger, true);
DependencyTree dependencyTree = createDependencyTree(goDriver, logger, true, false);
moduleName = dependencyTree.toString();

String cachePath = getCachePath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ public void testTidyListUsedModules() throws IOException {
driver.modTidy(false, false);

// Run "go list -f {{with .Module}}{{.Path}} {{.Version}}{{end}} all"
CommandResults results = driver.getUsedModules(false, false);
CommandResults results = driver.getUsedModules(false, false, true);
Set<String> actualUsedModules = Arrays.stream(results.getRes().split("\\r?\\n"))
.map(String::trim)
.collect(Collectors.toSet());
assertEquals(actualUsedModules, EXPECTED_USED_MODULES);

// Run "go list -e -f {{with .Module}}{{.Path}} {{.Version}}{{end}} all"
results = driver.getUsedModules(false, true);
results = driver.getUsedModules(false, true, true);
actualUsedModules = Arrays.stream(results.getRes().split("\\r?\\n"))
.map(String::trim)
.collect(Collectors.toSet());
Expand All @@ -77,10 +77,10 @@ public void testTidyListUsedModulesErroneous() throws IOException {
driver.modTidy(false, true);

// Run "go list -f {{with .Module}}{{.Path}} {{.Version}}{{end}} all"
Assert.assertThrows(() -> driver.getUsedModules(false, false));
Assert.assertThrows(() -> driver.getUsedModules(false, false, true));

// Run "go list -e -f {{with .Module}}{{.Path}} {{.Version}}{{end}} all"
CommandResults results = driver.getUsedModules(false, true);
CommandResults results = driver.getUsedModules(false, true, true);
Set<String> actualUsedModules = Arrays.stream(results.getRes().split("\\r?\\n"))
.map(String::trim)
.collect(Collectors.toSet());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package org.jfrog.build.extractor.go.extractor;

import com.google.common.collect.Sets;
import org.jfrog.build.api.util.NullLog;
import org.jfrog.build.extractor.scan.DependencyTree;
import org.testng.annotations.Test;

import java.util.*;

import static org.jfrog.build.extractor.go.extractor.GoDependencyTree.populateDependenciesMap;
import static org.jfrog.build.extractor.go.extractor.GoDependencyTree.populateDependencyTree;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

/**
* @author yahavi
**/
public class GoDependencyTreeTest {

@Test
public void testPopulateDependenciesMap() {
// Output of 'go mod graph'.
String[] dependenciesGraph = new String[]{
"my/pkg/name1 github.com/jfrog/[email protected]",
"my/pkg/name1 github.com/jfrog/[email protected]",
"my/pkg/name1 github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected] github.com/jfrog/[email protected]",
// github.com/jfrog/[email protected] does not appear in the used modules set:
"github.com/jfrog/[email protected] github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected] github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected] github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected] github.com/jfrog/[email protected]"
};
Set<String> usedModules = Sets.newHashSet("github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]");
// Run method.
Map<String, List<String>> expectedAllDependencies = getAllDependenciesForTest();
Map<String, List<String>> actualAllDependencies = new HashMap<>();
populateDependenciesMap(dependenciesGraph, usedModules, actualAllDependencies);
// Validate result.
assertEquals(expectedAllDependencies, actualAllDependencies);
}

@Test
public void testPopulateDependencyTree() {
Map<String, Integer> expected = new HashMap<String, Integer>() {{
put("github.com/jfrog/directDep1:0.1", 2);
put("github.com/jfrog/directDep2:0.2", 1);
put("github.com/jfrog/directDep3:0.3", 0);
}};
Map<String, List<String>> allDependencies = getAllDependenciesForTest();
DependencyTree rootNode = new DependencyTree();
populateDependencyTree(rootNode, "my/pkg/name1", allDependencies, new NullLog());

Vector<DependencyTree> children = rootNode.getChildren();
assertEquals(children.size(), expected.size());
for (DependencyTree current : children) {
assertTrue(expected.containsKey(current.toString()));
assertEquals(current.getChildren().size(), expected.get(current.toString()).intValue());
}
}

private Map<String, List<String>> getAllDependenciesForTest() {
return new HashMap<String, List<String>>() {{
put("my/pkg/name1", Arrays.asList(
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]"));
put("github.com/jfrog/[email protected]", List.of(
"github.com/jfrog/[email protected]",
"github.com/jfrog/[email protected]"));
put("github.com/jfrog/[email protected]", Collections.singletonList(
"github.com/jfrog/[email protected]"));
put("github.com/jfrog/[email protected]", Collections.singletonList(
"github.com/jfrog/[email protected]"));
}};
}
}

0 comments on commit 8ae1132

Please sign in to comment.