diff --git a/rspec-tools/rspec_template/common/metadata.json b/rspec-tools/rspec_template/multi_language/common/metadata.json similarity index 100% rename from rspec-tools/rspec_template/common/metadata.json rename to rspec-tools/rspec_template/multi_language/common/metadata.json diff --git a/rspec-tools/rspec_template/language_specific/metadata.json b/rspec-tools/rspec_template/multi_language/language_specific/metadata.json similarity index 100% rename from rspec-tools/rspec_template/language_specific/metadata.json rename to rspec-tools/rspec_template/multi_language/language_specific/metadata.json diff --git a/rspec-tools/rspec_template/language_specific/rule.adoc b/rspec-tools/rspec_template/multi_language/language_specific/rule.adoc similarity index 100% rename from rspec-tools/rspec_template/language_specific/rule.adoc rename to rspec-tools/rspec_template/multi_language/language_specific/rule.adoc diff --git a/rspec-tools/rspec_template/single_language/common/metadata.json b/rspec-tools/rspec_template/single_language/common/metadata.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/rspec-tools/rspec_template/single_language/common/metadata.json @@ -0,0 +1,2 @@ +{ +} diff --git a/rspec-tools/rspec_template/single_language/language_specific/metadata.json b/rspec-tools/rspec_template/single_language/language_specific/metadata.json new file mode 100644 index 0000000000..be2dce3ee2 --- /dev/null +++ b/rspec-tools/rspec_template/single_language/language_specific/metadata.json @@ -0,0 +1,16 @@ +{ + "title": "FIXME", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-${RSPEC_ID}", + "sqKey": "S${RSPEC_ID}", + "scope": "All", + "qualityProfiles": ["Sonar way"] +} \ No newline at end of file diff --git a/rspec-tools/rspec_template/single_language/language_specific/rule.adoc b/rspec-tools/rspec_template/single_language/language_specific/rule.adoc new file mode 100644 index 0000000000..128882dbc3 --- /dev/null +++ b/rspec-tools/rspec_template/single_language/language_specific/rule.adoc @@ -0,0 +1,20 @@ +FIXME: add a description + +// If you want to factorize the description uncomment the following line and create the file. +//include::../description.adoc[] + +== Noncompliant Code Example + +---- +FIXME +---- + +== Compliant Solution + +---- +FIXME +---- + +== See + +FIXME: A list of links \ No newline at end of file diff --git a/rspec-tools/rspec_tools/create_rule.py b/rspec-tools/rspec_tools/create_rule.py index 47c1115575..04acdd7a54 100644 --- a/rspec-tools/rspec_tools/create_rule.py +++ b/rspec-tools/rspec_tools/create_rule.py @@ -70,27 +70,47 @@ class RuleCreator: repo_dir = Path(self.repository.working_dir) rule_dir = repo_dir.joinpath('rules', f'S{rule_number}') rule_dir.mkdir() - common_template = self.TEMPLATE_PATH.joinpath('common') - lang_specific_template = self.TEMPLATE_PATH.joinpath('language_specific') - copy_directory_content(common_template, rule_dir) + lang_count = sum(1 for l in languages) + if lang_count > 1: + self._fill_multi_lang_template_files(rule_dir, rule_number, languages) + else: + self._fill_single_lang_template_files(rule_dir, rule_number, next(iter(languages))) - for lang in languages: - lang_dir = rule_dir.joinpath(lang) - lang_dir.mkdir() - copy_directory_content(lang_specific_template, lang_dir) - - for rule_item in rule_dir.glob('**/*'): - if rule_item.is_file(): - template_content = rule_item.read_text() - final_content = template_content.replace('${RSPEC_ID}', str(rule_number)) - rule_item.write_text(final_content) self.repository.git.add('--all') self.repository.index.commit(f'Create rule S{rule_number}') - self.repository.git.push('origin', branch_name) - return branch_name - + + def _fill_in_the_blanks_in_the_template(self, rule_dir: Path, rule_number: int): + for rule_item in rule_dir.glob('**/*'): + if rule_item.is_file(): + template_content = rule_item.read_text() + final_content = template_content.replace('${RSPEC_ID}', str(rule_number)) + rule_item.write_text(final_content) + + def _fill_multi_lang_template_files(self, rule_dir: Path, rule_number: int, languages: Iterable[str]): + common_template = self.TEMPLATE_PATH.joinpath('multi_language', 'common') + lang_specific_template = self.TEMPLATE_PATH.joinpath('multi_language', 'language_specific') + copy_directory_content(common_template, rule_dir) + + for lang in languages: + lang_dir = rule_dir.joinpath(lang) + lang_dir.mkdir() + copy_directory_content(lang_specific_template, lang_dir) + + self._fill_in_the_blanks_in_the_template(rule_dir, rule_number) + + def _fill_single_lang_template_files(self, rule_dir: Path, rule_number: int, language: str): + common_template = self.TEMPLATE_PATH.joinpath('single_language', 'common') + lang_specific_template = self.TEMPLATE_PATH.joinpath('single_language', 'language_specific') + copy_directory_content(common_template, rule_dir) + + lang_dir = rule_dir.joinpath(language) + lang_dir.mkdir() + copy_directory_content(lang_specific_template, lang_dir) + + self._fill_in_the_blanks_in_the_template(rule_dir, rule_number) + def create_new_rule_pull_request(self, token: str, rule_number: int, languages: Iterable[str], *, user: Optional[str]) -> PullRequest: branch_name = self.create_new_rule_branch(rule_number, languages) click.echo(f'Created rule Branch {branch_name}') @@ -126,4 +146,4 @@ class RuleCreator: self.repository.git.checkout('-B', new_branch) yield finally: - self.repository.git.checkout(past_branch) \ No newline at end of file + self.repository.git.checkout(past_branch) diff --git a/rspec-tools/tests/test_create_rule.py b/rspec-tools/tests/test_create_rule.py index ff5fb9ec83..3d1b3fc582 100644 --- a/rspec-tools/tests/test_create_rule.py +++ b/rspec-tools/tests/test_create_rule.py @@ -77,8 +77,8 @@ def read_counter_file(repo): return counter_path.read_text() -def test_create_new_rule_branch(rule_creator: RuleCreator, mock_rspec_repo: Repo): - '''Test create_new_rule_branch.''' +def test_create_new_multi_lang_rule_branch(rule_creator: RuleCreator, mock_rspec_repo: Repo): + '''Test create_new_rule_branch for a multi-language rule.''' rule_number = rule_creator.reserve_rule_number() languages = ['java', 'javascript'] @@ -89,7 +89,7 @@ def test_create_new_rule_branch(rule_creator: RuleCreator, mock_rspec_repo: Repo rule_dir = Path(mock_rspec_repo.working_dir).joinpath('rules', f'S{rule_number}') assert rule_dir.exists() - common_root = rule_creator.TEMPLATE_PATH.joinpath('common') + common_root = rule_creator.TEMPLATE_PATH.joinpath('multi_language', 'common') for common_item in common_root.glob('**/*'): if common_item.is_file(): expected_content = common_item.read_text().replace('${RSPEC_ID}', str(rule_number)) @@ -97,7 +97,36 @@ def test_create_new_rule_branch(rule_creator: RuleCreator, mock_rspec_repo: Repo actual_content = rule_dir.joinpath(relative_path).read_text() assert actual_content == expected_content - lang_root = rule_creator.TEMPLATE_PATH.joinpath('language_specific') + lang_root = rule_creator.TEMPLATE_PATH.joinpath('multi_language', 'language_specific') + for lang in languages: + for lang_item in lang_root.glob('**/*'): + if lang_item.is_file(): + expected_content = lang_item.read_text().replace('${RSPEC_ID}', str(rule_number)) + relative_path = lang_item.relative_to(lang_root) + actual_content = rule_dir.joinpath(lang, relative_path).read_text() + assert actual_content == expected_content + +def test_create_new_single_lang_rule_branch(rule_creator: RuleCreator, mock_rspec_repo: Repo): + '''Test create_new_rule_branch for a single-language rule.''' + rule_number = rule_creator.reserve_rule_number() + + languages = ['cfamily'] + branch = rule_creator.create_new_rule_branch(rule_number, languages) + + # Check that the branch was pushed successfully to the origin + mock_rspec_repo.git.checkout(branch) + rule_dir = Path(mock_rspec_repo.working_dir).joinpath('rules', f'S{rule_number}') + assert rule_dir.exists() + + common_root = rule_creator.TEMPLATE_PATH.joinpath('single_language', 'common') + for common_item in common_root.glob('**/*'): + if common_item.is_file(): + expected_content = common_item.read_text().replace('${RSPEC_ID}', str(rule_number)) + relative_path = common_item.relative_to(common_root) + actual_content = rule_dir.joinpath(relative_path).read_text() + assert actual_content == expected_content + + lang_root = rule_creator.TEMPLATE_PATH.joinpath('single_language', 'language_specific') for lang in languages: for lang_item in lang_root.glob('**/*'): if lang_item.is_file():