Skip to content

Commit

Permalink
feat: Implement updated pull request comments (HTML and MD)
Browse files Browse the repository at this point in the history
Signed-off-by: Oleg Kopysov <[email protected]>
  • Loading branch information
o-kopysov committed Aug 27, 2024
1 parent 62d4c96 commit e5d8ff3
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 53 deletions.
222 changes: 222 additions & 0 deletions src/main/java/com/lpvs/entity/report/LPVSReportBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,228 @@ public static void saveHTMLToFile(String htmlContent, String filePath) {
}
}

/**
* Generates a comment to the pull request for publication to the VCS.
*
* @param scanResults the results of the license scan
* @param conflicts a list of license conflicts found during the scan
* @param webhookConfig configuration related to the repository and webhook
* @param vcs the string representation of the version control system
* @return the code of the generated VCS comment
*/
public String generatePullRequestComment(List<LPVSFile> scanResults,
List<LPVSLicenseService.Conflict<String, String>> conflicts,
LPVSQueue webhookConfig,
LPVSVcs vcs) {

StringBuilder commitCommentBuilder = new StringBuilder();
commitCommentBuilder.append("**Detected licenses:**\n\n");

Map<String, GroupInfo<?>> detectedLicenseInfo = groupScanResultsForLicenseTable(scanResults);
long prohibitedLicenses = getDetectedLicenseCountByType(detectedLicenseInfo, prohibited);
long restrictedLicenses = getDetectedLicenseCountByType(detectedLicenseInfo, restricted);
long unreviewedLicenses = getDetectedLicenseCountByType(detectedLicenseInfo, unreviewed);
long licenseDetected = prohibitedLicenses + restrictedLicenses + unreviewedLicenses;

if (licenseDetected > 0) {
commitCommentBuilder.append("Potential license problem(s) detected:\n");
if (prohibitedLicenses > 0) {
commitCommentBuilder.append(" - Prohibited license(s): " + prohibitedLicenses + "\n");
}
if (restrictedLicenses > 0) {
commitCommentBuilder.append(" - Restricted license(s): " + restrictedLicenses + "\n");
}
if (unreviewedLicenses > 0) {
commitCommentBuilder.append(" - Unreviewed license(s): " + unreviewedLicenses + "\n");
}
} else {
commitCommentBuilder.append("No license problems detected.\n");
}
if (scanResults != null && !scanResults.isEmpty()) {
commitCommentBuilder.append("\n")
.append(generateLicenseTable(detectedLicenseInfo, webhookConfig, vcs))
.append("\n");
}
commitCommentBuilder.append("\n");
commitCommentBuilder.append("**Detected License Conflicts:**\n\n");
if (conflicts != null && !conflicts.isEmpty()) {
commitCommentBuilder.append(
"Potential license conflict(s) detected: "
+ conflicts.size()
+ "\n");
commitCommentBuilder.append("\n")
.append(generateLicenseConflictsTable(conflicts, vcs))
.append("\n");
} else {
commitCommentBuilder.append("No license conflicts detected.\n");
}
commitCommentBuilder.append("\n");

return commitCommentBuilder.toString();
}

/**
* Generates an HTML code of the license table to pull request comments
*
* @param detectedLicenseInfo grouped scan results by license SPDX ID and access type, component name and vendor
* @param webhookConfig configuration related to the repository and webhook
* @param vcs the string representation of the version control system
* @return the HTML code of the generated license table
*/
private String generateLicenseTable(Map<String, GroupInfo<?>> detectedLicenseInfo, LPVSQueue webhookConfig, LPVSVcs vcs) {
if (vcs != null && vcs.equals(LPVSVcs.GITHUB)) {
return "<details>" +
"\n" +
"<summary>" +
"Detailed description of detected licenses" +
"\n" +
"</summary>" +
"\n" +
generateLicenseTableHTML(detectedLicenseInfo, webhookConfig, vcs) +
"\n" +
"</details>";
}
return generateLicenseTableMD(detectedLicenseInfo, webhookConfig, vcs);
}

