Custom Plugin - Unable to Access Sonar Parameters and Share Measures in MeasureComputer

What are you trying to accomplish?
I am developing a custom SonarQube plugin and trying to:

  • Access SonarQube configuration parameters within MeasureComputer.
  • Share computed measures from MeasureComputer with other parts of the plugin, such as Sensor or other MeasureComputer instances.

What’s your specific coding challenge in developing your plugin?

  1. Unable to Access Sonar Parameters in MeasureComputer
  • When trying to access configuration parameters from sonar.properties or sonar-project.properties within MeasureComputer, the values always return null.
  • These parameters are accessible within Sensor, but not within MeasureComputer. The returned value is null.
  1. Unable to Pass Data Between Sensor and MeasureComputer
  • It appears that it is not possible to directly pass data from Sensor to MeasureComputer or vice versa. I have tried doing this using metrics, but it is not working.
  • Measures added in Sensor cannot be retrieved in MeasureComputer, and vice versa.

Any guidance on resolving these issues would be greatly appreciated. Thank you!

Hi,

Welcome to the community!

Could you share, in broader strokes, what you’re trying to accomplish? Why do you feel you need to access analysis parameters from a MeasureComputer?

 
Ann

I’m developing a custom SonarQube plugin that should display total coverage data for a specified set of folders. My idea is to pass the following JSON to the Sonar plugin via a property:

{
  "ListOfFolders1": [
    "/somePath1/destinationFolder1/",
    "/somePath1/destinationFolder1/",
    ...
  ],
  ...

Then, I would calculate the total coverage of these folders and save the result to custom metrics, after which the data can be displayed on the plugin’s UI page. As I understand it, I can only get directory metrics from the MeasureComputer:

    @Override
    public void compute(MeasureComputerContext context) {
        try {
            if (context.getComponent().getType() == Component.Type.DIRECTORY) {

                var coverage = context.getMeasure(CoreMetrics.COVERAGE.getKey());
                var linesOfCode = context.getMeasure(CoreMetrics.LINES.getKey());

                if (coverage != null && linesOfCode != null) {
                    LOGGER.info(
                            "folder:{} Coverage:{}, Number of lines:{}",
                            context.getComponent().getKey(),
                            context.getMeasure(CoreMetrics.COVERAGE.getKey()).getDoubleValue(),
                            context.getMeasure(CoreMetrics.LINES.getKey()).getIntValue()
                    );
                }
            }
            ...

The issue is that in MeasureComputer, my Sonar property is always null (while in Sensor, it is correctly populated), and I can’t compare the calculated data with the list of required folders. Additionally, I can’t save the measure metrics values to a custom metric, as in the Sensor it’s always null.

Hi,

I believe the underlying assumption is that a MeasureComputer will only need the granular measures collected during CI-side analysis, since its purpose is to aggregate that data into higher-level values.

To make this work, I suspect you’ll need to start CI-side, where your property should be available.

Tangentially, “total coverage” should probably include condition coverage, which I don’t see reflected in your code snippet.

One last point is that your life will probably be easier if you just pass a comma-delimited listof directories, rather than a JSON structure.

 
HTH,
Ann

Thank you for the answer, Ann!

If I understand your answer correctly, the CI side is already configured properly, and the parameter value is accessible in the ProjectSensor subclass in the plugin but not in the MeasureComputer.

Let me explain more simply:

Let’s say I have the following Sonar property configured on the CI side:

sonar.pathForTheFolderWhichShouldBeDisplayedWithCoverageInPluginUIPage=/someFolderPath  

I can retrieve all project directory measures in the MeasureComputer, but I can’t identify the exact folder I need because the property value is always null:

public class MyMeasureComputer implements MeasureComputer {  

    private final Configuration configuration;  
    private static final String MY_FOLDER_PATH = "sonar.pathForTheFolderWhichShouldBeDisplayedWithCoverageInPluginUIPage";  

    public MyMeasureComputer(Configuration configuration) { 
        this.configuration = configuration;  
    }  

    @Override  
    public void compute(MeasureComputerContext context) {  
        String path = configuration.get(MY_FOLDER_PATH).orElse(null); // Always `null`  
    }  
}  

My question is: are there any suggestions on where in the plugin I can retrieve both values: my provided property and the folders measures?

Hi,

What I’m suggesting is that you begin on the CI side by collecting folder-level mySpecialCoverageMetric values. Then its easy to aggregate them server-side.

 
HTH,
Ann