I’m developing a plugin for SonarQube that will run a custom post analysis task, but only if a named scanner parameter is supplied to the sonar-scanner command. Can I do something like this? I’m unfamiliar with the scope/lifecycle of my plugin objects. Are they unique per scan or per SonarQube server instance?
public class MyPlugin implements Plugin {
@Override
public void define(Context context) {
context.addExtension(MyPostAnalysisTask.class);
}
}
public class MyPostAnalysisTask implements PostProjectAnalysisTask, Sensor {
private String param = "";
@Override
public void describe(SensorDescriptor descriptor) {
descriptor.name(getClass().getName());
}
@Override
public void execute(SensorContext context) {
// Get command line param.
Optional<String> param = context.config().get('my.param.name');
if (param.isPresent()) {
this.param = param.get();
}
}
@Override
public void finished(final ProjectAnalysis analysis) {
if (!this.param.isEmpty()) {
// Perform custom post analysis task.
}
}
}
Hi Andrew,
Sensor is a scanner side extension point. It will run during the analysis on your build agent.
PostProjectAnalysisTask is a server side extension point, that will be instantiated/called at the end of the analysis report processing. You can’t share state like you did using a class attribute, since at runtime two classes will be instantiated on different JVM.
I think it is better to implement the two extension points in separate classes, and use the scanner context to pass values between scanner side and server side:
public class MyPlugin implements Plugin {
@Override
public void define(Context context) {
context.addExtensions(
MySensor.class,
MyPostAnalysisTask.class);
}
}
public class MySensor implements Sensor {
@Override
public void describe(SensorDescriptor descriptor) {
descriptor.name(getClass().getName());
}
@Override
public void execute(SensorContext context) {
// Get command line param.
Optional<String> param = context.config().get("my.param.name");
if (param.isPresent()) {
context.addContextProperty("my.context.key", param.get());
}
}
}
public class MyPostAnalysisTask implements PostProjectAnalysisTask {
@Override
public void finished(final ProjectAnalysis analysis) {
if (analysis.getScannerContext().getProperties().containsKey("my.context.key")) {
// Perform custom post analysis task.
}
}
}
3 Likes
Thank you for the explanation and solution! I also posted this question on StackOverflow. If you post your answer there, I’ll be happy to accept it.
I’m confused about the use of getScannerContext()
in MyPostAnalysisTask.finished()
Where is that method defined or how should I implement it?
Thank you for your help. I have published my plugin here: https://github.com/aensley/sonar-teams-notifier
Hopefully this will help someone else!