Skip to content

Commit

Permalink
Merge branch '9.6.z'
Browse files Browse the repository at this point in the history
# Conflicts:
#	build.gradle
#	documentation/src/main/markdown/currentreleasenotes.md
  • Loading branch information
gopanna committed Apr 23, 2024
2 parents 33b6b99 + b763d6c commit 1fb3927
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 43 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ dependencies {
implementation 'com.blackducksoftware.bdio:bdio-protobuf:3.2.10'
implementation "com.synopsys.integration:blackduck-common:${blackDuckCommonVersion}"
implementation 'com.synopsys:method-analyzer-core:0.2.9'
implementation "${locatorGroup}:${locatorModule}:1.1.10"
implementation "${locatorGroup}:${locatorModule}:1.1.11"

implementation 'org.apache.maven.shared:maven-invoker:3.0.0'

Expand Down Expand Up @@ -362,4 +362,4 @@ task submitToPlatform1 (type: Exec, dependsOn: [buildPlatform1]){
}

artifactoryPublish.dependsOn ':documentation:publishDitaSource'
artifactoryPublish.dependsOn signJar
artifactoryPublish.dependsOn signJar
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.synopsys.integration.detectable.detectables.gradle.inspection.model.GradleTreeNode;
import org.apache.commons.lang3.StringUtils;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.synopsys.integration.detectable.detectables.gradle.inspection.parse;

import java.util.Map;
import java.util.Queue;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.LinkedList;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
Expand All @@ -27,15 +25,34 @@ public class GradleReportLineParser {
private static final String REQUIRE = "require";
private static final String PREFER = "prefer";
private static final String REJECT = "reject";
private static final Map<String, String> gradleRichVersions = new HashMap<>();
private static final Map<String, HashSet<String>> richVersionGroup = new HashMap<>();
private static final Map<String, String> relationsMap = new HashMap<>();

// This map handles all the dependencies which uses rich version
// declarations with the respect to the project they are declared in.
// The nested map has dependencies with their versions and each
// module will have its own nested map.
private final Map<String, Map<String, String>> gradleRichVersions = new HashMap<>();

// This map handles all the transitives whose parent uses rich version
// declarations with the respect to the project they are declared in.
// The nested map has dependencies with their versions and each
// module will have its own nested map.
private final Map<String, Map<String, String>> transitiveRichVersions = new HashMap<>();

// This map is handling all the child-parent relationships which are found in the entire project
// with each child as a key and their respective parent as the value.
private final Map<String, String> relationsMap = new HashMap<>();
private String richVersionProject = null;
private boolean richVersionDeclared = false;
private String projectName;
private String rootProjectName;
private String projectParent;
private int level;
public static final String PROJECT_NAME_PREFIX = "projectName:";
public static final String ROOT_PROJECT_NAME_PREFIX = "rootProjectName:";
public static final String PROJECT_PARENT_PREFIX = "projectParent:";

public GradleTreeNode parseLine(String line, Map<String, String> metadata) {
int level = parseTreeLevel(line);
level = parseTreeLevel(line);
if (!line.contains(COMPONENT_PREFIX)) {
return GradleTreeNode.newUnknown(level);
} else if (StringUtils.containsAny(line, PROJECT_INDICATORS)) {
Expand Down Expand Up @@ -92,58 +109,74 @@ private List<String> parseGav(String line, Map<String, String> metadata) {
}
}

String projectName = metadata.getOrDefault(PROJECT_NAME_PREFIX, "orphanProject");
String rootProjectName = metadata.getOrDefault(ROOT_PROJECT_NAME_PREFIX, "");
String projectParent = metadata.getOrDefault(PROJECT_PARENT_PREFIX, "null");
projectName = metadata.getOrDefault(PROJECT_NAME_PREFIX, "orphanProject");
rootProjectName = metadata.getOrDefault(ROOT_PROJECT_NAME_PREFIX, "");
projectParent = metadata.getOrDefault(PROJECT_PARENT_PREFIX, "null");

addRelation(projectParent, projectName, rootProjectName);
addRelation();

if(gavPieces.size() == 3) {
String dependencyGroupName = gavPieces.get(0) + ":" + gavPieces.get(1);
if ((cleanedOutput.contains(STRICTLY) || cleanedOutput.contains(REJECT) || cleanedOutput.contains(REQUIRE) || cleanedOutput.contains(PREFER))) {
gradleRichVersions.putIfAbsent(dependencyGroupName, gavPieces.get(2));
richVersionGroup.computeIfAbsent(projectName, value -> new HashSet<>()).add(dependencyGroupName);
}

if(gradleRichVersions.containsKey(dependencyGroupName)) {
updateRichVersion(dependencyGroupName, projectParent, projectName, rootProjectName, gavPieces);
if(level == 0 && checkRichVersionUse(cleanedOutput)) {
storeDirectRichVersion(dependencyGroupName, gavPieces);
} else {
storeOrUpdateRichVersion(dependencyGroupName, gavPieces);
}

}

return gavPieces;
}

private void updateRichVersion(String dependencyGroupName, String projectParent, String projectName, String rootProjectName, List<String> gavPieces) {
if(richVersionGroup.containsKey(projectName) && richVersionGroup.get(projectName).contains(dependencyGroupName)) {
gavPieces.set(2, gradleRichVersions.get(dependencyGroupName));
} else if(richVersionGroup.containsKey(rootProjectName) && richVersionGroup.get(rootProjectName).contains(dependencyGroupName)) {
gavPieces.set(2, gradleRichVersions.get(dependencyGroupName));
} else if (checkParentRichVersion(rootProjectName, projectParent, dependencyGroupName)) {
gavPieces.set(2, gradleRichVersions.get(dependencyGroupName));
private void storeDirectRichVersion(String dependencyGroupName, List<String> gavPieces) {
gradleRichVersions.computeIfAbsent(projectName, value -> new HashMap<>()).putIfAbsent(dependencyGroupName, gavPieces.get(2));
richVersionProject = projectName;
richVersionDeclared = true;
}

private void storeOrUpdateRichVersion(String dependencyGroupName, List<String> gavPieces) {
if (checkParentRichVersion(dependencyGroupName)) {
gavPieces.set(2, gradleRichVersions.get(richVersionProject).get(dependencyGroupName));
} else if(checkIfTransitiveRichVersion() && transitiveRichVersions.containsKey(richVersionProject) && transitiveRichVersions.get(richVersionProject).containsKey(dependencyGroupName)) {
gavPieces.set(2, transitiveRichVersions.get(richVersionProject).get(dependencyGroupName));
} else if (checkIfTransitiveRichVersion() && richVersionDeclared) {
transitiveRichVersions.computeIfAbsent(richVersionProject, value -> new HashMap<>()).putIfAbsent(dependencyGroupName, gavPieces.get(2));
} else {
richVersionDeclared = false;
richVersionProject = null;
}
}

private void addRelation(String projectParent, String projectName, String rootProjectName) {
private void addRelation() {
if (!projectParent.equals("null") && !projectParent.contains("root project")) {
String parentString = projectParent.substring(projectParent.lastIndexOf(":") + 1, projectParent.lastIndexOf("'"));
relationsMap.putIfAbsent(projectName, parentString);
} else if (!projectParent.equals("null") && !projectName.equals(rootProjectName)) {
relationsMap.putIfAbsent(projectName, rootProjectName);
} else {
relationsMap.putIfAbsent(rootProjectName, null);
}
}

private boolean checkParentRichVersion(String rootProjectName, String projectParent, String dependencyGroupName) {
String currentProject = projectParent.substring(projectParent.lastIndexOf(":") + 1, projectParent.lastIndexOf("'"));
while(!currentProject.equals(rootProjectName)) {
if(richVersionGroup.containsKey(currentProject) && richVersionGroup.get(currentProject).contains(dependencyGroupName)) {
return true;
}
currentProject = relationsMap.getOrDefault(currentProject, rootProjectName);
}
private boolean checkParentRichVersion(String dependencyGroupName) {
String currentProject = projectName;
while (currentProject != null) {
if (gradleRichVersions.containsKey(currentProject) && gradleRichVersions.get(currentProject).containsKey(dependencyGroupName)) {
richVersionProject = currentProject;
return true;
}
currentProject = relationsMap.getOrDefault(currentProject, null);
}
return false;
}

private boolean checkRichVersionUse(String dependencyLine) {
return dependencyLine.contains(STRICTLY) || dependencyLine.contains(REJECT) || dependencyLine.contains(REQUIRE) || dependencyLine.contains(PREFER);
}

private boolean checkIfTransitiveRichVersion() {
return richVersionProject != null && level != 0;
}

private int parseTreeLevel(String line) {
if (StringUtils.startsWithAny(line, TREE_LEVEL_TERMINALS)) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class GradleReportParser {
public static final String ROOT_PROJECT_VERSION_PREFIX = "rootProjectVersion:";
public static final String DETECT_META_DATA_HEADER = "DETECT META DATA START";
public static final String DETECT_META_DATA_FOOTER = "DETECT META DATA END";
public static Map<String, String> metadata = new HashMap<>();
private final Map<String, String> metadata = new HashMap<>();
private final GradleReportConfigurationParser gradleReportConfigurationParser = new GradleReportConfigurationParser();

public Optional<GradleReport> parseReport(File reportFile) {
Expand Down
8 changes: 7 additions & 1 deletion documentation/src/main/markdown/packagemgrs/gradle.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ the output of the `dependencies` Gradle task invoked by the 'gradlew gatherDepen

The init-detect.gradle script configures each project with the custom 'gatherDependencies' task, which invokes the 'dependencies' Gradle task on each project. This ensures the same output is produced as previous versions. The inspector consumes the output of `gradlew gatherDependencies` task.

### Rich version declaration support

Rich version declarations allow a user to define rules around which version of a given direct or transitive dependency are resolved when Gradle performs its dependency conflict resolution. Typically, these are set in a parent build.gradle file, and because these rich version declarations set a specific requirement that conflict resolution must respect, the subsequent child modules will pull dependencies according to the rich version declaration.
[company_name] [solution_name] derives this information from the dependency graph that Gradle Native Inspector generates as described above. If the information is not mentioned in the graph then [company_name] [solution_name] will not support those declarations.
See Gradle documentation: [Rich Version Declaration](https://docs.gradle.org/current/userguide/rich_versions.html).

### Running the Gradle inspector with a proxy

[company_name] [solution_name] will pass along supplied [proxy host](../properties/configuration/proxy.md#proxy-host-advanced) and [proxy port](../properties/configuration/proxy.md#proxy-port-advanced) properties to the Gradle daemon if applicable.
Expand All @@ -46,4 +52,4 @@ The buildless gradle detector uses Project Inspector to find dependencies and do
It currently supports "build.gradle" and does not support Kotlin build files.

As of [company_name] [solution_name] 9.5.0 the version of Project Inspector in use supports the `--build-system GRADLE` argument in place of `--strategy GRADLE`.
The `--force-gradle-repos "url"` argument will be removed from support in the next [company_name] [solution_name] major release and replaced with the `--conf "maven.repo:url"` argument.
The `--force-gradle-repos "url"` argument will be removed from support in the next [company_name] [solution_name] major release and replaced with the `--conf "maven.repo:url"` argument.
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ Identification of malware displayed to [blackduck_product_name] users will inclu
* [threat_intel] scans require network connectivity (Air gap mode is not supported).
* [threat_intel] scan does not provide project and version name defaults so you need to set project and version names via properties when [threat_intel] is the only tool invoked. (If the specified project or version does not exist in [blackduck_product_name], it will be created.)

### Limitations
* [threat_intel] Scan is limited to images of 5GB or less for hosted services.
* [threat_intel] Scan is limited to images of 6GB or less for local, on-prem services.

## Invocation
To invoke a [threat_intel] scan, which only executes in "Intelligent" mode, the following must be provided at a minimum in addition to [blackduck_product_name] Server related configuration properties:
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Transforms {@link BdioResult} to list of {@link Component}s, which will then be used to assemble the input to
Expand All @@ -21,6 +23,8 @@
*/
public class BdioToComponentListTransformer {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

/**
* Given a BDIO, creates a set containing each detected component's corresponding {@link Component} representation.
* Each component is included once, duplicates are ignored.
Expand Down Expand Up @@ -70,6 +74,8 @@ private Set<Component> externalIDsToComponentSet(List<ExternalId> gavs) {
for (ExternalId gav : gavs) {
if (gav.getName()!=null && gav.getVersion()!=null) {
componentSet.add(new Component(gav.getGroup(), gav.getName(), gav.getVersion(), new JsonObject()));
} else {
logger.warn("Invalid component entry {} from BDIO is not included for component location analysis.", gav.toString());
}
}
return componentSet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ void gradleRichVersions() throws IntegrationException, IOException {
blackduckAssertions.checkComponentVersionExists("graphql-java", "18.2");
blackduckAssertions.checkComponentVersionNotExists("SLF4J API Module", "2.0.4");
blackduckAssertions.checkComponentVersionExists("google-guava", "v29.0");
blackduckAssertions.checkComponentVersionNotExists("Apache Log4J API", "2.22.1");

}
}
Expand Down

0 comments on commit 1fb3927

Please sign in to comment.