/**
* Generates an HTML code of the license conflicts table to pull request comments
*
* @param conflicts a list of license conflicts found during the scan
* @param vcs the string representation of the version control system
* @return the code of the generated license conflicts table
*/
private String generateLicenseConflictsTable(List<LPVSLicenseService.Conflict<String, String>> conflicts, LPVSVcs vcs) {
if (vcs != null && vcs.equals(LPVSVcs.GITHUB)) {
return "<details>" +
"\n" +
"<summary>" +
"Detailed description of detected license conflicts" +
"\n" +
"</summary>" +
"\n" +
generateLicenseConflictsTableHTML(conflicts) +
"\n" +
"</details>";
}
return generateLicenseConflictsTableMD(conflicts);
}

/**
* Generates an MD code of the license table to pull request comments
*
* @param detectedLicenseInfo grouped scan results by license SPDX ID and access type, component name and vendor
* @param webhookConfig configuration related to the repository and webhook
* @param vcs the string representation of the version control system
* @return the MD code of the generated license table
*/
private String generateLicenseTableMD(Map<String, GroupInfo<?>> detectedLicenseInfo, LPVSQueue webhookConfig, LPVSVcs vcs) {
StringBuilder mdBuilder = new StringBuilder();
mdBuilder.append("|License Type / Explanation")
.append("|License SPDX ID")
.append("|Vendor / Component")
.append("|Version")
.append("|Repository File Path")
.append("|Component File Path")
.append("|Matched Lines")
.append("|Match Value|")
.append("\n")
.append("|-|-|-|-|-|-|-|-|")
.append("\n");
// Prohibited licenses
addBlockOfTableForLicenseTypeMD(mdBuilder, detectedLicenseInfo, prohibited, webhookConfig, vcs);
// Restricted licenses
addBlockOfTableForLicenseTypeMD(mdBuilder, detectedLicenseInfo, restricted, webhookConfig, vcs);
// Unreviewed licenses
addBlockOfTableForLicenseTypeMD(mdBuilder, detectedLicenseInfo, unreviewed, webhookConfig, vcs);
// Permitted licenses
addBlockOfTableForLicenseTypeMD(mdBuilder, detectedLicenseInfo, permitted, webhookConfig, vcs);

return mdBuilder.toString();
}

/**
* Generates the license conflicts table MD content.
*
* @param conflicts a list of license conflicts
* @return the MDmvn content for the license conflicts table
*/
private String generateLicenseConflictsTableMD(
List<LPVSLicenseService.Conflict<String, String>> conflicts) {
StringBuilder mdBuilder = new StringBuilder();
mdBuilder
.append("|Conflict>")
.append("|Explanation|")
.append("\n")
.append("|-|-|")
.append("\n");

for (LPVSLicenseService.Conflict<String, String> conflict : conflicts) {
mdBuilder
.append("|")
.append(conflict.l1)
.append(" and ")
.append(conflict.l2)
.append("|")
.append(getExplanationForLicenseConflict(conflict.l1, conflict.l2))
.append("|")
.append("\n");
}
return mdBuilder.toString();
}

/**
* Generates an MD code of the license conflicts table to pull request comments
*
* @param mdBuilder the StringBuilder object to which the MD content will be appended
* @param detectedLicenseInfo grouped scan results by license SPDX ID and access type, component name and vendor
* @param webhookConfig configuration related to the repository and webhook
* @param vcs the string representation of the version control system
*/
private void addBlockOfTableForLicenseTypeMD(StringBuilder mdBuilder, Map<String, GroupInfo<?>> detectedLicenseInfo, String type, LPVSQueue webhookConfig, LPVSVcs vcs) {
long detectedLicenseCountByType = getDetectedLicenseCountByType(detectedLicenseInfo, type);
if (detectedLicenseCountByType > 0) {
// license spdx id
Map<String, GroupInfo<?>> licenseSpdxIds =
(Map<String, GroupInfo<?>>) detectedLicenseInfo.get(type).elements;
for (String licenseSpdxId : licenseSpdxIds.keySet()) {
// vendor + component
Map<String, GroupInfo<?>> componentAndVendor =
(Map<String, GroupInfo<?>>) licenseSpdxIds.get(licenseSpdxId).elements;
for (String componentInfo : componentAndVendor.keySet()) {
// file info
List<LPVSFile> fileInfos =
(List<LPVSFile>) componentAndVendor.get(componentInfo).elements;
for (LPVSFile fileInfo : fileInfos) {
mdBuilder.append("|")
.append(type)
.append(" / ")
.append(getExplanationForLicenseType(type))
.append("|")
.append(licenseSpdxId)
.append("|")
.append(componentInfo.split(":::")[0])
.append(" (")
.append(componentInfo.split(":::")[1])
.append(")")
.append("|")
.append(fileInfo.getComponentVersion())
.append("|")
.append(fileInfo.getFilePath())
.append("|")
.append(fileInfo.getComponentFilePath())
.append("|")
.append(getMatchedLinesAsLink(webhookConfig, fileInfo, vcs))
.append("|")
.append(fileInfo.getSnippetMatch())
.append("|")
.append("\n");
}
}
}
}
}

