2021-06-10 11:03:05 +02:00
|
|
|
from rspec_tools.errors import InvalidArgumentError
|
2021-02-16 21:21:46 +01:00
|
|
|
from pathlib import Path
|
|
|
|
import shutil
|
2021-09-30 17:47:25 +02:00
|
|
|
import re
|
|
|
|
import tempfile
|
|
|
|
import json
|
2021-10-01 14:52:12 +02:00
|
|
|
import contextlib
|
|
|
|
import os
|
2021-02-16 21:21:46 +01:00
|
|
|
|
2021-06-10 11:03:05 +02:00
|
|
|
SUPPORTED_LANGUAGES_FILENAME = '../supported_languages.adoc'
|
|
|
|
LANG_TO_LABEL = {'abap': 'abap',
|
|
|
|
'apex': 'slang',
|
|
|
|
'cfamily': 'cfamily',
|
|
|
|
'cobol': 'cobol',
|
2021-12-01 16:18:31 +01:00
|
|
|
'common': 'common',
|
2021-06-10 11:03:05 +02:00
|
|
|
'csharp': 'dotnet',
|
|
|
|
'css': 'css',
|
|
|
|
'flex': 'flex',
|
|
|
|
'go': 'slang',
|
|
|
|
'html': 'html',
|
|
|
|
'java': 'java',
|
|
|
|
'javascript': 'jsts',
|
|
|
|
'kotlin': 'kotlin',
|
|
|
|
'php': 'php',
|
|
|
|
'pli': 'pli',
|
|
|
|
'plsql': 'plsql',
|
|
|
|
'python': 'python',
|
|
|
|
'rpg': 'rpg',
|
|
|
|
'ruby': 'slang',
|
|
|
|
'rust': 'rust',
|
|
|
|
'scala': 'slang',
|
2021-07-01 14:26:02 +02:00
|
|
|
'secrets': 'secrets',
|
2021-06-10 11:03:05 +02:00
|
|
|
'solidity': 'solidity',
|
|
|
|
'swift': 'swift',
|
|
|
|
'tsql': 'tsql',
|
|
|
|
'vb6': 'vb6',
|
|
|
|
'vbnet': 'dotnet',
|
|
|
|
'cloudformation': 'iac',
|
|
|
|
'terraform': 'iac',
|
|
|
|
'xml': 'xml',
|
|
|
|
}
|
|
|
|
|
2022-01-13 09:25:17 +01:00
|
|
|
METADATA_FILE = 'metadata.json'
|
|
|
|
|
2021-02-16 21:21:46 +01:00
|
|
|
def copy_directory_content(src:Path, dest:Path):
|
|
|
|
for item in src.iterdir():
|
|
|
|
if (item.is_dir()):
|
|
|
|
shutil.copytree(item, dest)
|
|
|
|
else:
|
|
|
|
shutil.copy2(item, dest)
|
2021-06-10 11:03:05 +02:00
|
|
|
|
2021-09-30 17:47:25 +02:00
|
|
|
def swap_metadata_files(dir1:Path, dir2:Path):
|
2022-01-13 09:25:17 +01:00
|
|
|
meta1 = dir1.joinpath(METADATA_FILE)
|
|
|
|
meta2 = dir2.joinpath(METADATA_FILE)
|
2021-09-30 17:47:25 +02:00
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
2022-01-13 09:25:17 +01:00
|
|
|
tmp = Path(tmpdir).joinpath(METADATA_FILE)
|
2021-09-30 17:47:25 +02:00
|
|
|
shutil.copy2(meta1, tmp)
|
|
|
|
shutil.copy2(meta2, meta1)
|
|
|
|
shutil.copy2(tmp, meta2)
|
|
|
|
|
|
|
|
def is_empty_metadata(rule_dir:Path):
|
2022-01-13 09:25:17 +01:00
|
|
|
with open(rule_dir.joinpath(METADATA_FILE), 'r') as meta:
|
2021-09-30 17:47:25 +02:00
|
|
|
return not json.load(meta)
|
|
|
|
|
2021-06-10 11:03:05 +02:00
|
|
|
def load_valid_languages():
|
|
|
|
with open(SUPPORTED_LANGUAGES_FILENAME, 'r') as supported_langs_file:
|
|
|
|
supported_langs = supported_langs_file.read()
|
|
|
|
supported_langs = supported_langs.replace(' or', '')
|
|
|
|
supported_langs = supported_langs.replace('`', '')
|
|
|
|
supported_langs = supported_langs.replace(' ', '')
|
|
|
|
supported_langs = supported_langs.replace('\n', '')
|
|
|
|
return supported_langs.split(',')
|
|
|
|
|
|
|
|
def get_mapped_languages():
|
|
|
|
'''Get all the languages we have a label for.
|
|
|
|
Necessary to make sure all valid languages are mapped (see test_utils.py).'''
|
|
|
|
return LANG_TO_LABEL.keys();
|
|
|
|
|
|
|
|
def parse_and_validate_language_list(languages):
|
|
|
|
lang_list = [lang.strip() for lang in languages.split(',')]
|
|
|
|
if len(languages.strip()) == 0 or len(lang_list) == 0:
|
|
|
|
raise InvalidArgumentError('Invalid argument for "languages". At least one language should be provided.')
|
|
|
|
valid_langs = load_valid_languages()
|
|
|
|
for lang in lang_list:
|
|
|
|
if lang not in valid_langs:
|
|
|
|
raise InvalidArgumentError(f"Unsupported language: \"{lang}\". See {SUPPORTED_LANGUAGES_FILENAME} for the list of supported languages.")
|
|
|
|
return lang_list
|
|
|
|
|
2021-09-30 17:47:25 +02:00
|
|
|
def validate_language(language):
|
|
|
|
valid_langs = load_valid_languages()
|
|
|
|
if language not in valid_langs:
|
|
|
|
raise InvalidArgumentError(f"Unsupported language: \"{language}\". See {SUPPORTED_LANGUAGES_FILENAME} for the list of supported languages.")
|
|
|
|
|
2021-06-10 11:03:05 +02:00
|
|
|
def get_labels_for_languages(lang_list):
|
|
|
|
labels = [LANG_TO_LABEL[lang] for lang in lang_list]
|
|
|
|
return list(set(labels))
|
|
|
|
|
2021-09-30 17:47:25 +02:00
|
|
|
def get_label_for_language(language: str) -> str:
|
|
|
|
return LANG_TO_LABEL[language]
|
|
|
|
|
2022-01-13 09:25:17 +01:00
|
|
|
def resolve_rule(rule_id: str) -> int:
|
|
|
|
m = re.search('^S([0-9]{3,4})$', rule_id)
|
2021-09-30 17:47:25 +02:00
|
|
|
if not m:
|
2022-01-13 09:25:17 +01:00
|
|
|
raise InvalidArgumentError(f"Unrecognized rule id format: \"{rule_id}\". Rule id must start with an \"S\" followed by 3 or 4 digits.")
|
2021-09-30 17:47:25 +02:00
|
|
|
else:
|
|
|
|
return int(m.group(1))
|
|
|
|
|
2021-10-01 14:52:12 +02:00
|
|
|
def load_json(file):
|
|
|
|
with open(file) as json_file:
|
|
|
|
return json.load(json_file)
|
|
|
|
|
|
|
|
@contextlib.contextmanager
|
|
|
|
def pushd(new_dir):
|
|
|
|
previous_dir = os.getcwd()
|
|
|
|
os.chdir(new_dir)
|
|
|
|
try:
|
|
|
|
yield
|
|
|
|
finally:
|
|
|
|
os.chdir(previous_dir)
|