Embarcadero's official version of the Sonar Delphi plugin for analyzing Delphi source code with SonarQube. Working to collect updates and contributions from other versions into this one and move if forward with new features. Thanks to Joachim Marder of JAM Software, and Laurens van Run of Mendrix for working with us on this, and everyone else who's contributed to the Sonar-Delphi projects on GitHub.
We are accepting pull requests and looking for more contributors.
Is a SonarQube plugin that provides
- 49 Rules for Delphi
- TestCoverage using DelphiCodeCoverage or SmartBear's AQtime (license required)
- Optional
.html
output for TestCoverage - Unit test results using DUnitX
This is Plugin-Version 1.0. SonarQube 7.9(LTS) or higher is needed (tested with SonarQube 7.9.3 and 8.2.0)
SonarQube Delphi Plugin uses GitHub's integrated issue tracking system to record bugs and feature requests. If you want to raise an issue, please follow the recommendations below:
- Before you log a bug, please search the issue tracker to see if someone has already reported the problem.
- If the issue doesn't already exist, create a new issue
- Please provide as much information as possible with the issue report, we like to know the version of SonarQube Delphi Plugin that you are using, as well as the SonarQube version.
- If possible try to create a test-case or project that replicates the issue.
- Counting lines of code, statements, number of files
- Counting number of classes, number of packages, methods, accessors
- Counting number of public API (methods, classes and fields)
- Counting comments ratio, comment lines (including blank lines)
- CPD (code duplication, how many lines, block and in how many files)
- Code Complexity (per method, class, file; complexity distribution over methods, classes and files)
- LCOM4 and RFC
- Code colorization
- Assembler syntax in grammar
- Include statement
- Parsing preprocessor statements
- Rules
- Tagable Issues
- "Dead" code recognition
- Unused files recognition
- Unused functions
- Unused procedures
(Optional with AQtime and DelphiCodeCoverage)
- Coverage using AQtime
- Sufficient Coverage on new Code (Optional with DUnit)
- Test results
- Install SonarQube Server (Local Zip is easiest for more details). Check supported versions of the latest release of the plugin.
- Install the SonarQube Scanner runner and be sure you can call it from the directory where you have your source code
- Install Delphi Plugin (see Installing a Plugin for more details).
- Check the sample project corresponding to your Runner to know which config file you need to create. You can find the samples in sonar-delphi/samples.
- Run your Analyzer command from the project root dir
- Follow the link provided at the end of the analysis to browse your project's quality in SonarQube UI (see: Browsing SonarQube)
- Grammar is NOT case insensitive, but Delphi code is. Plugin deals with it by DelphiSourceSanitizer class, which feeds ANTLR parser lowercase characters (the "LA" method)
- Number of classes includes: classes, records
- Directory is count as a package. Number of packages equals number of directories.
- Preprocessor definitions between {$if xxx} and {$ifend} are removed, the {$else} part is kept. (DefineResolver class).
- Sources imported to SonarQube are parsed through IncludeResolver class. It means, that the source will be lowercased and unknown preprocessor definitions will be cut out.
CodeCoverage can be done through the DelphiCodeCoverage tool. Use
CodeCoverage.exe -xml -xmllines
to create a XML output that can be importeded through this plugin. Therefore you have to edit your sonar project properties:
sonar.delphi.codecoverage.tool=dcc
sonar.delphi.codecoverage.report=Test/CoverageResults/CodeCoverage_Summary.xml
To import the testresults from DUnit, you have to use the [DUnit extension] (https://github.com/mendrix/dunit-extension) and use the supplied runner (it is not necessary to change your test classes to TTestCaseExtension).
ExitCode := TTestRunnerUtils.RunRegisteredTests;
This will run your tests with GUI if no parameters are given. With the parameter -xml
the tool will create a XML output that is compatible with JUnit for SonarQube. With -output
your can specify the output directory
MyTester.exe -xml -output <outputdirectory>
To import these test results, add the following line to your sonar project properties:
sonar.junit.reportsPath=TestResults
You also have to specify where the plugin can find your testfiles. It is important that the sourcefiles from your tests are EXCLUDED in your sources directory.
sonar.exclusions=MyTestFiles/*
sonar.tests=MyTestFiles
It is also possible to import results from DUnitX. Therefore you have to add the file
DUnitX.Loggers.XML.SonarQube.pas
to your DUnitX project. Then change the .dpr of your application and add functionality for a sources directory (this is used to find the correct .pas file corresponding to the Delphi unit of the unittest):
TOptionsRegistry.RegisterOption<String>('sources', 's', 'Specify a file with on each line a directory where the PAS-files of the unittests can be found.', procedure (AString: String) begin
LSourcesDir := AString;
end);
sqLogger := TDUnitXXMLSonarQubeFileLogger.Create(LSourcesDir, TDUnitX.Options.XMLOutputFile);
runner.AddLogger(sqLogger);
To import the resulting XML file, add the following line to your sonar project properties:
sonar.testExecutionReportPaths=Test/TEST-dunitx-sqresults.xml
To have both codecoverage and unittests results for SonarQube, you have to combine above options. For example:
CodeCoverage.exe -e MyTester.exe -m MyTester.map -a ^^-xml^^ ^^-output TestResults^^ -ife -spf sourcedirs.txt -uf unitstotest.txt -od CoverageResults\ -html -xml -xmllines
To build a plugin, you need Java 8 and Maven 3.1 (or greater).
mvn compile
mvn test
mvn package
Now you can copy the plugin from the /target/
directory to the SonarQube plugin directory.
First run the eclipse maven goal:
mvn eclipse:eclipse
The project can then be imported into Eclipse using File -> Import and then selecting General -> Existing Projects into Workspace.
Simply open the pom.xml in Intellij should solve most dependecies by itself.
SonarQube has great documentation about developing a plugin. To debug this plugin with the SonarQube scanner you to just set the following environment variable (on Windows):
SET SONAR_SCANNER_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"
Now you attach your Eclipse (or other) debugger to port 8000 to start debugging.
The plugin uses an ANTLR3 grammar to parse the Delphi language. The grammar definition can be found in /src/main/antlr3/org/sonar/plugins/delphi/antlr/delphi.g
. An easy way to check and modify this grammar is using ANTLRWorks. Here you can test your grammar on new files and implement new language definitions.
After successfully changing and testing the Delphi.g grammar you have to generate the new parser code (menu Generate, option Generate Code). Now copy the files DelphiLexer.java and DelphiParser.java from /src/main/antlr3/org/sonar/plugins/delphi/antlr/output/
to /src/main/java/org/sonar/plugins/delphi/antlr/
and (re)build the plugin.
Note: it is important to make sure your new grammar changes are also tested. If you only have to make sure that they can be parsed without errors, you can add your new language features to one of the existing grammar files in /src/main/java/org/sonar/plugins/delphi/antlr (the newest is GrammarTest2020.pas).