/**
* Generates the license conflicts table HTML content.
*
Expand Down
38 changes: 7 additions & 31 deletions src/main/java/com/lpvs/service/LPVSGitHubService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.lpvs.entity.LPVSQueue;
import com.lpvs.entity.enums.LPVSPullRequestStatus;
import com.lpvs.entity.enums.LPVSVcs;
import com.lpvs.entity.report.LPVSReportBuilder;
import com.lpvs.repository.LPVSDetectedLicenseRepository;
import com.lpvs.repository.LPVSLicenseConflictRepository;
import com.lpvs.repository.LPVSLicenseRepository;
Expand Down Expand Up @@ -249,25 +250,12 @@ public void commentResults(

boolean hasProhibitedOrRestricted = false;
boolean hasConflicts = false;
String commitComment = "";
LPVSReportBuilder reportBuilder = new LPVSReportBuilder(null);
String commitComment = reportBuilder.generatePullRequestComment(scanResults, conflicts, webhookConfig, LPVSVcs.GITHUB);

if (scanResults != null && scanResults.size() != 0) {
commitComment = "**Detected licenses:**\n\n\n";

if (scanResults != null && !scanResults.isEmpty()) {
for (LPVSFile file : scanResults) {
commitComment += "**File:** " + file.getFilePath() + "\n";
commitComment += "**License(s):** " + file.convertLicensesToString(LPVSVcs.GITHUB);
commitComment +=
"**Component:** "
+ file.getComponentName()
+ " ("
+ file.getComponentFilePath()
+ ")\n";
commitComment +=
"**Matched Lines:** "
+ LPVSCommentUtil.getMatchedLinesAsLink(
webhookConfig, file, LPVSVcs.GITHUB)
+ "\n";
commitComment += "**Snippet Match:** " + file.getSnippetMatch() + "\n\n\n\n";
for (LPVSLicense license : file.getLicenses()) {
LPVSDetectedLicense detectedIssue = new LPVSDetectedLicense();
detectedIssue.setPullRequest(lpvsPullRequest);
Expand Down Expand Up @@ -297,13 +285,9 @@ public void commentResults(
}
}

StringBuilder commitCommentBuilder = new StringBuilder();
if (conflicts != null && conflicts.size() > 0) {
if (conflicts != null && !conflicts.isEmpty()) {
hasConflicts = true;
commitCommentBuilder.append("**Detected license conflicts:**\n\n\n");
commitCommentBuilder.append("<ul>");
for (LPVSLicenseService.Conflict<String, String> conflict : conflicts) {
commitCommentBuilder.append("<li>" + conflict.l1 + " and " + conflict.l2 + "</li>");
LPVSDetectedLicense detectedIssue = new LPVSDetectedLicense();
detectedIssue.setPullRequest(lpvsPullRequest);
Long l1 =
Expand All @@ -330,15 +314,7 @@ public void commentResults(
detectedIssue.setIssue(true);
lpvsDetectedLicenseRepository.saveAndFlush(detectedIssue);
}
commitCommentBuilder.append("</ul>");
}
if (null != webhookConfig.getHubLink()) {
commitCommentBuilder.append(
"\n\n###### <p align='right'>Check the validation details at the [link](");
commitCommentBuilder.append(webhookConfig.getHubLink());
commitCommentBuilder.append(")</p>");
}
commitComment += commitCommentBuilder.toString();

if (hasProhibitedOrRestricted || hasConflicts) {
lpvsPullRequest.setStatus(LPVSPullRequestStatus.ISSUES_DETECTED.toString());
Expand All @@ -362,7 +338,7 @@ public void commentResults(
webhookConfig.getHeadCommitSHA(),
GHCommitState.SUCCESS,
null,
"No license issue detected",
"No license issue(s) detected",
"[License Pre-Validation Service]");
}
}
Expand Down
Loading

0 comments on commit e5d8ff3

Please sign in to comment.