I defined a Custom rule using java. deployed it to sonarqube server, and sonarqube picked it up.
but why Can’t I update my custom rule’s detail by API ?
public void updateRule(Rule r) {
org.sonarqube.ws.client.rules.UpdateRequest ur = new org.sonarqube.ws.client.rules.UpdateRequest();
ur.setKey(r.getKey());
ur.setMarkdownDescription(r.getMdDesc());
ur.setMarkdownNote(r.getMdNote());
ur.setName(r.getName());
// TODO params
// ur.setParams(r.getParams());
ur.setRemediationFnBaseEffort(r.getRemFnBaseEffort());
ur.setRemediationFnType(r.getRemFnType());
ur.setRemediationFyGapMultiplier(r.getRemFnGapMultiplier());
ur.setSeverity(r.getSeverity());
ur.setStatus(r.getStatus().name());
List<String> tags = new ArrayList<String>();
for(int i = 0 ;i < r.getTags().getTagsCount(); i++) {
tags.add(r.getTags().getTags(i));
}
if(!tags.isEmpty()) {
ur.setTags(tags);
}
client.rules().update(ur);
}
public static void main(String[] args) {
SonarApi sonarApi = new SonarApi("http://172.25.160.238:9876", "cac3b3c65347e87cdf1f9a7352935db79e2435f5");
Rule r = sonarApi.getRule("custom-rules-java:ExampleRules01");
sonarApi.updateRule(Rule.newBuilder(r).setMdNote("*注意,这仅仅是一个演示自定义规则的示例,并不具有实际意义!111*").build());
}
exceptions:
Exception in thread "main" org.sonarqube.ws.client.HttpException: Error 400 on http://172.25.160.238:9876/api/rules/update : {"errors":[{"msg":"Not a custom rule"}]}
at org.sonarqube.ws.client.BaseResponse.failIfNotSuccessful(BaseResponse.java:36)
at org.sonarqube.ws.client.BaseService.call(BaseService.java:55)
at org.sonarqube.ws.client.BaseService.call(BaseService.java:50)
at org.sonarqube.ws.client.BaseService.call(BaseService.java:45)
at org.sonarqube.ws.client.rules.RulesService.update(RulesService.java:200)
at com.bgzchina.devops.cq.sonar.SonarApi.updateRule(SonarApi.java:456)
at com.bgzchina.devops.cq.sonar.SonarApi.main(SonarApi.java:462)
the error message is confusing, my rule is obviously a custom rule.
my rule deinition and registrar if those matters:
// 规则定义
public class ExampleRulesDefinition implements RulesDefinition {
// 元信息路径,不能修改,在CheckVerifier中是写死的
private static final String RESOURCE_BASE_PATH = "org/sonar/l10n/java/rules/java";
// 规则集-Key
public static final String REPOSITORY_KEY = "custom-rules-java";
// 规则集名称
public static final String REPOSITORY_NAME = "示例自定义规则(仅供演示)";
// 哪些规则应当被当成模板,本示例中无
private static final Set<String> RULE_TEMPLATES_KEY = Collections.emptySet();
private final SonarRuntime runtime;
public ExampleRulesDefinition(SonarRuntime runtime) {
this.runtime = runtime;
}
@Override
public void define(Context context) {
NewRepository repository = context.createRepository(REPOSITORY_KEY, "java").setName(REPOSITORY_NAME);
RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, runtime);
ruleMetadataLoader.addRulesByAnnotatedClass(repository, new ArrayList<>(RulesList.getChecks()));
setTemplates(repository);
repository.done();
}
private static void setTemplates(NewRepository repository) {
RULE_TEMPLATES_KEY.stream().map(repository::rule).filter(Objects::nonNull).forEach(rule -> rule.setTemplate(true));
}
}
public class ExampleRegistrar implements CheckRegistrar {
// 注册规则
@Override
public void register(RegistrarContext registrarContext) {
// Call to registerClassesForRepository to associate the classes with the
// correct repository key
registrarContext.registerClassesForRepository(ExampleRulesDefinition.REPOSITORY_KEY, checkClasses(), testCheckClasses());
}
// 源码检查规则
public static List<Class<? extends JavaCheck>> checkClasses() {
return RulesList.getJavaChecks();
}
// 测试检查规则
public static List<Class<? extends JavaCheck>> testCheckClasses() {
return RulesList.getJavaTestChecks();
}
}
the markdown note is actually can be updated on web UI…