RULEAPI-770 Fix bug due to multiple sonarpedia.json files (#3983)

When there are multiple sonarpedia.json files for the same language, the rules
picked up for the next sonarpedia.json file will override the ones picked up
previously. With this fix, the rules are not overwritten but all are collected,
so one repository can have multiple sonarpedia.json files for the same language.
This commit is contained in:
Johann Beleites 2024-06-11 12:15:51 +02:00 committed by GitHub
parent 665476af86
commit e2c4c4b8fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 20 additions and 4 deletions

View File

@ -1,6 +1,7 @@
import os
import sys
import json
import collections
from git import Repo
from git import Git
from pathlib import Path
@ -133,7 +134,7 @@ class Coverage:
self.rule_implemented(rule_id, language, analyzer, version)
def all_implemented_rules():
implemented_rules = {}
implemented_rules = collections.defaultdict(list)
for sp_file in Path('.').rglob('sonarpedia.json'):
print(sp_file)
sonarpedia_path=sp_file.parents[0]
@ -141,7 +142,10 @@ def all_implemented_rules():
sonarpedia = load_json(sp_file)
path = str(sonarpedia_path) + '/' + sonarpedia['rules-metadata-path'].replace('\\', '/')
languages = sonarpedia['languages']
implemented_rules.update(get_implemented_rules(path, languages))
implemented_rules_in_path = get_implemented_rules(path, languages)
for lang, rules in implemented_rules_in_path.items():
implemented_rules[lang] += rules
except Exception as e:
print(f"failed to collect implemented rules for {sp_file}: {e}")
continue

View File

@ -65,6 +65,17 @@ MOCK_REPOS=[{'name':'SonarJS',
['sonarpedia.json', '{"rules-metadata-path": "rules", "languages":["XML"]}'],
['rules/S103.json', '{}']]}
]},
{'name':'sonar-java',
'versions': [
{'name': '1.2.0.123',
'date': '2020-01-02 10:00:00',
'files': [['module1/rules/Sonar_way_profile.json', '{}'],
['module1/sonarpedia.json', '{"rules-metadata-path": "rules", "languages":["JAVA"]}'],
['module1/rules/S100.json', '{}'],
['module2/rules/Sonar_way_profile.json', '{}'],
['module2/sonarpedia.json', '{"rules-metadata-path": "rules", "languages":["JAVA"]}'],
['module2/rules/S101.json', '{}']]}
]},
{'name':'broken',
'versions': [
{'name': 'v1',
@ -159,19 +170,20 @@ def test_update_coverage_for_repo(tmpdir, rules_dir: Path, mock_git_analyzer_rep
assert cov['JAVASCRIPT']['S1145'] == {'since': REPO + ' 3.3.0.5702', 'until': REPO + ' 6.7.0.14237'}
@patch('rspec_tools.coverage.REPOS', ['SonarJS', 'sonar-xml'])
@patch('rspec_tools.coverage.REPOS', ['SonarJS', 'sonar-xml', 'sonar-java'])
def test_update_coverage_for_all_repos(tmpdir, rules_dir: Path, mock_git_analyzer_repos):
with pushd(tmpdir), patch('rspec_tools.coverage.Repo', mock_git_analyzer_repos):
update_coverage_for_all_repos(rules_dir)
coverage = tmpdir.join('covered_rules.json')
assert coverage.exists()
cov = load_json(coverage)
assert {'JAVASCRIPT', 'TYPESCRIPT', 'XML', 'CSS'} == set(cov.keys())
assert {'JAVASCRIPT', 'TYPESCRIPT', 'XML', 'CSS', 'JAVA'} == set(cov.keys())
assert 'S100' in cov['JAVASCRIPT']
assert 'MethodName' not in cov['JAVASCRIPT'] # MethodName is a legacy key for S100
assert {'S100'} == set(cov['CSS'].keys())
assert {'S103', 'S1000'} == set(cov['XML'].keys())
assert cov['XML']['S1000'] == 'SonarJS 7.0.0.14528'
assert {'S100', 'S101'} == set(cov['JAVA'].keys())
def test_update_coverage_no_sonarpedia(tmpdir, rules_dir: Path, mock_git_analyzer_repos, capsys):
with pushd(tmpdir), patch('rspec_tools.coverage.Repo', mock_git_analyzer_repos):