├── .github ├── ci-build.sh ├── dependabot.yml └── workflows │ ├── build.yml │ └── deploy.yml ├── .gitignore ├── .gitmodules ├── .mvn └── maven.config ├── CHANGELOG.md ├── LICENSE-header-java.txt ├── LICENSE.txt ├── README.md ├── codenarc-converter ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── sonar │ │ └── plugins │ │ └── groovy │ │ └── codenarc │ │ ├── ParseResult.java │ │ ├── Rule.java │ │ ├── RuleConverter.java │ │ ├── RuleParameter.java │ │ ├── RuleSet.java │ │ ├── parser │ │ ├── RuleParser.java │ │ ├── RuleParserResult.java │ │ └── markdown │ │ │ ├── MarkdownParser.java │ │ │ ├── RuleDescription.java │ │ │ ├── RuleSetVisitor.java │ │ │ └── RuleVisitor.java │ │ └── printer │ │ └── XMLPrinter.java │ └── test │ └── java │ └── org │ └── sonar │ └── plugins │ └── groovy │ └── codenarc │ └── RuleConverterTest.java ├── pom.xml └── sonar-groovy-plugin ├── pom.xml └── src ├── main ├── java │ └── org │ │ └── sonar │ │ └── plugins │ │ └── groovy │ │ ├── GroovyPlugin.java │ │ ├── GroovySensor.java │ │ ├── GroovySonarWayProfile.java │ │ ├── cobertura │ │ ├── CoberturaReportParser.java │ │ ├── CoberturaSensor.java │ │ └── package-info.java │ │ ├── codenarc │ │ ├── CodeNarcProfileExporter.java │ │ ├── CodeNarcRulesDefinition.java │ │ ├── CodeNarcSensor.java │ │ ├── CodeNarcSourceAnalyzer.java │ │ ├── CodeNarcXMLParser.java │ │ └── package-info.java │ │ ├── foundation │ │ ├── Groovy.java │ │ ├── GroovyFileSystem.java │ │ ├── GroovyHighlighterAndTokenizer.java │ │ └── package-info.java │ │ ├── gmetrics │ │ ├── GMetricsSourceAnalyzer.java │ │ └── package-info.java │ │ ├── jacoco │ │ ├── ExecutionDataVisitor.java │ │ ├── JaCoCoAnalyzer.java │ │ ├── JaCoCoConfiguration.java │ │ ├── JaCoCoExtensions.java │ │ ├── JaCoCoReportMerger.java │ │ ├── JaCoCoReportReader.java │ │ ├── JaCoCoSensor.java │ │ └── package-info.java │ │ ├── package-info.java │ │ ├── surefire │ │ ├── GroovySurefireParser.java │ │ ├── GroovySurefireSensor.java │ │ ├── api │ │ │ ├── SurefireUtils.java │ │ │ └── package-info.java │ │ ├── data │ │ │ ├── SurefireStaxHandler.java │ │ │ ├── UnitTestClassReport.java │ │ │ ├── UnitTestIndex.java │ │ │ ├── UnitTestResult.java │ │ │ └── package-info.java │ │ └── package-info.java │ │ └── utils │ │ ├── StaxParser.java │ │ └── package-info.java └── resources │ └── org │ └── sonar │ └── plugins │ └── groovy │ ├── cost.csv │ ├── profile-default.txt │ └── rules.xml └── test ├── java └── org │ └── sonar │ └── plugins │ └── groovy │ ├── GroovyPluginTest.java │ ├── GroovySensorTest.java │ ├── GroovySonarWayProfileTest.java │ ├── TestUtils.java │ ├── cobertura │ └── CoberturaSensorTest.java │ ├── codenarc │ ├── ActiveRulesBuilderWrapper.java │ ├── CodeNarcProfileExporterTest.java │ ├── CodeNarcRulesDefinitionTest.java │ ├── CodeNarcSensorTest.java │ └── CodeNarcXMLParserTest.java │ ├── foundation │ ├── GroovyFileSystemTest.java │ ├── GroovyHighlighterAndTokenizerTest.java │ └── GroovyTest.java │ ├── jacoco │ ├── ExecutionDataVisitorTest.java │ ├── JaCoCoConfigurationTest.java │ ├── JaCoCoExtensionsTest.java │ ├── JaCoCoItSensorTest.java │ ├── JaCoCoOverallSensorTest.java │ ├── JaCoCoReportMergerTest.java │ ├── JaCoCoReportReaderTest.java │ └── JaCoCoSensorTest.java │ ├── surefire │ ├── GroovySurefireParserTest.java │ ├── GroovySurefireSensorTest.java │ ├── api │ │ └── SurefireUtilsTest.java │ └── data │ │ └── UnitTestResultTest.java │ └── utils │ └── StaxParserTest.java └── resources └── org └── sonar └── plugins └── groovy ├── cobertura └── coverage.xml ├── codenarc ├── exportProfile │ ├── exportEscapedParameters.xml │ ├── exportFixedRules.xml │ ├── exportNullParameters.xml │ ├── exportParameters.xml │ └── exportProfile.xml └── parsing │ ├── Sample.groovy │ ├── line-number-not-specified.xml │ └── sample.xml ├── foundation ├── Error.groovy └── Greet.groovy ├── gmetrics └── Greeting.groovy ├── jacoco ├── Hello$InnerClass.class.toCopy ├── Hello.class.toCopy ├── JaCoCoSensor_0_7_4 │ ├── jacoco-ut.exec │ └── readme.txt ├── JaCoCoSensor_0_7_5 │ ├── jacoco-ut.exec │ └── readme.txt └── JaCoCo_incompatible_merge │ ├── jacoco-0.7.4.exec │ ├── jacoco-0.7.5.exec │ ├── jacoco-it-0.7.4.exec │ └── jacoco-it-0.7.5.exec └── surefire ├── SurefireParserTest ├── innerClasses │ └── TEST-org.apache.commons.collections.TestAllPackages.xml ├── multipleReports │ ├── TEST-ch.hortis.sonar.mvn.SonarMojoTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.CheckstyleCollectorTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.CloverCollectorTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.JDependsCollectorTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.JavaNCSSCollectorTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.MetricsCollectorRegistryTest.xml │ └── TESTS-AllTests.xml ├── negativeTestTime │ └── TEST-java.xml ├── nestedInnerClasses │ ├── TEST-org.sonar.plugins.surefire.NestedTest$Inner1$Run.xml │ └── TEST-org.sonar.plugins.surefire.NestedTest$Inner2$Run.xml ├── noTests │ └── TEST-noTests.xml └── onlyTestSuiteReport │ └── TESTS-AllTests.xml ├── SurefireSensorTest ├── doNotSaveInnerClasses │ └── TEST-org.apache.commons.collections.TestAllPackages.xml ├── ignoreSuiteAsInnerClass │ ├── TEST-org.apache.shindig.protocol.TestHandler$Input.xml │ └── TEST-org.apache.shindig.protocol.TestHandler.xml ├── many-results │ ├── TEST-ch.hortis.sonar.mvn.SonarMojoTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.CheckstyleCollectorTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.CloverCollectorTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.JDependsCollectorTest.xml │ ├── TEST-ch.hortis.sonar.mvn.mc.JavaNCSSCollectorTest.xml │ └── TEST-ch.hortis.sonar.mvn.mc.MetricsCollectorRegistryTest.xml ├── measuresShouldNotIncludeSkippedTests │ └── TEST-FooTest.xml ├── noSuccessRatioIfNoTests │ └── TEST-FooTest.xml ├── roundingTests │ └── TEST-Rounding.xml ├── shouldHandleMultipleSuitesInSameFile │ └── TESTS-MutlipleSuites.xml ├── shouldHandleTestSuiteDetails │ ├── ExtensionsFinderTest-expected-result.xml │ ├── ExtensionsFinderTest2-expected-result.xml │ ├── ExtensionsFinderTest3-expected-result.xml │ └── TEST-org.sonar.core.ExtensionsFinderTestSuite.xml ├── shouldManageClassesWithDefaultPackage │ └── TEST-NoPackagesTest.xml ├── shouldSaveErrorsAndFailuresInXML │ ├── TEST-org.sonar.core.ExtensionsFinderTest.xml │ └── expected-test-details.xml └── successRatioIsZeroWhenAllTestsFail │ └── TEST-FooTest.xml └── api └── SurefireUtilsTest └── shouldGetReportsFromProperty ├── pom.xml └── target ├── surefire └── hack.txt └── surefire2 └── hack.txt /.github/ci-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | add= 4 | 5 | if [ "$SONAR_VERSION" ] 6 | then 7 | add="$add -Dsonar.version=$SONAR_VERSION" 8 | elif [ -n "$SONAR_TOKEN" ] 9 | then 10 | # Only run SonarQube analysis on one matrix configuration 11 | # (namely: empty $SONAR_VERSION and Java 11 12 | java -Xmx32m -version 2>&1 | grep -q "11\.0" && add="sonar:sonar $add" 13 | fi 14 | 15 | export MAVEN_OPTS="-Djansi.force=true" 16 | # shellcheck disable=2086 17 | mvn --batch-mode --no-transfer-progress --errors -Dstyle.color=always verify $add 18 | 19 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | 13 | - package-ecosystem: "gitsubmodule" 14 | directory: "/" 15 | schedule: 16 | interval: "weekly" 17 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | build: 9 | strategy: 10 | matrix: 11 | java: [8, 11] 12 | sonar: 13 | - "" 14 | - "8.9.0.43852" 15 | include: 16 | - java: 8 17 | sonar: "" 18 | archive: "yes" 19 | - java: 11 20 | sonar: "9.0.0.45539" 21 | 22 | runs-on: ubuntu-latest 23 | 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v3 27 | with: 28 | fetch-depth: 0 29 | submodules: true 30 | 31 | - name: Set up JDK 32 | uses: actions/setup-java@v3 33 | with: 34 | java-version: ${{ matrix.java }} 35 | distribution: 'adopt' 36 | 37 | - name: Cache SonarCloud packages 38 | uses: actions/cache@v3 39 | with: 40 | path: ~/.sonar/cache 41 | key: ${{ runner.os }}-sonar 42 | restore-keys: ${{ runner.os }}-sonar 43 | 44 | - name: Cache Maven packages 45 | uses: actions/cache@v3 46 | with: 47 | path: ~/.m2/repository 48 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 49 | restore-keys: ${{ runner.os }}-maven 50 | 51 | - name: Build 52 | run: .github/ci-build.sh 53 | env: 54 | SONAR_VERSION: ${{ matrix.sonar }} 55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 56 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 57 | 58 | - name: Upload Plugin JAR 59 | uses: actions/upload-artifact@v3 60 | with: 61 | name: Plugin 62 | path: sonar-groovy-plugin/target/*.jar 63 | if: matrix.archive == 'yes' 64 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Publish package to GitHub Packages 2 | on: 3 | release: 4 | types: [created] 5 | jobs: 6 | publish: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | contents: read 10 | packages: write 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 0 16 | submodules: true 17 | 18 | - name: Set up JDK 19 | uses: actions/setup-java@v3 20 | with: 21 | java-version: '8' 22 | distribution: 'adopt' 23 | 24 | - name: Publish package 25 | run: mvn --batch-mode --no-transfer-progress deploy 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven 2 | target/ 3 | dependency-reduced-pom.xml 4 | 5 | # IntelliJ IDEA 6 | *.iws 7 | *.iml 8 | *.ipr 9 | .idea/ 10 | 11 | # Eclipse 12 | .classpath 13 | .project 14 | .settings 15 | 16 | # ---- Mac OS X 17 | .DS_Store 18 | Icon? 19 | # Thumbnails 20 | ._* 21 | # Files that might appear on external disk 22 | .Spotlight-V100 23 | .Trashes 24 | 25 | # ---- Windows 26 | # Windows image file caches 27 | Thumbs.db 28 | # Folder config file 29 | Desktop.ini 30 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "codenarc-converter/CodeNarc"] 2 | path = codenarc-converter/CodeNarc 3 | url = ../../CodeNarc/CodeNarc.git 4 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pcoverage 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 5 | 6 | ## [Unreleased] 7 | 8 | ## [1.8] - 2021-08-19 9 | 10 | ### Changed 11 | - Updated CodeNarc to 1.6.1 (thanks to @goober, #58) 12 | - Use Spotless for code formatting 13 | 14 | ### Fixed 15 | - Fixed compatibility with SonarQube 9.0 (fixes #65) 16 | - Get rid of some deprecation warnings (fixes #57) 17 | 18 | 19 | ## [1.7] - 2021-05-30 20 | 21 | ### Changed 22 | - Remove backwards compatibility hacks (drop support for everything older then 23 | SonarQube 7.8) 24 | - Some dependency updates 25 | - Deprecates support for JaCoCo binary format (use the SonarQube JaCoCo plugin 26 | instead) 27 | - Switch CI from Travis to GitHub Actions 28 | - Run tests against SonarQube 7.8-8.9 29 | 30 | ### Fixed 31 | - Align JUnit property with Java plugin (fixes #43) 32 | 33 | ### Removed 34 | - Compatibility with JaCoCo older then 0.7.5 (released in mid-2015) 35 | 36 | ## [1.6] - 2019-07-04 37 | 38 | ### Added 39 | - This changelog 40 | 41 | ### Changed 42 | - Moved project from SonarSource to community 43 | - Update plugin to be compatible with SonarQube 6.7-7.8 44 | - Analyze plugin on SonarCloud 45 | - Do CI builds on Travis & AppVeyor 46 | - Integrate codenarc converter into the default build 47 | - Include CodeNarc as a git submodule (so the converter can run on Travis) 48 | - Fix a bunch of deprecated constructs 49 | - Only report overall JaCoCo test coverage 50 | - Updated CodeNarc to 1.4 & GMetrics to 1.0 51 | 52 | ### Fixed 53 | - fix multiple codenarc files (pmayweg#60) 54 | - Fix bug in JaCoCo package name handling (pmayweg#74) 55 | - Update JaCoCo for Java 10+ support 56 | - Remove old metrics (fixes #6) 57 | 58 | ### Removed 59 | - Coupling metrics, since SonarQube doesn't support them anymore 60 | 61 | ## [1.5] - 2017-05-10 62 | 63 | Please see the Git history for older changes 64 | 65 | ## [1.4-RC1] - 2016-08-05 66 | 67 | ## [1.3.1] - 2015-12-02 68 | 69 | ## [1.3] - 2015-11-06 70 | 71 | ## [1.2] - 2015-08-12 72 | 73 | ## [1.1.1] - 2015-05-28 74 | 75 | ## [1.1] - 2015-03-17 76 | 77 | ## [1.0.1] - 2014-03-14 78 | 79 | ## [1.0] - 2014-02-24 80 | 81 | ## [0.6] - 2012-08-06 82 | 83 | [Unreleased]: https://github.com/Inform-Software/sonar-groovy/compare/1.8...HEAD 84 | [1.8]: https://github.com/Inform-Software/sonar-groovy/compare/1.7...1.8 85 | [1.7]: https://github.com/Inform-Software/sonar-groovy/compare/1.6...1.7 86 | [1.6]: https://github.com/Inform-Software/sonar-groovy/compare/1.5...1.6 87 | [1.5]: https://github.com/Inform-Software/sonar-groovy/compare/1.4-RC1...1.5 88 | [1.4-RC1]: https://github.com/Inform-Software/sonar-groovy/compare/1.3.1...1.4-RC1 89 | [1.3.1]: https://github.com/Inform-Software/sonar-groovy/compare/1.3...1.3.1 90 | [1.3]: https://github.com/Inform-Software/sonar-groovy/compare/1.2...1.3 91 | [1.2]: https://github.com/Inform-Software/sonar-groovy/compare/1.1.1...1.2 92 | [1.1.1]: https://github.com/Inform-Software/sonar-groovy/compare/1.1...1.1.1 93 | [1.1]: https://github.com/Inform-Software/sonar-groovy/compare/1.0.1...1.1 94 | [1.0.1]: https://github.com/Inform-Software/sonar-groovy/compare/1.0...1.0.1 95 | [1.0]: https://github.com/Inform-Software/sonar-groovy/compare/0.6...1.0 96 | [0.6]: https://github.com/Inform-Software/sonar-groovy/releases/tag/0.6 97 | 98 | -------------------------------------------------------------------------------- /LICENSE-header-java.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-$YEAR SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | -------------------------------------------------------------------------------- /codenarc-converter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.sonarsource.groovy 7 | groovy 8 | 1.9-SNAPSHOT 9 | 10 | 11 | sonar-codenarc-converter 12 | 13 | Sonar CodeNarc Converter 14 | 15 | 16 | 1.10.1 17 | 0.21.0 18 | true 19 | 20 | 21 | 22 | 23 | org.commonmark 24 | commonmark 25 | ${commonmark.version} 26 | 27 | 28 | org.commonmark 29 | commonmark-ext-yaml-front-matter 30 | ${commonmark.version} 31 | 32 | 33 | org.commonmark 34 | commonmark-ext-gfm-tables 35 | ${commonmark.version} 36 | 37 | 38 | 39 | org.slf4j 40 | slf4j-simple 41 | 42 | 43 | com.googlecode.java-diff-utils 44 | diffutils 45 | 1.3.0 46 | test 47 | 48 | 49 | org.sonarsource.sonarqube 50 | sonar-plugin-api 51 | 52 | 53 | org.codenarc 54 | CodeNarc 55 | 56 | 57 | com.google.guava 58 | guava 59 | 31.1-jre 60 | 61 | 62 | commons-io 63 | commons-io 64 | 65 | 66 | commons-lang 67 | commons-lang 68 | 69 | 70 | junit 71 | junit 72 | 73 | 74 | 75 | com.google.auto.value 76 | auto-value-annotations 77 | ${auto.version} 78 | 79 | 80 | com.google.auto.value 81 | auto-value 82 | ${auto.version} 83 | provided 84 | 85 | 86 | 87 | 88 | 89 | run-converter 90 | 91 | 92 | ${basedir}/CodeNarc/docs 93 | 94 | 95 | 96 | 97 | 98 | org.codehaus.mojo 99 | exec-maven-plugin 100 | 3.0.0 101 | 102 | 103 | run-codenarc-converter 104 | generate-test-sources 105 | 106 | java 107 | 108 | 109 | org.sonar.plugins.groovy.codenarc.RuleConverter 110 | 111 | ${project.basedir} 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/ParseResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import java.util.Set; 23 | 24 | public interface ParseResult { 25 | boolean hasParameters(); 26 | 27 | Set getParameters(); 28 | 29 | String getDescription(); 30 | } 31 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/RuleConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import org.codenarc.ruleregistry.PropertiesFileRuleRegistry; 23 | import org.commonmark.ext.front.matter.YamlFrontMatterExtension; 24 | import org.commonmark.ext.gfm.tables.TablesExtension; 25 | import org.commonmark.parser.Parser; 26 | import org.commonmark.renderer.html.HtmlRenderer; 27 | import org.commonmark.renderer.text.TextContentRenderer; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | import org.sonar.plugins.groovy.codenarc.parser.RuleParser; 31 | import org.sonar.plugins.groovy.codenarc.parser.RuleParserResult; 32 | import org.sonar.plugins.groovy.codenarc.parser.markdown.MarkdownParser; 33 | import org.sonar.plugins.groovy.codenarc.printer.XMLPrinter; 34 | 35 | import java.io.IOException; 36 | import java.nio.file.Files; 37 | import java.nio.file.Path; 38 | import java.nio.file.Paths; 39 | import java.util.Arrays; 40 | import java.util.Collections; 41 | 42 | public class RuleConverter { 43 | 44 | private static final Logger log = LoggerFactory.getLogger(RuleConverter.class); 45 | 46 | public static void main(String[] args) throws IOException, ReflectiveOperationException { 47 | Path baseDir = Paths.get("."); 48 | if (args.length > 0) { 49 | baseDir = Paths.get(args[0]); 50 | } 51 | 52 | Path targetFile = getResultFile(baseDir); 53 | RuleParser parser = createParser(); 54 | 55 | RuleParserResult result = parser.parse(baseDir); 56 | 57 | new XMLPrinter().process(result).printAll(targetFile); 58 | 59 | printResultsByCategory(result); 60 | printResultsByVersion(result); 61 | log.info("{} rules processed", result.getCount()); 62 | } 63 | 64 | public static RuleParser createParser() { 65 | Parser parser = Parser.builder() 66 | .extensions(Arrays.asList(YamlFrontMatterExtension.create(), TablesExtension.create())) 67 | .build(); 68 | 69 | HtmlRenderer htmlRenderer = HtmlRenderer.builder().extensions(Collections.singletonList(TablesExtension.create())).build(); 70 | TextContentRenderer textRenderer = TextContentRenderer.builder().extensions(Collections.singletonList(TablesExtension.create())).build(); 71 | 72 | return new MarkdownParser(new PropertiesFileRuleRegistry(), parser, htmlRenderer, textRenderer); 73 | } 74 | 75 | 76 | private static Path getResultFile(Path baseDir) throws IOException { 77 | Path folder = baseDir.resolve("target/results/rules.xml"); 78 | Files.createDirectories(folder.getParent()); 79 | return folder; 80 | } 81 | 82 | private static void printResultsByVersion(RuleParserResult result) { 83 | log.info("Rules by Version:"); 84 | result.getRuleCountByVersion().forEach((version, count) -> log.info(" - {} : {}", version, count)); 85 | } 86 | 87 | private static void printResultsByCategory(RuleParserResult result) { 88 | log.info("Rules by category:"); 89 | result.getRuleCountByCategory().forEach((category, count) -> log.info(" - {} : {}", category, count)); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/RuleParameter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import com.google.auto.value.AutoValue; 23 | import org.apache.commons.lang.StringUtils; 24 | 25 | @AutoValue 26 | public abstract class RuleParameter implements Comparable { 27 | 28 | public abstract String key(); 29 | 30 | public abstract String description(); 31 | 32 | public abstract String defaultValue(); 33 | 34 | public static RuleParameter createEmpty() { 35 | return create("", "", ""); 36 | } 37 | 38 | public static RuleParameter create(String key, String defaultValue) { 39 | return create(key, "", defaultValue); 40 | } 41 | 42 | public static RuleParameter create(String key, String description, String defaultValue) { 43 | return new AutoValue_RuleParameter(key, description, defaultValue); 44 | } 45 | 46 | public boolean isEmpty() { 47 | return StringUtils.isBlank(key()) 48 | && StringUtils.isBlank(defaultValue()) 49 | && StringUtils.isBlank(description()); 50 | } 51 | 52 | public boolean hasDefaultValue() { 53 | return StringUtils.isNotBlank(defaultValue()); 54 | } 55 | 56 | public RuleParameter merge(RuleParameter parameter) { 57 | if (key() != null && key().equals(parameter.key())) { 58 | String newDescription = selectValue(description(), parameter.description()); 59 | String newDefaultValue = selectValue(defaultValue(), parameter.defaultValue()); 60 | return create(key(), newDescription, newDefaultValue); 61 | } else { 62 | return this; 63 | } 64 | } 65 | 66 | public RuleParameter withExpandedKey(String keyAdd) { 67 | return create(key() + keyAdd, description(), defaultValue()); 68 | } 69 | 70 | public RuleParameter withNewDefaultValue(String newDefaultValue) { 71 | return create(key(), description(), newDefaultValue); 72 | } 73 | 74 | public RuleParameter withExpandedDescription(String descAdd) { 75 | String newDesc = description(); 76 | newDesc += (newDesc.isEmpty() ? "" : " ") + descAdd; 77 | return create(key(), newDesc, defaultValue()); 78 | } 79 | 80 | private static String selectValue(String currentValue, String newValue) { 81 | if (StringUtils.isBlank(currentValue) && StringUtils.isNotBlank(newValue)) { 82 | return newValue; 83 | } 84 | return currentValue; 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | return "RuleParameter [key=" 90 | + key() 91 | + ", defaultValue=" 92 | + defaultValue() 93 | + ", description=" 94 | + StringUtils.abbreviate(description(), 30) 95 | + "]"; 96 | } 97 | 98 | @Override 99 | public int compareTo(RuleParameter o) { 100 | return key().compareTo(o.key()); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/RuleSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import org.codenarc.rule.AbstractRule; 23 | 24 | public enum RuleSet { 25 | BASIC("basic"), 26 | BRACES("braces"), 27 | COMMENTS("comments"), // new in 1.3 28 | CONCURRENCY("concurrency"), 29 | CONVENTION("convention"), // new in 0.16 30 | DESIGN("design"), 31 | DRY("dry"), 32 | ENHANCED("enhanced"), // new in 1.1 33 | EXCEPTIONS("exceptions"), 34 | FORMATTING("formatting"), // new in 0.15 35 | GENERIC("generic"), 36 | GRAILS("grails"), 37 | GROOVYISM("groovyism"), // new in 0.16 38 | IMPORTS("imports"), 39 | JDBC("jdbc"), // new in 0.14 40 | JUNIT("junit"), 41 | LOGGING("logging"), 42 | NAMING("naming"), 43 | SECURITY("security"), // new in 0.14 44 | SERIALIZATION("serialization"), // new in 0.14 45 | SIZE("size"), 46 | UNNECESSARY("unnecessary"), 47 | UNUSED("unused"); 48 | 49 | private final String label; 50 | 51 | RuleSet(String label) { 52 | this.label = label; 53 | } 54 | 55 | public String getLabel() { 56 | return label; 57 | } 58 | 59 | public static RuleSet getCategory(Class ruleClass) { 60 | String[] name = ruleClass.getCanonicalName().split("\\."); 61 | return RuleSet.valueOf(name[3].toUpperCase()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/parser/RuleParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc.parser; 21 | 22 | import java.io.IOException; 23 | import java.nio.file.Path; 24 | 25 | public interface RuleParser { 26 | RuleParserResult parse(Path source) throws IOException, ReflectiveOperationException; 27 | 28 | Path getSourceFolder(Path source); 29 | } 30 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/parser/RuleParserResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc.parser; 21 | 22 | import com.google.common.collect.LinkedListMultimap; 23 | import com.google.common.collect.Multimap; 24 | import org.sonar.plugins.groovy.codenarc.Rule; 25 | import org.sonar.plugins.groovy.codenarc.RuleSet; 26 | 27 | import java.util.*; 28 | import java.util.function.Function; 29 | import java.util.stream.Collectors; 30 | 31 | public class RuleParserResult { 32 | private final String version; 33 | private final Multimap result = LinkedListMultimap.create(); 34 | 35 | public RuleParserResult(String codenarcVersion) { 36 | this.version = codenarcVersion; 37 | } 38 | 39 | public void addRule(RuleSet ruleSet, Rule rule) { 40 | result.put(ruleSet, rule); 41 | } 42 | 43 | public String getCodeNarcVersion() { 44 | return version; 45 | } 46 | 47 | public Collection getRulesBy(RuleSet ruleSet) { 48 | return Collections.unmodifiableCollection(result.get(ruleSet)); 49 | } 50 | 51 | public long getCount() { 52 | return result.asMap().values().stream().mapToLong(Collection::size).sum(); 53 | } 54 | 55 | public Map getRuleCountByVersion() { 56 | return result.asMap().values().stream().flatMap(Collection::stream) 57 | .sorted(Comparator.comparing(r -> withDefault(r.version))) 58 | .collect(Collectors.groupingBy(r -> withDefault(r.version), LinkedHashMap::new, Collectors.counting())); 59 | } 60 | 61 | public Map getRuleCountByCategory() { 62 | return result.asMap().values().stream().flatMap(Collection::stream) 63 | .flatMap(r -> r.tags.stream()) 64 | .sorted(Comparator.comparing(Function.identity())) 65 | .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting())); 66 | } 67 | 68 | private String withDefault(String version) { 69 | return Optional.ofNullable(version).orElse("legacy"); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/parser/markdown/MarkdownParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc.parser.markdown; 21 | 22 | import org.apache.commons.io.IOUtils; 23 | import org.codenarc.rule.AbstractRule; 24 | import org.codenarc.ruleregistry.RuleRegistry; 25 | import org.commonmark.node.Node; 26 | import org.commonmark.parser.Parser; 27 | import org.commonmark.renderer.html.HtmlRenderer; 28 | import org.commonmark.renderer.text.TextContentRenderer; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | import org.sonar.plugins.groovy.codenarc.RuleConverter; 32 | import org.sonar.plugins.groovy.codenarc.Rule; 33 | import org.sonar.plugins.groovy.codenarc.parser.RuleParser; 34 | import org.sonar.plugins.groovy.codenarc.parser.RuleParserResult; 35 | 36 | import java.io.File; 37 | import java.io.FileNotFoundException; 38 | import java.io.IOException; 39 | import java.nio.charset.StandardCharsets; 40 | import java.nio.file.Files; 41 | import java.nio.file.Path; 42 | import java.util.HashMap; 43 | import java.util.Map; 44 | import java.util.Properties; 45 | 46 | public class MarkdownParser implements RuleParser { 47 | 48 | /** 49 | * location of the markdown files in the CodeNarc project (see git submodule) 50 | */ 51 | private static final String RULES_MARKDOWN_FILES_LOCATION = "CodeNarc/docs"; 52 | 53 | private static final Logger log = LoggerFactory.getLogger(MarkdownParser.class); 54 | 55 | private final RuleRegistry registry; 56 | 57 | private final Parser parser; 58 | private final HtmlRenderer htmlRenderer; 59 | private final TextContentRenderer textRenderer; 60 | 61 | public MarkdownParser(RuleRegistry registry, Parser parser, HtmlRenderer htmlRenderer, TextContentRenderer textRenderer) { 62 | this.registry = registry; 63 | this.parser = parser; 64 | this.htmlRenderer = htmlRenderer; 65 | this.textRenderer = textRenderer; 66 | } 67 | 68 | @Override 69 | public RuleParserResult parse(Path source) throws IOException, ReflectiveOperationException { 70 | File docsFolder = getSourceFolder(source).toFile(); 71 | File[] docs = docsFolder.listFiles((dir, name) -> name.startsWith("codenarc-rules-")); 72 | if (docs == null) { 73 | throw new FileNotFoundException(String.format("%s does not contain any files matching pattern codenarc-rules-*", docsFolder.getAbsolutePath())); 74 | } 75 | String version = 76 | IOUtils.toString( 77 | MarkdownParser.class.getResourceAsStream("/codenarc-version.txt"), StandardCharsets.UTF_8); 78 | 79 | RuleParserResult result = new RuleParserResult(version); 80 | 81 | Properties props = new Properties(); 82 | props.load(RuleConverter.class.getResourceAsStream("/codenarc-base-messages.properties")); 83 | 84 | for (File doc : docs) { 85 | Node document = parser.parseReader(Files.newBufferedReader(doc.toPath())); 86 | RuleSetVisitor visitor = new RuleSetVisitor(registry, htmlRenderer, textRenderer); 87 | document.accept(visitor); 88 | 89 | Map parametersByRule = new HashMap<>(); 90 | 91 | for (RuleDescription r : visitor.getRules()) { 92 | parametersByRule.put(r.getName(), r); 93 | } 94 | 95 | for (RuleDescription r : visitor.getRules()) { 96 | Class clazz = registry.getRuleClass(r.getName()); 97 | if (clazz != null) { 98 | result.addRule(visitor.getRuleset(), new Rule(clazz.asSubclass(AbstractRule.class), r.getSince(), props, parametersByRule)); 99 | } else { 100 | log.warn("Could not find rule file for {}", r.getName()); 101 | } 102 | } 103 | 104 | } 105 | return result; 106 | } 107 | 108 | public Path getSourceFolder(Path source) { 109 | return source.resolve(RULES_MARKDOWN_FILES_LOCATION); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/parser/markdown/RuleDescription.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc.parser.markdown; 21 | 22 | import org.sonar.plugins.groovy.codenarc.ParseResult; 23 | import org.sonar.plugins.groovy.codenarc.RuleParameter; 24 | 25 | import java.util.*; 26 | 27 | public class RuleDescription implements ParseResult { 28 | private String name; 29 | private final StringBuilder description = new StringBuilder(); 30 | private String since; 31 | private final Set parameters = new HashSet<>(); 32 | 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public void setName(String name) { 39 | this.name = name; 40 | } 41 | 42 | @Override 43 | public boolean hasParameters() { 44 | return !parameters.isEmpty(); 45 | } 46 | 47 | @Override 48 | public Set getParameters() { 49 | return Collections.unmodifiableSet(parameters); 50 | } 51 | 52 | public String getDescription() { 53 | return description.toString(); 54 | } 55 | 56 | public void appendDescription(String description) { 57 | this.description.append(description); 58 | } 59 | 60 | public void addParameter(String key, String description, String defaultValue) { 61 | parameters.add(RuleParameter.create(key, description,defaultValue)); 62 | } 63 | 64 | public String getSince() { 65 | return since; 66 | } 67 | 68 | public void setSince(String since) { 69 | this.since = since; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/parser/markdown/RuleSetVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc.parser.markdown; 21 | 22 | import org.codenarc.ruleregistry.RuleRegistry; 23 | import org.commonmark.node.AbstractVisitor; 24 | import org.commonmark.node.Heading; 25 | import org.commonmark.node.Node; 26 | import org.commonmark.node.Text; 27 | import org.commonmark.renderer.html.HtmlRenderer; 28 | import org.commonmark.renderer.text.TextContentRenderer; 29 | import org.sonar.plugins.groovy.codenarc.RuleSet; 30 | 31 | import java.util.ArrayList; 32 | import java.util.Collections; 33 | import java.util.List; 34 | 35 | public class RuleSetVisitor extends AbstractVisitor { 36 | 37 | private final RuleRegistry registry; 38 | 39 | private final HtmlRenderer htmlRenderer; 40 | private final TextContentRenderer textRenderer; 41 | 42 | private RuleSet ruleset; 43 | private final List rules = new ArrayList<>(); 44 | 45 | public RuleSetVisitor(RuleRegistry registry, HtmlRenderer htmlRenderer, TextContentRenderer textContentRenderer) { 46 | this.registry = registry; 47 | 48 | this.htmlRenderer = htmlRenderer; 49 | this.textRenderer = textContentRenderer; 50 | } 51 | 52 | public RuleSet getRuleset() { 53 | return ruleset; 54 | } 55 | 56 | public List getRules() { 57 | return Collections.unmodifiableList(rules); 58 | } 59 | 60 | public int getCount() { 61 | return rules.size(); 62 | } 63 | 64 | @Override 65 | public void visit(Heading heading) { 66 | if (isRuleDescriptionSection(heading)) { 67 | RuleVisitor ruleVisitor = new RuleVisitor(htmlRenderer, textRenderer); 68 | heading.accept(ruleVisitor); 69 | rules.add(ruleVisitor.getRule()); 70 | } 71 | visitChildren(heading); 72 | } 73 | 74 | @Override 75 | public void visit(Text text) { 76 | if (text.getLiteral().startsWith("rulesets/")) { 77 | ruleset = RuleSet.valueOf(text.getLiteral().replaceFirst("rulesets/(.*)\\.xml", "$1").toUpperCase()); 78 | } 79 | visitChildren(text); 80 | } 81 | 82 | private boolean isRuleDescriptionSection(Heading heading) { 83 | if (heading.getLevel() == 2) { 84 | Node header = heading.getFirstChild(); 85 | if (header.getClass().isAssignableFrom(Text.class)) { 86 | Text t = (Text) header; 87 | return registry.getRuleClass(t.getLiteral().split(" ")[0]) != null; 88 | } 89 | } 90 | return false; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /codenarc-converter/src/main/java/org/sonar/plugins/groovy/codenarc/parser/markdown/RuleVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar CodeNarc Converter 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc.parser.markdown; 21 | 22 | import org.commonmark.ext.gfm.tables.TableBlock; 23 | import org.commonmark.ext.gfm.tables.TableBody; 24 | import org.commonmark.ext.gfm.tables.TableCell; 25 | import org.commonmark.ext.gfm.tables.TableRow; 26 | import org.commonmark.node.AbstractVisitor; 27 | import org.commonmark.node.Heading; 28 | import org.commonmark.node.Node; 29 | import org.commonmark.node.Text; 30 | import org.commonmark.renderer.Renderer; 31 | import org.commonmark.renderer.html.HtmlRenderer; 32 | import org.commonmark.renderer.text.TextContentRenderer; 33 | 34 | public class RuleVisitor extends AbstractVisitor { 35 | 36 | private RuleDescription rule; 37 | 38 | private final Renderer htmlRenderer; 39 | private final Renderer textRenderer; 40 | 41 | RuleVisitor(HtmlRenderer htmlRenderer, TextContentRenderer textRenderer) { 42 | this.htmlRenderer = htmlRenderer; 43 | this.textRenderer = textRenderer; 44 | } 45 | 46 | public RuleDescription getRule() { 47 | return rule; 48 | } 49 | 50 | @Override 51 | public void visit(Heading node) { 52 | rule = new RuleDescription(); 53 | Text name = (Text) node.getFirstChild(); 54 | rule.setName(name.getLiteral().split(" ")[0]); 55 | Text versionString = ((Text) node.getNext().getFirstChild().getFirstChild()); 56 | if (versionString != null && versionString.getLiteral().startsWith("Since CodeNarc")) { 57 | rule.setSince(versionString.getLiteral().replaceAll("Since CodeNarc ([0-9.]+)(.*)", "$1").trim()); 58 | } 59 | for (Node next = rule.getSince() == null ? node.getNext() : node.getNext().getNext(); isWithinSection(next, 2); next = next.getNext()) { 60 | if (isParametersTable(next)) { 61 | parseParameters((TableBlock) next); 62 | } else { 63 | rule.appendDescription(htmlRenderer.render(next)); 64 | } 65 | } 66 | } 67 | 68 | private void parseParameters(TableBlock table) { 69 | TableBody body = (TableBody) table.getLastChild(); 70 | TableRow row = (TableRow) body.getFirstChild(); 71 | while (row != null) { 72 | TableCell propertyCell = ((TableCell) row.getFirstChild()); 73 | TableCell descriptionCell = ((TableCell) row.getFirstChild().getNext()); 74 | TableCell defaultValueCell = null; 75 | if (descriptionCell.getNext() != null) { 76 | defaultValueCell = (TableCell) descriptionCell.getNext(); 77 | } 78 | 79 | String property = ((Text) propertyCell.getFirstChild()).getLiteral(); 80 | String description = textRenderer.render(descriptionCell).trim(); 81 | description = description.substring(0, description.length() - 1); // Strips last | character 82 | String defaultValue = defaultValueCell == null ? "" : textRenderer.render(defaultValueCell).trim(); 83 | defaultValue = defaultValue.substring(0, defaultValue.length() - 1).replaceAll("\"", ""); // Strips last | character 84 | 85 | 86 | rule.addParameter(property, description, defaultValue); 87 | row = (TableRow) row.getNext(); 88 | } 89 | 90 | } 91 | 92 | private boolean isParametersTable(Node node) { 93 | if (TableBlock.class.isAssignableFrom(node.getClass())) { 94 | TableBlock table = (TableBlock) node; 95 | return "Property".equals(((Text) table.getFirstChild().getFirstChild().getFirstChild().getFirstChild()).getLiteral()); 96 | } 97 | return false; 98 | } 99 | 100 | private boolean isWithinSection(Node node, int level) { 101 | if (node == null) { 102 | return false; 103 | } 104 | if (Heading.class.isAssignableFrom(node.getClass())) { 105 | return ((Heading) node).getLevel() != level; 106 | } 107 | return true; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.sonarsource.groovy 7 | groovy 8 | 1.9-SNAPSHOT 9 | 10 | 11 | sonar-groovy-plugin 12 | sonar-plugin 13 | 14 | Sonar Groovy Plugin 15 | Code Analyzer for Groovy 16 | 17 | 18 | org.sonar.plugins.groovy.GroovyPlugin 19 | Groovy 20 | 21 | 22 | 23 | 24 | com.github.spotbugs 25 | spotbugs-annotations 26 | 4.5.3 27 | provided 28 | 29 | 30 | org.sonarsource.sonarqube 31 | sonar-plugin-api 32 | provided 33 | 34 | 35 | org.apache.ant 36 | ant 37 | 1.10.13 38 | 39 | 40 | commons-io 41 | commons-io 42 | 43 | 44 | commons-lang 45 | commons-lang 46 | 47 | 48 | com.fasterxml.staxmate 49 | staxmate 50 | 2.4.0 51 | 52 | 53 | com.fasterxml.woodstox 54 | woodstox-core 55 | 6.4.0 56 | 57 | 58 | 59 | org.codenarc 60 | CodeNarc 61 | 62 | 63 | org.gmetrics 64 | GMetrics 65 | 66 | 67 | 68 | org.jacoco 69 | org.jacoco.core 70 | ${version.jacoco.plugin} 71 | 72 | 73 | 74 | 75 | org.sonarsource.sonarqube 76 | sonar-plugin-api-impl 77 | test 78 | 79 | 80 | junit 81 | junit 82 | 83 | 84 | xmlunit 85 | xmlunit 86 | 1.6 87 | test 88 | 89 | 90 | org.assertj 91 | assertj-core 92 | 93 | 94 | org.mockito 95 | mockito-core 96 | 3.12.4 97 | test 98 | 99 | 100 | org.slf4j 101 | slf4j-simple 102 | test 103 | 104 | 105 | 106 | 107 | 108 | 109 | org.apache.maven.plugins 110 | maven-enforcer-plugin 111 | 112 | 113 | enforce-plugin-size 114 | 115 | enforce 116 | 117 | verify 118 | 119 | 120 | 121 | 15000000 122 | 11000000 123 | 124 | ${project.build.directory}/${project.build.finalName}.jar 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/GroovyPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy; 20 | 21 | import org.sonar.api.Plugin; 22 | import org.sonar.plugins.groovy.cobertura.CoberturaSensor; 23 | import org.sonar.plugins.groovy.codenarc.CodeNarcSensor; 24 | import org.sonar.plugins.groovy.foundation.Groovy; 25 | import org.sonar.plugins.groovy.jacoco.JaCoCoExtensions; 26 | import org.sonar.plugins.groovy.surefire.GroovySurefireSensor; 27 | 28 | public class GroovyPlugin implements Plugin { 29 | 30 | @Override 31 | public void define(Context context) { 32 | context 33 | .addExtensions(Groovy.getExtensions()) 34 | .addExtensions(GroovySensor.getExtensions()) 35 | .addExtensions(CodeNarcSensor.getExtensions()) 36 | .addExtensions(GroovySurefireSensor.getExtensions()) 37 | .addExtensions(CoberturaSensor.getExtensions()) 38 | .addExtensions(JaCoCoExtensions.getExtensions()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/GroovySonarWayProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy; 20 | 21 | import java.io.BufferedReader; 22 | import java.io.IOException; 23 | import java.io.InputStreamReader; 24 | import java.nio.charset.StandardCharsets; 25 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 26 | import org.sonar.plugins.groovy.codenarc.CodeNarcRulesDefinition; 27 | import org.sonar.plugins.groovy.foundation.Groovy; 28 | import org.sonarsource.api.sonarlint.SonarLintSide; 29 | 30 | @SonarLintSide 31 | public class GroovySonarWayProfile implements BuiltInQualityProfilesDefinition { 32 | 33 | @Override 34 | public void define(Context context) { 35 | NewBuiltInQualityProfile sonarWay = 36 | context.createBuiltInQualityProfile("Sonar way", Groovy.KEY); 37 | 38 | addRulesFromText(CodeNarcRulesDefinition.REPOSITORY_KEY, sonarWay); 39 | sonarWay.done(); 40 | } 41 | 42 | private static void addRulesFromText(String repo, NewBuiltInQualityProfile profile) { 43 | try (BufferedReader reader = 44 | new BufferedReader( 45 | new InputStreamReader( 46 | GroovySonarWayProfile.class.getResourceAsStream("profile-default.txt"), 47 | StandardCharsets.UTF_8))) { 48 | reader 49 | .lines() 50 | .forEach( 51 | (String rule) -> { 52 | if (!rule.isEmpty()) { 53 | profile.activateRule(repo, rule); 54 | } 55 | }); 56 | } catch (IOException e) { 57 | throw new IllegalStateException("Failed to read: profile-default.txt", e); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/cobertura/CoberturaSensor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.cobertura; 20 | 21 | import java.io.File; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import java.util.Optional; 25 | import org.sonar.api.batch.fs.FileSystem; 26 | import org.sonar.api.batch.sensor.Sensor; 27 | import org.sonar.api.batch.sensor.SensorContext; 28 | import org.sonar.api.batch.sensor.SensorDescriptor; 29 | import org.sonar.api.config.Configuration; 30 | import org.sonar.api.config.PropertyDefinition; 31 | import org.sonar.api.resources.Qualifiers; 32 | import org.sonar.api.utils.log.Logger; 33 | import org.sonar.api.utils.log.Loggers; 34 | import org.sonar.plugins.groovy.foundation.Groovy; 35 | import org.sonar.plugins.groovy.foundation.GroovyFileSystem; 36 | 37 | public class CoberturaSensor implements Sensor { 38 | public static final String COBERTURA_REPORT_PATH = "sonar.groovy.cobertura.reportPath"; 39 | 40 | private static final Logger LOG = Loggers.get(CoberturaSensor.class); 41 | 42 | private final Configuration settings; 43 | private final FileSystem fileSystem; 44 | private final GroovyFileSystem groovyFileSystem; 45 | 46 | public CoberturaSensor(Configuration settings, FileSystem fileSystem) { 47 | this.settings = settings; 48 | this.fileSystem = fileSystem; 49 | this.groovyFileSystem = new GroovyFileSystem(fileSystem); 50 | } 51 | 52 | @Override 53 | public void describe(SensorDescriptor descriptor) { 54 | descriptor.onlyOnLanguage(Groovy.KEY).name(this.toString()); 55 | } 56 | 57 | @Override 58 | public void execute(SensorContext context) { 59 | if (shouldExecuteOnProject()) { 60 | analyse(context); 61 | } 62 | } 63 | 64 | // VisibleForTesting 65 | boolean shouldExecuteOnProject() { 66 | return groovyFileSystem.hasGroovyFiles(); 67 | } 68 | 69 | public void analyse(SensorContext context) { 70 | Optional reportPath = settings.get(COBERTURA_REPORT_PATH); 71 | 72 | if (reportPath.isPresent()) { 73 | File xmlFile = new File(reportPath.get()); 74 | if (!xmlFile.isAbsolute()) { 75 | xmlFile = new File(fileSystem.baseDir(), reportPath.get()); 76 | } 77 | if (xmlFile.exists()) { 78 | LOG.info("Analyzing Cobertura report: " + reportPath); 79 | new CoberturaReportParser(context, fileSystem).parseReport(xmlFile); 80 | } else { 81 | LOG.info("Cobertura xml report not found: " + reportPath); 82 | } 83 | } else { 84 | LOG.info("No Cobertura report provided (see '" + COBERTURA_REPORT_PATH + "' property)"); 85 | } 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return "Groovy CoberturaSensor"; 91 | } 92 | 93 | public static List getExtensions() { 94 | return Arrays.asList( 95 | CoberturaSensor.class, 96 | PropertyDefinition.builder(COBERTURA_REPORT_PATH) 97 | .name("Cobertura Report") 98 | .description( 99 | "Path to the Cobertura XML report. Path may be absolute or relative to the project base directory.") 100 | .category(Groovy.NAME) 101 | .subCategory("Cobertura") 102 | .onQualifiers(Qualifiers.PROJECT) 103 | .build()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/cobertura/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.cobertura; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/codenarc/CodeNarcProfileExporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import java.io.IOException; 23 | import java.io.Writer; 24 | import java.util.Collection; 25 | import java.util.Map; 26 | import org.apache.commons.lang.StringEscapeUtils; 27 | import org.apache.commons.lang.StringUtils; 28 | import org.sonar.api.batch.rule.ActiveRule; 29 | import org.sonar.api.batch.rule.ActiveRules; 30 | 31 | public class CodeNarcProfileExporter { 32 | 33 | private static final String AUTO_CLOSING_TAG = "\"/>\n"; 34 | private Writer writer; 35 | 36 | public CodeNarcProfileExporter(Writer writer) { 37 | this.writer = writer; 38 | } 39 | 40 | public void exportProfile(ActiveRules activeRules) { 41 | try { 42 | generateXML(activeRules.findByRepository(CodeNarcRulesDefinition.REPOSITORY_KEY)); 43 | 44 | } catch (IOException e) { 45 | throw new IllegalStateException( 46 | "Fail to export CodeNarc profile : " + CodeNarcRulesDefinition.REPOSITORY_KEY, e); 47 | } 48 | } 49 | 50 | private void generateXML(Collection activeRules) throws IOException { 51 | appendXmlHeader(); 52 | for (ActiveRule activeRule : activeRules) { 53 | appendRule(activeRule); 54 | } 55 | appendXmlFooter(); 56 | } 57 | 58 | private void appendXmlHeader() throws IOException { 59 | writer 60 | .append("\n") 61 | .append("\n") 62 | .append("\n"); 68 | } 69 | 70 | private void appendXmlFooter() throws IOException { 71 | writer.append(""); 72 | } 73 | 74 | private void appendRule(ActiveRule activeRule) throws IOException { 75 | String ruleKey = activeRule.ruleKey().rule(); 76 | // SONARGROOV-40 : key of rule having null parameters have been suffixed with ".fixed" 77 | if (ruleKey.endsWith(".fixed")) { 78 | ruleKey = ruleKey.substring(0, ruleKey.length() - ".fixed".length()); 79 | } 80 | writer.append("\n"); 85 | for (Map.Entry activeRuleParam : activeRule.params().entrySet()) { 86 | String value = activeRuleParam.getValue(); 87 | if (StringUtils.isNotBlank(value)) { 88 | writer 89 | .append("\n"); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/codenarc/CodeNarcRulesDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import java.io.IOException; 23 | import java.nio.charset.StandardCharsets; 24 | import java.util.Collection; 25 | import java.util.HashMap; 26 | import java.util.List; 27 | import java.util.Map; 28 | import org.apache.commons.io.IOUtils; 29 | import org.sonar.api.server.debt.DebtRemediationFunction; 30 | import org.sonar.api.server.rule.RulesDefinition; 31 | import org.sonar.api.server.rule.RulesDefinitionXmlLoader; 32 | import org.sonar.api.utils.MessageException; 33 | import org.sonar.plugins.groovy.foundation.Groovy; 34 | 35 | public class CodeNarcRulesDefinition implements RulesDefinition { 36 | 37 | public static final String REPOSITORY_KEY = Groovy.KEY; 38 | public static final String REPOSITORY_NAME = "CodeNarc"; 39 | private static final String COST_FILE_PATH = "/org/sonar/plugins/groovy/cost.csv"; 40 | 41 | @Override 42 | public void define(Context context) { 43 | NewRepository repository = 44 | context.createRepository(REPOSITORY_KEY, Groovy.KEY).setName(REPOSITORY_NAME); 45 | 46 | RulesDefinitionXmlLoader ruleLoader = new RulesDefinitionXmlLoader(); 47 | ruleLoader.load( 48 | repository, 49 | CodeNarcRulesDefinition.class.getResourceAsStream("/org/sonar/plugins/groovy/rules.xml"), 50 | "UTF-8"); 51 | addRemediationCost(repository.rules()); 52 | repository.done(); 53 | } 54 | 55 | private static void addRemediationCost(Collection rules) { 56 | Map costByRule = getCostByRule(); 57 | for (NewRule newRule : rules) { 58 | String ruleKey = newRule.key(); 59 | if (costByRule.containsKey(ruleKey)) { 60 | DebtRemediationFunction linear = 61 | newRule.debtRemediationFunctions().linear(costByRule.get(ruleKey)); 62 | newRule.setDebtRemediationFunction(linear); 63 | } 64 | } 65 | } 66 | 67 | private static Map getCostByRule() { 68 | Map result = new HashMap<>(); 69 | List lines; 70 | try { 71 | lines = 72 | IOUtils.readLines( 73 | CodeNarcRulesDefinition.class.getResourceAsStream(COST_FILE_PATH), 74 | StandardCharsets.UTF_8); 75 | } catch (IOException e) { 76 | throw MessageException.of("Unable to load rules remediation function/factor", e); 77 | } 78 | 79 | lines.stream().skip(1).forEach(line -> CodeNarcRulesDefinition.completeCost(line, result)); 80 | 81 | return result; 82 | } 83 | 84 | private static void completeCost(String line, Map costByRule) { 85 | String[] blocks = line.split(";"); 86 | String ruleKey = blocks[0]; 87 | // block 1 contains the function (always linear) 88 | String ruleCost = blocks[2]; 89 | costByRule.put(ruleKey, ruleCost); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/codenarc/CodeNarcSourceAnalyzer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import java.io.IOException; 23 | import java.util.ArrayList; 24 | import java.util.HashMap; 25 | import java.util.LinkedList; 26 | import java.util.List; 27 | import java.util.Map; 28 | import org.codenarc.analyzer.AbstractSourceAnalyzer; 29 | import org.codenarc.results.DirectoryResults; 30 | import org.codenarc.results.FileResults; 31 | import org.codenarc.results.Results; 32 | import org.codenarc.rule.Violation; 33 | import org.codenarc.ruleset.RuleSet; 34 | import org.codenarc.source.SourceString; 35 | import org.sonar.api.batch.fs.InputFile; 36 | import org.sonar.api.utils.log.Logger; 37 | import org.sonar.api.utils.log.Loggers; 38 | 39 | public class CodeNarcSourceAnalyzer extends AbstractSourceAnalyzer { 40 | private static final Logger LOG = Loggers.get(CodeNarcSourceAnalyzer.class); 41 | 42 | private final Map> violationsByFile = new HashMap<>(); 43 | private final List sourceFiles; 44 | 45 | public CodeNarcSourceAnalyzer(List sourceFiles) { 46 | this.sourceFiles = sourceFiles; 47 | } 48 | 49 | @Override 50 | public Results analyze(RuleSet ruleSet) { 51 | List resultsByFile = processFiles(ruleSet); 52 | DirectoryResults directoryResults = new DirectoryResults("."); 53 | resultsByFile.forEach(directoryResults::addChild); 54 | return directoryResults; 55 | } 56 | 57 | private List processFiles(RuleSet ruleSet) { 58 | List results = new LinkedList<>(); 59 | for (InputFile inputFile : sourceFiles) { 60 | try { 61 | List violations = collectViolations(new SourceString(inputFile.contents()), ruleSet); 62 | violationsByFile.put(inputFile, violations); 63 | FileResults result = new FileResults(inputFile.uri().toString(), violations); 64 | results.add(result); 65 | } catch (IOException e) { 66 | LOG.error("Could not read input file: " + inputFile.toString(), e); 67 | } 68 | } 69 | return results; 70 | } 71 | 72 | @Override 73 | public List getSourceDirectories() { 74 | return new ArrayList<>(); 75 | } 76 | 77 | public Map> getViolationsByFile() { 78 | return violationsByFile; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/codenarc/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.codenarc; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/foundation/Groovy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.foundation; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import org.apache.commons.lang.StringUtils; 25 | import org.sonar.api.config.Configuration; 26 | import org.sonar.api.config.PropertyDefinition; 27 | import org.sonar.api.resources.AbstractLanguage; 28 | import org.sonar.api.resources.Qualifiers; 29 | 30 | public class Groovy extends AbstractLanguage { 31 | 32 | public static final String KEY = "grvy"; 33 | public static final String NAME = "Groovy"; 34 | public static final String FILE_SUFFIXES_KEY = "sonar.groovy.file.suffixes"; 35 | static final String DEFAULT_FILE_SUFFIXES = ".groovy"; 36 | 37 | /** Settings of the plugin. */ 38 | private final Configuration settings; 39 | 40 | /** Default constructor */ 41 | public Groovy(Configuration settings) { 42 | super(KEY, NAME); 43 | this.settings = settings; 44 | } 45 | 46 | @Override 47 | public String[] getFileSuffixes() { 48 | String[] suffixes = filterEmptyStrings(settings.getStringArray(FILE_SUFFIXES_KEY)); 49 | if (suffixes.length == 0) { 50 | suffixes = StringUtils.split(DEFAULT_FILE_SUFFIXES, ","); 51 | } 52 | return addDot(suffixes); 53 | } 54 | 55 | private static String[] addDot(String[] suffixes) { 56 | String[] results = new String[suffixes.length]; 57 | for (int i = 0; i < suffixes.length; i++) { 58 | String suffix = suffixes[i]; 59 | String dot = suffix.startsWith(".") ? "" : "."; 60 | results[i] = dot + suffix; 61 | } 62 | return results; 63 | } 64 | 65 | private static String[] filterEmptyStrings(String[] stringArray) { 66 | List nonEmptyStrings = new ArrayList<>(); 67 | for (String string : stringArray) { 68 | if (StringUtils.isNotBlank(string.trim())) { 69 | nonEmptyStrings.add(string.trim()); 70 | } 71 | } 72 | return nonEmptyStrings.toArray(new String[nonEmptyStrings.size()]); 73 | } 74 | 75 | public static List getExtensions() { 76 | return Arrays.asList( 77 | Groovy.class, 78 | GroovyFileSystem.class, 79 | PropertyDefinition.builder(FILE_SUFFIXES_KEY) 80 | .name("File suffixes") 81 | .description( 82 | "Comma-separated list of suffixes for files to analyze. To not filter, leave the list empty.") 83 | .category(Groovy.NAME) 84 | .subCategory("Base") 85 | .onQualifiers(Qualifiers.PROJECT) 86 | .defaultValue(DEFAULT_FILE_SUFFIXES) 87 | .multiValues(true) 88 | .build()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/foundation/GroovyFileSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.foundation; 21 | 22 | import java.io.File; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import javax.annotation.CheckForNull; 26 | import org.sonar.api.batch.ScannerSide; 27 | import org.sonar.api.batch.fs.FilePredicate; 28 | import org.sonar.api.batch.fs.FilePredicates; 29 | import org.sonar.api.batch.fs.FileSystem; 30 | import org.sonar.api.batch.fs.InputFile; 31 | import org.sonar.api.batch.fs.InputFile.Type; 32 | 33 | @ScannerSide 34 | public class GroovyFileSystem { 35 | 36 | private final FileSystem fileSystem; 37 | private final FilePredicates predicates; 38 | private final FilePredicate isGroovyLanguage; 39 | private final FilePredicate isMainTypeFile; 40 | 41 | public GroovyFileSystem(FileSystem fileSystem) { 42 | this.fileSystem = fileSystem; 43 | this.predicates = fileSystem.predicates(); 44 | this.isGroovyLanguage = predicates.hasLanguage(Groovy.KEY); 45 | this.isMainTypeFile = predicates.hasType(Type.MAIN); 46 | } 47 | 48 | public boolean hasGroovyFiles() { 49 | return fileSystem.hasFiles(isGroovyLanguage); 50 | } 51 | 52 | public List groovyInputFiles() { 53 | Iterable inputFiles = fileSystem.inputFiles(isGroovyLanguage); 54 | List list = new ArrayList<>(); 55 | inputFiles.iterator().forEachRemaining(list::add); 56 | return list; 57 | } 58 | 59 | public List sourceInputFiles() { 60 | Iterable inputFiles = 61 | fileSystem.inputFiles(predicates.and(isGroovyLanguage, isMainTypeFile)); 62 | List list = new ArrayList<>(); 63 | inputFiles.iterator().forEachRemaining(list::add); 64 | return list; 65 | } 66 | 67 | @CheckForNull 68 | public InputFile sourceInputFileFromRelativePath(String relativePath) { 69 | return fileSystem.inputFile( 70 | predicates.and( 71 | predicates.matchesPathPattern("**/" + relativePath), isGroovyLanguage, isMainTypeFile)); 72 | } 73 | 74 | public File baseDir() { 75 | return fileSystem.baseDir(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/foundation/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.foundation; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/gmetrics/GMetricsSourceAnalyzer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.gmetrics; 21 | 22 | import java.io.File; 23 | import java.util.ArrayList; 24 | import java.util.Arrays; 25 | import java.util.HashMap; 26 | import java.util.HashSet; 27 | import java.util.List; 28 | import java.util.Map; 29 | import java.util.Map.Entry; 30 | import java.util.Set; 31 | import org.apache.tools.ant.Project; 32 | import org.apache.tools.ant.types.FileSet; 33 | import org.gmetrics.GMetricsRunner; 34 | import org.gmetrics.analyzer.SourceAnalyzer; 35 | import org.gmetrics.ant.AntFileSetSourceAnalyzer; 36 | import org.gmetrics.metric.cyclomatic.CyclomaticComplexityMetric; 37 | import org.gmetrics.metric.linecount.ClassLineCountMetric; 38 | import org.gmetrics.metric.linecount.MethodLineCountMetric; 39 | import org.gmetrics.resultsnode.ClassResultsNode; 40 | import org.gmetrics.resultsnode.PackageResultsNode; 41 | import org.gmetrics.resultsnode.ResultsNode; 42 | import org.sonar.api.batch.fs.FileSystem; 43 | import org.sonar.api.batch.fs.InputFile; 44 | 45 | public class GMetricsSourceAnalyzer { 46 | 47 | private static final List GMETRICS = 48 | Arrays.asList( 49 | new CyclomaticComplexityMetric(), 50 | new ClassLineCountMetric(), 51 | new MethodLineCountMetric()); 52 | 53 | private final Map> resultsByFile = new HashMap<>(); 54 | 55 | private final Map pathToInputFile = new HashMap<>(); 56 | private final Set files = new HashSet<>(); 57 | 58 | private final File fileSystemBaseDir; 59 | 60 | public GMetricsSourceAnalyzer(FileSystem fileSystem, List sourceFiles) { 61 | this.fileSystemBaseDir = fileSystem.baseDir(); 62 | 63 | for (InputFile inputFile : sourceFiles) { 64 | pathToInputFile.put(inputFile.absolutePath(), inputFile); 65 | files.add(inputFile.file()); 66 | } 67 | } 68 | 69 | public Map> resultsByFile() { 70 | return resultsByFile; 71 | } 72 | 73 | public void analyze() { 74 | FileSet fileSet = new FileSet(); 75 | fileSet.setDir(fileSystemBaseDir); 76 | fileSet.add((basedir, filename, file) -> files.contains(file)); 77 | 78 | List fileSets = new ArrayList<>(); 79 | fileSets.add(fileSet); 80 | 81 | Project project = new Project(); 82 | project.setBaseDir(fileSystemBaseDir); 83 | 84 | SourceAnalyzer analyzer = new AntFileSetSourceAnalyzer(project, fileSets); 85 | 86 | GMetricsRunner runner = new GMetricsRunner(); 87 | runner.setMetricSet(() -> GMETRICS); 88 | runner.setSourceAnalyzer(analyzer); 89 | ResultsNode resultNode = runner.execute(); 90 | 91 | processResults(resultNode, pathToInputFile); 92 | } 93 | 94 | private void processResults(ResultsNode resultNode, Map pathToInputFile) { 95 | if (resultNode instanceof PackageResultsNode) { 96 | processPackageResults((PackageResultsNode) resultNode, pathToInputFile); 97 | } else { 98 | processClassResults((ClassResultsNode) resultNode, pathToInputFile); 99 | } 100 | } 101 | 102 | private void processPackageResults( 103 | PackageResultsNode resultNode, Map pathToInputFile) { 104 | for (Entry entry : resultNode.getChildren().entrySet()) { 105 | processResults(entry.getValue(), pathToInputFile); 106 | } 107 | } 108 | 109 | private void processClassResults( 110 | ClassResultsNode resultNode, Map pathToInputFile) { 111 | String filePath = resultNode.getFilePath(); 112 | InputFile inputFile = pathToInputFile.get(filePath); 113 | if (inputFile != null) { 114 | resultsByFile.putIfAbsent(inputFile, new ArrayList<>()); 115 | resultsByFile.get(inputFile).add(resultNode); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/gmetrics/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.gmetrics; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/jacoco/ExecutionDataVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | import org.jacoco.core.data.ExecutionData; 25 | import org.jacoco.core.data.ExecutionDataStore; 26 | import org.jacoco.core.data.IExecutionDataVisitor; 27 | import org.jacoco.core.data.ISessionInfoVisitor; 28 | import org.jacoco.core.data.SessionInfo; 29 | 30 | public class ExecutionDataVisitor implements ISessionInfoVisitor, IExecutionDataVisitor { 31 | 32 | private final Map sessions = new HashMap<>(); 33 | 34 | private ExecutionDataStore executionDataStore; 35 | private ExecutionDataStore merged = new ExecutionDataStore(); 36 | 37 | @Override 38 | public void visitSessionInfo(SessionInfo info) { 39 | String sessionId = info.getId(); 40 | executionDataStore = sessions.get(sessionId); 41 | if (executionDataStore == null) { 42 | executionDataStore = new ExecutionDataStore(); 43 | sessions.put(sessionId, executionDataStore); 44 | } 45 | } 46 | 47 | @Override 48 | public void visitClassExecution(ExecutionData data) { 49 | executionDataStore.put(data); 50 | merged.put(defensiveCopy(data)); 51 | } 52 | 53 | public Map getSessions() { 54 | return sessions; 55 | } 56 | 57 | public ExecutionDataStore getMerged() { 58 | return merged; 59 | } 60 | 61 | private static ExecutionData defensiveCopy(ExecutionData data) { 62 | boolean[] src = data.getProbes(); 63 | boolean[] dest = new boolean[src.length]; 64 | System.arraycopy(src, 0, dest, 0, src.length); 65 | return new ExecutionData(data.getId(), data.getName(), dest); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/jacoco/JaCoCoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.jacoco; 20 | 21 | import java.util.Arrays; 22 | import java.util.List; 23 | import org.sonar.api.PropertyType; 24 | import org.sonar.api.batch.ScannerSide; 25 | import org.sonar.api.batch.fs.FileSystem; 26 | import org.sonar.api.config.Configuration; 27 | import org.sonar.api.config.PropertyDefinition; 28 | import org.sonar.api.resources.Qualifiers; 29 | import org.sonar.plugins.groovy.foundation.Groovy; 30 | 31 | @ScannerSide 32 | public class JaCoCoConfiguration { 33 | 34 | static final String REPORT_PATH_PROPERTY = "sonar.groovy.jacoco.reportPath"; 35 | static final String REPORT_PATH_DEFAULT_VALUE = "target/jacoco.exec"; 36 | static final String IT_REPORT_PATH_PROPERTY = "sonar.groovy.jacoco.itReportPath"; 37 | static final String IT_REPORT_PATH_DEFAULT_VALUE = "target/jacoco-it.exec"; 38 | static final String REPORT_MISSING_FORCE_ZERO = "sonar.groovy.jacoco.reportMissing.force.zero"; 39 | static final String SONAR_GROOVY_BINARIES = "sonar.groovy.binaries"; 40 | static final String SONAR_GROOVY_BINARIES_FALLBACK = "sonar.binaries"; 41 | static final boolean REPORT_MISSING_FORCE_ZERO_DEFAULT_VALUE = false; 42 | 43 | private static final String SUBCATEGORY = "JaCoCo"; 44 | 45 | private final Configuration settings; 46 | private final FileSystem fileSystem; 47 | 48 | public JaCoCoConfiguration(Configuration settings, FileSystem fileSystem) { 49 | this.settings = settings; 50 | this.fileSystem = fileSystem; 51 | } 52 | 53 | public boolean shouldExecuteOnProject(boolean reportFound) { 54 | return hasGroovyFiles() && (reportFound || isCoverageToZeroWhenNoReport()); 55 | } 56 | 57 | private boolean hasGroovyFiles() { 58 | return fileSystem.hasFiles(fileSystem.predicates().hasLanguage(Groovy.KEY)); 59 | } 60 | 61 | public String getReportPath() { 62 | return settings.get(REPORT_PATH_PROPERTY).orElseThrow(IllegalStateException::new); 63 | } 64 | 65 | public String getItReportPath() { 66 | return settings.get(IT_REPORT_PATH_PROPERTY).orElseThrow(IllegalStateException::new); 67 | } 68 | 69 | private boolean isCoverageToZeroWhenNoReport() { 70 | return settings.getBoolean(REPORT_MISSING_FORCE_ZERO).orElse(false); 71 | } 72 | 73 | public static List getPropertyDefinitions() { 74 | return Arrays.asList( 75 | PropertyDefinition.builder(JaCoCoConfiguration.REPORT_PATH_PROPERTY) 76 | .defaultValue(JaCoCoConfiguration.REPORT_PATH_DEFAULT_VALUE) 77 | .name("UT JaCoCo Report") 78 | .description( 79 | "Path to the JaCoCo report file containing coverage data by unit tests. The path may be absolute or relative to the project base directory.") 80 | .category(Groovy.NAME) 81 | .subCategory(SUBCATEGORY) 82 | .onQualifiers(Qualifiers.PROJECT) 83 | .build(), 84 | PropertyDefinition.builder(JaCoCoConfiguration.IT_REPORT_PATH_PROPERTY) 85 | .defaultValue(JaCoCoConfiguration.IT_REPORT_PATH_DEFAULT_VALUE) 86 | .name("IT JaCoCo Report") 87 | .description( 88 | "Path to the JaCoCo report file containing coverage data by integration tests. The path may be absolute or relative to the project base directory.") 89 | .category(Groovy.NAME) 90 | .subCategory(SUBCATEGORY) 91 | .onQualifiers(Qualifiers.PROJECT) 92 | .build(), 93 | PropertyDefinition.builder(JaCoCoConfiguration.REPORT_MISSING_FORCE_ZERO) 94 | .defaultValue( 95 | Boolean.toString(JaCoCoConfiguration.REPORT_MISSING_FORCE_ZERO_DEFAULT_VALUE)) 96 | .name("Force zero coverage") 97 | .description("Force coverage to 0% if no JaCoCo reports are found during analysis.") 98 | .category(Groovy.NAME) 99 | .subCategory(SUBCATEGORY) 100 | .onQualifiers(Qualifiers.PROJECT) 101 | .type(PropertyType.BOOLEAN) 102 | .build(), 103 | PropertyDefinition.builder(SONAR_GROOVY_BINARIES) 104 | .name("Binary directories") 105 | .description( 106 | "Comma-separated list of optional directories that contain the compiled groovy sources.") 107 | .category(Groovy.NAME) 108 | .subCategory(SUBCATEGORY) 109 | .onQualifiers(Qualifiers.PROJECT) 110 | .multiValues(true) 111 | .build()); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/jacoco/JaCoCoExtensions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import java.util.ArrayList; 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import org.sonar.api.utils.log.Logger; 26 | import org.sonar.api.utils.log.Loggers; 27 | 28 | public class JaCoCoExtensions { 29 | 30 | private static final Logger LOG = Loggers.get(JaCoCoExtensions.class); 31 | 32 | private JaCoCoExtensions() {} 33 | 34 | public static List getExtensions() { 35 | List extensions = new ArrayList<>(); 36 | 37 | extensions.addAll(JaCoCoConfiguration.getPropertyDefinitions()); 38 | extensions.addAll( 39 | Arrays.asList( 40 | JaCoCoConfiguration.class, 41 | // Unit tests 42 | JaCoCoSensor.class)); 43 | 44 | return extensions; 45 | } 46 | 47 | public static Logger logger() { 48 | return LOG; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/jacoco/JaCoCoReportMerger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import java.io.BufferedOutputStream; 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.io.OutputStream; 26 | import java.nio.file.Files; 27 | import java.nio.file.Path; 28 | import org.jacoco.core.data.ExecutionDataStore; 29 | import org.jacoco.core.data.ExecutionDataWriter; 30 | import org.jacoco.core.data.IExecutionDataVisitor; 31 | import org.jacoco.core.data.ISessionInfoVisitor; 32 | import org.jacoco.core.data.SessionInfoStore; 33 | 34 | /** 35 | * Utility class to merge JaCoCo reports. 36 | * 37 | *

