diff --git a/src/main/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationService.java b/src/main/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationService.java index 71a12915721..622874f83d8 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationService.java +++ b/src/main/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationService.java @@ -16,4 +16,8 @@ public SonarApplicationService(SonarService sonarService) { public void addSonarJavaBackend(Project project) { this.sonarService.addSonarJavaBackend(project); } + + public void addSonarJavaBackendAndFrontend(Project project) { + this.sonarService.addSonarJavaBackendAndFrontend(project); + } } diff --git a/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarDomainService.java b/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarDomainService.java index e5996c2c882..f7458521523 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarDomainService.java +++ b/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarDomainService.java @@ -29,6 +29,14 @@ public void addSonarJavaBackend(Project project) { addDockerCompose(project); } + @Override + public void addSonarJavaBackendAndFrontend(Project project) { + addPropertiesPlugin(project); + addSonarScannerPluginManagement(project); + addFullstackPropertiesFile(project); + addDockerCompose(project); + } + private void addPropertiesPlugin(Project project) { Plugin plugin = Plugin .builder() @@ -73,6 +81,12 @@ private void addPropertiesFile(Project project) { projectRepository.template(project, SOURCE, "sonar-project.properties"); } + private void addFullstackPropertiesFile(Project project) { + project.addDefaultConfig(BASE_NAME); + project.addDefaultConfig(PROJECT_NAME); + projectRepository.template(project, SOURCE, "sonar-fullstack-project.properties", "", "sonar-project.properties"); + } + private void addDockerCompose(Project project) { project.addDefaultConfig(BASE_NAME); project.addConfig("sonarqubeDockerImage", Sonar.getSonarqubeDockerImage()); diff --git a/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarService.java b/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarService.java index 7fbea48e8c7..c2268105b02 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarService.java +++ b/src/main/java/tech/jhipster/lite/generator/server/sonar/domain/SonarService.java @@ -4,4 +4,5 @@ public interface SonarService { void addSonarJavaBackend(Project project); + void addSonarJavaBackendAndFrontend(Project project); } diff --git a/src/main/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResource.java b/src/main/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResource.java index 9f46e967df9..e83972ef390 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResource.java +++ b/src/main/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResource.java @@ -23,12 +23,21 @@ public SonarResource(SonarApplicationService sonarApplicationService) { this.sonarApplicationService = sonarApplicationService; } - @Operation(summary = "Add Sonar configuration to inspect code quality") - @ApiResponse(responseCode = "500", description = "An error occurred while adding Sonar configuration") + @Operation(summary = "Add Sonar configuration for Java Backend to inspect code quality") + @ApiResponse(responseCode = "500", description = "An error occurred while adding Sonar configuration for Java Backend") @PostMapping("/java-backend") @GeneratorStep(id = "sonar-java-backend") public void addSonarJavaBackend(@RequestBody ProjectDTO projectDTO) { Project project = ProjectDTO.toProject(projectDTO); sonarApplicationService.addSonarJavaBackend(project); } + + @Operation(summary = "Add Sonar configuration for Java Backend and Frontend to inspect code quality") + @ApiResponse(responseCode = "500", description = "An error occurred while adding Sonar configuration for Java Backend and Frontend") + @PostMapping("/java-backend-and-frontend") + @GeneratorStep(id = "sonar-java-backend-and-frontend") + public void addSonarJavaBackendAndFrontend(@RequestBody ProjectDTO projectDTO) { + Project project = ProjectDTO.toProject(projectDTO); + sonarApplicationService.addSonarJavaBackendAndFrontend(project); + } } diff --git a/src/main/resources/generator/server/sonar/sonar-fullstack-project.properties.mustache b/src/main/resources/generator/server/sonar/sonar-fullstack-project.properties.mustache new file mode 100644 index 00000000000..ad4182d2034 --- /dev/null +++ b/src/main/resources/generator/server/sonar/sonar-fullstack-project.properties.mustache @@ -0,0 +1,39 @@ +sonar.projectKey={{baseName}} +sonar.projectName={{projectName}} + +sonar.sources=src/main/ +sonar.tests=src/test/ +sonar.host.url=http://localhost:9001 + +sonar.test.inclusions=src/test/**/*.*, src/main/webapp/app/**/*.spec.ts +sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco.xml +sonar.java.codeCoveragePlugin=jacoco +sonar.junit.reportPaths=target/surefire-reports,target/failsafe-reports + +sonar.testExecutionReportPaths=target/test-results/jest/TESTS-results-sonar.xml +sonar.javascript.lcov.reportPaths=target/test-results/lcov.info + +sonar.sourceEncoding=UTF-8 +sonar.exclusions=src/main/webapp/app/main.ts, src/main/webapp/content/**/*.*, src/main/webapp/i18n/*.js, target/classes/static/**/*.* + +sonar.issue.ignore.multicriteria=S3437,S4502,S4684,S4032,UndocumentedApi + +# Rule https://rules.sonarsource.com/java/RSPEC-3437 is ignored, as a JPA-managed field cannot be transient +sonar.issue.ignore.multicriteria.S3437.resourceKey=src/main/java/**/* +sonar.issue.ignore.multicriteria.S3437.ruleKey=squid:S3437 + +# Rule https://rules.sonarsource.com/java/RSPEC-1176 is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names should be self-explanatory +sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey=src/main/java/**/* +sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey=squid:UndocumentedApi + +# Rule https://rules.sonarsource.com/java/RSPEC-4502 is ignored, as for JWT tokens we are not subject to CSRF attack +sonar.issue.ignore.multicriteria.S4502.resourceKey=src/main/java/**/* +sonar.issue.ignore.multicriteria.S4502.ruleKey=java:S4502 + +# Rule https://rules.sonarsource.com/java/RSPEC-4684 +sonar.issue.ignore.multicriteria.S4684.resourceKey=src/main/java/**/* +sonar.issue.ignore.multicriteria.S4684.ruleKey=java:S4684 + +# Rule: Packages containing only "package-info.java" should be removed +sonar.issue.ignore.multicriteria.S4032.resourceKey=src/main/java/**/* +sonar.issue.ignore.multicriteria.S4032.ruleKey=java:S4032 diff --git a/src/test/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationServiceIT.java b/src/test/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationServiceIT.java index 966534e5c0f..eddadac991e 100644 --- a/src/test/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationServiceIT.java +++ b/src/test/java/tech/jhipster/lite/generator/server/sonar/application/SonarApplicationServiceIT.java @@ -31,50 +31,20 @@ void shouldAddSonarJavaBackend() { sonarApplicationService.addSonarJavaBackend(project); - assertFileExist(project, "src/main/docker/sonar.yml"); - assertFileExist(project, "sonar-project.properties"); - - assertFileContent(project, POM_XML, ""); - assertFileContent(project, POM_XML, ""); - - assertFileContent(project, POM_XML, ""); - assertFileContent(project, POM_XML, ""); - - assertFileContent(project, POM_XML, sonarSourcePlugin()); - - assertFileContent(project, POM_XML, propertiesPlugin()); + SonarAssert.assertFiles(project); + SonarAssert.assertPomXml(project); } - private List propertiesPlugin() { - return List.of( - "", - "org.codehaus.mojo", - "properties-maven-plugin", - "${properties-maven-plugin.version}", - "", - "", - "initialize", - "", - "read-project-properties", - "", - "", - "", - "sonar-project.properties", - "", - "", - "", - "", - "" - ); - } + @Test + void shouldAddSonarJavaBackendAndFrontend() { + Project project = tmpProject(); + initApplicationService.init(project); + mavenApplicationService.addPomXml(project); + + sonarApplicationService.addSonarJavaBackendAndFrontend(project); - private List sonarSourcePlugin() { - return List.of( - "", - "org.sonarsource.scanner.maven", - "sonar-maven-plugin", - "${sonar-maven-plugin.version}", - "" - ); + SonarAssert.assertFiles(project); + SonarAssert.assertFrontProperties(project); + SonarAssert.assertPomXml(project); } } diff --git a/src/test/java/tech/jhipster/lite/generator/server/sonar/application/SonarAssert.java b/src/test/java/tech/jhipster/lite/generator/server/sonar/application/SonarAssert.java new file mode 100644 index 00000000000..e0e7b310c39 --- /dev/null +++ b/src/test/java/tech/jhipster/lite/generator/server/sonar/application/SonarAssert.java @@ -0,0 +1,66 @@ +package tech.jhipster.lite.generator.server.sonar.application; + +import static tech.jhipster.lite.TestUtils.assertFileContent; +import static tech.jhipster.lite.TestUtils.assertFileExist; +import static tech.jhipster.lite.generator.project.domain.Constants.POM_XML; + +import java.util.List; +import tech.jhipster.lite.generator.project.domain.Project; + +public class SonarAssert { + + private SonarAssert() {} + + public static void assertFiles(Project project) { + assertFileExist(project, "src/main/docker/sonar.yml"); + assertFileExist(project, "sonar-project.properties"); + } + + public static void assertFrontProperties(Project project) { + assertFileContent(project, "sonar-project.properties", "sonar.testExecutionReportPaths"); + assertFileContent(project, "sonar-project.properties", "sonar.javascript.lcov.reportPaths"); + } + + public static void assertPomXml(Project project) { + assertFileContent(project, POM_XML, ""); + assertFileContent(project, POM_XML, ""); + assertFileContent(project, POM_XML, ""); + assertFileContent(project, POM_XML, ""); + + assertFileContent(project, POM_XML, sonarSourcePlugin()); + assertFileContent(project, POM_XML, propertiesPlugin()); + } + + private static List sonarSourcePlugin() { + return List.of( + "", + "org.sonarsource.scanner.maven", + "sonar-maven-plugin", + "${sonar-maven-plugin.version}", + "" + ); + } + + private static List propertiesPlugin() { + return List.of( + "", + "org.codehaus.mojo", + "properties-maven-plugin", + "${properties-maven-plugin.version}", + "", + "", + "initialize", + "", + "read-project-properties", + "", + "", + "", + "sonar-project.properties", + "", + "", + "", + "", + "" + ); + } +} diff --git a/src/test/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResourceIT.java b/src/test/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResourceIT.java index 951fd145a16..75fd9413a7b 100644 --- a/src/test/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResourceIT.java +++ b/src/test/java/tech/jhipster/lite/generator/server/sonar/infrastructure/primary/rest/SonarResourceIT.java @@ -17,6 +17,7 @@ import tech.jhipster.lite.generator.project.domain.Project; import tech.jhipster.lite.generator.project.infrastructure.primary.dto.ProjectDTO; import tech.jhipster.lite.generator.server.sonar.application.SonarApplicationService; +import tech.jhipster.lite.generator.server.sonar.application.SonarAssert; @IntegrationTest @AutoConfigureMockMvc @@ -28,9 +29,6 @@ class SonarResourceIT { @Autowired MavenApplicationService mavenApplicationService; - @Autowired - SonarApplicationService sonarApplicationService; - @Autowired MockMvc mockMvc; @@ -40,7 +38,6 @@ void shouldAddSonarJavaBackend() throws Exception { Project project = ProjectDTO.toProject(projectDTO); initApplicationService.init(project); mavenApplicationService.init(project); - sonarApplicationService.addSonarJavaBackend(project); mockMvc .perform( @@ -50,9 +47,27 @@ void shouldAddSonarJavaBackend() throws Exception { ) .andExpect(status().isOk()); - String projectPath = projectDTO.getFolder(); + SonarAssert.assertFiles(project); + SonarAssert.assertPomXml(project); + } + + @Test + void shouldAddSonarJavaBackendAndFrontend() throws Exception { + ProjectDTO projectDTO = TestUtils.readFileToObject("json/chips.json", ProjectDTO.class).folder(FileUtils.tmpDirForTest()); + Project project = ProjectDTO.toProject(projectDTO); + initApplicationService.init(project); + mavenApplicationService.init(project); + + mockMvc + .perform( + post("/api/servers/sonar/java-backend-and-frontend") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtils.convertObjectToJsonBytes(projectDTO)) + ) + .andExpect(status().isOk()); - assertFileExist(projectPath, "sonar-project.properties"); - assertFileExist(projectPath, "src/main/docker/sonar.yml"); + SonarAssert.assertFiles(project); + SonarAssert.assertFrontProperties(project); + SonarAssert.assertPomXml(project); } }