rspec/rule_coverage/coverage.py

116 lines
3.5 KiB
Python

import os
import sys
import argparse
import json
from git import Repo
from git import Git
from pathlib import Path
repos=['sonar-abap','sonar-cpp','sonar-cobol','sonar-dotnet','sonar-css','sonar-flex','slang-enterprise','sonar-java','SonarJS','sonar-php','sonar-pli','sonar-plsql','sonar-python','sonar-rpg','sonar-swift','sonar-tsql','sonar-vb','sonar-html','sonar-xml','sonar-kotlin', 'sonar-secrets']
#repos=['sonar-php','sonar-pli','sonar-plsql','sonar-python','sonar-rpg','sonar-swift','sonar-tsql','sonar-vb','sonar-html','sonar-xml']
def load_json(file):
with open(file) as json_file:
return json.load(json_file)
def get_rules_json(path,languages,version):
print(f"Getting rules from {os.getcwd()} {path}")
for filename in os.listdir(path):
if filename.endswith(".json") and not filename.startswith("Sonar_way"):
rule=load_json(os.path.join(path, filename))
dump_rule(filename[:-5],rule,languages,version)
else:
continue
def dump_rule(name,rule,languages,version):
if "compatibleLanguages" in rule:
for language in rule['compatibleLanguages']:
store_rule(name,rule,language,version)
else:
for language in languages:
store_rule(name,rule,language,version)
def store_rule(name,rule,language,version):
if language not in rules:
print(f"create entry for {language}")
rules[language] = {}
if '_' in name:
name=name[:name.find('_')]
if name not in rules[language]:
rules[language][name]=version
def dump_rules(repo,version):
for sp_file in Path('.').rglob('sonarpedia.json'):
print(sp_file)
sonarpedia_path=sp_file.parents[0]
sonarpedia = load_json(sp_file)
path=str(sonarpedia_path)+'/'+sonarpedia['rules-metadata-path'].replace('\\','/')
languages=sonarpedia['languages']
get_rules_json(path,languages,version)
with open(f"../{rules_filename}", 'w') as outfile:
json.dump(rules, outfile, indent=2)
def checkout(repo,version,batch_mode):
token=os.getenv('GITHUB_TOKEN')
if not token:
git_url=f"git@github.com:SonarSource/{repo}"
else:
git_url=f"https://{token}@github.com/SonarSource/{repo}"
git_repo=None
g=Git(repo)
if not os.path.exists(repo):
git_repo=Repo.clone_from(git_url, repo)
else:
git_repo=Repo(repo)
if batch_mode:
os.chdir(repo)
for tag in git_repo.tags:
if not '-' in tag.name:
print(f"{repo} {tag.name}")
try:
g.checkout(tag.name)
except Exception:
print("checkout failed, resetting and cleaning")
g.reset('--hard',tag)
g.clean('-xfd')
dump_rules(repo,tag.name)
os.chdir('..')
else:
g=Git(repo)
g.checkout(version)
os.chdir(repo)
def main():
parser = argparse.ArgumentParser(description='rules coverage')
parser.add_argument('command', nargs='+', help='see code for help')
args = parser.parse_args()
global rules
global rules_filename
rules_filename='covered_rules.json'
if os.path.exists(rules_filename):
rules=load_json(rules_filename)
else:
rules={}
if args.command[0] == "batchall":
print(f"batch mode for {repos}")
for repo in repos:
checkout(repo,None,True)
elif args.command[0] == "batch":
repo=args.command[1]
print(f"batch mode for {repo}")
checkout(repo,None,True)
else:
repo=args.command[0]
version=args.command[1]
print(f"checking {repo} version {version}")
checkout(repo,version,False)
dump_rules(repo,version)
if __name__ == '__main__':
main()