This class handles two versions of JaCoCo binary format to merge. 38 | */ 39 | public class JaCoCoReportMerger { 40 | 41 | private JaCoCoReportMerger() {} 42 | 43 | /** 44 | * Merge all reports in reportOverall. 45 | * 46 | * @param reportOverall destination file of merge. 47 | * @param reports files to be merged. 48 | */ 49 | public static void mergeReports(Path reportOverall, File... reports) { 50 | SessionInfoStore infoStore = new SessionInfoStore(); 51 | ExecutionDataStore dataStore = new ExecutionDataStore(); 52 | loadSourceFiles(infoStore, dataStore, reports); 53 | 54 | try (OutputStream fos = Files.newOutputStream(reportOverall); 55 | BufferedOutputStream outputStream = new BufferedOutputStream(fos)) { 56 | Object visitor; 57 | visitor = new ExecutionDataWriter(outputStream); 58 | infoStore.accept((ISessionInfoVisitor) visitor); 59 | dataStore.accept((IExecutionDataVisitor) visitor); 60 | } catch (IOException e) { 61 | throw new IllegalStateException( 62 | String.format("Unable to write overall coverage report %s", reportOverall), e); 63 | } 64 | } 65 | 66 | private static void loadSourceFiles( 67 | ISessionInfoVisitor infoStore, IExecutionDataVisitor dataStore, File... reports) { 68 | for (File report : reports) { 69 | if (report.isFile()) { 70 | new JaCoCoReportReader(report).readJacocoReport(dataStore, infoStore); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/jacoco/JaCoCoReportReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import java.io.BufferedInputStream; 23 | import java.io.DataInputStream; 24 | import java.io.File; 25 | import java.io.FileInputStream; 26 | import java.io.IOException; 27 | import java.io.InputStream; 28 | import java.util.Collection; 29 | import javax.annotation.Nullable; 30 | import org.jacoco.core.analysis.Analyzer; 31 | import org.jacoco.core.analysis.CoverageBuilder; 32 | import org.jacoco.core.data.ExecutionDataReader; 33 | import org.jacoco.core.data.ExecutionDataStore; 34 | import org.jacoco.core.data.ExecutionDataWriter; 35 | import org.jacoco.core.data.IExecutionDataVisitor; 36 | import org.jacoco.core.data.ISessionInfoVisitor; 37 | 38 | public class JaCoCoReportReader { 39 | 40 | // Visible for testing 41 | static final String INCOMPATIBLE_JACOCO_ERROR = 42 | "You are using an incompatible JaCoCo binary format version, please consider upgrading to a supported JaCoCo version (0.8.x)."; 43 | 44 | @Nullable private final File jacocoExecutionData; 45 | 46 | public JaCoCoReportReader(@Nullable File jacocoExecutionData) { 47 | this.jacocoExecutionData = jacocoExecutionData; 48 | verifyCurrentReportFormat(jacocoExecutionData); 49 | } 50 | 51 | /** 52 | * Read JaCoCo report determining the format to be used. 53 | * 54 | * @param executionDataVisitor visitor to store execution data. 55 | * @param sessionInfoStore visitor to store info session. 56 | * @return true if binary format is the latest one. 57 | * @throws IOException in case of error or binary format not supported. 58 | */ 59 | public JaCoCoReportReader readJacocoReport( 60 | IExecutionDataVisitor executionDataVisitor, ISessionInfoVisitor sessionInfoStore) { 61 | if (jacocoExecutionData == null) { 62 | return this; 63 | } 64 | 65 | JaCoCoExtensions.logger().info("Analysing {}", jacocoExecutionData); 66 | try (InputStream inputStream = 67 | new BufferedInputStream(new FileInputStream(jacocoExecutionData))) { 68 | ExecutionDataReader reader = new ExecutionDataReader(inputStream); 69 | reader.setSessionInfoVisitor(sessionInfoStore); 70 | reader.setExecutionDataVisitor(executionDataVisitor); 71 | reader.read(); 72 | } catch (IOException e) { 73 | throw new IllegalArgumentException( 74 | String.format("Unable to read %s", jacocoExecutionData.getAbsolutePath()), e); 75 | } 76 | return this; 77 | } 78 | 79 | private static void verifyCurrentReportFormat(@Nullable File jacocoExecutionData) { 80 | if (jacocoExecutionData == null) { 81 | return; 82 | } 83 | try (DataInputStream dis = new DataInputStream(new FileInputStream(jacocoExecutionData))) { 84 | byte firstByte = dis.readByte(); 85 | if (firstByte != ExecutionDataWriter.BLOCK_HEADER 86 | || dis.readChar() != ExecutionDataWriter.MAGIC_NUMBER) { 87 | throw new IllegalStateException(); 88 | } 89 | if (dis.readChar() != ExecutionDataWriter.FORMAT_VERSION) { 90 | throw new IllegalArgumentException( 91 | INCOMPATIBLE_JACOCO_ERROR); 92 | } 93 | } catch (IOException | IllegalStateException e) { 94 | throw new IllegalArgumentException( 95 | String.format( 96 | "Unable to read %s to determine JaCoCo binary format.", 97 | jacocoExecutionData.getAbsolutePath()), 98 | e); 99 | } 100 | } 101 | 102 | /** Caller must guarantee that {@code classFiles} are actually class file. */ 103 | public CoverageBuilder analyzeFiles( 104 | ExecutionDataStore executionDataStore, Collection classFiles) { 105 | CoverageBuilder coverageBuilder = new CoverageBuilder(); 106 | Analyzer analyzer = new Analyzer(executionDataStore, coverageBuilder); 107 | for (File classFile : classFiles) { 108 | analyzeClassFile(analyzer, classFile); 109 | } 110 | return coverageBuilder; 111 | } 112 | 113 | /** Caller must guarantee that {@code classFile} is actually class file. */ 114 | private static void analyzeClassFile(Analyzer analyzer, File classFile) { 115 | try (InputStream inputStream = new FileInputStream(classFile)) { 116 | analyzer.analyzeClass(inputStream, classFile.getPath()); 117 | } catch (IOException e) { 118 | // (Godin): in fact JaCoCo includes name into exception 119 | JaCoCoExtensions.logger() 120 | .warn("Exception during analysis of file " + classFile.getAbsolutePath(), e); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/jacoco/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.jacoco; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/GroovySurefireSensor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.surefire; 20 | 21 | import java.io.File; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import org.sonar.api.batch.DependedUpon; 25 | import org.sonar.api.batch.fs.FileSystem; 26 | import org.sonar.api.batch.sensor.Sensor; 27 | import org.sonar.api.batch.sensor.SensorContext; 28 | import org.sonar.api.batch.sensor.SensorDescriptor; 29 | import org.sonar.api.config.Configuration; 30 | import org.sonar.api.scan.filesystem.PathResolver; 31 | import org.sonar.api.utils.log.Logger; 32 | import org.sonar.api.utils.log.Loggers; 33 | import org.sonar.plugins.groovy.foundation.Groovy; 34 | import org.sonar.plugins.groovy.surefire.api.SurefireUtils; 35 | 36 | @DependedUpon("surefire-java") 37 | public class GroovySurefireSensor implements Sensor { 38 | 39 | private static final Logger LOGGER = Loggers.get(GroovySurefireSensor.class); 40 | 41 | private final GroovySurefireParser groovySurefireParser; 42 | private final Configuration settings; 43 | private final FileSystem fs; 44 | private final PathResolver pathResolver; 45 | 46 | public GroovySurefireSensor( 47 | GroovySurefireParser groovySurefireParser, 48 | Configuration settings, 49 | FileSystem fs, 50 | PathResolver pathResolver) { 51 | this.groovySurefireParser = groovySurefireParser; 52 | this.settings = settings; 53 | this.fs = fs; 54 | this.pathResolver = pathResolver; 55 | } 56 | 57 | @Override 58 | public void describe(SensorDescriptor descriptor) { 59 | descriptor.onlyOnLanguage(Groovy.KEY).name("GroovySurefireSensor"); 60 | } 61 | 62 | @Override 63 | public void execute(SensorContext context) { 64 | List dirs = SurefireUtils.getReportDirectories(settings, fs, pathResolver); 65 | collect(context, dirs); 66 | } 67 | 68 | protected void collect(SensorContext context, List reportsDirs) { 69 | LOGGER.info("parsing {}", reportsDirs); 70 | groovySurefireParser.collect(context, reportsDirs); 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return getClass().getSimpleName(); 76 | } 77 | 78 | public static List getExtensions() { 79 | return Arrays.asList(GroovySurefireParser.class, GroovySurefireSensor.class); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/api/SurefireUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.surefire.api; 21 | 22 | import edu.umd.cs.findbugs.annotations.CheckForNull; 23 | import java.io.File; 24 | import java.nio.file.InvalidPathException; 25 | import java.util.Arrays; 26 | import java.util.Collections; 27 | import java.util.List; 28 | import java.util.Objects; 29 | import java.util.stream.Collectors; 30 | import org.sonar.api.batch.fs.FileSystem; 31 | import org.sonar.api.config.Configuration; 32 | import org.sonar.api.scan.filesystem.PathResolver; 33 | import org.sonar.api.utils.log.Logger; 34 | import org.sonar.api.utils.log.Loggers; 35 | 36 | public final class SurefireUtils { 37 | 38 | private static final Logger LOGGER = Loggers.get(SurefireUtils.class); 39 | /** @since 1.7 */ 40 | public static final String SUREFIRE_REPORT_PATHS_PROPERTY = "sonar.junit.reportPaths"; 41 | 42 | private SurefireUtils() {} 43 | 44 | /** 45 | * Find the directories containing the surefire reports. 46 | * 47 | * @param settings Analysis settings. 48 | * @param fs FileSystem containing indexed files. 49 | * @param pathResolver Path solver. 50 | * @return The directories containing the surefire reports or default one 51 | * (target/surefire-reports) if not found (not configured or not found). 52 | */ 53 | public static List getReportDirectories( 54 | Configuration settings, FileSystem fs, PathResolver pathResolver) { 55 | List dirs = getReportDirectoriesFromProperty(settings, fs, pathResolver); 56 | if (dirs.size() > 0) { 57 | return dirs; 58 | } 59 | return Collections.singletonList(new File(fs.baseDir(), "target/surefire-reports")); 60 | } 61 | 62 | private static List getReportDirectoriesFromProperty( 63 | Configuration settings, FileSystem fs, PathResolver pathResolver) { 64 | if (settings.hasKey(SUREFIRE_REPORT_PATHS_PROPERTY)) { 65 | return Arrays.stream(settings.getStringArray(SUREFIRE_REPORT_PATHS_PROPERTY)) 66 | .map(String::trim) 67 | .map(path -> resolvePath(pathResolver, fs.baseDir(), path)) 68 | .filter(Objects::nonNull) 69 | .collect(Collectors.toList()); 70 | } 71 | return Collections.emptyList(); 72 | } 73 | 74 | @CheckForNull 75 | private static File resolvePath(PathResolver pathResolver, File baseDir, String path) { 76 | try { 77 | return pathResolver.relativeFile(baseDir, path); 78 | } catch (InvalidPathException e) { 79 | // This probably won't happen in production SQ, catch anyways. 80 | LOGGER.info("Surefire report path: {}/{} not found.", baseDir, path); 81 | } 82 | return null; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/api/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.surefire.api; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/data/UnitTestClassReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.surefire.data; 21 | 22 | import java.util.ArrayList; 23 | import java.util.Collections; 24 | import java.util.List; 25 | 26 | public final class UnitTestClassReport { 27 | private int errors = 0; 28 | private int failures = 0; 29 | private int skipped = 0; 30 | private int tests = 0; 31 | private long durationMilliseconds = 0L; 32 | 33 | private long negativeTimeTestNumber = 0L; 34 | private List results = null; 35 | 36 | public UnitTestClassReport add(UnitTestClassReport other) { 37 | for (UnitTestResult otherResult : other.getResults()) { 38 | add(otherResult); 39 | } 40 | return this; 41 | } 42 | 43 | public UnitTestClassReport add(UnitTestResult result) { 44 | initResults(); 45 | results.add(result); 46 | if (result.getStatus().equals(UnitTestResult.STATUS_SKIPPED)) { 47 | skipped += 1; 48 | 49 | } else if (result.getStatus().equals(UnitTestResult.STATUS_FAILURE)) { 50 | failures += 1; 51 | 52 | } else if (result.getStatus().equals(UnitTestResult.STATUS_ERROR)) { 53 | errors += 1; 54 | } 55 | tests += 1; 56 | if (result.getDurationMilliseconds() < 0) { 57 | negativeTimeTestNumber += 1; 58 | } else { 59 | durationMilliseconds += result.getDurationMilliseconds(); 60 | } 61 | return this; 62 | } 63 | 64 | private void initResults() { 65 | if (results == null) { 66 | results = new ArrayList<>(); 67 | } 68 | } 69 | 70 | public int getErrors() { 71 | return errors; 72 | } 73 | 74 | public int getFailures() { 75 | return failures; 76 | } 77 | 78 | public int getSkipped() { 79 | return skipped; 80 | } 81 | 82 | public int getTests() { 83 | return tests; 84 | } 85 | 86 | public long getDurationMilliseconds() { 87 | return durationMilliseconds; 88 | } 89 | 90 | public long getNegativeTimeTestNumber() { 91 | return negativeTimeTestNumber; 92 | } 93 | 94 | public List getResults() { 95 | if (results == null) { 96 | return Collections.emptyList(); 97 | } 98 | return results; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/data/UnitTestIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.surefire.data; 21 | 22 | import java.util.HashMap; 23 | import java.util.HashSet; 24 | import java.util.Map; 25 | import java.util.Set; 26 | 27 | public class UnitTestIndex { 28 | 29 | private Map indexByClassname; 30 | 31 | public UnitTestIndex() { 32 | this.indexByClassname = new HashMap<>(); 33 | } 34 | 35 | public UnitTestClassReport index(String classname) { 36 | UnitTestClassReport classReport = indexByClassname.get(classname); 37 | if (classReport == null) { 38 | classReport = new UnitTestClassReport(); 39 | indexByClassname.put(classname, classReport); 40 | } 41 | return classReport; 42 | } 43 | 44 | public UnitTestClassReport get(String classname) { 45 | return indexByClassname.get(classname); 46 | } 47 | 48 | public Set getClassnames() { 49 | return new HashSet<>(indexByClassname.keySet()); 50 | } 51 | 52 | public Map getIndexByClassname() { 53 | return indexByClassname; 54 | } 55 | 56 | public int size() { 57 | return indexByClassname.size(); 58 | } 59 | 60 | public UnitTestClassReport merge(String classname, String intoClassname) { 61 | UnitTestClassReport from = indexByClassname.get(classname); 62 | if (from != null) { 63 | UnitTestClassReport to = index(intoClassname); 64 | to.add(from); 65 | indexByClassname.remove(classname); 66 | return to; 67 | } 68 | return null; 69 | } 70 | 71 | public void remove(String classname) { 72 | indexByClassname.remove(classname); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/data/UnitTestResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.surefire.data; 21 | 22 | public final class UnitTestResult { 23 | public static final String STATUS_OK = "ok"; 24 | public static final String STATUS_ERROR = "error"; 25 | public static final String STATUS_FAILURE = "failure"; 26 | public static final String STATUS_SKIPPED = "skipped"; 27 | 28 | private String name; 29 | private String status; 30 | private String stackTrace; 31 | private String message; 32 | private long durationMilliseconds = 0L; 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public UnitTestResult setName(String name) { 39 | this.name = name; 40 | return this; 41 | } 42 | 43 | public String getStatus() { 44 | return status; 45 | } 46 | 47 | public UnitTestResult setStatus(String status) { 48 | this.status = status; 49 | return this; 50 | } 51 | 52 | public String getStackTrace() { 53 | return stackTrace; 54 | } 55 | 56 | public UnitTestResult setStackTrace(String stackTrace) { 57 | this.stackTrace = stackTrace; 58 | return this; 59 | } 60 | 61 | public String getMessage() { 62 | return message; 63 | } 64 | 65 | public UnitTestResult setMessage(String message) { 66 | this.message = message; 67 | return this; 68 | } 69 | 70 | public long getDurationMilliseconds() { 71 | return durationMilliseconds; 72 | } 73 | 74 | public UnitTestResult setDurationMilliseconds(long l) { 75 | this.durationMilliseconds = l; 76 | return this; 77 | } 78 | 79 | public boolean isErrorOrFailure() { 80 | return STATUS_ERROR.equals(status) || STATUS_FAILURE.equals(status); 81 | } 82 | 83 | public boolean isError() { 84 | return STATUS_ERROR.equals(status); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/data/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.surefire.data; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/surefire/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.surefire; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/utils/StaxParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.utils; 21 | 22 | import com.ctc.wstx.stax.WstxInputFactory; 23 | 24 | import org.codehaus.staxmate.SMInputFactory; 25 | import org.codehaus.staxmate.in.SMHierarchicCursor; 26 | 27 | import javax.xml.stream.XMLInputFactory; 28 | import javax.xml.stream.XMLStreamException; 29 | 30 | import java.io.File; 31 | import java.io.FileInputStream; 32 | import java.io.IOException; 33 | 34 | public class StaxParser { 35 | 36 | @FunctionalInterface 37 | public interface XmlStreamHandler { 38 | void stream(SMHierarchicCursor rootCursor) throws XMLStreamException; 39 | } 40 | 41 | private SMInputFactory inf; 42 | private XmlStreamHandler streamHandler; 43 | 44 | public StaxParser(XmlStreamHandler streamHandler) { 45 | this.streamHandler = streamHandler; 46 | XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); 47 | if (xmlFactory instanceof WstxInputFactory) { 48 | WstxInputFactory wstxInputfactory = (WstxInputFactory) xmlFactory; 49 | wstxInputfactory.configureForLowMemUsage(); 50 | wstxInputfactory.getConfig().setUndeclaredEntityResolver((String publicID, String systemID, String baseURI, String namespace) -> namespace); 51 | } 52 | xmlFactory.setProperty(XMLInputFactory.IS_VALIDATING, false); 53 | xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); 54 | xmlFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false); 55 | inf = new SMInputFactory(xmlFactory); 56 | } 57 | 58 | public void parse(File xmlFile) throws XMLStreamException { 59 | try(FileInputStream input = new FileInputStream(xmlFile)) { 60 | parse(inf.rootElementCursor(input)); 61 | } catch (IOException e) { 62 | throw new XMLStreamException(e); 63 | } 64 | } 65 | 66 | private void parse(SMHierarchicCursor rootCursor) throws XMLStreamException { 67 | try { 68 | streamHandler.stream(rootCursor); 69 | } finally { 70 | rootCursor.getStreamReader().closeCompletely(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/java/org/sonar/plugins/groovy/utils/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | @ParametersAreNonnullByDefault 21 | package org.sonar.plugins.groovy.utils; 22 | 23 | import javax.annotation.ParametersAreNonnullByDefault; 24 | 25 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/main/resources/org/sonar/plugins/groovy/profile-default.txt: -------------------------------------------------------------------------------- 1 | org.codenarc.rule.basic.AssignmentInConditionalRule 2 | org.codenarc.rule.exceptions.CatchErrorRule 3 | org.codenarc.rule.exceptions.CatchExceptionRule 4 | org.codenarc.rule.exceptions.CatchNullPointerExceptionRule 5 | org.codenarc.rule.exceptions.CatchRuntimeExceptionRule 6 | org.codenarc.rule.design.CloneableWithoutCloneRule 7 | org.codenarc.rule.braces.ElseBlockBracesRule 8 | org.codenarc.rule.grails.GrailsPublicControllerMethodRule.fixed 9 | org.codenarc.rule.grails.GrailsServletContextReferenceRule 10 | org.codenarc.rule.grails.GrailsStatelessServiceRule 11 | org.codenarc.rule.size.NestedBlockDepthRule 12 | org.codenarc.rule.concurrency.NestedSynchronizationRule 13 | org.codenarc.rule.logging.PrintStackTraceRule 14 | org.codenarc.rule.logging.PrintlnRule 15 | org.codenarc.rule.basic.ReturnFromFinallyBlockRule 16 | org.codenarc.rule.concurrency.SynchronizedMethodRule 17 | org.codenarc.rule.logging.SystemErrPrintRule 18 | org.codenarc.rule.logging.SystemOutPrintRule 19 | org.codenarc.rule.concurrency.SystemRunFinalizersOnExitRule 20 | org.codenarc.rule.concurrency.ThreadYieldRule 21 | org.codenarc.rule.exceptions.ThrowErrorRule 22 | org.codenarc.rule.exceptions.ThrowExceptionRule 23 | org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule 24 | org.codenarc.rule.exceptions.ThrowNullPointerExceptionRule 25 | org.codenarc.rule.exceptions.ThrowRuntimeExceptionRule 26 | org.codenarc.rule.exceptions.ThrowThrowableRule 27 | org.codenarc.rule.imports.UnnecessaryGroovyImportRule 28 | org.codenarc.rule.imports.UnusedImportRule 29 | org.codenarc.rule.unused.UnusedPrivateFieldRule 30 | org.codenarc.rule.unused.UnusedPrivateMethodRule 31 | org.codenarc.rule.unused.UnusedVariableRule.fixed 32 | org.codenarc.rule.concurrency.VolatileLongOrDoubleFieldRule 33 | org.codenarc.rule.basic.DuplicateCaseStatementRule 34 | org.codenarc.rule.basic.EmptyCatchBlockRule 35 | org.codenarc.rule.basic.EmptyElseBlockRule 36 | org.codenarc.rule.basic.EmptyFinallyBlockRule 37 | org.codenarc.rule.basic.EmptyForStatementRule 38 | org.codenarc.rule.basic.EmptyIfStatementRule 39 | org.codenarc.rule.basic.EmptyInstanceInitializerRule 40 | org.codenarc.rule.basic.EmptyMethodRule 41 | org.codenarc.rule.basic.EmptyStaticInitializerRule 42 | org.codenarc.rule.basic.EmptySwitchStatementRule 43 | org.codenarc.rule.basic.EmptySynchronizedStatementRule 44 | org.codenarc.rule.basic.EmptyTryBlockRule 45 | org.codenarc.rule.basic.EmptyWhileStatementRule 46 | org.codenarc.rule.basic.EqualsAndHashCodeRule 47 | org.codenarc.rule.basic.EqualsOverloadedRule 48 | org.codenarc.rule.basic.EmptyClassRule 49 | org.codenarc.rule.imports.DuplicateImportRule 50 | org.codenarc.rule.imports.ImportFromSamePackageRule 51 | org.codenarc.rule.imports.ImportFromSunPackagesRule 52 | org.codenarc.rule.naming.ClassNameSameAsFilenameRule 53 | org.codenarc.rule.unused.UnusedPrivateMethodParameterRule 54 | org.codenarc.rule.unused.UnusedMethodParameterRule 55 | org.codenarc.rule.convention.ConfusingTernaryRule 56 | org.codenarc.rule.convention.InvertedIfElseRule 57 | org.codenarc.rule.convention.VectorIsObsoleteRule 58 | org.codenarc.rule.convention.HashtableIsObsoleteRule 59 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/GroovyPluginTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | import org.junit.Test; 24 | import org.sonar.api.Plugin; 25 | import org.sonar.api.SonarEdition; 26 | import org.sonar.api.SonarQubeSide; 27 | import org.sonar.api.SonarRuntime; 28 | import org.sonar.api.internal.SonarRuntimeImpl; 29 | import org.sonar.api.utils.Version; 30 | 31 | public class GroovyPluginTest { 32 | public static final Version VERSION_7_9 = Version.create(7, 9); 33 | 34 | @Test 35 | public void testExtensions() { 36 | GroovyPlugin plugin = new GroovyPlugin(); 37 | 38 | SonarRuntime runtime = 39 | SonarRuntimeImpl.forSonarQube(VERSION_7_9, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); 40 | Plugin.Context context = new Plugin.Context(runtime); 41 | plugin.define(context); 42 | assertThat(context.getExtensions()).hasSize(19); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/GroovySonarWayProfileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | import java.util.HashSet; 24 | import java.util.List; 25 | import java.util.Set; 26 | import org.junit.Test; 27 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 28 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInActiveRule; 29 | import org.sonar.api.server.rule.RulesDefinition; 30 | import org.sonar.api.utils.ValidationMessages; 31 | import org.sonar.plugins.groovy.codenarc.CodeNarcRulesDefinition; 32 | import org.sonar.plugins.groovy.foundation.Groovy; 33 | 34 | public class GroovySonarWayProfileTest { 35 | 36 | @Test 37 | public void shouldCreateSonarWayProfile() { 38 | ValidationMessages messages = ValidationMessages.create(); 39 | 40 | GroovySonarWayProfile profileDef = new GroovySonarWayProfile(); 41 | BuiltInQualityProfilesDefinition.Context profileContext = 42 | new BuiltInQualityProfilesDefinition.Context(); 43 | profileDef.define(profileContext); 44 | BuiltInQualityProfilesDefinition.BuiltInQualityProfile profile = 45 | profileContext.profile(Groovy.KEY, "Sonar way"); 46 | assertThat(profile.language()).isEqualTo(Groovy.KEY); 47 | List activeRules = profile.rules(); 48 | assertThat(activeRules).as("Expected number of rules in profile").hasSize(58); 49 | assertThat(profile.name()).isEqualTo("Sonar way"); 50 | 51 | // Check that we use severity from the read rule and not default one. 52 | assertThat(activeRules.get(0).overriddenSeverity()).isNull(); 53 | assertThat(messages.hasErrors()).isFalse(); 54 | 55 | // Check that all rules in "Sonar way" actually exist 56 | CodeNarcRulesDefinition definition = new CodeNarcRulesDefinition(); 57 | RulesDefinition.Context rulesContext = new RulesDefinition.Context(); 58 | definition.define(rulesContext); 59 | RulesDefinition.Repository repository = 60 | rulesContext.repository(CodeNarcRulesDefinition.REPOSITORY_KEY); 61 | 62 | Set rules = new HashSet<>(); 63 | for (RulesDefinition.Rule rule : repository.rules()) { 64 | rules.add(rule.key()); 65 | } 66 | for (BuiltInActiveRule activeRule : profile.rules()) { 67 | assertThat(rules.contains(activeRule.ruleKey())) 68 | .as("No such rule: " + activeRule.ruleKey()) 69 | .isTrue(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy; 21 | 22 | import java.io.File; 23 | import java.lang.reflect.Constructor; 24 | import java.net.URL; 25 | import java.nio.file.Path; 26 | import java.util.Collection; 27 | import org.apache.commons.io.FileUtils; 28 | import org.apache.commons.lang.StringUtils; 29 | import org.sonar.api.config.PropertyDefinitions; 30 | import org.sonar.api.config.internal.MapSettings; 31 | import org.sonar.api.utils.System2; 32 | import org.sonar.plugins.groovy.jacoco.JaCoCoConfiguration; 33 | 34 | public final class TestUtils { 35 | 36 | private TestUtils() {} 37 | 38 | /** 39 | * Search for a test resource in the classpath. For example 40 | * getResource("org/sonar/MyClass/foo.txt"); 41 | * 42 | * @param path the starting slash is optional 43 | * @return the resource. Null if resource not found 44 | */ 45 | public static File getResource(String path) { 46 | String resourcePath = path; 47 | if (!resourcePath.startsWith("/")) { 48 | resourcePath = "/" + resourcePath; 49 | } 50 | URL url = TestUtils.class.getResource(resourcePath); 51 | if (url != null) { 52 | return FileUtils.toFile(url); 53 | } 54 | return null; 55 | } 56 | 57 | /** 58 | * Search for a resource in the classpath. For example calling the method getResource(getClass(), 59 | * "myTestName/foo.txt") from the class org.sonar.Foo loads the file 60 | * $basedir/src/test/resources/org/sonar/Foo/myTestName/foo.txt 61 | * 62 | * @return the resource. Null if resource not found 63 | */ 64 | public static Path getResource(Class baseClass, String path) { 65 | String resourcePath = StringUtils.replaceChars(baseClass.getCanonicalName(), '.', '/'); 66 | if (!path.startsWith("/")) { 67 | resourcePath += "/"; 68 | } 69 | resourcePath += path; 70 | return getResource(resourcePath).toPath(); 71 | } 72 | 73 | public static MapSettings jacocoDefaultSettings() { 74 | PropertyDefinitions prop = null; 75 | try { 76 | // Legacy declaration, doesn't compile on modern SonarQube 77 | Constructor c = 78 | PropertyDefinitions.class.getConstructor(Collection.class); 79 | prop = c.newInstance(JaCoCoConfiguration.getPropertyDefinitions()); 80 | } catch (ReflectiveOperationException | IllegalArgumentException e) { 81 | prop = 82 | new PropertyDefinitions(System2.INSTANCE, JaCoCoConfiguration.getPropertyDefinitions()); 83 | } 84 | return new MapSettings(prop); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/codenarc/ActiveRulesBuilderWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import org.sonar.api.batch.rule.ActiveRules; 23 | import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; 24 | import org.sonar.api.batch.rule.internal.NewActiveRule; 25 | import org.sonar.api.rule.RuleKey; 26 | 27 | public class ActiveRulesBuilderWrapper { 28 | 29 | private ActiveRulesBuilder builder = new ActiveRulesBuilder(); 30 | private NewActiveRule.Builder lastRule; 31 | 32 | boolean newType = false; 33 | 34 | public ActiveRulesBuilderWrapper addRule(String key) { 35 | addLastRule(); 36 | RuleKey ruleKey = RuleKey.of(CodeNarcRulesDefinition.REPOSITORY_KEY, key); 37 | lastRule = new NewActiveRule.Builder(); 38 | lastRule.setRuleKey(ruleKey); 39 | setInternalKey(key); 40 | return this; 41 | } 42 | 43 | public ActiveRulesBuilderWrapper setName(String name) { 44 | lastRule.setName(name); 45 | return this; 46 | } 47 | 48 | public ActiveRulesBuilderWrapper setInternalKey(String key) { 49 | lastRule.setInternalKey(key); 50 | return this; 51 | } 52 | 53 | public ActiveRulesBuilderWrapper addParam(String key, String value) { 54 | lastRule.setParam(key, value); 55 | return this; 56 | } 57 | 58 | private void addLastRule() { 59 | if (lastRule != null) { 60 | builder.addRule(lastRule.build()); 61 | lastRule = null; 62 | } 63 | } 64 | 65 | public ActiveRules build() { 66 | addLastRule(); 67 | return builder.build(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/codenarc/CodeNarcRulesDefinitionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.codenarc; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | import java.util.LinkedList; 24 | import java.util.List; 25 | import org.junit.Test; 26 | import org.sonar.api.server.rule.RulesDefinition; 27 | import org.sonar.api.server.rule.RulesDefinition.Rule; 28 | import org.sonar.plugins.groovy.foundation.Groovy; 29 | 30 | public class CodeNarcRulesDefinitionTest { 31 | 32 | @Test 33 | public void test() { 34 | CodeNarcRulesDefinition definition = new CodeNarcRulesDefinition(); 35 | RulesDefinition.Context context = new RulesDefinition.Context(); 36 | definition.define(context); 37 | RulesDefinition.Repository repository = 38 | context.repository(CodeNarcRulesDefinition.REPOSITORY_KEY); 39 | 40 | assertThat(repository.name()).isEqualTo(CodeNarcRulesDefinition.REPOSITORY_NAME); 41 | assertThat(repository.language()).isEqualTo(Groovy.KEY); 42 | 43 | List rules = repository.rules(); 44 | assertThat(rules).hasSize(394); 45 | 46 | List missingDebt = new LinkedList<>(); 47 | for (Rule rule : rules) { 48 | assertThat(rule.key()).isNotNull(); 49 | assertThat(rule.internalKey()).isNotNull(); 50 | assertThat(rule.name()).isNotNull(); 51 | assertThat(rule.htmlDescription()).isNotNull(); 52 | if (rule.debtRemediationFunction() == null) { 53 | missingDebt.add(rule.key()); 54 | } 55 | } 56 | // From SONARGROOV-36, 'org.codenarc.rule.generic.IllegalSubclassRule' does not have debt by 57 | // purpose 58 | assertThat(missingDebt).containsOnly("org.codenarc.rule.generic.IllegalSubclassRule.fixed"); 59 | 60 | Rule rule = repository.rule("org.codenarc.rule.braces.ElseBlockBracesRule"); 61 | assertThat(rule.params()).hasSize(1); 62 | assertThat(rule.params().get(0).defaultValue()).isEqualToIgnoringCase("false"); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/codenarc/CodeNarcXMLParserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.codenarc; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | import static org.mockito.ArgumentMatchers.*; 24 | 25 | import java.util.List; 26 | import org.apache.commons.io.FileUtils; 27 | import org.junit.Test; 28 | import org.mockito.Mockito; 29 | import org.sonar.api.batch.fs.FilePredicate; 30 | import org.sonar.api.batch.fs.FilePredicates; 31 | import org.sonar.api.batch.fs.FileSystem; 32 | import org.sonar.plugins.groovy.codenarc.CodeNarcXMLParser.CodeNarcViolation; 33 | 34 | public class CodeNarcXMLParserTest { 35 | 36 | @Test 37 | public void should_parse_report() throws Exception { 38 | FileSystem fileSystem = Mockito.mock(FileSystem.class); 39 | Mockito.when(fileSystem.predicates()).thenReturn(Mockito.mock(FilePredicates.class)); 40 | Mockito.when(fileSystem.hasFiles(nullable(FilePredicate.class))).thenReturn(true); 41 | List violations = 42 | CodeNarcXMLParser.parse( 43 | FileUtils.toFile(getClass().getResource("parsing/sample.xml")), fileSystem); 44 | 45 | assertThat(violations.size()).isEqualTo(17); 46 | 47 | CodeNarcViolation violation = violations.get(0); 48 | assertThat(violation.getRuleName()).isEqualTo("EmptyElseBlock"); 49 | assertThat(violation.getFilename()) 50 | .isEqualTo("[sourcedir]/org/codenarc/sample/domain/SampleDomain.groovy"); 51 | assertThat(violation.getLine()).isEqualTo(24); 52 | assertThat(violation.getMessage()).isEqualTo(""); 53 | 54 | violation = violations.get(1); 55 | assertThat(violation.getRuleName()).isEqualTo("EmptyIfStatement"); 56 | assertThat(violation.getFilename()) 57 | .isEqualTo("[sourcedir]/org/codenarc/sample/domain/SampleDomain.groovy"); 58 | assertThat(violation.getLine()).isEqualTo(21); 59 | assertThat(violation.getMessage()).isEqualTo(""); 60 | } 61 | 62 | @Test 63 | public void should_not_fail_if_line_number_not_specified() throws Exception { 64 | FileSystem fileSystem = Mockito.mock(FileSystem.class); 65 | Mockito.when(fileSystem.predicates()).thenReturn(Mockito.mock(FilePredicates.class)); 66 | Mockito.when(fileSystem.hasFiles(any(FilePredicate.class))).thenReturn(true); 67 | List violations = 68 | CodeNarcXMLParser.parse( 69 | FileUtils.toFile(getClass().getResource("parsing/line-number-not-specified.xml")), 70 | fileSystem); 71 | 72 | assertThat(violations.size()).isEqualTo(1); 73 | 74 | CodeNarcViolation violation = violations.get(0); 75 | assertThat(violation.getRuleName()).isEqualTo("CyclomaticComplexity"); 76 | assertThat(violation.getFilename()).isEqualTo("org/example/Example.groovy"); 77 | assertThat(violation.getLine()).isNull(); 78 | assertThat(violation.getMessage()) 79 | .isEqualTo("The cyclomatic complexity for class [org.example.Example] is [27.0]"); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/foundation/GroovyFileSystemTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.foundation; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | import java.nio.file.Paths; 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | import org.sonar.api.batch.fs.InputFile.Type; 28 | import org.sonar.api.batch.fs.internal.DefaultFileSystem; 29 | import org.sonar.api.batch.fs.internal.TestInputFileBuilder; 30 | 31 | public class GroovyFileSystemTest { 32 | 33 | private DefaultFileSystem fileSystem; 34 | private GroovyFileSystem groovyFileSystem; 35 | 36 | @Before 37 | public void setUp() { 38 | fileSystem = new DefaultFileSystem(Paths.get(".")); 39 | groovyFileSystem = new GroovyFileSystem(fileSystem); 40 | } 41 | 42 | @Test 43 | public void isEnabled() { 44 | assertThat(groovyFileSystem.hasGroovyFiles()).isFalse(); 45 | 46 | fileSystem.add(TestInputFileBuilder.create("", "fake.file").build()); 47 | assertThat(groovyFileSystem.hasGroovyFiles()).isFalse(); 48 | 49 | fileSystem.add(TestInputFileBuilder.create("", "fake.groovy").setLanguage(Groovy.KEY).build()); 50 | assertThat(groovyFileSystem.hasGroovyFiles()).isTrue(); 51 | } 52 | 53 | @Test 54 | public void inputFileFromRelativePath() { 55 | assertThat(groovyFileSystem.sourceInputFileFromRelativePath(null)).isNull(); 56 | 57 | fileSystem.add(TestInputFileBuilder.create("", "fake1.file").build()); 58 | assertThat(groovyFileSystem.sourceInputFileFromRelativePath("fake1.file")).isNull(); 59 | 60 | fileSystem.add( 61 | TestInputFileBuilder.create("", "fake2.file") 62 | .setType(Type.MAIN) 63 | .setLanguage(Groovy.KEY) 64 | .build()); 65 | assertThat(groovyFileSystem.sourceInputFileFromRelativePath("fake2.file")).isNotNull(); 66 | 67 | fileSystem.add( 68 | TestInputFileBuilder.create("", "org/sample/foo/fake3.file") 69 | .setType(Type.MAIN) 70 | .setLanguage(Groovy.KEY) 71 | .build()); 72 | assertThat(groovyFileSystem.sourceInputFileFromRelativePath("foo/fake3.file")).isNotNull(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/foundation/GroovyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.foundation; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | import org.junit.Test; 24 | import org.sonar.api.config.internal.MapSettings; 25 | 26 | public class GroovyTest { 27 | 28 | @Test 29 | public void test() { 30 | MapSettings settings = new MapSettings(); 31 | Groovy language = new Groovy(settings.asConfig()); 32 | assertThat(language.getKey()).isEqualTo("grvy"); 33 | assertThat(language.getName()).isEqualTo("Groovy"); 34 | assertThat(language.getFileSuffixes()).isEqualTo(new String[] {".groovy"}); 35 | 36 | settings.setProperty(Groovy.FILE_SUFFIXES_KEY, ""); 37 | assertThat(language.getFileSuffixes()).containsOnly(".groovy"); 38 | 39 | settings.setProperty(Groovy.FILE_SUFFIXES_KEY, ".groovy, .grvy"); 40 | assertThat(language.getFileSuffixes()).containsOnly(".groovy", ".grvy"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/jacoco/ExecutionDataVisitorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import org.jacoco.core.data.ExecutionData; 23 | import org.jacoco.core.data.SessionInfo; 24 | import org.junit.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class ExecutionDataVisitorTest { 29 | @Test 30 | public void test() { 31 | ExecutionDataVisitor visitor = new ExecutionDataVisitor(); 32 | 33 | visitor.visitSessionInfo(new SessionInfo("foo", 1L, 1L)); 34 | visitor.visitClassExecution(new ExecutionData(1, "", new boolean[] {true, false, false})); 35 | 36 | visitor.visitSessionInfo(new SessionInfo("bar", 2L, 2L)); 37 | visitor.visitClassExecution(new ExecutionData(1, "", new boolean[] {false, true, false})); 38 | 39 | visitor.visitSessionInfo(new SessionInfo("foo", 3L, 3L)); 40 | visitor.visitClassExecution(new ExecutionData(1, "", new boolean[] {false, false, true})); 41 | 42 | assertThat(visitor.getSessions()).hasSize(2); 43 | assertThat(visitor.getSessions().get("foo").getContents()).hasSize(1); 44 | assertThat(visitor.getSessions().get("foo").get(1).getProbes()).isEqualTo(new boolean[] {true, false, true}); 45 | assertThat(visitor.getSessions().get("bar").getContents()).hasSize(1); 46 | assertThat(visitor.getSessions().get("bar").get(1).getProbes()).isEqualTo(new boolean[] {false, true, false}); 47 | assertThat(visitor.getMerged().get(1).getProbes()).isEqualTo(new boolean[] {true, true, true}); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/jacoco/JaCoCoConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | import java.nio.file.Paths; 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | import org.sonar.api.batch.fs.internal.DefaultFileSystem; 28 | import org.sonar.api.batch.fs.internal.TestInputFileBuilder; 29 | import org.sonar.api.config.internal.MapSettings; 30 | import org.sonar.plugins.groovy.TestUtils; 31 | import org.sonar.plugins.groovy.foundation.Groovy; 32 | 33 | public class JaCoCoConfigurationTest { 34 | 35 | private MapSettings settings = TestUtils.jacocoDefaultSettings(); 36 | private JaCoCoConfiguration jacocoSettings; 37 | private DefaultFileSystem fileSystem; 38 | 39 | @Before 40 | public void setUp() { 41 | fileSystem = new DefaultFileSystem(Paths.get(".")); 42 | jacocoSettings = new JaCoCoConfiguration(settings.asConfig(), fileSystem); 43 | } 44 | 45 | @Test 46 | public void shouldExecuteOnProject() { 47 | // no files 48 | assertThat(jacocoSettings.shouldExecuteOnProject(true)).isFalse(); 49 | assertThat(jacocoSettings.shouldExecuteOnProject(false)).isFalse(); 50 | 51 | fileSystem.add(TestInputFileBuilder.create("", "src/foo/bar.java").setLanguage("java").build()); 52 | assertThat(jacocoSettings.shouldExecuteOnProject(true)).isFalse(); 53 | assertThat(jacocoSettings.shouldExecuteOnProject(false)).isFalse(); 54 | 55 | fileSystem.add( 56 | TestInputFileBuilder.create("", "src/foo/bar.groovy").setLanguage(Groovy.KEY).build()); 57 | assertThat(jacocoSettings.shouldExecuteOnProject(true)).isTrue(); 58 | assertThat(jacocoSettings.shouldExecuteOnProject(false)).isFalse(); 59 | 60 | settings.setProperty(JaCoCoConfiguration.REPORT_MISSING_FORCE_ZERO, true); 61 | assertThat(jacocoSettings.shouldExecuteOnProject(true)).isTrue(); 62 | assertThat(jacocoSettings.shouldExecuteOnProject(false)).isTrue(); 63 | } 64 | 65 | @Test 66 | public void defaults() { 67 | assertThat(jacocoSettings.getReportPath()).isEqualTo("target/jacoco.exec"); 68 | assertThat(jacocoSettings.getItReportPath()).isEqualTo("target/jacoco-it.exec"); 69 | } 70 | 71 | @Test 72 | public void shouldReturnItReportPathWhenModified() { 73 | settings.setProperty(JaCoCoConfiguration.IT_REPORT_PATH_PROPERTY, "target/it-jacoco-test.exec"); 74 | assertThat(jacocoSettings.getItReportPath()).isEqualTo("target/it-jacoco-test.exec"); 75 | } 76 | 77 | @Test 78 | public void shouldReturnReportPathWhenModified() { 79 | settings.setProperty(JaCoCoConfiguration.REPORT_PATH_PROPERTY, "jacoco.exec"); 80 | assertThat(jacocoSettings.getReportPath()).isEqualTo("jacoco.exec"); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/jacoco/JaCoCoExtensionsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.jacoco; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | import org.junit.Test; 24 | 25 | public class JaCoCoExtensionsTest { 26 | 27 | @Test 28 | public void testExtensions() { 29 | assertThat(JaCoCoExtensions.getExtensions().size()).isEqualTo(6); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/jacoco/JaCoCoItSensorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | package org.sonar.plugins.groovy.jacoco; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | import static org.mockito.Mockito.mock; 23 | 24 | import java.io.IOException; 25 | import java.nio.file.Files; 26 | import java.nio.file.Path; 27 | import org.junit.Before; 28 | import org.junit.Rule; 29 | import org.junit.Test; 30 | import org.junit.rules.TemporaryFolder; 31 | import org.sonar.api.batch.fs.InputFile; 32 | import org.sonar.api.batch.fs.InputFile.Type; 33 | import org.sonar.api.batch.fs.internal.DefaultFileSystem; 34 | import org.sonar.api.batch.fs.internal.TestInputFileBuilder; 35 | import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; 36 | import org.sonar.api.config.internal.MapSettings; 37 | import org.sonar.api.notifications.AnalysisWarnings; 38 | import org.sonar.api.scan.filesystem.PathResolver; 39 | import org.sonar.plugins.groovy.TestUtils; 40 | import org.sonar.plugins.groovy.foundation.Groovy; 41 | import org.sonar.plugins.groovy.foundation.GroovyFileSystem; 42 | 43 | public class JaCoCoItSensorTest { 44 | 45 | @Rule public final TemporaryFolder tmpDir = new TemporaryFolder(); 46 | 47 | private MapSettings settings = TestUtils.jacocoDefaultSettings(); 48 | private JaCoCoSensor sensor; 49 | 50 | @Before 51 | public void setUp() throws IOException { 52 | Path outputDir = tmpDir.newFolder().toPath(); 53 | Files.copy( 54 | TestUtils.getResource(getClass(), "../JaCoCoSensor_0_7_5/jacoco-ut.exec"), 55 | outputDir.resolve("jacoco-it.exec")); 56 | Files.copy( 57 | TestUtils.getResource(getClass(), "../Hello.class.toCopy"), 58 | outputDir.resolve("Hello.class")); 59 | Files.copy( 60 | TestUtils.getResource(getClass(), "../Hello$InnerClass.class.toCopy"), 61 | outputDir.resolve("Hello$InnerClass.class")); 62 | 63 | settings.setProperty(JaCoCoConfiguration.SONAR_GROOVY_BINARIES, "."); 64 | settings.setProperty(JaCoCoConfiguration.IT_REPORT_PATH_PROPERTY, "jacoco-it.exec"); 65 | 66 | DefaultFileSystem fileSystem = new DefaultFileSystem(outputDir); 67 | InputFile inputFile = 68 | TestInputFileBuilder.create("", "example/Hello.groovy") 69 | .setLanguage(Groovy.KEY) 70 | .setType(Type.MAIN) 71 | .setLines(50) 72 | .build(); 73 | fileSystem.add(inputFile); 74 | JaCoCoConfiguration configuration = new JaCoCoConfiguration(settings.asConfig(), fileSystem); 75 | 76 | sensor = 77 | new JaCoCoSensor( 78 | configuration, 79 | new GroovyFileSystem(fileSystem), 80 | new PathResolver(), 81 | settings.asConfig(), 82 | mock(AnalysisWarnings.class)); 83 | } 84 | 85 | @Test 86 | public void testDescription() { 87 | DefaultSensorDescriptor defaultSensorDescriptor = new DefaultSensorDescriptor(); 88 | sensor.describe(defaultSensorDescriptor); 89 | assertThat(defaultSensorDescriptor.languages()).containsOnly(Groovy.KEY); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/jacoco/JaCoCoReportMergerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import java.io.File; 23 | import org.junit.Rule; 24 | import org.junit.Test; 25 | import org.junit.rules.ExpectedException; 26 | import org.junit.rules.TemporaryFolder; 27 | import org.sonar.plugins.groovy.TestUtils; 28 | 29 | public class JaCoCoReportMergerTest { 30 | 31 | @Rule public TemporaryFolder testFolder = new TemporaryFolder(); 32 | 33 | @Rule public ExpectedException exception = ExpectedException.none(); 34 | 35 | @Test 36 | public void mergeDifferentFormatShouldFail1() { 37 | exception.expect(IllegalArgumentException.class); 38 | exception.expectMessage(JaCoCoReportReader.INCOMPATIBLE_JACOCO_ERROR); 39 | merge("jacoco-0.7.5.exec", "jacoco-it-0.7.4.exec"); 40 | } 41 | 42 | @Test 43 | public void mergeDifferentFormatShouldFail2() { 44 | exception.expect(IllegalArgumentException.class); 45 | exception.expectMessage(JaCoCoReportReader.INCOMPATIBLE_JACOCO_ERROR); 46 | merge("jacoco-0.7.4.exec", "jacoco-it-0.7.5.exec"); 47 | } 48 | 49 | @Test 50 | public void merge_same_format_should_not_fail() { 51 | merge("jacoco-0.7.5.exec", "jacoco-it-0.7.5.exec"); 52 | } 53 | 54 | private void merge(String file1, String file2) { 55 | File current = 56 | TestUtils.getResource( 57 | "/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/" + file1); 58 | File previous = 59 | TestUtils.getResource( 60 | "/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/" + file2); 61 | JaCoCoReportMerger.mergeReports( 62 | testFolder.getRoot().toPath().resolve("dummy"), current, previous); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/jacoco/JaCoCoReportReaderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.jacoco; 21 | 22 | import java.io.File; 23 | import java.util.Arrays; 24 | import java.util.Collection; 25 | import org.apache.commons.io.FileUtils; 26 | import org.assertj.core.api.Fail; 27 | import org.jacoco.core.data.IExecutionDataVisitor; 28 | import org.jacoco.core.data.ISessionInfoVisitor; 29 | import org.junit.Rule; 30 | import org.junit.Test; 31 | import org.junit.rules.ExpectedException; 32 | import org.junit.rules.TemporaryFolder; 33 | import org.sonar.plugins.groovy.TestUtils; 34 | 35 | import static org.mockito.Mockito.mock; 36 | 37 | public class JaCoCoReportReaderTest { 38 | 39 | @Rule 40 | public ExpectedException expectedException = ExpectedException.none(); 41 | 42 | @Rule 43 | public TemporaryFolder testFolder = new TemporaryFolder(); 44 | 45 | private File dummy = new File("DummyFile.dummy"); 46 | 47 | @Test 48 | public void reading_unexisting_file_should_fail() { 49 | expectedException.expect(IllegalArgumentException.class); 50 | new JaCoCoReportReader(dummy); 51 | } 52 | 53 | @Test 54 | public void reading_file_no_tfound_should_do_nothing() { 55 | new JaCoCoReportReader(null).readJacocoReport(mock(IExecutionDataVisitor.class), mock(ISessionInfoVisitor.class)); 56 | } 57 | 58 | @Test 59 | public void notExistingClassFilesShouldNotBeAnalyzed() { 60 | File report = TestUtils.getResource("/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-0.7.5.exec"); 61 | Collection classFile = Arrays.asList(dummy); 62 | new JaCoCoReportReader(report).analyzeFiles(null, classFile); 63 | } 64 | 65 | @Test 66 | public void analyzing_a_deleted_file_should_fail() throws Exception { 67 | File report = testFolder.newFile("jacoco.exec"); 68 | FileUtils.copyFile(TestUtils.getResource("/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-0.7.5.exec"), report); 69 | JaCoCoReportReader jacocoReportReader = new JaCoCoReportReader(report); 70 | expectedException.expect(IllegalArgumentException.class); 71 | if (!report.delete()) { 72 | Fail.fail("report was not deleted, unable to complete test."); 73 | } 74 | ExecutionDataVisitor edv = new ExecutionDataVisitor(); 75 | jacocoReportReader.readJacocoReport(edv, edv); 76 | } 77 | 78 | @Test 79 | public void incorrect_binary_format_should_fail() throws Exception { 80 | File report = TestUtils.getResource("/org/sonar/plugins/groovy/jacoco/Hello.class.toCopy"); 81 | expectedException.expect(IllegalArgumentException.class); 82 | new JaCoCoReportReader(report); 83 | } 84 | 85 | @Test 86 | public void unknown_exec_file_should_fail() { 87 | expectedException.expect(IllegalArgumentException.class); 88 | new JaCoCoReportReader(new File("unknown.exec")); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/surefire/api/SurefireUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.surefire.api; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | import java.io.File; 25 | import java.util.List; 26 | import org.junit.Test; 27 | import org.sonar.api.batch.fs.FileSystem; 28 | import org.sonar.api.batch.fs.internal.DefaultFileSystem; 29 | import org.sonar.api.config.internal.MapSettings; 30 | import org.sonar.api.scan.filesystem.PathResolver; 31 | import org.sonar.plugins.groovy.TestUtils; 32 | 33 | public class SurefireUtilsTest { 34 | 35 | private FileSystem fs = 36 | new DefaultFileSystem(TestUtils.getResource(getClass(), "shouldGetReportsFromProperty")); 37 | private PathResolver pathResolver = new PathResolver(); 38 | 39 | @Test 40 | public void should_get_reports_from_property() { 41 | MapSettings settings = new MapSettings(); 42 | settings.setProperty(SurefireUtils.SUREFIRE_REPORT_PATHS_PROPERTY, "target/surefire"); 43 | assertThat(SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver).size()) 44 | .isEqualTo(1); 45 | assertThat( 46 | SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver) 47 | .get(0) 48 | .exists()) 49 | .isTrue(); 50 | assertThat( 51 | SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver) 52 | .get(0) 53 | .isDirectory()) 54 | .isTrue(); 55 | } 56 | 57 | @Test 58 | public void should_get_2_reports_from_property() { 59 | MapSettings settings = new MapSettings(); 60 | settings.setProperty( 61 | SurefireUtils.SUREFIRE_REPORT_PATHS_PROPERTY, "target/surefire, target/surefire2"); 62 | assertThat(SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver).size()) 63 | .isEqualTo(2); 64 | assertThat( 65 | SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver) 66 | .get(0) 67 | .exists()) 68 | .isTrue(); 69 | assertThat( 70 | SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver) 71 | .get(0) 72 | .isDirectory()) 73 | .isTrue(); 74 | assertThat( 75 | SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver) 76 | .get(1) 77 | .exists()) 78 | .isTrue(); 79 | assertThat( 80 | SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver) 81 | .get(1) 82 | .isDirectory()) 83 | .isTrue(); 84 | } 85 | 86 | @Test 87 | public void return_default_value_if_property_unset() throws Exception { 88 | List directories = 89 | SurefireUtils.getReportDirectories(new MapSettings().asConfig(), fs, pathResolver); 90 | assertThat(directories.size()).isEqualTo(1); 91 | assertThat(directories.get(0).getCanonicalPath()) 92 | .endsWith("target" + File.separator + "surefire-reports"); 93 | assertThat(directories.get(0).exists()).isFalse(); 94 | assertThat(directories.get(0).isDirectory()).isFalse(); 95 | } 96 | 97 | @Test 98 | public void return_default_value_if_can_not_read_file() throws Exception { 99 | MapSettings settings = new MapSettings(); 100 | settings.setProperty(SurefireUtils.SUREFIRE_REPORT_PATHS_PROPERTY, "../target/\u0000:surefire"); 101 | List directories = 102 | SurefireUtils.getReportDirectories(settings.asConfig(), fs, pathResolver); 103 | assertThat(directories.size()).isEqualTo(1); 104 | assertThat(directories.get(0).getCanonicalPath()) 105 | .endsWith("target" + File.separator + "surefire-reports"); 106 | assertThat(directories.get(0).exists()).isFalse(); 107 | assertThat(directories.get(0).isDirectory()).isFalse(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/surefire/data/UnitTestResultTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.surefire.data; 21 | 22 | import static org.hamcrest.CoreMatchers.is; 23 | import static org.hamcrest.MatcherAssert.assertThat; 24 | 25 | import org.junit.Test; 26 | 27 | public class UnitTestResultTest { 28 | @Test 29 | public void shouldBeError() { 30 | UnitTestResult result = new UnitTestResult().setStatus(UnitTestResult.STATUS_ERROR); 31 | assertThat(result.getStatus(), is(UnitTestResult.STATUS_ERROR)); 32 | assertThat(result.isError(), is(true)); 33 | assertThat(result.isErrorOrFailure(), is(true)); 34 | } 35 | 36 | @Test 37 | public void shouldBeFailure() { 38 | UnitTestResult result = new UnitTestResult().setStatus(UnitTestResult.STATUS_FAILURE); 39 | assertThat(result.getStatus(), is(UnitTestResult.STATUS_FAILURE)); 40 | assertThat(result.isError(), is(false)); 41 | assertThat(result.isErrorOrFailure(), is(true)); 42 | } 43 | 44 | @Test 45 | public void shouldBeSuccess() { 46 | UnitTestResult result = new UnitTestResult().setStatus(UnitTestResult.STATUS_OK); 47 | assertThat(result.getStatus(), is(UnitTestResult.STATUS_OK)); 48 | assertThat(result.isError(), is(false)); 49 | assertThat(result.isErrorOrFailure(), is(false)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/java/org/sonar/plugins/groovy/utils/StaxParserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Sonar Groovy Plugin 3 | * Copyright (C) 2010-2021 SonarQube Community 4 | *   5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.plugins.groovy.utils; 21 | 22 | import org.junit.Rule; 23 | import org.junit.Test; 24 | import org.junit.rules.ExpectedException; 25 | 26 | import javax.xml.stream.XMLStreamException; 27 | 28 | import java.io.File; 29 | 30 | public class StaxParserTest { 31 | 32 | @Rule 33 | public ExpectedException thrown = ExpectedException.none(); 34 | 35 | @Test 36 | public void should_fail_parsing_ig_file_does_not_exist() throws Exception { 37 | thrown.expect(XMLStreamException.class); 38 | StaxParser parser = new StaxParser(rootCursor -> {}); 39 | parser.parse(new File("fake.xml")); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/codenarc/exportProfile/exportEscapedParameters.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/codenarc/exportProfile/exportFixedRules.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/codenarc/exportProfile/exportNullParameters.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/codenarc/exportProfile/exportParameters.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/codenarc/exportProfile/exportProfile.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/codenarc/parsing/Sample.groovy: -------------------------------------------------------------------------------- 1 | 2 | class Sample { 3 | String format(Integer i) { 4 | i.toString() 5 | } 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | // file is pretty long 39 | 40 | } 41 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/codenarc/parsing/line-number-not-specified.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/foundation/Error.groovy: -------------------------------------------------------------------------------- 1 | class Error { 2 | def name# 3 | def missing 4 | } 5 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/foundation/Greet.groovy: -------------------------------------------------------------------------------- 1 | class Greet { 2 | def name 3 | Greet(who) { name = who } 4 | def salute() { println "Hello $name and $name!" } 5 | } 6 | 7 | /** 8 | * Javadoc style 9 | */ 10 | @groovy.beans.Bindable 11 | class Cool { 12 | double x = 1.4 // Comment 13 | } 14 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/gmetrics/Greeting.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Header Comment 3 | * plop 4 | */ 5 | package example; 6 | 7 | class Greeting { 8 | 9 | def void sayHello() { 10 | if (true) { 11 | print "Hello world!" 12 | } else { 13 | } 14 | } 15 | 16 | } 17 | 18 | class OneMoreClass { //comment line 19 | 20 | def void sayHello() { 21 | /* 22 | * Multi-line comment 23 | * 24 | * with empty lines. 25 | */ 26 | if (true) { 27 | // 28 | print "Hello world!" 29 | } else { 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/Hello$InnerClass.class.toCopy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/Hello$InnerClass.class.toCopy -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/Hello.class.toCopy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/Hello.class.toCopy -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCoSensor_0_7_4/jacoco-ut.exec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCoSensor_0_7_4/jacoco-ut.exec -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCoSensor_0_7_4/readme.txt: -------------------------------------------------------------------------------- 1 | Coverage generated using 2 | 3 | mvn clean install 4 | 5 | on project : 6 | 7 | https://github.com/SonarSource/sonar-examples/tree/master/projects/languages/groovy/groovy-sonar-runner-jacoco 8 | 9 | based on commit 10 | 11 | 052dda3ea6c7bfb61e0f7e6cb7b396b7d1d4a92a -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCoSensor_0_7_5/jacoco-ut.exec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCoSensor_0_7_5/jacoco-ut.exec -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCoSensor_0_7_5/readme.txt: -------------------------------------------------------------------------------- 1 | Coverage generated using 2 | 3 | mvn clean install -Djacoco.version=0.7.5.201505241946 4 | 5 | on project : 6 | 7 | https://github.com/SonarSource/sonar-examples/tree/master/projects/languages/groovy/groovy-sonar-runner-jacoco 8 | 9 | based on commit 10 | 11 | 052dda3ea6c7bfb61e0f7e6cb7b396b7d1d4a92a -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-0.7.4.exec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-0.7.4.exec -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-0.7.5.exec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-0.7.5.exec -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-it-0.7.4.exec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-it-0.7.4.exec -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-it-0.7.5.exec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inform-Software/sonar-groovy/12d120ca772662854f5bbdd0f02ce4b046b21124/sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/jacoco/JaCoCo_incompatible_merge/jacoco-it-0.7.5.exec -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireParserTest/innerClasses/TEST-org.apache.commons.collections.TestAllPackages.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 9 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | java.io.InvalidClassException: 27 | org.apache.commons.collections.FastArrayList; 28 | local class incompatible: stream classdesc serialVersionUID = 1566341225434603896, local class serialVersionUID = 29 | 7918928878747177577 30 | at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562) 31 | at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583) 32 | at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496) 33 | at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732) 34 | at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329) 35 | at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) 36 | at org.apache.commons.collections.AbstractTestObject.readExternalFormFromStream(AbstractTestObject.java:326) 37 | at org.apache.commons.collections.AbstractTestObject.readExternalFormFromDisk(AbstractTestObject.java:301) 38 | at org.apache.commons.collections.list.AbstractTestList.testEmptyListCompatibility(AbstractTestList.java:1077) 39 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 40 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 41 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 42 | at java.lang.reflect.Method.invoke(Method.java:597) 43 | at junit.framework.TestCase.runTest(TestCase.java:154) 44 | at junit.framework.TestCase.runBare(TestCase.java:127) 45 | at junit.framework.TestResult$1.protect(TestResult.java:106) 46 | at junit.framework.TestResult.runProtected(TestResult.java:124) 47 | at junit.framework.TestResult.run(TestResult.java:109) 48 | at junit.framework.TestCase.run(TestCase.java:118) 49 | at junit.framework.TestSuite.runTest(TestSuite.java:208) 50 | at junit.framework.TestSuite.run(TestSuite.java:203) 51 | at junit.framework.TestSuite.runTest(TestSuite.java:208) 52 | at junit.framework.TestSuite.run(TestSuite.java:203) 53 | at junit.framework.TestSuite.runTest(TestSuite.java:208) 54 | at junit.framework.TestSuite.run(TestSuite.java:203) 55 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 56 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 57 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 58 | at java.lang.reflect.Method.invoke(Method.java:597) 59 | at org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213) 60 | at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140) 61 | at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127) 62 | at org.apache.maven.surefire.Surefire.run(Surefire.java:177) 63 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 64 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 65 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 66 | at java.lang.reflect.Method.invoke(Method.java:597) 67 | at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345) 68 | at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009) 69 | 70 | 71 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireParserTest/noTests/TEST-noTests.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireParserTest/onlyTestSuiteReport/TESTS-AllTests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireSensorTest/doNotSaveInnerClasses/TEST-org.apache.commons.collections.TestAllPackages.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 9 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | java.io.InvalidClassException: 27 | org.apache.commons.collections.FastArrayList; 28 | local class incompatible: stream classdesc serialVersionUID = 1566341225434603896, local class serialVersionUID = 29 | 7918928878747177577 30 | at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562) 31 | at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583) 32 | at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496) 33 | at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732) 34 | at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329) 35 | at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) 36 | at org.apache.commons.collections.AbstractTestObject.readExternalFormFromStream(AbstractTestObject.java:326) 37 | at org.apache.commons.collections.AbstractTestObject.readExternalFormFromDisk(AbstractTestObject.java:301) 38 | at org.apache.commons.collections.list.AbstractTestList.testEmptyListCompatibility(AbstractTestList.java:1077) 39 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 40 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 41 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 42 | at java.lang.reflect.Method.invoke(Method.java:597) 43 | at junit.framework.TestCase.runTest(TestCase.java:154) 44 | at junit.framework.TestCase.runBare(TestCase.java:127) 45 | at junit.framework.TestResult$1.protect(TestResult.java:106) 46 | at junit.framework.TestResult.runProtected(TestResult.java:124) 47 | at junit.framework.TestResult.run(TestResult.java:109) 48 | at junit.framework.TestCase.run(TestCase.java:118) 49 | at junit.framework.TestSuite.runTest(TestSuite.java:208) 50 | at junit.framework.TestSuite.run(TestSuite.java:203) 51 | at junit.framework.TestSuite.runTest(TestSuite.java:208) 52 | at junit.framework.TestSuite.run(TestSuite.java:203) 53 | at junit.framework.TestSuite.runTest(TestSuite.java:208) 54 | at junit.framework.TestSuite.run(TestSuite.java:203) 55 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 56 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 57 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 58 | at java.lang.reflect.Method.invoke(Method.java:597) 59 | at org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213) 60 | at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140) 61 | at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127) 62 | at org.apache.maven.surefire.Surefire.run(Surefire.java:177) 63 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 64 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 65 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 66 | at java.lang.reflect.Method.invoke(Method.java:597) 67 | at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345) 68 | at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009) 69 | 70 | 71 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireSensorTest/many-results/TEST-ch.hortis.sonar.mvn.mc.MetricsCollectorRegistryTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireSensorTest/roundingTests/TEST-Rounding.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireSensorTest/shouldHandleMultipleSuitesInSameFile/TESTS-MutlipleSuites.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireSensorTest/shouldHandleTestSuiteDetails/ExtensionsFinderTest-expected-result.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37 | 38 | 39 | 40 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireSensorTest/shouldHandleTestSuiteDetails/ExtensionsFinderTest2-expected-result.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/SurefireSensorTest/shouldHandleTestSuiteDetails/ExtensionsFinderTest3-expected-result.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/api/SurefireUtilsTest/shouldGetReportsFromProperty/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | fake.group 5 | fake.artifactId 6 | jar 7 | 1.0-SNAPSHOT 8 | 9 | -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/api/SurefireUtilsTest/shouldGetReportsFromProperty/target/surefire/hack.txt: -------------------------------------------------------------------------------- 1 | hack for maven in order the directory target/surefire to be included in unit tests classpath -------------------------------------------------------------------------------- /sonar-groovy-plugin/src/test/resources/org/sonar/plugins/groovy/surefire/api/SurefireUtilsTest/shouldGetReportsFromProperty/target/surefire2/hack.txt: -------------------------------------------------------------------------------- 1 | hack for maven in order the directory target/surefire to be included in unit tests classpath --------------------------------------------------------------------------------