From ee6d1990a4bc2cc2f1e0ad2999e025b90bb4e5be Mon Sep 17 00:00:00 2001 From: azinneera Date: Wed, 19 Nov 2025 12:11:10 +0530 Subject: [PATCH 1/5] Support scanning workspace projects --- gradle.properties | 2 +- .../io/ballerina/scan/test/TestScanCmd.java | 9 +- scan-command/build.gradle | 18 ++- .../io/ballerina/scan/internal/ScanCmd.java | 125 +++++++++++++++--- .../io/ballerina/scan/utils/Constants.java | 5 +- .../io/ballerina/scan/utils/ScanUtils.java | 16 ++- .../scan/internal/ProjectAnalyzerTest.java | 18 +-- .../scan/internal/ReporterImplTest.java | 12 +- .../ballerina/scan/internal/ScanCmdTest.java | 65 ++++++--- .../scan/internal/StaticCodeAnalyzerTest.java | 4 +- .../ballerina/scan/utils/ScanUtilsTest.java | 28 ++-- .../unix/exclude-rules-issues-report.txt | 6 +- .../unix/include-rules-issues-report.txt | 2 +- .../unix/platform-plugin-issue-output.txt | 2 +- .../unix/toml-exclude-rules-issues-report.txt | 6 +- .../unix/toml-include-rules-issues-report.txt | 2 +- .../command-outputs/unix/workspace-issues.txt | 42 ++++++ .../windows/exclude-rules-issues-report.txt | 6 +- .../windows/include-rules-issues-report.txt | 2 +- .../windows/platform-plugin-issue-output.txt | 2 +- .../toml-exclude-rules-issues-report.txt | 6 +- .../toml-include-rules-issues-report.txt | 2 +- .../workspace-project/Ballerina.toml | 2 + .../.gitignore | 4 + .../Ballerina.toml | 4 + .../Scan.toml | 15 +++ .../main.bal | 22 +++ .../.gitignore | 4 + .../Ballerina.toml | 4 + .../Scan.toml | 20 +++ .../main.bal | 22 +++ scan-command/tool-scan/Ballerina.toml | 2 +- scan-command/tool-scan/Dependencies.toml | 2 +- 33 files changed, 374 insertions(+), 107 deletions(-) create mode 100644 scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/Ballerina.toml create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/.gitignore create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Ballerina.toml create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Scan.toml create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/main.bal create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/.gitignore create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Ballerina.toml create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Scan.toml create mode 100644 scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/main.bal diff --git a/gradle.properties b/gradle.properties index fdfa4b60..7d2a761a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ enterprisePluginVersion=3.18.1 # Dependency versions picoCLIVersion=4.7.5 gsonVersion=2.10.1 -ballerinaLangVersion=2201.12.0 +ballerinaLangVersion=2201.13.0 puppycrawlCheckstyleVersion=10.12.1 apacheCommonsLang3Version=3.0 commonsIoVersion=2.15.1 diff --git a/scan-command-test-utils/src/main/java/io/ballerina/scan/test/TestScanCmd.java b/scan-command-test-utils/src/main/java/io/ballerina/scan/test/TestScanCmd.java index 79351836..84d08747 100644 --- a/scan-command-test-utils/src/main/java/io/ballerina/scan/test/TestScanCmd.java +++ b/scan-command-test-utils/src/main/java/io/ballerina/scan/test/TestScanCmd.java @@ -20,8 +20,7 @@ import io.ballerina.projects.Project; import io.ballerina.projects.ProjectEnvironmentBuilder; -import io.ballerina.projects.directory.BuildProject; -import io.ballerina.projects.directory.SingleFileProject; +import io.ballerina.projects.directory.ProjectLoader; import io.ballerina.projects.environment.Environment; import io.ballerina.projects.environment.EnvironmentBuilder; import io.ballerina.scan.internal.ProjectAnalyzer; @@ -72,11 +71,7 @@ public class TestScanCmd extends ScanCmd { Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - if (projectPath.toFile().isDirectory()) { - project = BuildProject.load(getEnvironmentBuilder(distributionPath), projectPath); - } else { - project = SingleFileProject.load(getEnvironmentBuilder(distributionPath), projectPath); - } + project = ProjectLoader.load(projectPath, getEnvironmentBuilder(distributionPath)).project(); } @Override diff --git a/scan-command/build.gradle b/scan-command/build.gradle index 3a0bfbab..5a0c6e67 100644 --- a/scan-command/build.gradle +++ b/scan-command/build.gradle @@ -279,8 +279,22 @@ build { // Configuring tests tasks.test { - systemProperty "ballerina.home", Paths.get(System.getenv("BALLERINA_HOME")).resolve("distributions") - .resolve("ballerina-${ballerinaLangVersion}").toString() + // set ballerina home is env var is set + def ballerinaHome = System.getenv("BALLERINA_HOME") + if (ballerinaHome != null) { + systemProperty 'ballerina.home', ballerinaHome + } else { + try { + def balHomeOutput = new ByteArrayOutputStream() + exec { + commandLine 'bal', 'home' + standardOutput = balHomeOutput + } + systemProperty 'ballerina.home', balHomeOutput.toString().trim() + } catch (Exception e) { + println "Warning: Could not determine ballerina.home from 'bal home' command: ${e.message}" + } + } useTestNG() { suites 'src/test/resources/testng.xml' diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java b/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java index 6b1aa2c3..d9486f1a 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java @@ -18,18 +18,25 @@ package io.ballerina.scan.internal; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; import io.ballerina.cli.BLauncherCmd; import io.ballerina.projects.Project; import io.ballerina.projects.ProjectKind; +import io.ballerina.projects.ProjectLoadResult; import io.ballerina.projects.directory.BuildProject; -import io.ballerina.projects.directory.SingleFileProject; +import io.ballerina.projects.directory.ProjectLoader; +import io.ballerina.projects.directory.WorkspaceProject; import io.ballerina.projects.util.ProjectConstants; +import io.ballerina.projects.util.ProjectPaths; import io.ballerina.projects.util.ProjectUtils; import io.ballerina.scan.Issue; import io.ballerina.scan.PlatformPluginContext; import io.ballerina.scan.ReportFormat; import io.ballerina.scan.Rule; import io.ballerina.scan.StaticCodeAnalysisPlatformPlugin; +import io.ballerina.scan.utils.Constants; import io.ballerina.scan.utils.DiagnosticCode; import io.ballerina.scan.utils.DiagnosticLog; import io.ballerina.scan.utils.ScanTomlFile; @@ -46,6 +53,7 @@ import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -107,6 +115,7 @@ public class ScanCmd implements BLauncherCmd { private List platforms = new ArrayList<>(); private final List allRules = new ArrayList<>(); + private final List allIssues; public ScanCmd() { this(System.out); @@ -115,6 +124,7 @@ public ScanCmd() { ScanCmd(PrintStream outputStream) { this.projectPath = Paths.get(System.getProperty(ProjectConstants.USER_DIR)); this.outputStream = outputStream; + this.allIssues = new ArrayList<>(); } protected ScanCmd( @@ -140,6 +150,7 @@ protected ScanCmd( this.includeRules.addAll(includeRules.stream().map(Rule::id).toList()); this.excludeRules.addAll(excludeRules.stream().map(Rule::id).toList()); this.platforms.addAll(platforms); + this.allIssues = new ArrayList<>(); } @Override @@ -176,12 +187,75 @@ public void execute() { return; } + if (project.get().kind() == ProjectKind.WORKSPACE_PROJECT) { + outputStream.println(); + outputStream.println("Resolving workspace dependencies"); + WorkspaceProject workspaceProject = (WorkspaceProject) project.get(); + List topologicallySortedList = + workspaceProject.getResolution().dependencyGraph().toTopologicallySortedList(); + for (BuildProject buildProject : topologicallySortedList) { + if (ProjectUtils.isProjectEmpty(buildProject)) { + outputStream.println(DiagnosticLog.error(DiagnosticCode.EMPTY_PACKAGE)); + continue; + } + executeProject(buildProject); + } + + outputStream.println(); + Path jsonReportPath; + try { + String reportContent = accumulateWorkspaceReports(topologicallySortedList); + jsonReportPath = ScanUtils.getTargetPath(project.get(), targetDir).getReportPath() + .resolve(Constants.RESULTS_JSON_FILE); + Files.writeString(jsonReportPath, reportContent); + } catch (IOException e) { + throw new RuntimeException("Error while obtaining report path: " + e.getMessage()); + } + + outputStream.println("View scan results at:"); + outputStream.println("\t" + jsonReportPath.toUri()); + outputStream.println(); + if (scanReport) { + Path scanReportPath = ScanUtils.generateScanReport(allIssues, project.get(), targetDir); + outputStream.println(); + outputStream.println("View scan report at:"); + outputStream.println("\t" + scanReportPath.toUri() + System.lineSeparator()); + } + + return; + } if (ProjectUtils.isProjectEmpty(project.get())) { outputStream.println(DiagnosticLog.error(DiagnosticCode.EMPTY_PACKAGE)); return; } + executeProject(project.get()); + } + + private String accumulateWorkspaceReports(List topologicallySortedList) { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonArray allIssuesArray = new JsonArray(); - Optional scanTomlFile = ScanUtils.loadScanTomlConfigurations(project.get(), outputStream); + for (BuildProject buildProject : topologicallySortedList) { + try { + Path reportPath = ScanUtils.getTargetPath(buildProject, targetDir).getReportPath() + .resolve(Constants.RESULTS_JSON_FILE); + if (Files.exists(reportPath)) { + String content = Files.readString(reportPath, StandardCharsets.UTF_8); + JsonArray issuesArray = gson.fromJson(content, JsonArray.class); + if (issuesArray != null) { + issuesArray.forEach(allIssuesArray::add); + } + } + } catch (IOException e) { + throw new RuntimeException("Error while obtaining report path: " + e.getMessage()); + } + } + + return gson.toJson(allIssues); + } + + public void executeProject(Project project) { + Optional scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, outputStream); if (scanTomlFile.isEmpty()) { return; } @@ -189,7 +263,7 @@ public void execute() { outputStream.println(); outputStream.println(RUNNING_SCANS_LOG); - ProjectAnalyzer projectAnalyzer = getProjectAnalyzer(project.get(), scanTomlFile.get()); + ProjectAnalyzer projectAnalyzer = getProjectAnalyzer(project, scanTomlFile.get()); List coreRules = CoreRule.rules(); Map> externalAnalyzers; try { @@ -247,25 +321,30 @@ public void execute() { issues.removeIf(issue -> excludeRules.contains(issue.rule().id())); } + allIssues.addAll(issues); + if (platforms.isEmpty() && !platformTriggered) { boolean isSarifFormat = ReportFormat.SARIF.equals(format); - ScanUtils.printToConsole(issues, outputStream, isSarifFormat, project.get()); - if (project.get().kind().equals(ProjectKind.BUILD_PROJECT)) { + ScanUtils.printToConsole(issues, outputStream, isSarifFormat, project); + if (project.kind().equals(ProjectKind.BUILD_PROJECT)) { Path reportPath; if (isSarifFormat) { - reportPath = ScanUtils.saveSarifToDirectory(issues, project.get(), targetDir); + reportPath = ScanUtils.saveSarifToDirectory(issues, project, targetDir); } else { - reportPath = ScanUtils.saveToDirectory(issues, project.get(), targetDir); + reportPath = ScanUtils.saveToDirectory(issues, project, targetDir); } - outputStream.println(); - outputStream.println("View scan results at:"); - outputStream.println("\t" + reportPath.toUri()); - outputStream.println(); - if (scanReport) { - Path scanReportPath = ScanUtils.generateScanReport(issues, project.get(), targetDir); + + if (project.workspaceProject().isEmpty()) { outputStream.println(); - outputStream.println("View scan report at:"); - outputStream.println("\t" + scanReportPath.toUri() + System.lineSeparator()); + outputStream.println("View scan results at:"); + outputStream.println("\t" + reportPath.toUri()); + outputStream.println(); + if (scanReport) { + Path scanReportPath = ScanUtils.generateScanReport(issues, project, targetDir); + outputStream.println(); + outputStream.println("View scan report at:"); + outputStream.println("\t" + scanReportPath.toUri() + System.lineSeparator()); + } } } else { if (targetDir != null) { @@ -315,10 +394,20 @@ private StringBuilder helpMessage() { protected Optional getProject() { try { - if (projectPath.toFile().isDirectory()) { - return Optional.of(BuildProject.load(projectPath)); + if (!ProjectPaths.isBuildProjectRoot(projectPath) + && !ProjectPaths.isStandaloneBalFile(projectPath) + && !ProjectPaths.isWorkspaceProjectRoot(projectPath)) { + outputStream.println("The specified path is not a valid Ballerina project: " + projectPath + ". Please " + + "provide a valid Ballerina project path and try again."); + return Optional.empty(); + } + + ProjectLoadResult loadResult = ProjectLoader.load(projectPath); + if (loadResult.diagnostics().hasErrors()) { + loadResult.diagnostics().errors().forEach(outputStream::println); + return Optional.empty(); } - return Optional.of(SingleFileProject.load(projectPath)); + return Optional.of(loadResult.project()); } catch (RuntimeException ex) { outputStream.println(ex.getMessage()); return Optional.empty(); diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java index 113883ac..d86d7717 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java @@ -18,6 +18,7 @@ package io.ballerina.scan.utils; + import java.io.IOException; import java.io.InputStream; import java.util.Properties; @@ -28,8 +29,8 @@ * @since 0.1.0 */ public class Constants { - static final String RESULTS_JSON_FILE = "scan_results.json"; - static final String RESULTS_SARIF_FILE = "scan_results.sarif"; + public static final String RESULTS_JSON_FILE = "scan_results.json"; + public static final String RESULTS_SARIF_FILE = "scan_results.sarif"; static final String RESULTS_HTML_FILE = "index.html"; static final String REPORT_DATA_PLACEHOLDER = "__data__"; static final String SCAN_REPORT_PROJECT_NAME = "projectName"; diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java b/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java index 6a9f88de..9b16698f 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java @@ -161,7 +161,7 @@ public static void printToConsole(List issues, PrintStream outputStream, * @param issues generated issues * @return json string array of generated issues */ - private static String convertIssuesToJsonString(List issues) { + public static String convertIssuesToJsonString(List issues) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); JsonArray issuesAsJson = gson.toJsonTree(issues).getAsJsonArray(); return gson.toJson(issuesAsJson); @@ -396,7 +396,7 @@ public static Path saveSarifToDirectory(List issues, Project project, Str * @param directoryName target directory name * @return generated target directory */ - private static Target getTargetPath(Project project, String directoryName) { + public static Target getTargetPath(Project project, String directoryName) { try { if (directoryName == null) { return new Target(project.targetDir()); @@ -423,7 +423,13 @@ private static Target getTargetPath(Project project, String directoryName) { */ public static Path generateScanReport(List issues, Project project, String directoryName) { JsonObject scannedProject = new JsonObject(); - scannedProject.addProperty(SCAN_REPORT_PROJECT_NAME, project.currentPackage().packageName().toString()); + String name; + if (project.kind() == ProjectKind.WORKSPACE_PROJECT) { + name = Optional.of(project.sourceRoot().getFileName()).get().toString(); + } else { + name = project.currentPackage().packageName().toString(); + } + scannedProject.addProperty(SCAN_REPORT_PROJECT_NAME, name); Map scanReportPathAndFile = new HashMap<>(); for (Issue issue : issues) { @@ -503,8 +509,8 @@ private static JsonObject getJsonIssue(IssueImpl issueImpl) { scanReportIssueTextRange.addProperty(SCAN_REPORT_ISSUE_TEXT_RANGE_START_LINE, lineRange.startLine().line()); scanReportIssueTextRange.addProperty(SCAN_REPORT_ISSUE_TEXT_RANGE_START_LINE_OFFSET, lineRange.startLine() .offset()); - scanReportIssueTextRange.addProperty(SCAN_REPORT_ISSUE_TEXT_RANGE_END_LINE, lineRange.endLine().line()); - scanReportIssueTextRange.addProperty(SCAN_REPORT_ISSUE_TEXT_RANGE_END_LINE_OFFSET, lineRange.endLine() + scanReportIssueTextRange.addProperty(SCAN_REPORT_ISSUE_TEXT_RANGE_END_LINE, (int) lineRange.endLine().line()); + scanReportIssueTextRange.addProperty(SCAN_REPORT_ISSUE_TEXT_RANGE_END_LINE_OFFSET, (int) lineRange.endLine() .offset()); scanReportIssue.add(SCAN_REPORT_ISSUE_TEXT_RANGE, scanReportIssueTextRange); diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/ProjectAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/ProjectAnalyzerTest.java index 2fa55a04..da2db375 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/ProjectAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/ProjectAnalyzerTest.java @@ -23,7 +23,7 @@ import io.ballerina.projects.DocumentId; import io.ballerina.projects.Module; import io.ballerina.projects.Project; -import io.ballerina.projects.directory.BuildProject; +import io.ballerina.projects.directory.ProjectLoader; import io.ballerina.scan.BaseTest; import io.ballerina.scan.Issue; import io.ballerina.scan.Rule; @@ -51,8 +51,8 @@ * @since 0.1.0 */ public class ProjectAnalyzerTest extends BaseTest { - private final Project project = BuildProject.load(testResources.resolve("test-resources") - .resolve("bal-project-with-config-file")); + private final Project project = ProjectLoader.load(testResources.resolve("test-resources") + .resolve("bal-project-with-config-file")).project(); private ProjectAnalyzer projectAnalyzer = null; @BeforeMethod @@ -153,8 +153,8 @@ private void assertIssue(Issue issue, String fileName, int startLine, int startO @Test(description = "Test analyzing project with invalid external analyzer rules.json configurations") void testAnalyzingProjectWithInvalidExternalAnalyzerRules() throws IOException { - Project invalidProject = BuildProject.load(testResources.resolve("test-resources") - .resolve("bal-project-with-invalid-external-analyzer-rules")); + Project invalidProject = ProjectLoader.load(testResources.resolve("test-resources") + .resolve("bal-project-with-invalid-external-analyzer-rules")).project(); System.setProperty("user.dir", invalidProject.sourceRoot().toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(invalidProject, printStream) .orElse(null); @@ -175,8 +175,8 @@ void testAnalyzingProjectWithInvalidExternalAnalyzerRules() throws IOException { @Test(description = "Test analyzing project with invalid external analyzer rule format") void testAnalyzingProjectWithInvalidExternalAnalyzerRuleFormat() throws IOException { - Project invalidProject = BuildProject.load(testResources.resolve("test-resources") - .resolve("bal-project-with-invalid-external-analyzer-rule-format")); + Project invalidProject = ProjectLoader.load(testResources.resolve("test-resources") + .resolve("bal-project-with-invalid-external-analyzer-rule-format")).project(); System.setProperty("user.dir", invalidProject.sourceRoot().toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(invalidProject, printStream) .orElse(null); @@ -197,8 +197,8 @@ void testAnalyzingProjectWithInvalidExternalAnalyzerRuleFormat() throws IOExcept @Test(description = "Test analyzing project with invalid external analyzer rule kind") void testAnalyzingProjectWithInvalidExternalAnalyzerRuleKind() throws IOException { - Project invalidProject = BuildProject.load(testResources.resolve("test-resources") - .resolve("bal-project-with-invalid-external-analyzer-rule-kind")); + Project invalidProject = ProjectLoader.load(testResources.resolve("test-resources") + .resolve("bal-project-with-invalid-external-analyzer-rule-kind")).project(); System.setProperty("user.dir", invalidProject.sourceRoot().toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(invalidProject, printStream) .orElse(null); diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/ReporterImplTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/ReporterImplTest.java index 7959366b..90f0be4f 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/ReporterImplTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/ReporterImplTest.java @@ -22,7 +22,7 @@ import io.ballerina.projects.Document; import io.ballerina.projects.Module; import io.ballerina.projects.Project; -import io.ballerina.projects.directory.SingleFileProject; +import io.ballerina.projects.directory.ProjectLoader; import io.ballerina.scan.Issue; import io.ballerina.scan.Rule; import io.ballerina.scan.RuleKind; @@ -54,7 +54,7 @@ void testReporterWithNumericId() { ReporterImpl reporter = new ReporterImpl(Collections.singletonList(rule)); Path validBalProject = Paths.get("src", "test", "resources", "test-resources", "valid-single-file-project", "main.bal"); - Project project = SingleFileProject.load(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Module defaultModule = project.currentPackage().getDefaultModule(); Document document = defaultModule.document(defaultModule.documentIds().iterator().next()); ModulePartNode modulePartNode = document.syntaxTree().rootNode(); @@ -84,7 +84,7 @@ void testReporterWithExternalNumericId() { ReporterImpl reporter = new ReporterImpl(rules); Path validBalProject = Paths.get("src", "test", "resources", "test-resources", "valid-single-file-project", "main.bal"); - Project project = SingleFileProject.load(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Module defaultModule = project.currentPackage().getDefaultModule(); Document document = defaultModule.document(defaultModule.documentIds().iterator().next()); ModulePartNode modulePartNode = document.syntaxTree().rootNode(); @@ -110,7 +110,7 @@ void testReporterWithNonExistentNumericId() { ReporterImpl reporter = new ReporterImpl(rules); Path validBalProject = Paths.get("src", "test", "resources", "test-resources", "valid-single-file-project", "main.bal"); - Project project = SingleFileProject.load(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Module defaultModule = project.currentPackage().getDefaultModule(); Document document = defaultModule.document(defaultModule.documentIds().iterator().next()); ModulePartNode modulePartNode = document.syntaxTree().rootNode(); @@ -137,7 +137,7 @@ void testReporterWithRule() { ReporterImpl reporter = new ReporterImpl(rules); Path validBalProject = Paths.get("src", "test", "resources", "test-resources", "valid-single-file-project", "main.bal"); - Project project = SingleFileProject.load(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Module defaultModule = project.currentPackage().getDefaultModule(); Document document = defaultModule.document(defaultModule.documentIds().iterator().next()); ModulePartNode modulePartNode = (ModulePartNode) document.syntaxTree().rootNode(); @@ -166,7 +166,7 @@ void testReporterWithExternalRule() { ReporterImpl reporter = new ReporterImpl(rules); Path validBalProject = Paths.get("src", "test", "resources", "test-resources", "valid-single-file-project", "main.bal"); - Project project = SingleFileProject.load(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Module defaultModule = project.currentPackage().getDefaultModule(); Document document = defaultModule.document(defaultModule.documentIds().iterator().next()); ModulePartNode modulePartNode = (ModulePartNode) document.syntaxTree().rootNode(); diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java index de1991c1..5cb46328 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java @@ -19,7 +19,6 @@ package io.ballerina.scan.internal; import io.ballerina.projects.Project; -import io.ballerina.projects.directory.BuildProject; import io.ballerina.projects.directory.ProjectLoader; import io.ballerina.projects.util.ProjectUtils; import io.ballerina.scan.BaseTest; @@ -121,17 +120,19 @@ void testScanCommandEmptyProject() throws IOException { scanCmd.execute(); System.setProperty("user.dir", userDir); String expected = error(EMPTY_PACKAGE); - Assert.assertEquals(readOutput(true).trim().split("\n")[0], expected); + String actual = readOutput(true).trim().split("\n")[0]; + Assert.assertEquals(actual, expected); } @Test(description = "test scan command with Ballerina project with single file as argument") void testScanCommandProjectWithArgument() throws IOException { ScanCmd scanCmd = new ScanCmd(printStream); - String[] args = {validBalProject.resolve("main.bal").toString()}; + String inputPath = validBalProject.resolve("main.bal").toString(); + String[] args = {inputPath}; new CommandLine(scanCmd).parseArgs(args); scanCmd.execute(); - String expected = "The source file '" + validBalProject.resolve("main.bal") + - "' belongs to a Ballerina package."; + String expected = "The specified path is not a valid Ballerina project: " + inputPath + ". Please " + + "provide a valid Ballerina project path and try again."; Assert.assertEquals(readOutput(true).trim().split("\n")[0], expected); } @@ -150,11 +151,12 @@ void testScanCommandSingleFileProject() throws IOException { void testScanCommandSingleFileProjectWithDirectoryAsArgument() throws IOException { Path parentDirectory = testResources.resolve("test-resources").toAbsolutePath(); ScanCmd scanCmd = new ScanCmd(printStream); - String[] args = {parentDirectory.resolve("valid-single-file-project").toString()}; + String inputPath = parentDirectory.resolve("valid-single-file-project").toString(); + String[] args = {inputPath}; new CommandLine(scanCmd).parseArgs(args); scanCmd.execute(); - String expected = "Invalid Ballerina package directory: " + - parentDirectory.resolve("valid-single-file-project") + ", cannot find 'Ballerina.toml' file."; + String expected = "The specified path is not a valid Ballerina project: " + inputPath + ". Please " + + "provide a valid Ballerina project path and try again."; Assert.assertEquals(readOutput(true).trim(), expected); } @@ -165,8 +167,8 @@ void testScanCommandSingleFileProjectWithoutArgument() throws IOException { ScanCmd scanCmd = new ScanCmd(printStream); scanCmd.execute(); System.setProperty("user.dir", userDir); - String expected = "Invalid Ballerina package directory: " + validBalProject + - ", cannot find 'Ballerina.toml' file."; + String expected = "The specified path is not a valid Ballerina project: " + validBalProject + ". Please " + + "provide a valid Ballerina project path and try again."; Assert.assertEquals(readOutput(true).trim(), expected); } @@ -199,7 +201,7 @@ void testScanCommandSaveToDirectoryMethodWhenIssuePresent() throws IOException { validBalProject.resolve("main.bal").toString())); issues.add(new IssueImpl(location, externalRule, Source.EXTERNAL, "main.bal", validBalProject.resolve("main.bal").toString())); - Project project = ProjectLoader.loadProject(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Path resultsFile = ScanUtils.saveToDirectory(issues, project, null); String result = Files.readString(resultsFile, StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); @@ -220,7 +222,7 @@ void testScanCommandGenerateScanReportMethodWhenIssuePresent() throws IOExceptio validBalProject.resolve("main.bal").toString())); issues.add(new IssueImpl(location, externalRule, Source.EXTERNAL, "main.bal", validBalProject.resolve("main.bal").toString())); - Project project = ProjectLoader.loadProject(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Path resultsFile = ScanUtils.generateScanReport(issues, project, null); String result = Files.readString(resultsFile, StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); @@ -232,7 +234,7 @@ void testScanCommandGenerateScanReportMethodWhenIssuePresent() throws IOExceptio void testPrintRulesToConsole() throws IOException { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-config-file"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); Assert.assertNotNull(scanTomlFile); @@ -350,7 +352,25 @@ void testScanCommandWithIncludeRulesFlag() throws IOException { String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("include-rules-issues-report.txt"); + String expected = getExpectedOutput("include-rules-issues-report.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); + Assert.assertEquals(result, expected); + } + + @Test(description = "test scan command with include rules flag") + void testScanCommandInWorkspace() throws IOException { + Path ballerinaProject = testResources.resolve("test-resources").resolve("workspace-project"); + System.setProperty("user.dir", ballerinaProject.toString()); + ScanCmd scanCmd = new ScanCmd(printStream); + String[] args = {"--include-rules=ballerina:1"}; + new CommandLine(scanCmd).parseArgs(args); + scanCmd.execute(); + System.setProperty("user.dir", userDir); + String result = Files.readString(ballerinaProject.resolve("target").resolve("report") + .resolve("scan_results.json"), StandardCharsets.UTF_8) + .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); + String expected = getExpectedOutput("workspace-issues.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(result, expected); } @@ -367,7 +387,8 @@ void testScanCommandWithExcludeRulesFlag() throws IOException { String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("exclude-rules-issues-report.txt"); + String expected = getExpectedOutput("exclude-rules-issues-report.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(result, expected); } @@ -381,7 +402,7 @@ void testScanCommandWithIncludeAndExcludeRulesFlags() throws IOException { new CommandLine(scanCmd).parseArgs(args); scanCmd.execute(); System.setProperty("user.dir", userDir); - String expected = getExpectedOutput("include-exclude-rules.txt"); + String expected = getExpectedOutput("include-exclude-rules.txt").trim(); Assert.assertEquals(readOutput(true).trim(), expected); } @@ -396,7 +417,8 @@ void testScanCommandWithIncludeRulesScanTomlConfigurations() throws IOException String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("toml-include-rules-issues-report.txt"); + String expected = getExpectedOutput("toml-include-rules-issues-report.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(result, expected); } @@ -413,7 +435,8 @@ void testScanCommandWithExcludeRulesScanTomlConfigurations() throws IOException String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("toml-exclude-rules-issues-report.txt"); + String expected = getExpectedOutput("toml-exclude-rules-issues-report.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(result, expected); } @@ -466,10 +489,12 @@ void testScanCommandWithPlatformPluginConfigurations() throws IOException { .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); removeFile(result); - String expected = getExpectedOutput("platform-plugin-issue-output.txt"); + String expected = getExpectedOutput("platform-plugin-issue-output.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(platformIssuesOutput, expected); - expected = getExpectedOutput("platform-plugin-arguments-output.txt"); + expected = getExpectedOutput("platform-plugin-arguments-output.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(platformArgumentsOutput, expected); } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java index 32faf327..d8fca66f 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java @@ -21,7 +21,7 @@ import io.ballerina.projects.Document; import io.ballerina.projects.Module; import io.ballerina.projects.Project; -import io.ballerina.projects.directory.SingleFileProject; +import io.ballerina.projects.directory.ProjectLoader; import io.ballerina.scan.BaseTest; import io.ballerina.scan.Issue; import io.ballerina.scan.Rule; @@ -41,7 +41,7 @@ public class StaticCodeAnalyzerTest extends BaseTest { private final Path coreRuleBalFiles = testResources.resolve("test-resources").resolve("core-rules"); Document loadDocument(String documentName) { - Project project = SingleFileProject.load(coreRuleBalFiles.resolve(documentName)); + Project project = ProjectLoader.load(coreRuleBalFiles.resolve(documentName)).project(); Module defaultModule = project.currentPackage().getDefaultModule(); return defaultModule.document(defaultModule.documentIds().iterator().next()); } diff --git a/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java b/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java index a55184b0..6bec9b00 100644 --- a/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java @@ -19,9 +19,7 @@ package io.ballerina.scan.utils; import io.ballerina.projects.Project; -import io.ballerina.projects.directory.BuildProject; import io.ballerina.projects.directory.ProjectLoader; -import io.ballerina.projects.directory.SingleFileProject; import io.ballerina.projects.util.ProjectUtils; import io.ballerina.scan.BaseTest; import io.ballerina.scan.Issue; @@ -70,7 +68,7 @@ void testPrintToConsole() throws IOException { @Test(description = "test method for saving results to file when no directory is provided") void testSaveToDirectory() throws IOException { List issues = new ArrayList<>(); - Project project = ProjectLoader.loadProject(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Path resultsFile = ScanUtils.saveToDirectory(issues, project, null); String result = Files.readString(resultsFile, StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); @@ -81,7 +79,7 @@ void testSaveToDirectory() throws IOException { @Test(description = "test method for saving results to file when directory is provided") void testSaveToProvidedDirectory() throws IOException { List issues = new ArrayList<>(); - Project project = ProjectLoader.loadProject(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Path resultsFile = ScanUtils.saveToDirectory(issues, project, RESULTS_DIRECTORY); String result = Files.readString(resultsFile, StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); @@ -92,7 +90,7 @@ void testSaveToProvidedDirectory() throws IOException { @Test(description = "test method for creating html analysis report from analysis results") void testGenerateScanReport() throws IOException { List issues = new ArrayList<>(); - Project project = ProjectLoader.loadProject(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Path scanReportPath = ScanUtils.generateScanReport(issues, project, null); String result = Files.readString(scanReportPath, StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); @@ -104,7 +102,7 @@ void testGenerateScanReport() throws IOException { "test method for creating html analysis report from analysis results when directory is provided") void testGenerateScanReportToProvidedDirectory() throws IOException { List issues = new ArrayList<>(); - Project project = ProjectLoader.loadProject(validBalProject); + Project project = ProjectLoader.load(validBalProject).project(); Path scanReportPath = ScanUtils.generateScanReport(issues, project, RESULTS_DIRECTORY); String result = Files.readString(scanReportPath, StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); @@ -117,7 +115,7 @@ void testGenerateScanReportToProvidedDirectory() throws IOException { void testloadScanTomlConfigurationsForSingleFileProject() { Path ballerinaProject = testResources.resolve("test-resources") .resolve("single-file-project-with-config-file").resolve("main.bal"); - Project project = SingleFileProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -128,7 +126,7 @@ void testloadScanTomlConfigurationsForSingleFileProject() { void testloadScanTomlConfigurations() { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-config-file"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -167,7 +165,7 @@ void testloadScanTomlConfigurations() { void testloadInvalidPlatformJAR() throws IOException { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-invalid-platform-jar"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -181,7 +179,7 @@ void testloadInvalidPlatformJAR() throws IOException { void testloadInvalidPlatformScanTomlConfigurations() throws IOException { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-invalid-platform-config-file"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -195,7 +193,7 @@ void testloadInvalidPlatformScanTomlConfigurations() throws IOException { void testloadScanTomlConfigurationsWithInvalidBallerinaTomlConfiguration() throws IOException { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-invalid-file-configuration"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -208,7 +206,7 @@ void testloadScanTomlConfigurationsWithInvalidBallerinaTomlConfiguration() throw void testloadExternalScanTomlConfigurations() { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-external-config-file"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -246,7 +244,7 @@ void testloadExternalScanTomlConfigurations() { void testloadInvalidExternalScanTomlConfigurations() throws IOException { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-invalid-external-config-file"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -259,7 +257,7 @@ void testloadInvalidExternalScanTomlConfigurations() throws IOException { void testloadRemoteScanTomlConfigurations() { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-remote-config-file"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); @@ -297,7 +295,7 @@ void testloadRemoteScanTomlConfigurations() { void testloadInvalidRemoteScanTomlConfigurations() throws IOException { Path ballerinaProject = testResources.resolve("test-resources") .resolve("bal-project-with-invalid-remote-config-file"); - Project project = BuildProject.load(ballerinaProject); + Project project = ProjectLoader.load(ballerinaProject).project(); System.setProperty("user.dir", ballerinaProject.toString()); ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); diff --git a/scan-command/src/test/resources/command-outputs/unix/exclude-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/unix/exclude-rules-issues-report.txt index d0ef1d6f..17890f38 100644 --- a/scan-command/src/test/resources/command-outputs/unix/exclude-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/unix/exclude-rules-issues-report.txt @@ -17,7 +17,7 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-analyzer-configurations/main.bal" + "filePath": "/main.bal" }, { "location": { @@ -37,7 +37,7 @@ }, "source": "EXTERNAL", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-analyzer-configurations/main.bal" + "filePath": "/main.bal" }, { "location": { @@ -57,6 +57,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-analyzer-configurations/main.bal" + "filePath": "/main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/include-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/unix/include-rules-issues-report.txt index 5cc1460c..1757e720 100644 --- a/scan-command/src/test/resources/command-outputs/unix/include-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/unix/include-rules-issues-report.txt @@ -17,6 +17,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-analyzer-configurations/main.bal" + "filePath": "/main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/platform-plugin-issue-output.txt b/scan-command/src/test/resources/command-outputs/unix/platform-plugin-issue-output.txt index 76a33092..7aa051fa 100644 --- a/scan-command/src/test/resources/command-outputs/unix/platform-plugin-issue-output.txt +++ b/scan-command/src/test/resources/command-outputs/unix/platform-plugin-issue-output.txt @@ -17,6 +17,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_platform_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-platform-configurations/main.bal" + "filePath": "/main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/toml-exclude-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/unix/toml-exclude-rules-issues-report.txt index eb21530e..d58ec69e 100644 --- a/scan-command/src/test/resources/command-outputs/unix/toml-exclude-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/unix/toml-exclude-rules-issues-report.txt @@ -17,7 +17,7 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_exclude_rule_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-exclude-rule-configurations/main.bal" + "filePath": "/main.bal" }, { "location": { @@ -37,7 +37,7 @@ }, "source": "EXTERNAL", "fileName": "bal_project_with_exclude_rule_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-exclude-rule-configurations/main.bal" + "filePath": "/main.bal" }, { "location": { @@ -57,6 +57,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_exclude_rule_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-exclude-rule-configurations/main.bal" + "filePath": "/main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/toml-include-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/unix/toml-include-rules-issues-report.txt index 154b303a..e9ea12c5 100644 --- a/scan-command/src/test/resources/command-outputs/unix/toml-include-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/unix/toml-include-rules-issues-report.txt @@ -17,6 +17,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_include_rule_configurations/main.bal", - "filePath": "src/test/resources/test-resources/bal-project-with-include-rule-configurations/main.bal" + "filePath": "/main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt b/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt new file mode 100644 index 00000000..20fb2116 --- /dev/null +++ b/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt @@ -0,0 +1,42 @@ +[ + { + "location": { + "filePath": "main.bal", + "startLine": 20, + "endLine": 20, + "startColumn": 17, + "endColumn": 39, + "startOffset": 757, + "length": 22 + }, + "rule": { + "id": "ballerina:1", + "numericId": 1, + "description": "Avoid checkpanic", + "ruleKind": "CODE_SMELL" + }, + "source": "BUILT_IN", + "fileName": "bal_project_with_analyzer_configurations/main.bal", + "filePath": "/Users/asmaj/ballerina/static-code-analysis-tool/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/main.bal" + }, + { + "location": { + "filePath": "main.bal", + "startLine": 20, + "endLine": 20, + "startColumn": 17, + "endColumn": 39, + "startOffset": 757, + "length": 22 + }, + "rule": { + "id": "ballerina:1", + "numericId": 1, + "description": "Avoid checkpanic", + "ruleKind": "CODE_SMELL" + }, + "source": "BUILT_IN", + "fileName": "bal_project_with_include_rule_configurations/main.bal", + "filePath": "/Users/asmaj/ballerina/static-code-analysis-tool/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/main.bal" + } +] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/exclude-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/windows/exclude-rules-issues-report.txt index 7990d007..5afe9c20 100644 --- a/scan-command/src/test/resources/command-outputs/windows/exclude-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/windows/exclude-rules-issues-report.txt @@ -17,7 +17,7 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-analyzer-configurations\\main.bal" + "filePath": "\\main.bal" }, { "location": { @@ -37,7 +37,7 @@ }, "source": "EXTERNAL", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-analyzer-configurations\\main.bal" + "filePath": "\\main.bal" }, { "location": { @@ -57,6 +57,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-analyzer-configurations\\main.bal" + "filePath": "\\main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/include-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/windows/include-rules-issues-report.txt index a3619160..17a9d55a 100644 --- a/scan-command/src/test/resources/command-outputs/windows/include-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/windows/include-rules-issues-report.txt @@ -17,6 +17,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-analyzer-configurations\\main.bal" + "filePath": "\\main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/platform-plugin-issue-output.txt b/scan-command/src/test/resources/command-outputs/windows/platform-plugin-issue-output.txt index 06c7247c..262719a4 100644 --- a/scan-command/src/test/resources/command-outputs/windows/platform-plugin-issue-output.txt +++ b/scan-command/src/test/resources/command-outputs/windows/platform-plugin-issue-output.txt @@ -17,6 +17,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_platform_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-platform-configurations\\main.bal" + "filePath": "\\main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/toml-exclude-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/windows/toml-exclude-rules-issues-report.txt index 14c0935c..b306c6f8 100644 --- a/scan-command/src/test/resources/command-outputs/windows/toml-exclude-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/windows/toml-exclude-rules-issues-report.txt @@ -17,7 +17,7 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_exclude_rule_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-exclude-rule-configurations\\main.bal" + "filePath": "\\main.bal" }, { "location": { @@ -37,7 +37,7 @@ }, "source": "EXTERNAL", "fileName": "bal_project_with_exclude_rule_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-exclude-rule-configurations\\main.bal" + "filePath": "\\main.bal" }, { "location": { @@ -57,6 +57,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_exclude_rule_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-exclude-rule-configurations\\main.bal" + "filePath": "\\main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/toml-include-rules-issues-report.txt b/scan-command/src/test/resources/command-outputs/windows/toml-include-rules-issues-report.txt index c5a0716f..0bbe7551 100644 --- a/scan-command/src/test/resources/command-outputs/windows/toml-include-rules-issues-report.txt +++ b/scan-command/src/test/resources/command-outputs/windows/toml-include-rules-issues-report.txt @@ -17,6 +17,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_include_rule_configurations/main.bal", - "filePath": "src\\test\\resources\\test-resources\\bal-project-with-include-rule-configurations\\main.bal" + "filePath": "\\main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/test-resources/workspace-project/Ballerina.toml b/scan-command/src/test/resources/test-resources/workspace-project/Ballerina.toml new file mode 100644 index 00000000..189af540 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/Ballerina.toml @@ -0,0 +1,2 @@ +[workspace] +packages = ["bal-project-with-analyzer-configurations", "bal-project-with-include-rule-configurations"] diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/.gitignore b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/.gitignore new file mode 100644 index 00000000..3749d15a --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/.gitignore @@ -0,0 +1,4 @@ +target +generated +Config.toml +Dependencies.toml diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Ballerina.toml b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Ballerina.toml new file mode 100644 index 00000000..b20c5b4f --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "ballerina" +name = "bal_project_with_analyzer_configurations" +version = "0.1.0" diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Scan.toml b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Scan.toml new file mode 100644 index 00000000..1902ca70 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/Scan.toml @@ -0,0 +1,15 @@ +# custom compiler plugins +[[analyzer]] +org = "exampleOrg" +name = "example_module_static_code_analyzer" + +[[analyzer]] +org = "ballerina" +name = "example_module_static_code_analyzer" +version = "0.1.0" + +[[analyzer]] +org = "ballerinax" +name = "example_module_static_code_analyzer" +version = "0.1.0" +repository = "local" diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/main.bal b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/main.bal new file mode 100644 index 00000000..011d9b36 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/main.bal @@ -0,0 +1,22 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +function getResult() returns int|error => 1; + +public function main() { + // Non-compliant + int result = checkpanic getResult(); +} diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/.gitignore b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/.gitignore new file mode 100644 index 00000000..3749d15a --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/.gitignore @@ -0,0 +1,4 @@ +target +generated +Config.toml +Dependencies.toml diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Ballerina.toml b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Ballerina.toml new file mode 100644 index 00000000..927820f0 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "ballerina" +name = "bal_project_with_include_rule_configurations" +version = "0.1.0" diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Scan.toml b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Scan.toml new file mode 100644 index 00000000..215b3483 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/Scan.toml @@ -0,0 +1,20 @@ +# custom compiler plugins +[[analyzer]] +org = "exampleOrg" +name = "example_module_static_code_analyzer" + +[[analyzer]] +org = "ballerina" +name = "example_module_static_code_analyzer" +version = "0.1.0" + +[[analyzer]] +org = "ballerinax" +name = "example_module_static_code_analyzer" +version = "0.1.0" +repository = "local" + +[rule] +include =[ + "ballerina:1" +] diff --git a/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/main.bal b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/main.bal new file mode 100644 index 00000000..011d9b36 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/main.bal @@ -0,0 +1,22 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +function getResult() returns int|error => 1; + +public function main() { + // Non-compliant + int result = checkpanic getResult(); +} diff --git a/scan-command/tool-scan/Ballerina.toml b/scan-command/tool-scan/Ballerina.toml index 6214f637..1f8eb729 100644 --- a/scan-command/tool-scan/Ballerina.toml +++ b/scan-command/tool-scan/Ballerina.toml @@ -2,7 +2,7 @@ org = "ballerina" name = "tool_scan" version = "0.11.1-SNAPSHOT" -distribution = "2201.12.0" +distribution = "2201.13.0" authors = ["Ballerina"] keywords = ["scan", "static code analysis"] license = ["Apache-2.0"] diff --git a/scan-command/tool-scan/Dependencies.toml b/scan-command/tool-scan/Dependencies.toml index 48fa3206..29941111 100644 --- a/scan-command/tool-scan/Dependencies.toml +++ b/scan-command/tool-scan/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.12.9" +distribution-version = "2201.13.0" [[package]] org = "ballerina" From 28a417600ab26b3d2382315aa7ecf3ccf98721e2 Mon Sep 17 00:00:00 2001 From: azinneera Date: Thu, 20 Nov 2025 12:10:09 +0530 Subject: [PATCH 2/5] Update workflows to use U13 --- .github/workflows/central-publish.yml | 2 +- .github/workflows/full_build.yml | 8 ++++---- .github/workflows/publish-release.yml | 2 +- scan-command/build.gradle | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/central-publish.yml b/.github/workflows/central-publish.yml index 58ffc528..4cd9c789 100644 --- a/.github/workflows/central-publish.yml +++ b/.github/workflows/central-publish.yml @@ -30,7 +30,7 @@ jobs: - name: Set Up Ballerina uses: ballerina-platform/setup-ballerina@v1.1.0 with: - version: 2201.12.0 + version: 2201.13.0 - name: Build with Gradle env: diff --git a/.github/workflows/full_build.yml b/.github/workflows/full_build.yml index 92e3dfb8..c774a405 100644 --- a/.github/workflows/full_build.yml +++ b/.github/workflows/full_build.yml @@ -26,7 +26,7 @@ jobs: - name: Set Up Ballerina uses: ballerina-platform/setup-ballerina@v1.1.1 with: - version: 2201.12.0 + version: 2201.13.0 - name: Grant execute permission for gradlew run: chmod +x gradlew @@ -35,7 +35,7 @@ jobs: env: packageUser: ${{ github.actor }} packagePAT: ${{ secrets.GITHUB_TOKEN }} - run: ./gradlew build --scan + run: unset BALLERINA_HOME && ./gradlew build --scan - name: Generate Jacoco report run: ./gradlew createCodeCoverageReport @@ -66,10 +66,10 @@ jobs: - name: Set Up Ballerina uses: ballerina-platform/setup-ballerina@v1.1.1 with: - version: 2201.12.0 + version: 2201.13.0 - name: Build with Gradle env: packageUser: ${{ github.actor }} packagePAT: ${{ secrets.GITHUB_TOKEN }} - run: ./gradlew build --scan + run: Remove-Item Env:BALLERINA_HOME -ErrorAction SilentlyContinue; ./gradlew build --scan diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index cacc4da6..f420420a 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -22,7 +22,7 @@ jobs: - name: Set Up Ballerina uses: ballerina-platform/setup-ballerina@v1.1.0 with: - version: 2201.12.0 + version: 2201.13.0 - name: Set version env variable run: echo "VERSION=$((grep -w "version" | cut -d= -f2) < gradle.properties | rev | cut --complement -d- -f1 | rev)" >> $GITHUB_ENV diff --git a/scan-command/build.gradle b/scan-command/build.gradle index 5a0c6e67..5036d0a1 100644 --- a/scan-command/build.gradle +++ b/scan-command/build.gradle @@ -282,7 +282,7 @@ tasks.test { // set ballerina home is env var is set def ballerinaHome = System.getenv("BALLERINA_HOME") if (ballerinaHome != null) { - systemProperty 'ballerina.home', ballerinaHome + systemProperty "ballerina.home", Paths.get(ballerinaHome).resolve("distributions").toString() } else { try { def balHomeOutput = new ByteArrayOutputStream() From 7b6577000db1e67667a7cd1f18d047e834643951 Mon Sep 17 00:00:00 2001 From: azinneera Date: Fri, 21 Nov 2025 14:31:37 +0530 Subject: [PATCH 3/5] Fix test output for workspaces --- .../test/resources/command-outputs/unix/workspace-issues.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt b/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt index 20fb2116..d6512535 100644 --- a/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt +++ b/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt @@ -17,7 +17,7 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "/Users/asmaj/ballerina/static-code-analysis-tool/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-analyzer-configurations/main.bal" + "filePath": "/main.bal" }, { "location": { @@ -37,6 +37,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_include_rule_configurations/main.bal", - "filePath": "/Users/asmaj/ballerina/static-code-analysis-tool/scan-command/src/test/resources/test-resources/workspace-project/bal-project-with-include-rule-configurations/main.bal" + "filePath": "/main.bal" } ] \ No newline at end of file From 5237c2b853efd44c7e28929a83751b43db029394 Mon Sep 17 00:00:00 2001 From: azinneera Date: Fri, 21 Nov 2025 14:33:23 +0530 Subject: [PATCH 4/5] Fix test output for workspaces and ballerina home --- scan-command/build.gradle | 23 +++---- .../io/ballerina/scan/internal/ScanCmd.java | 67 +++++++++++-------- .../io/ballerina/scan/utils/ScanUtils.java | 5 +- .../ballerina/scan/internal/ScanCmdTest.java | 28 +++++--- .../ballerina/scan/utils/ScanUtilsTest.java | 9 ++- .../unix/include-exclude-rules.txt | 2 +- ...invalid-platform-plugin-configurations.txt | 2 +- .../unix/list-rules-output.txt | 2 +- .../unix/print-rules-to-console.txt | 2 +- .../scan-toml-invalid-platform-config.txt | 2 +- .../unix/scan-toml-invalid-platform-jar.txt | 2 +- .../unix/toml-include-exclude-rules.txt | 2 +- .../command-outputs/unix/workspace-issues.txt | 4 +- .../windows/include-exclude-rules.txt | 2 +- ...invalid-platform-plugin-configurations.txt | 2 +- .../windows/list-rules-output.txt | 2 +- .../windows/print-rules-to-console.txt | 2 +- .../scan-toml-invalid-platform-config.txt | 2 +- .../scan-toml-invalid-platform-jar.txt | 2 +- .../windows/toml-include-exclude-rules.txt | 2 +- .../windows/workspace-issues.txt | 42 ++++++++++++ scan-command/tool-scan/Dependencies.toml | 2 +- 22 files changed, 135 insertions(+), 73 deletions(-) create mode 100644 scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt diff --git a/scan-command/build.gradle b/scan-command/build.gradle index 5036d0a1..8062186d 100644 --- a/scan-command/build.gradle +++ b/scan-command/build.gradle @@ -279,21 +279,16 @@ build { // Configuring tests tasks.test { - // set ballerina home is env var is set - def ballerinaHome = System.getenv("BALLERINA_HOME") - if (ballerinaHome != null) { - systemProperty "ballerina.home", Paths.get(ballerinaHome).resolve("distributions").toString() - } else { - try { - def balHomeOutput = new ByteArrayOutputStream() - exec { - commandLine 'bal', 'home' - standardOutput = balHomeOutput - } - systemProperty 'ballerina.home', balHomeOutput.toString().trim() - } catch (Exception e) { - println "Warning: Could not determine ballerina.home from 'bal home' command: ${e.message}" + // set ballerina home system property for java based tests + try { + def balHomeOutput = new ByteArrayOutputStream() + exec { + commandLine 'bal', 'home' + standardOutput = balHomeOutput } + systemProperty 'ballerina.home', balHomeOutput.toString().trim() + } catch (Exception e) { + println "Warning: Could not determine ballerina.home from 'bal home' command: ${e.message}" } useTestNG() { diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java b/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java index d9486f1a..8b5e051c 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/ScanCmd.java @@ -21,6 +21,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import io.ballerina.cli.BLauncherCmd; import io.ballerina.projects.Project; import io.ballerina.projects.ProjectKind; @@ -67,6 +68,7 @@ import static io.ballerina.scan.internal.ScanToolConstants.RUNNING_SCANS_LOG; import static io.ballerina.scan.internal.ScanToolConstants.SCAN_COMMAND; +import static io.ballerina.scan.utils.ScanUtils.convertIssuesToSarifString; /** * Represents the "bal scan" command. @@ -202,19 +204,7 @@ public void execute() { } outputStream.println(); - Path jsonReportPath; - try { - String reportContent = accumulateWorkspaceReports(topologicallySortedList); - jsonReportPath = ScanUtils.getTargetPath(project.get(), targetDir).getReportPath() - .resolve(Constants.RESULTS_JSON_FILE); - Files.writeString(jsonReportPath, reportContent); - } catch (IOException e) { - throw new RuntimeException("Error while obtaining report path: " + e.getMessage()); - } - - outputStream.println("View scan results at:"); - outputStream.println("\t" + jsonReportPath.toUri()); - outputStream.println(); + accumulateWorkspaceReports(topologicallySortedList, workspaceProject); if (scanReport) { Path scanReportPath = ScanUtils.generateScanReport(allIssues, project.get(), targetDir); outputStream.println(); @@ -231,27 +221,50 @@ public void execute() { executeProject(project.get()); } - private String accumulateWorkspaceReports(List topologicallySortedList) { + private void accumulateWorkspaceReports(List topologicallySortedList, + WorkspaceProject workspaceProject) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); JsonArray allIssuesArray = new JsonArray(); - - for (BuildProject buildProject : topologicallySortedList) { - try { - Path reportPath = ScanUtils.getTargetPath(buildProject, targetDir).getReportPath() - .resolve(Constants.RESULTS_JSON_FILE); - if (Files.exists(reportPath)) { + Path finalReportPath = null; + String finalReportContent = null; + try { + for (BuildProject buildProject : topologicallySortedList) { + Path reportPath = ScanUtils.getTargetPath(buildProject, targetDir).getReportPath(); + if (ReportFormat.SARIF.equals(format)) { + reportPath = reportPath.resolve(Constants.RESULTS_SARIF_FILE); + finalReportPath = ScanUtils.getTargetPath(workspaceProject, targetDir).getReportPath() + .resolve(Constants.RESULTS_SARIF_FILE); String content = Files.readString(reportPath, StandardCharsets.UTF_8); - JsonArray issuesArray = gson.fromJson(content, JsonArray.class); - if (issuesArray != null) { - issuesArray.forEach(allIssuesArray::add); + JsonObject jsonObject = gson.fromJson(content, JsonObject.class); + jsonObject.getAsJsonArray("runs").forEach(runElement -> { + JsonObject runObject = runElement.getAsJsonObject(); + JsonArray issuesArray = runObject.getAsJsonArray("results"); + if (issuesArray != null) { + issuesArray.forEach(allIssuesArray::add); + } + }); + finalReportContent = convertIssuesToSarifString(allIssues, workspaceProject); + } else { + reportPath = reportPath.resolve(Constants.RESULTS_JSON_FILE); + finalReportPath = ScanUtils.getTargetPath(workspaceProject, targetDir).getReportPath() + .resolve(Constants.RESULTS_JSON_FILE); + if (Files.exists(reportPath)) { + String content = Files.readString(reportPath, StandardCharsets.UTF_8); + JsonArray issuesArray = gson.fromJson(content, JsonArray.class); + if (issuesArray != null) { + issuesArray.forEach(allIssuesArray::add); + } } + finalReportContent = gson.toJson(allIssues); } - } catch (IOException e) { - throw new RuntimeException("Error while obtaining report path: " + e.getMessage()); } + Files.writeString(finalReportPath, finalReportContent); + outputStream.println("View scan results at:"); + outputStream.println("\t" + finalReportPath.toUri()); + outputStream.println(); + } catch (IOException e) { + throw new RuntimeException("Error while obtaining report path: " + e.getMessage()); } - - return gson.toJson(allIssues); } public void executeProject(Project project) { diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java b/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java index 9b16698f..a14d48e0 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/ScanUtils.java @@ -69,7 +69,6 @@ import java.util.zip.ZipInputStream; import static io.ballerina.projects.util.ProjectConstants.LOCAL_REPOSITORY_NAME; -import static io.ballerina.projects.util.ProjectConstants.USER_DIR_PROPERTY; import static io.ballerina.scan.utils.Constants.ANALYZER_NAME; import static io.ballerina.scan.utils.Constants.ANALYZER_ORG; import static io.ballerina.scan.utils.Constants.ANALYZER_REPOSITORY; @@ -175,7 +174,7 @@ public static String convertIssuesToJsonString(List issues) { * @param project Ballerina project * @return SARIF string representation of generated issues */ - private static String convertIssuesToSarifString(List issues, Project project) { + public static String convertIssuesToSarifString(List issues, Project project) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); // Create SARIF root object @@ -569,7 +568,7 @@ public static Optional loadScanTomlConfigurations(Project project, Path targetDir = project.targetDir(); if (ballerinaTomlDocumentContent.getTable(SCAN_TABLE).isEmpty()) { - Path scanTomlFilePath = Path.of(System.getProperty(USER_DIR_PROPERTY)).resolve(SCAN_FILE); + Path scanTomlFilePath = project.sourceRoot().resolve(SCAN_FILE); if (Files.exists(scanTomlFilePath)) { outputStream.println("Loading scan tool configurations from " + scanTomlFilePath); return loadScanFile(targetDir, scanTomlFilePath, outputStream); diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java index 5cb46328..007da31d 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java @@ -245,8 +245,10 @@ void testPrintRulesToConsole() throws IOException { List rules = CoreRule.rules(); externalAnalyzers.values().forEach(rules::addAll); ScanUtils.printRulesToConsole(rules, printStream); - String expected = getExpectedOutput("print-rules-to-console.txt"); - Assert.assertEquals(readOutput(true).trim(), expected); + String expected = getExpectedOutput("print-rules-to-console.txt").replace("", + ballerinaProject.toAbsolutePath().toString()); + String actual = readOutput(true).trim(); + Assert.assertEquals(actual, expected); } @Test(description = "test scan command with list rules flag") @@ -259,8 +261,10 @@ void testScanCommandWithListRulesFlag() throws IOException { new CommandLine(scanCmd).parseArgs(args); scanCmd.execute(); System.setProperty("user.dir", userDir); - String expected = getExpectedOutput("list-rules-output.txt"); - Assert.assertEquals(readOutput(true).trim(), expected); + String expected = getExpectedOutput("list-rules-output.txt").replaceAll("", + ballerinaProject.toAbsolutePath().toString()); + String actual = readOutput(true).trim(); + Assert.assertEquals(actual, expected); } @Test(description = "test scan command with target directory flag on single file project") @@ -402,8 +406,10 @@ void testScanCommandWithIncludeAndExcludeRulesFlags() throws IOException { new CommandLine(scanCmd).parseArgs(args); scanCmd.execute(); System.setProperty("user.dir", userDir); - String expected = getExpectedOutput("include-exclude-rules.txt").trim(); - Assert.assertEquals(readOutput(true).trim(), expected); + String expected = getExpectedOutput("include-exclude-rules.txt").trim().replace("", + ballerinaProject.toAbsolutePath().toString()); + String actual = readOutput(true).trim(); + Assert.assertEquals(actual, expected); } @Test(description = "test scan command with include rules Scan.toml configurations") @@ -450,8 +456,10 @@ void testScanCommandWithIncludeAndExcludeRulesScanTomlConfigurations() throws IO new CommandLine(scanCmd).parseArgs(args); scanCmd.execute(); System.setProperty("user.dir", userDir); - String expected = getExpectedOutput("toml-include-exclude-rules.txt"); - Assert.assertEquals(readOutput(true).trim(), expected); + String expected = getExpectedOutput("toml-include-exclude-rules.txt").replace("", + ballerinaProject.toAbsolutePath().toString()); + String actual = readOutput(true).trim(); + Assert.assertEquals(actual, expected); } @Test(description = "test scan command with platform plugin configurations") @@ -522,7 +530,9 @@ void testScanCommandWithInvalidPlatformPluginConfigurations() throws IOException ScanCmd scanCmd = new ScanCmd(printStream); scanCmd.execute(); System.setProperty("user.dir", userDir); - String expected = getExpectedOutput("invalid-platform-plugin-configurations.txt"); + String expected = getExpectedOutput("invalid-platform-plugin-configurations.txt") + .replaceAll("", + ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(readOutput(true).trim(), expected); } diff --git a/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java b/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java index 6bec9b00..d0d1d02b 100644 --- a/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java @@ -170,7 +170,8 @@ void testloadInvalidPlatformJAR() throws IOException { ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); Assert.assertNull(scanTomlFile); - String expected = getExpectedOutput("scan-toml-invalid-platform-jar.txt"); + String expected = getExpectedOutput("scan-toml-invalid-platform-jar.txt") + .replace("", ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(readOutput(true).trim(), expected); } @@ -184,8 +185,10 @@ void testloadInvalidPlatformScanTomlConfigurations() throws IOException { ScanTomlFile scanTomlFile = ScanUtils.loadScanTomlConfigurations(project, printStream).orElse(null); System.setProperty("user.dir", userDir); Assert.assertNull(scanTomlFile); - String expected = getExpectedOutput("scan-toml-invalid-platform-config.txt"); - Assert.assertEquals(readOutput(true).trim(), expected); + String expected = getExpectedOutput("scan-toml-invalid-platform-config.txt") + .replace("", ballerinaProject.toAbsolutePath().toString()); + String actual = readOutput(true).trim(); + Assert.assertEquals(actual, expected); } @Test(description = diff --git a/scan-command/src/test/resources/command-outputs/unix/include-exclude-rules.txt b/scan-command/src/test/resources/command-outputs/unix/include-exclude-rules.txt index 26126e71..9528df41 100644 --- a/scan-command/src/test/resources/command-outputs/unix/include-exclude-rules.txt +++ b/scan-command/src/test/resources/command-outputs/unix/include-exclude-rules.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-analyzer-configurations/Scan.toml +Loading scan tool configurations from /Scan.toml Running Scans cannot include and exclude rules at the same time \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/invalid-platform-plugin-configurations.txt b/scan-command/src/test/resources/command-outputs/unix/invalid-platform-plugin-configurations.txt index 6c3eeb1d..ea5bbb80 100644 --- a/scan-command/src/test/resources/command-outputs/unix/invalid-platform-plugin-configurations.txt +++ b/scan-command/src/test/resources/command-outputs/unix/invalid-platform-plugin-configurations.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-invalid-platform-configurations/Scan.toml +Loading scan tool configurations from /Scan.toml Running Scans diff --git a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt index 9d19578e..2724fe35 100644 --- a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml +Loading scan tool configurations from /Scan.toml Running Scans RuleID | Rule Kind | Rule Description diff --git a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt index 4df4d71c..c1234e44 100644 --- a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml +Loading scan tool configurations from /Scan.toml RuleID | Rule Kind | Rule Description --------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic diff --git a/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-config.txt b/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-config.txt index 90dddd42..80899d03 100644 --- a/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-config.txt +++ b/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-config.txt @@ -1,2 +1,2 @@ -Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-invalid-platform-config-file/Scan.toml +Loading scan tool configurations from /Scan.toml failed to retrieve remote platform file: no protocol: www.example.com/example-platform-analyzer-1.0.jar \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-jar.txt b/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-jar.txt index 54246a46..ad10f81a 100644 --- a/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-jar.txt +++ b/scan-command/src/test/resources/command-outputs/unix/scan-toml-invalid-platform-jar.txt @@ -1,2 +1,2 @@ -Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-invalid-platform-jar/Scan.toml +Loading scan tool configurations from /Scan.toml failed to download remote jar file: 'examplePlatform.jar' \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/toml-include-exclude-rules.txt b/scan-command/src/test/resources/command-outputs/unix/toml-include-exclude-rules.txt index d60d0fb6..9528df41 100644 --- a/scan-command/src/test/resources/command-outputs/unix/toml-include-exclude-rules.txt +++ b/scan-command/src/test/resources/command-outputs/unix/toml-include-exclude-rules.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-include-exclude-rule-configurations/Scan.toml +Loading scan tool configurations from /Scan.toml Running Scans cannot include and exclude rules at the same time \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt b/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt index d6512535..8e9a16a3 100644 --- a/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt +++ b/scan-command/src/test/resources/command-outputs/unix/workspace-issues.txt @@ -17,7 +17,7 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_analyzer_configurations/main.bal", - "filePath": "/main.bal" + "filePath": "/bal-project-with-analyzer-configurations/main.bal" }, { "location": { @@ -37,6 +37,6 @@ }, "source": "BUILT_IN", "fileName": "bal_project_with_include_rule_configurations/main.bal", - "filePath": "/main.bal" + "filePath": "/bal-project-with-include-rule-configurations/main.bal" } ] \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/include-exclude-rules.txt b/scan-command/src/test/resources/command-outputs/windows/include-exclude-rules.txt index df796347..19c59b73 100644 --- a/scan-command/src/test/resources/command-outputs/windows/include-exclude-rules.txt +++ b/scan-command/src/test/resources/command-outputs/windows/include-exclude-rules.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-analyzer-configurations\Scan.toml +Loading scan tool configurations from \Scan.toml Running Scans cannot include and exclude rules at the same time \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/invalid-platform-plugin-configurations.txt b/scan-command/src/test/resources/command-outputs/windows/invalid-platform-plugin-configurations.txt index 822d8aa8..7e36238d 100644 --- a/scan-command/src/test/resources/command-outputs/windows/invalid-platform-plugin-configurations.txt +++ b/scan-command/src/test/resources/command-outputs/windows/invalid-platform-plugin-configurations.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-invalid-platform-configurations\Scan.toml +Loading scan tool configurations from \Scan.toml Running Scans diff --git a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt index 3e3bef55..e4f14f3f 100644 --- a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml +Loading scan tool configurations from \Scan.toml Running Scans RuleID | Rule Kind | Rule Description diff --git a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt index 3d764481..5e8fb985 100644 --- a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml +Loading scan tool configurations from \Scan.toml RuleID | Rule Kind | Rule Description --------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic diff --git a/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-config.txt b/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-config.txt index f8e6433d..77506050 100644 --- a/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-config.txt +++ b/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-config.txt @@ -1,2 +1,2 @@ -Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-invalid-platform-config-file\Scan.toml +Loading scan tool configurations from \Scan.toml failed to retrieve remote platform file: no protocol: www.example.com/example-platform-analyzer-1.0.jar \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-jar.txt b/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-jar.txt index 4800873a..edb8f8bf 100644 --- a/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-jar.txt +++ b/scan-command/src/test/resources/command-outputs/windows/scan-toml-invalid-platform-jar.txt @@ -1,2 +1,2 @@ -Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-invalid-platform-jar\Scan.toml +Loading scan tool configurations from \Scan.toml failed to download remote jar file: 'examplePlatform.jar' \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/toml-include-exclude-rules.txt b/scan-command/src/test/resources/command-outputs/windows/toml-include-exclude-rules.txt index abd78c40..19c59b73 100644 --- a/scan-command/src/test/resources/command-outputs/windows/toml-include-exclude-rules.txt +++ b/scan-command/src/test/resources/command-outputs/windows/toml-include-exclude-rules.txt @@ -1,4 +1,4 @@ -Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-include-exclude-rule-configurations\Scan.toml +Loading scan tool configurations from \Scan.toml Running Scans cannot include and exclude rules at the same time \ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt b/scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt new file mode 100644 index 00000000..664250b0 --- /dev/null +++ b/scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt @@ -0,0 +1,42 @@ +[ + { + "location": { + "filePath": "main.bal", + "startLine": 20, + "endLine": 20, + "startColumn": 17, + "endColumn": 39, + "startOffset": 757, + "length": 22 + }, + "rule": { + "id": "ballerina:1", + "numericId": 1, + "description": "Avoid checkpanic", + "ruleKind": "CODE_SMELL" + }, + "source": "BUILT_IN", + "fileName": "bal_project_with_analyzer_configurations\\main.bal", + "filePath": "\\bal-project-with-analyzer-configurations\\main.bal" + }, + { + "location": { + "filePath": "main.bal", + "startLine": 20, + "endLine": 20, + "startColumn": 17, + "endColumn": 39, + "startOffset": 757, + "length": 22 + }, + "rule": { + "id": "ballerina:1", + "numericId": 1, + "description": "Avoid checkpanic", + "ruleKind": "CODE_SMELL" + }, + "source": "BUILT_IN", + "fileName": "bal_project_with_include_rule_configurations\\main.bal", + "filePath": "\\bal-project-with-include-rule-configurations\\main.bal" + } +] \ No newline at end of file diff --git a/scan-command/tool-scan/Dependencies.toml b/scan-command/tool-scan/Dependencies.toml index 29941111..85c0eca2 100644 --- a/scan-command/tool-scan/Dependencies.toml +++ b/scan-command/tool-scan/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.13.0" +distribution-version = "2201.13.1" [[package]] org = "ballerina" From 81139ea04fd4a0b886c52faa7ce0420746cc95cd Mon Sep 17 00:00:00 2001 From: azinneera Date: Fri, 23 Jan 2026 14:07:16 +0530 Subject: [PATCH 5/5] Fix tests for windows --- scan-command/build.gradle | 13 +++++++-- .../ballerina/scan/internal/ScanCmdTest.java | 29 ++++++++++--------- .../ballerina/scan/utils/ScanUtilsTest.java | 2 +- .../windows/workspace-issues.txt | 4 +-- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/scan-command/build.gradle b/scan-command/build.gradle index 8062186d..1c676b55 100644 --- a/scan-command/build.gradle +++ b/scan-command/build.gradle @@ -280,15 +280,22 @@ build { // Configuring tests tasks.test { // set ballerina home system property for java based tests + def balHomeOutput = "" try { - def balHomeOutput = new ByteArrayOutputStream() + balHomeOutput = new ByteArrayOutputStream() exec { - commandLine 'bal', 'home' + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + // Use cmd so Windows can run the .bat reliably + commandLine 'cmd', '/c', 'bal.bat home' + } else { + commandLine 'sh', '-c', 'bal home' + } standardOutput = balHomeOutput } systemProperty 'ballerina.home', balHomeOutput.toString().trim() } catch (Exception e) { - println "Warning: Could not determine ballerina.home from 'bal home' command: ${e.message}" + println "Warning: Could not determine ballerina.home from 'bal home' command: ${e.message}" + + "\nOutput: " + balHomeOutput } useTestNG() { diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java index 007da31d..15596701 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/ScanCmdTest.java @@ -261,7 +261,7 @@ void testScanCommandWithListRulesFlag() throws IOException { new CommandLine(scanCmd).parseArgs(args); scanCmd.execute(); System.setProperty("user.dir", userDir); - String expected = getExpectedOutput("list-rules-output.txt").replaceAll("", + String expected = getExpectedOutput("list-rules-output.txt").replace("", ballerinaProject.toAbsolutePath().toString()); String actual = readOutput(true).trim(); Assert.assertEquals(actual, expected); @@ -356,8 +356,8 @@ void testScanCommandWithIncludeRulesFlag() throws IOException { String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("include-rules-issues-report.txt").replaceAll("", - ballerinaProject.toAbsolutePath().toString()); + String expected = getExpectedOutput("include-rules-issues-report.txt").replace("", + ballerinaProject.toAbsolutePath().toString().replace("\\", "\\\\")); Assert.assertEquals(result, expected); } @@ -372,9 +372,10 @@ void testScanCommandInWorkspace() throws IOException { System.setProperty("user.dir", userDir); String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) - .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("workspace-issues.txt").replaceAll("", - ballerinaProject.toAbsolutePath().toString()); + .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR);; + String expected = getExpectedOutput("workspace-issues.txt") + .replace("", ballerinaProject.toAbsolutePath().toString() + .replace("\\", "\\\\")); Assert.assertEquals(result, expected); } @@ -391,8 +392,8 @@ void testScanCommandWithExcludeRulesFlag() throws IOException { String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("exclude-rules-issues-report.txt").replaceAll("", - ballerinaProject.toAbsolutePath().toString()); + String expected = getExpectedOutput("exclude-rules-issues-report.txt").replace("", + ballerinaProject.toAbsolutePath().toString().replace("\\", "\\\\")); Assert.assertEquals(result, expected); } @@ -423,8 +424,8 @@ void testScanCommandWithIncludeRulesScanTomlConfigurations() throws IOException String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("toml-include-rules-issues-report.txt").replaceAll("", - ballerinaProject.toAbsolutePath().toString()); + String expected = getExpectedOutput("toml-include-rules-issues-report.txt").replace("", + ballerinaProject.toAbsolutePath().toString().replace("\\", "\\\\")); Assert.assertEquals(result, expected); } @@ -441,7 +442,7 @@ void testScanCommandWithExcludeRulesScanTomlConfigurations() throws IOException String result = Files.readString(ballerinaProject.resolve("target").resolve("report") .resolve("scan_results.json"), StandardCharsets.UTF_8) .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); - String expected = getExpectedOutput("toml-exclude-rules-issues-report.txt").replaceAll("", + String expected = getExpectedOutput("toml-exclude-rules-issues-report.txt").replace("", ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(result, expected); } @@ -497,11 +498,11 @@ void testScanCommandWithPlatformPluginConfigurations() throws IOException { .replace(WINDOWS_LINE_SEPARATOR, LINUX_LINE_SEPARATOR); removeFile(result); - String expected = getExpectedOutput("platform-plugin-issue-output.txt").replaceAll("", - ballerinaProject.toAbsolutePath().toString()); + String expected = getExpectedOutput("platform-plugin-issue-output.txt").replace("", + ballerinaProject.toAbsolutePath().toString().replace("\\", "\\\\")); Assert.assertEquals(platformIssuesOutput, expected); - expected = getExpectedOutput("platform-plugin-arguments-output.txt").replaceAll("", + expected = getExpectedOutput("platform-plugin-arguments-output.txt").replace("", ballerinaProject.toAbsolutePath().toString()); Assert.assertEquals(platformArgumentsOutput, expected); } diff --git a/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java b/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java index d0d1d02b..896011f2 100644 --- a/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/utils/ScanUtilsTest.java @@ -112,7 +112,7 @@ void testGenerateScanReportToProvidedDirectory() throws IOException { @Test(description = "test method for loading configurations from a Scan.toml file in a Ballerina single file project") - void testloadScanTomlConfigurationsForSingleFileProject() { + void testLoadScanTomlConfigurationsForSingleFileProject() { Path ballerinaProject = testResources.resolve("test-resources") .resolve("single-file-project-with-config-file").resolve("main.bal"); Project project = ProjectLoader.load(ballerinaProject).project(); diff --git a/scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt b/scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt index 664250b0..72248d95 100644 --- a/scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt +++ b/scan-command/src/test/resources/command-outputs/windows/workspace-issues.txt @@ -16,7 +16,7 @@ "ruleKind": "CODE_SMELL" }, "source": "BUILT_IN", - "fileName": "bal_project_with_analyzer_configurations\\main.bal", + "fileName": "bal_project_with_analyzer_configurations\main.bal", "filePath": "\\bal-project-with-analyzer-configurations\\main.bal" }, { @@ -36,7 +36,7 @@ "ruleKind": "CODE_SMELL" }, "source": "BUILT_IN", - "fileName": "bal_project_with_include_rule_configurations\\main.bal", + "fileName": "bal_project_with_include_rule_configurations\main.bal", "filePath": "\\bal-project-with-include-rule-configurations\\main.bal" } ] \ No newline at end of file