RulesDefinition.Repository checkstyle = context.repository("checkstyle"); assertThat(checkstyle).isNotNull(); assertThat(checkstyle.key()).isEqualTo("checkstyle"); assertThat(checkstyle.name()).isEqualTo("Checkstyle"); assertThat(checkstyle.language()).isEqualTo("java"); assertThat(checkstyle.rules()).hasSize(1); RulesDefinition.Rule rule = checkstyle.rule("ConstantName"); assertThat(rule).isNotNull(); assertThat(rule.key()).isEqualTo("ConstantName");
for (Rule rule : repo.rules()) { if (rule.type() == RuleType.SECURITY_HOTSPOT) { continue; RuleKey ruleKey = RuleKey.of(repo.key(), rule.key()); Builder newAr = new NewActiveRule.Builder() .setRuleKey(ruleKey) .setLanguage(repo.language()) .setName(rule.name()) .setSeverity(rule.severity()) rule.severity(), rule.type().name(), repo.language(), rule.tags(), "", rule.activatedByDefault()); ruleDetailsMap.put(ruleKey.toString(), ruleDetails);
private RuleDefinitionDto createRuleDto(RulesDefinition.Rule ruleDef, DbSession session) { RuleDefinitionDto ruleDto = new RuleDefinitionDto() .setRuleKey(RuleKey.of(ruleDef.repository().key(), ruleDef.key())) .setPluginKey(ruleDef.pluginKey()) .setIsTemplate(ruleDef.template()) .setConfigKey(ruleDef.internalKey()) .setLanguage(ruleDef.repository().language()) .setName(ruleDef.name()) .setSeverity(ruleDef.severity()) .setType(RuleType.valueOf(ruleDef.type().name())) .setScope(toDtoScope(ruleDef.scope())) .setIsExternal(ruleDef.repository().isExternal()) .setCreatedAt(system2.now()) .setUpdatedAt(system2.now());
private void registerRule(RegisterRulesContext context, RulesDefinition.Rule ruleDef, DbSession session) { RuleKey ruleKey = RuleKey.of(ruleDef.repository().key(), ruleDef.key()); RuleDefinitionDto ruleDefinitionDto = context.getDbRuleFor(ruleDef) .orElseGet(() -> { RuleDefinitionDto newRule = createRuleDto(ruleDef, session); context.created(newRule); return newRule; }); // we must detect renaming __before__ we modify the DTO if (!ruleDefinitionDto.getKey().equals(ruleKey)) { context.renamed(ruleDefinitionDto); ruleDefinitionDto.setRuleKey(ruleKey); } if (mergeRule(ruleDef, ruleDefinitionDto)) { context.updated(ruleDefinitionDto); } if (mergeDebtDefinitions(ruleDef, ruleDefinitionDto)) { context.updated(ruleDefinitionDto); } if (mergeTags(ruleDef, ruleDefinitionDto)) { context.updated(ruleDefinitionDto); } if (context.isUpdated(ruleDefinitionDto) || context.isRenamed(ruleDefinitionDto)) { update(session, ruleDefinitionDto); } else if (!context.isCreated(ruleDefinitionDto)) { context.unchanged(ruleDefinitionDto); } mergeParams(ruleDef, ruleDefinitionDto, session); updateDeprecatedKeys(context, ruleDef, ruleDefinitionDto, session); }
private static void verifyRuleKeyConsistency(List<RulesDefinition.ExtendedRepository> repositories, RegisterRulesContext registerRulesContext) { List<RulesDefinition.Rule> definedRules = repositories.stream() .flatMap(r -> r.rules().stream()) .collect(toList()); Set<RuleKey> definedRuleKeys = definedRules.stream() .map(r -> RuleKey.of(r.repository().key(), r.key())) .collect(toSet()); List<RuleKey> definedDeprecatedRuleKeys = definedRules.stream() .flatMap(r -> r.deprecatedRuleKeys().stream()) .collect(toList()); // Find duplicates in declared deprecated rule keys Set<RuleKey> duplicates = findDuplicates(definedDeprecatedRuleKeys); checkState(duplicates.isEmpty(), "The following deprecated rule keys are declared at least twice [%s]", lazyToString(() -> duplicates.stream().map(RuleKey::toString).collect(Collectors.joining(",")))); // Find rule keys that are both deprecated and used Set<RuleKey> intersection = intersection(new HashSet<>(definedRuleKeys), new HashSet<>(definedDeprecatedRuleKeys)).immutableCopy(); checkState(intersection.isEmpty(), "The following rule keys are declared both as deprecated and used key [%s]", lazyToString(() -> intersection.stream().map(RuleKey::toString).collect(Collectors.joining(",")))); // Find incorrect usage of deprecated keys ImmutableMap<RuleKey, SingleDeprecatedRuleKey> dbDeprecatedRuleKeysByOldRuleKey = registerRulesContext.getDbDeprecatedKeysByOldRuleKey(); Set<String> incorrectRuleKeyMessage = definedRules.stream() .flatMap(r -> filterInvalidDeprecatedRuleKeys(dbDeprecatedRuleKeysByOldRuleKey, r)) .filter(Objects::nonNull) .collect(Collectors.toSet()); checkState(incorrectRuleKeyMessage.isEmpty(), "An incorrect state of deprecated rule keys has been detected.\n %s", lazyToString(() -> incorrectRuleKeyMessage.stream().collect(Collectors.joining("\n")))); }
private static Stream<String> filterInvalidDeprecatedRuleKeys(ImmutableMap<RuleKey, SingleDeprecatedRuleKey> dbDeprecatedRuleKeysByOldRuleKey, RulesDefinition.Rule rule) { return rule.deprecatedRuleKeys().stream() .map(rk -> { SingleDeprecatedRuleKey singleDeprecatedRuleKey = dbDeprecatedRuleKeysByOldRuleKey.get(rk); if (singleDeprecatedRuleKey == null) { // new deprecated rule key : OK return null; } RuleKey parentRuleKey = RuleKey.of(rule.repository().key(), rule.key()); if (parentRuleKey.equals(singleDeprecatedRuleKey.getNewRuleKeyAsRuleKey())) { // same parent : OK return null; } if (rule.deprecatedRuleKeys().contains(parentRuleKey)) { // the new rule is deprecating the old parentRuleKey : OK return null; } return format("The deprecated rule key [%s] was previously deprecated by [%s]. [%s] should be a deprecated key of [%s],", rk.toString(), singleDeprecatedRuleKey.getNewRuleKeyAsRuleKey().toString(), singleDeprecatedRuleKey.getNewRuleKeyAsRuleKey().toString(), RuleKey.of(rule.repository().key(), rule.key()).toString()); }); }
@Test public void test_external_repositories() { GoRulesDefinition rulesDefinition = new GoRulesDefinition(true); RulesDefinition.Context context = new RulesDefinition.Context(); rulesDefinition.define(context); RulesDefinition.Repository golintRepository = context.repository("external_golint"); RulesDefinition.Repository govetRepository = context.repository("external_govet"); assertThat(context.repositories()).hasSize(3); assertThat(golintRepository.name()).isEqualTo("Golint"); assertThat(govetRepository.name()).isEqualTo("go vet"); assertThat(golintRepository.language()).isEqualTo("go"); assertThat(govetRepository.language()).isEqualTo("go"); assertThat(golintRepository.isExternal()).isEqualTo(true); assertThat(govetRepository.isExternal()).isEqualTo(true); assertThat(golintRepository.rules().size()).isEqualTo(18); assertThat(ExternalKeyUtils.GO_LINT_KEYS.size()).isEqualTo(18); assertThat(govetRepository.rules().size()).isEqualTo(21); assertThat(ExternalKeyUtils.GO_VET_KEYS.size()).isEqualTo(21); List<String> govetKeysWithoutDefinition = ExternalKeyUtils.GO_VET_KEYS.stream() .map(x -> x.key) .filter(key -> govetRepository.rule(key) == null) .collect(Collectors.toList()); assertThat(govetKeysWithoutDefinition).isEmpty(); List<String> golintKeysWithoutDefinition = ExternalKeyUtils.GO_LINT_KEYS.stream() .map(x -> x.key) .filter(key -> golintRepository.rule(key) == null) .collect(Collectors.toList()); assertThat(golintKeysWithoutDefinition).isEmpty(); }
private RepositoryImpl(NewRepositoryImpl newRepository, @Nullable Repository mergeInto) { this.key = newRepository.key; this.language = newRepository.language; this.isExternal = newRepository.isExternal; Map<String, Rule> ruleBuilder = new HashMap<>(); if (mergeInto != null) { if (!StringUtils.equals(newRepository.language, mergeInto.language()) || !StringUtils.equals(newRepository.key, mergeInto.key())) { throw new IllegalArgumentException(format("Bug - language and key of the repositories to be merged should be the sames: %s and %s", newRepository, mergeInto)); } this.name = StringUtils.defaultIfBlank(mergeInto.name(), newRepository.name); for (Rule rule : mergeInto.rules()) { if (!newRepository.key().startsWith("common-") && ruleBuilder.containsKey(rule.key())) { Loggers.get(getClass()).warn("The rule '{}' of repository '{}' is declared several times", rule.key(), mergeInto.key()); } ruleBuilder.put(rule.key(), rule); } } else { this.name = newRepository.name; } for (NewRule newRule : newRepository.newRules.values()) { newRule.validate(); ruleBuilder.put(newRule.key, new Rule(this, newRule)); } this.rulesByKey = unmodifiableMap(ruleBuilder); }
private static Rules createRules(StandaloneRuleDefinitionsLoader pluginRulesLoader) { RulesBuilder builder = new RulesBuilder(); for (RulesDefinition.Repository repoDef : pluginRulesLoader.getContext().repositories()) { for (RulesDefinition.Rule ruleDef : repoDef.rules()) { if (ruleDef.type() == RuleType.SECURITY_HOTSPOT) { continue; } NewRule newRule = builder.add(RuleKey.of(ruleDef.repository().key(), ruleDef.key())) .setInternalKey(ruleDef.internalKey()) .setDescription(ruleDef.htmlDescription() != null ? ruleDef.htmlDescription() : Markdown.convertToHtml(ruleDef.markdownDescription())) .setSeverity(ruleDef.severity()) .setType(ruleDef.type() != null ? ruleDef.type().toString() : null) .setName(ruleDef.name()); for (Param p : ruleDef.params()) { newRule.addParam(p.key()) .setDescription(p.description()); } } } return builder.build(); } }
@Test public void test() { MyCustomPhpRulesDefinition rulesDefinition = new MyCustomPhpRulesDefinition(); RulesDefinition.Context context = new RulesDefinition.Context(); rulesDefinition.define(context); RulesDefinition.Repository repository = context.repository(REPOSITORY_KEY); assertThat(repository.name()).isEqualTo(REPOSITORY_NAME); assertThat(repository.language()).isEqualTo(PHPCustomRulesDefinition.LANGUAGE_KEY); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule customRule = repository.rule(RULE_KEY); assertThat(customRule).isNotNull(); assertThat(customRule.name()).isEqualTo(RULE_NAME); assertThat(customRule.htmlDescription()).isEqualTo("desc"); assertThat(customRule.tags()).contains("mybug"); assertThat(customRule.params()).hasSize(1); RulesDefinition.Param param = customRule.param("customParam"); assertThat(param.key()).isEqualTo("customParam"); assertThat(param.description()).isEqualTo("Custom parameter"); assertThat(param.defaultValue()).isEqualTo("value"); }
private Collection<Rule> byRepository(RuleQuery query) { Repository repository = context.repository(query.getRepositoryKey()); return repository != null ? repository.rules().stream().map(ruleTransformer).collect(Collectors.toList()) : Collections.<Rule>emptyList(); }
@Test public void test() { PerlCriticRulesDefinition def = new PerlCriticRulesDefinition(); RulesDefinition.Context context = new RulesDefinition.Context(); def.define(context); RulesDefinition.Repository repository = context.repository(PerlCriticRulesDefinition.getRepositoryKey()); assertThat(repository.name()).isEqualTo(PerlCriticRulesDefinition.getRepositoryName()); assertThat(repository.language()).isEqualTo(PerlLanguage.KEY); List<Rule> rules = repository.rules(); assertThat(rules).hasSize(272); for (Rule rule : rules) { assertThat(rule.debtRemediationFunction()).describedAs(rule.key()).isNotNull(); assertThat(rule.debtRemediationFunction().type()).describedAs(rule.key()).isEqualTo(LINEAR); } }
private static boolean noTemplateRuleWithOrganizationsEnabled(RegisterRulesContext registerRulesContext, boolean orgsEnabled, RulesDefinition.Rule ruleDef) { if (!ruleDef.template() || !orgsEnabled) { return false; } Optional<RuleDefinitionDto> dbRule = registerRulesContext.getDbRuleFor(ruleDef); if (dbRule.isPresent() && dbRule.get().getStatus() == RuleStatus.REMOVED) { RuleDefinitionDto dto = dbRule.get(); LOG.debug("Template rule {} kept removed, because organizations are enabled.", dto.getKey()); registerRulesContext.removed(dto); } else { LOG.info("Template rule {} will not be imported, because organizations are enabled.", RuleKey.of(ruleDef.repository().key(), ruleDef.key())); } return true; }
@Test void test() { GoRulesDefinition rulesDefinition = new GoRulesDefinition(false); RulesDefinition.Context context = new RulesDefinition.Context(); rulesDefinition.define(context); assertThat(context.repositories()).hasSize(1); RulesDefinition.Repository goRepository = context.repository("go"); assertThat(goRepository.name()).isEqualTo("SonarAnalyzer"); assertThat(goRepository.language()).isEqualTo("go"); assertThat(goRepository.rules()).hasSize(GoChecks.getChecks().size()); assertRuleProperties(goRepository); assertAllRuleParametersHaveDescription(goRepository); }
private Optional<RuleDefinitionDto> getDbRuleFor(RulesDefinition.Rule ruleDef) { RuleKey ruleKey = RuleKey.of(ruleDef.repository().key(), ruleDef.key()); Optional<RuleDefinitionDto> res = Stream.concat(Stream.of(ruleKey), ruleDef.deprecatedRuleKeys().stream()) .map(dbRules::get) .filter(Objects::nonNull) .findFirst(); // may occur in case of plugin downgrade if (!res.isPresent()) { return Optional.ofNullable(dbRulesByDbDeprecatedKey.get(ruleKey)); } return res; }
private static Rule toRuleNotNull(RulesDefinition.Rule ruleDef) { Rule rule = Rule.create(ruleDef.repository().key(), ruleDef.key()) .setName(ruleDef.name()) .setSeverity(RulePriority.valueOf(ruleDef.severity())) .setLanguage(ruleDef.repository().language()) .setIsTemplate(ruleDef.template()) .setConfigKey(ruleDef.internalKey()); for (Param param : ruleDef.params()) { rule.createParameter(param.key()).setDefaultValue(param.defaultValue()).setDescription(param.description()); } return rule; }
private void registerRepository(NewRepositoryImpl newRepository) { Repository existing = repositoriesByKey.get(newRepository.key()); if (existing != null) { String existingLanguage = existing.language(); checkState(existingLanguage.equals(newRepository.language), "The rule repository '%s' must not be defined for two different languages: %s and %s", newRepository.key, existingLanguage, newRepository.language); } repositoriesByKey.put(newRepository.key, new RepositoryImpl(newRepository, existing)); }
public static Set<SingleDeprecatedRuleKey> from(RulesDefinition.Rule rule) { return rule.deprecatedRuleKeys().stream() .map(r -> new SingleDeprecatedRuleKey() .setNewRepositoryKey(rule.repository().key()) .setNewRuleKey(rule.key()) .setOldRepositoryKey(r.repository()) .setOldRuleKey(r.rule())) .collect(MoreCollectors.toSet(rule.deprecatedRuleKeys().size())); }
@Override public Rule findByKey(RuleKey key) { Repository repository = context.repository(key.repository()); return repository != null ? toRule(repository.rule(key.rule())) : null; }