Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: HTML file report generation for single scan #576

Merged
merged 3 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
536 changes: 536 additions & 0 deletions src/main/java/com/lpvs/entity/report/LPVSReportBuilder.java

Large diffs are not rendered by default.

22 changes: 18 additions & 4 deletions src/main/java/com/lpvs/service/scan/LPVSDetectService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.Date;
import java.util.List;

import com.lpvs.entity.report.LPVSReportBuilder;
import com.lpvs.service.LPVSGitHubConnectionService;
import com.lpvs.service.LPVSGitHubService;
import com.lpvs.service.LPVSLicenseService;
Expand All @@ -32,6 +33,8 @@

import lombok.extern.slf4j.Slf4j;

import static com.lpvs.entity.report.LPVSReportBuilder.saveHTMLToFile;

/**
* Service class for detecting licenses in GitHub pull requests using a specified scanner.
*/
Expand Down Expand Up @@ -59,6 +62,11 @@ public class LPVSDetectService {
*/
private LPVSScanService scanService;

/**
* Component responsible for the generation of HTML reports.
*/
private LPVSReportBuilder reportBuilder;

/**
* Trigger value to start a single scan of a pull request (optional).
*/
Expand Down Expand Up @@ -91,6 +99,7 @@ public class LPVSDetectService {
* @param licenseService Service for license conflict analysis.
* @param gitHubService Service for GitHub connection and operation.
* @param scanServiceFactory Service for creating instance of the scanner.
* @param reportBuilder Service for generating HTML reports.
*/
@Autowired
public LPVSDetectService(
Expand All @@ -99,12 +108,14 @@ public LPVSDetectService(
LPVSGitHubConnectionService gitHubConnectionService,
LPVSLicenseService licenseService,
LPVSGitHubService gitHubService,
LPVSScanServiceFactory scanServiceFactory) {
LPVSScanServiceFactory scanServiceFactory,
LPVSReportBuilder reportBuilder) {
this.gitHubConnectionService = gitHubConnectionService;
this.licenseService = licenseService;
this.gitHubService = gitHubService;
this.scanService = scanServiceFactory.createScanService(scannerType, isInternal);
log.info("License detection scanner: " + scannerType);
this.reportBuilder = reportBuilder;
}

/**
Expand All @@ -117,6 +128,7 @@ public void runSingleScan() {
LPVSQueue webhookConfig = null;
List<LPVSFile> scanResult = null;
List<LPVSLicenseService.Conflict<String, String>> detectedConflicts = null;
String path = null;

// Error case when both pull request scan and local files scan are set to true
if (!StringUtils.isBlank(trigger) && !StringUtils.isBlank(localPath)) {
Expand All @@ -138,6 +150,7 @@ public void runSingleScan() {

detectedConflicts = licenseService.findConflicts(webhookConfig, scanResult);
generateReport = true;
path = HtmlUtils.htmlEscape(trigger);
log.info("Single scan of pull request completed.");
} catch (Exception ex) {
log.error("Single scan of pull request failed with error: " + ex.getMessage());
Expand Down Expand Up @@ -165,6 +178,7 @@ public void runSingleScan() {

detectedConflicts = licenseService.findConflicts(webhookConfig, scanResult);
generateReport = true;
path = localFile.getAbsolutePath();
log.info("Single scan of local file(s) completed.");
} else {
throw new Exception("File path does not exist: " + localPath);
Expand All @@ -187,9 +201,9 @@ public void runSingleScan() {
File folder = new File(folderPath);
if (folder.exists() && folder.isDirectory()) {
String reportFile =
LPVSCommentUtil.buildHTMLComment(
webhookConfig, scanResult, detectedConflicts);
LPVSCommentUtil.saveHTMLToFile(reportFile, report.getAbsolutePath());
reportBuilder.generateHtmlReportSingleScan(
path, scanResult, detectedConflicts, null, null);
saveHTMLToFile(reportFile, report.getAbsolutePath());
} else {
log.error("Error: The parent directory '" + folder.getPath() + "' does not exist.");
}
Expand Down
94 changes: 3 additions & 91 deletions src/main/java/com/lpvs/util/LPVSCommentUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
*/
package com.lpvs.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import com.lpvs.entity.LPVSDetectedLicense;
Expand Down Expand Up @@ -44,6 +39,9 @@ public class LPVSCommentUtil {
*/
public static String getMatchedLinesAsLink(
LPVSQueue webhookConfig, LPVSFile file, LPVSVcs vcs) {
if (webhookConfig == null) {
return file.getMatchedLines();
}
String prefix =
LPVSPayloadUtil.getRepositoryUrl(webhookConfig)
+ "/blob/"
Expand Down Expand Up @@ -138,90 +136,4 @@ public static String reportCommentBuilder(

return commitCommentBuilder.toString();
}

/**
* Generates a formatted string for an HTML report with scan results.
*
* @param webhookConfig The {@link LPVSQueue} configuration for the webhook.
* @param scanResults List containing preformatted scan results.
* @param conflicts List containing license conflict information.
* @return A string containing scan results in HTML format.
*/
public static String buildHTMLComment(
LPVSQueue webhookConfig,
List<LPVSFile> scanResults,
List<LPVSLicenseService.Conflict<String, String>> conflicts) {
StringBuilder htmlBuilder = new StringBuilder();

htmlBuilder.append("<html><body>");

if (scanResults != null && scanResults.size() != 0) {
htmlBuilder.append("<h2>Detected licenses:</h2>");
for (LPVSFile file : scanResults) {
htmlBuilder
.append("<p><strong>File:</strong> ")
.append(file.getFilePath())
.append("</p>");
htmlBuilder
.append("<p><strong>License(s):</strong> ")
.append(file.convertLicensesToString(LPVSVcs.GITHUB))
.append("</p>");
htmlBuilder
.append("<p><strong>Component:</strong> ")
.append(file.getComponentName())
.append(" (")
.append(file.getComponentFilePath())
.append(")</p>");
htmlBuilder
.append("<p><strong>Matched Lines:</strong> ")
.append(
LPVSCommentUtil.getMatchedLinesAsLink(
webhookConfig, file, LPVSVcs.GITHUB))
.append("</p>");
htmlBuilder
.append("<p><strong>Snippet Match:</strong> ")
.append(file.getSnippetMatch())
.append("</p>");
htmlBuilder.append("<hr>");
}
}

if (conflicts != null && conflicts.size() > 0) {
htmlBuilder.append("<h2>Detected license conflicts:</h2>");
htmlBuilder.append("<ul>");
for (LPVSLicenseService.Conflict<String, String> conflict : conflicts) {
htmlBuilder
.append("<li>")
.append(conflict.l1)
.append(" and ")
.append(conflict.l2)
.append("</li>");
}
htmlBuilder.append("</ul>");
if (webhookConfig.getHubLink() != null) {
htmlBuilder.append("<p>").append(webhookConfig.getHubLink()).append("</p>");
}
}

htmlBuilder.append("</body></html>");

return htmlBuilder.toString();
}

/**
* Saves HTML report to given location.
*
* @param htmlContent The string, containing report in HTML format.
* @param filePath The path to expected html report file.
*/
public static void saveHTMLToFile(String htmlContent, String filePath) {
File file = new File(filePath);
try (BufferedWriter writer =
new BufferedWriter(new FileWriter(file, StandardCharsets.UTF_8))) {
writer.write(htmlContent);
log.info("LPVS report saved to: " + filePath);
} catch (IOException ex) {
log.error("error during saving HTML report: " + ex.getMessage());
}
}
}
141 changes: 141 additions & 0 deletions src/main/resources/templates/report_single_scan.html

Large diffs are not rendered by default.

Loading
Loading