Skip to content

Commit e2680e1

Browse files
authored
chore: change report logic (#2689)
In this PR: - Show the package information report regardless of the analysis result. - Change report format (verified in unit tests).
1 parent fe0481e commit e2680e1

File tree

7 files changed

+118
-87
lines changed

7 files changed

+118
-87
lines changed

java-shared-dependencies/dependency-analyzer/src/main/java/com/google/cloud/DependencyAnalyzer.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.google.cloud.model.Advisory;
77
import com.google.cloud.model.AdvisoryKey;
88
import com.google.cloud.model.AnalysisResult;
9+
import com.google.cloud.model.License;
910
import com.google.cloud.model.ReportResult;
1011
import com.google.cloud.model.PackageInfo;
1112
import com.google.cloud.model.QueryResult;
@@ -52,11 +53,13 @@ public AnalysisResult analyze(String system, String packageName, String packageV
5253
List<PackageInfo> result = new ArrayList<>();
5354
for (VersionKey versionKey : dependencies) {
5455
QueryResult packageInfo = depsDevClient.getQueryResult(versionKey);
55-
List<String> licenses = new ArrayList<>();
56+
List<License> licenses = new ArrayList<>();
5657
List<Advisory> advisories = new ArrayList<>();
5758
for (Result res : packageInfo.results()) {
5859
Version version = res.version();
59-
licenses.addAll(version.licenses());
60+
for (String license : version.licenses()) {
61+
licenses.add(License.toLicense(license));
62+
}
6063
for (AdvisoryKey advisoryKey : version.advisoryKeys()) {
6164
advisories.add(depsDevClient.getAdvisory(advisoryKey.id()));
6265
}
@@ -65,7 +68,7 @@ public AnalysisResult analyze(String system, String packageName, String packageV
6568
result.add(new PackageInfo(versionKey, licenses, advisories));
6669
}
6770

68-
return AnalysisResult.of(root, result);
71+
return AnalysisResult.of(result);
6972
}
7073

7174
/**
@@ -109,7 +112,9 @@ public static void main(String[] args) throws IllegalArgumentException {
109112
System.exit(1);
110113
}
111114

112-
ReportResult result = analyzeReport.generateReport();
115+
System.out.println("Please copy and paste the package information below to your ticket.\n");
116+
System.out.println(analyzeReport.toString());
117+
ReportResult result = analyzeReport.getAnalysisResult();
113118
System.out.println(result);
114119
if (result.equals(ReportResult.FAIL)) {
115120
System.out.println(

java-shared-dependencies/dependency-analyzer/src/main/java/com/google/cloud/model/Advisory.java

+4
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@ public record Advisory(
2222
double cvss3Score,
2323
String cvss3Vector) {
2424

25+
@Override
26+
public String toString() {
27+
return String.format("Advisory (id: %s, more info: [%s](%s))", advisoryKey.id(), title, url);
28+
}
2529
}
2630

java-shared-dependencies/dependency-analyzer/src/main/java/com/google/cloud/model/AnalysisResult.java

+22-58
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,34 @@
77
import java.util.List;
88
import java.util.Map;
99
import java.util.Set;
10-
import java.util.logging.Level;
11-
import java.util.logging.Logger;
1210

1311
public class AnalysisResult {
1412

15-
private final VersionKey root;
1613
private final List<PackageInfo> packageInfos;
1714
private final Map<VersionKey, List<Advisory>> advisories;
18-
private final Map<VersionKey, List<String>> nonCompliantLicenses;
15+
private final Map<VersionKey, List<License>> nonCompliantLicenses;
1916

20-
private final static Logger LOGGER = Logger.getLogger(AnalysisResult.class.getName());
21-
22-
private AnalysisResult(VersionKey root, List<PackageInfo> result) {
23-
this.root = root;
17+
private AnalysisResult(List<PackageInfo> result) {
2418
this.packageInfos = result;
2519
this.advisories = getAdvisories(result);
2620
this.nonCompliantLicenses = getNonCompliantLicenses(result);
2721
}
2822

29-
public static AnalysisResult of(VersionKey root, List<PackageInfo> result) {
30-
return new AnalysisResult(root, result);
23+
public static AnalysisResult of(List<PackageInfo> result) {
24+
return new AnalysisResult(result);
3125
}
3226

33-
public ReportResult generateReport() {
34-
if (!advisories.isEmpty()) {
35-
formatLog(root, advisories, "New security vulnerability found in dependencies:");
36-
}
37-
38-
if (!nonCompliantLicenses.isEmpty()) {
39-
formatLog(root, nonCompliantLicenses, "Non-compliant license found in dependencies:");
27+
public ReportResult getAnalysisResult() {
28+
if (advisories.isEmpty() && nonCompliantLicenses.isEmpty()) {
29+
return ReportResult.PASS;
4030
}
4131

42-
if (!advisories.isEmpty() || !nonCompliantLicenses.isEmpty()) {
43-
LOGGER.log(Level.SEVERE, String.format("Found dependency risk in %s", root));
44-
return ReportResult.FAIL;
45-
}
46-
47-
LOGGER.log(Level.INFO,
48-
String.format("%s have no known vulnerabilities and non compliant licenses", root));
49-
LOGGER.log(Level.INFO, "Generate package information report...");
50-
System.out.println(packageInfoReport());
32+
return ReportResult.FAIL;
33+
}
5134

52-
return ReportResult.PASS;
35+
@Override
36+
public String toString() {
37+
return packageInfoReport();
5338
}
5439

5540
private Map<VersionKey, List<Advisory>> getAdvisories(List<PackageInfo> result) {
@@ -63,22 +48,21 @@ private Map<VersionKey, List<Advisory>> getAdvisories(List<PackageInfo> result)
6348
return advisories;
6449
}
6550

66-
private Map<VersionKey, List<String>> getNonCompliantLicenses(List<PackageInfo> result) {
67-
Map<VersionKey, List<String>> licenses = new HashMap<>();
51+
private Map<VersionKey, List<License>> getNonCompliantLicenses(List<PackageInfo> result) {
52+
Map<VersionKey, List<License>> licenses = new HashMap<>();
6853
Set<LicenseCategory> compliantCategories = LicenseCategory.compliantCategories();
6954

7055
result.forEach(packageInfo -> {
71-
List<String> nonCompliantLicenses = new ArrayList<>();
72-
for (String licenseStr : packageInfo.licenses()) {
73-
License license = License.toLicense(licenseStr);
56+
List<License> nonCompliantLicenses = new ArrayList<>();
57+
for (License license : packageInfo.licenses()) {
7458
// fiter out all compliant categories, the remaining ones are non-compliant.
7559
List<LicenseCategory> nonCompliantCategories = license
7660
.getCategories()
7761
.stream()
7862
.filter(category -> !compliantCategories.contains(category))
7963
.toList();
8064
if (!nonCompliantCategories.isEmpty()) {
81-
nonCompliantLicenses.add(licenseStr);
65+
nonCompliantLicenses.add(license);
8266
}
8367
}
8468
if (!nonCompliantLicenses.isEmpty()) {
@@ -88,39 +72,18 @@ private Map<VersionKey, List<String>> getNonCompliantLicenses(List<PackageInfo>
8872
return licenses;
8973
}
9074

91-
private <T> void formatLog(VersionKey root, Map<VersionKey, List<T>> map, String message) {
92-
LOGGER.log(Level.SEVERE, message);
93-
map.forEach((versionKey, list) -> {
94-
LOGGER.log(Level.SEVERE, beginSeparator(versionKey, root));
95-
list.forEach(item -> LOGGER.log(Level.SEVERE, item.toString()));
96-
LOGGER.log(Level.SEVERE, endSeparator());
97-
});
98-
}
99-
100-
private String beginSeparator(VersionKey versionKey, VersionKey root) {
101-
String relation = versionKey.equals(root) ? "self" : "dependency";
102-
return String.format("====================== %s, %s of %s ======================",
103-
versionKey, relation, root);
104-
}
105-
106-
private String endSeparator() {
107-
return "===========================================================";
108-
}
109-
110-
public String packageInfoReport() {
75+
private String packageInfoReport() {
11176
StringBuilder builder = new StringBuilder();
11277
PackageInfo root = packageInfos.get(0);
11378
String title = String.format("""
114-
Please copy and paste the package information below to your ticket.
115-
11679
## Package information of %s
11780
%s
11881
""", root.versionKey(), packageInfoSection(root));
11982
builder.append(title);
12083

121-
builder.append("## Dependencies:\n");
84+
builder.append("## Dependencies\n");
12285
if (packageInfos.size() == 1) {
123-
builder.append("None");
86+
builder.append(String.format("%s has no dependency.", root.versionKey()));
12487
} else {
12588
for (int i = 1; i < packageInfos.size(); i++) {
12689
PackageInfo info = packageInfos.get(i);
@@ -141,11 +104,12 @@ private String packageInfoSection(PackageInfo packageInfo) {
141104
// generate the report using Markdown format.
142105
String packageInfoReport = """
143106
Licenses: %s
144-
Vulnerabilities: None.
107+
Vulnerabilities: %s.
145108
Checked in [%s (%s)](%s)
146109
""";
147110
return String.format(packageInfoReport,
148111
packageInfo.licenses(),
112+
packageInfo.advisories(),
149113
versionKey.name(),
150114
versionKey.version(),
151115
getQueryUrl(

java-shared-dependencies/dependency-analyzer/src/main/java/com/google/cloud/model/License.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,17 @@ public Set<LicenseCategory> getCategories() {
5151

5252
@Override
5353
public String toString() {
54+
String nonCompliantPrefix = "%s (Not Google-compliant!)";
55+
String compliantPrefix = "%s (Google-compliant)";
5456
Set<LicenseCategory> compliantCategories = LicenseCategory.compliantCategories();
57+
if (this.categories.isEmpty()) {
58+
return String.format(nonCompliantPrefix, this.licenseStr);
59+
}
5560
for (LicenseCategory category : this.categories) {
5661
if (!compliantCategories.contains(category)) {
57-
return this.licenseStr;
62+
return String.format(nonCompliantPrefix, this.licenseStr);
5863
}
5964
}
60-
return String.format("%s (Google-compliant)", this.licenseStr);
65+
return String.format(compliantPrefix, this.licenseStr);
6166
}
6267
}

java-shared-dependencies/dependency-analyzer/src/main/java/com/google/cloud/model/PackageInfo.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
*/
1010
public record PackageInfo(
1111
VersionKey versionKey,
12-
List<String> licenses,
12+
List<License> licenses,
1313
List<Advisory> advisories) {
1414

15-
public List<String> licenses() {
15+
public List<License> licenses() {
1616
return ImmutableList.copyOf(licenses);
1717
}
1818

java-shared-dependencies/dependency-analyzer/src/test/java/com/google/cloud/model/AnalysisResultTest.java

+66-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
public class AnalysisResultTest {
1010

1111
@Test
12-
public void testGenerateReportWithAdvisoriesThrowsException()
12+
public void testGenerateReportWithAdvisoriesReturnsFailure()
1313
throws IllegalArgumentException {
1414
VersionKey root = VersionKey.from("maven", "com.example:artifact", "1.2.3");
1515
List<PackageInfo> results = List.of(
@@ -26,22 +26,22 @@ public void testGenerateReportWithAdvisoriesThrowsException()
2626
))
2727
)
2828
);
29-
ReportResult result = AnalysisResult.of(root, results).generateReport();
29+
ReportResult result = AnalysisResult.of(results).getAnalysisResult();
3030
assertEquals(ReportResult.FAIL, result);
3131
}
3232

3333
@Test
34-
public void testGenerateReportWithNonCompliantLicenseThrowsException()
34+
public void testGenerateReportWithNonCompliantLicenseReturnsFailure()
3535
throws IllegalArgumentException {
3636
VersionKey root = VersionKey.from("maven", "com.example:artifact", "1.2.3");
3737
List<PackageInfo> results = List.of(
3838
new PackageInfo(
3939
root,
40-
List.of("BCL"),
40+
List.of(License.toLicense("BCL")),
4141
List.of()
4242
)
4343
);
44-
ReportResult result = AnalysisResult.of(root, results).generateReport();
44+
ReportResult result = AnalysisResult.of(results).getAnalysisResult();
4545
assertEquals(ReportResult.FAIL, result);
4646
}
4747

@@ -52,54 +52,100 @@ public void testGenerateReportWithoutRiskSucceeds()
5252
List<PackageInfo> results = List.of(
5353
new PackageInfo(
5454
root,
55-
List.of("Apache-2.0"),
55+
List.of(License.toLicense("Apache-2.0")),
5656
List.of()
5757
)
5858
);
59-
ReportResult result = AnalysisResult.of(root, results).generateReport();
59+
ReportResult result = AnalysisResult.of(results).getAnalysisResult();
6060
assertEquals(ReportResult.PASS, result);
6161
}
6262

6363
@Test
64-
public void testPackageInfoReportReturnsCorrectContents() {
64+
public void testToStringReturnsNoRiskInformation() {
6565
VersionKey root = VersionKey.from("maven", "com.example:artifact", "1.2.3");
6666
List<PackageInfo> results = List.of(
6767
new PackageInfo(
6868
root,
69-
List.of("Apache-2.0"),
69+
List.of(License.toLicense("Apache-2.0")),
7070
List.of()
7171
),
7272
new PackageInfo(
7373
VersionKey.from("maven", "com.example:dependency", "4.5.6"),
74-
List.of("Apache-2.0", "MIT"),
74+
List.of(License.toLicense("Apache-2.0"), License.toLicense("MIT")),
7575
List.of()
7676
),
7777
new PackageInfo(
7878
VersionKey.from("maven", "com.example:nested-dependency", "2.3.1"),
79-
List.of("Apache-2.0", "MIT"),
79+
List.of(License.toLicense("Apache-2.0"), License.toLicense("MIT")),
8080
List.of()
8181
)
8282
);
8383
assertEquals("""
84-
Please copy and paste the package information below to your ticket.
84+
## Package information of com.example:artifact:1.2.3
85+
Licenses: [Apache-2.0 (Google-compliant)]
86+
Vulnerabilities: [].
87+
Checked in [com.example:artifact (1.2.3)](https://api.deps.dev/v3/query?versionKey.system=MAVEN&versionKey.name=com.example:artifact&versionKey.version=1.2.3)
88+
89+
## Dependencies
90+
### Package information of com.example:dependency:4.5.6
91+
Licenses: [Apache-2.0 (Google-compliant), MIT (Google-compliant)]
92+
Vulnerabilities: [].
93+
Checked in [com.example:dependency (4.5.6)](https://api.deps.dev/v3/query?versionKey.system=MAVEN&versionKey.name=com.example:dependency&versionKey.version=4.5.6)
94+
95+
### Package information of com.example:nested-dependency:2.3.1
96+
Licenses: [Apache-2.0 (Google-compliant), MIT (Google-compliant)]
97+
Vulnerabilities: [].
98+
Checked in [com.example:nested-dependency (2.3.1)](https://api.deps.dev/v3/query?versionKey.system=MAVEN&versionKey.name=com.example:nested-dependency&versionKey.version=2.3.1)
99+
85100
101+
""", AnalysisResult.of(results).toString());
102+
}
103+
104+
@Test
105+
public void testToStringReturnsRiskInformation() {
106+
VersionKey root = VersionKey.from("maven", "com.example:artifact", "1.2.3");
107+
List<PackageInfo> results = List.of(
108+
new PackageInfo(
109+
root,
110+
List.of(License.APACHE_2_0, License.BCL),
111+
List.of()
112+
),
113+
new PackageInfo(
114+
VersionKey.from("maven", "com.example:dependency", "4.5.6"),
115+
List.of(License.MIT),
116+
List.of(new Advisory(
117+
new AdvisoryKey("GHSA-2qrg-x229-3v8q"),
118+
"https://osv.dev/vulnerability/GHSA-2qrg-x229-3v8q",
119+
"Deserialization of Untrusted Data in Log4j",
120+
new String[]{"CVE-2019-17571"},
121+
9.8,
122+
"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
123+
))
124+
),
125+
new PackageInfo(
126+
VersionKey.from("maven", "com.example:nested-dependency", "2.3.1"),
127+
List.of(License.MIT, License.GL2PS),
128+
List.of()
129+
)
130+
);
131+
assertEquals("""
86132
## Package information of com.example:artifact:1.2.3
87-
Licenses: [Apache-2.0]
88-
Vulnerabilities: None.
133+
Licenses: [Apache-2.0 (Google-compliant), BCL (Not Google-compliant!)]
134+
Vulnerabilities: [].
89135
Checked in [com.example:artifact (1.2.3)](https://api.deps.dev/v3/query?versionKey.system=MAVEN&versionKey.name=com.example:artifact&versionKey.version=1.2.3)
90136
91-
## Dependencies:
137+
## Dependencies
92138
### Package information of com.example:dependency:4.5.6
93-
Licenses: [Apache-2.0, MIT]
94-
Vulnerabilities: None.
139+
Licenses: [MIT (Google-compliant)]
140+
Vulnerabilities: [Advisory (id: GHSA-2qrg-x229-3v8q, more info: [Deserialization of Untrusted Data in Log4j](https://osv.dev/vulnerability/GHSA-2qrg-x229-3v8q))].
95141
Checked in [com.example:dependency (4.5.6)](https://api.deps.dev/v3/query?versionKey.system=MAVEN&versionKey.name=com.example:dependency&versionKey.version=4.5.6)
96142
97143
### Package information of com.example:nested-dependency:2.3.1
98-
Licenses: [Apache-2.0, MIT]
99-
Vulnerabilities: None.
144+
Licenses: [MIT (Google-compliant), GL2PS (Not Google-compliant!)]
145+
Vulnerabilities: [].
100146
Checked in [com.example:nested-dependency (2.3.1)](https://api.deps.dev/v3/query?versionKey.system=MAVEN&versionKey.name=com.example:nested-dependency&versionKey.version=2.3.1)
101147
102148
103-
""", AnalysisResult.of(root, results).packageInfoReport());
149+
""", AnalysisResult.of(results).toString());
104150
}
105151
}

0 commit comments

Comments
 (0)