From 86d65e1fa7f9d41c054bfee14bcfb230fa8159c8 Mon Sep 17 00:00:00 2001 From: Bugale Bugalit Date: Mon, 11 Jul 2022 18:21:41 +0300 Subject: [PATCH] Issue #60 - Add support for custom comment tag (#3) --- lintly/backends/base.py | 6 +++--- lintly/backends/dummy.py | 6 +++--- lintly/backends/github.py | 18 +++++++++--------- lintly/backends/gitlab.py | 8 ++++---- lintly/builds.py | 9 +++++---- lintly/cli.py | 3 +++ lintly/config.py | 4 ++++ lintly/constants.py | 2 +- lintly/formatters.py | 12 ++++++------ 9 files changed, 38 insertions(+), 30 deletions(-) diff --git a/lintly/backends/base.py b/lintly/backends/base.py index 4ee27ee..2bf7d45 100644 --- a/lintly/backends/base.py +++ b/lintly/backends/base.py @@ -27,7 +27,7 @@ def create_pull_request_comment(self, pr, comment): """ raise NotImplementedError - def delete_pull_request_comments(self, pr): + def delete_pull_request_comments(self, pr, comment_tag): """ Deletes all pull request comments for the bot account. """ @@ -39,13 +39,13 @@ def get_pr_diff(self, pr): """ raise NotImplementedError - def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body): + def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body, comment_tag): """ Creates a pull request review for the given build. """ raise NotImplementedError - def delete_pull_request_review_comments(self, pr): + def delete_pull_request_review_comments(self, pr, comment_tag): """ Deletes all pull request review comments for the bot account. """ diff --git a/lintly/backends/dummy.py b/lintly/backends/dummy.py index f02e7bb..7a092d7 100644 --- a/lintly/backends/dummy.py +++ b/lintly/backends/dummy.py @@ -14,13 +14,13 @@ def get_pull_request(self, pr): def create_pull_request_comment(self, pr, comment): pass - def delete_pull_request_comments(self, pr): + def delete_pull_request_comments(self, pr, comment_tag): pass - def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body): + def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body, comment_tag): pass - def delete_pull_request_review_comments(self, pr): + def delete_pull_request_review_comments(self, pr, comment_tag): pass def post_status(self, state, description, sha, target_url): diff --git a/lintly/backends/github.py b/lintly/backends/github.py index 5368957..c492676 100644 --- a/lintly/backends/github.py +++ b/lintly/backends/github.py @@ -123,8 +123,8 @@ def __init__(self, token, project, context): self.client = Github(token, user_agent=GITHUB_USER_AGENT, per_page=DEFAULT_PER_PAGE) self.context = context - def _should_delete_comment(self, comment): - return LINTLY_IDENTIFIER in comment.body + def _should_delete_comment(self, comment, comment_tag): + return (LINTLY_IDENTIFIER % comment_tag) in comment.body @translate_github_exception def get_pull_request(self, pr): @@ -152,11 +152,11 @@ def create_pull_request_comment(self, pr, comment): ) @translate_github_exception - def delete_pull_request_comments(self, pr): + def delete_pull_request_comments(self, pr, comment_tag): repo = self.client.get_repo(self.project.full_name) pull_request = repo.get_issue(int(pr)) for comment in pull_request.get_comments(): - if self._should_delete_comment(comment): + if self._should_delete_comment(comment, comment_tag): comment.delete() def get_pr_diff(self, pr): @@ -180,7 +180,7 @@ def _get_event(self, review_action): elif review_action == ACTION_REVIEW_APPROVE: return 'APPROVE' - def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body): + def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body, comment_tag): comments = [] for file_path in all_violations: violations = all_violations[file_path] @@ -192,7 +192,7 @@ def create_pull_request_review(self, pr, patch, all_violations, pr_review_action comments.append({ 'path': file_path, 'position': patch_position, - 'body': build_pr_review_line_comment(violation) + 'body': build_pr_review_line_comment(violation, self, comment_tag) }) client = GitHubAPIClient(token=self.token) @@ -213,7 +213,7 @@ def create_pull_request_review(self, pr, patch, all_violations, pr_review_action 'comments': comments_batch, } if has_body: - data['body'] = build_pr_review_body(all_violations) + data['body'] = build_pr_review_body(all_violations, comment_tag) url = '/repos/{owner}/{repo_name}/pulls/{pr_number}/reviews'.format( owner=self.project.owner_login, @@ -225,11 +225,11 @@ def create_pull_request_review(self, pr, patch, all_violations, pr_review_action comments_batch.clear() @translate_github_exception - def delete_pull_request_review_comments(self, pr): + def delete_pull_request_review_comments(self, pr, comment_tag): repo = self.client.get_repo(self.project.full_name) pull_request = repo.get_pull(int(pr)) for comment in pull_request.get_review_comments(): - if self._should_delete_comment(comment): + if self._should_delete_comment(comment, comment_tag): comment.delete() def post_status(self, state, description, sha, target_url=''): diff --git a/lintly/backends/gitlab.py b/lintly/backends/gitlab.py index 2595c21..ec96127 100644 --- a/lintly/backends/gitlab.py +++ b/lintly/backends/gitlab.py @@ -131,23 +131,23 @@ def create_pull_request_comment(self, pr, comment): mr.notes.create({'body': comment}) @translate_gitlab_exception - def delete_pull_request_comments(self, pr): + def delete_pull_request_comments(self, pr, comment_tag): project = self.client.projects.get(self.project.full_name) mr = project.mergerequests.list(iid=pr)[0] client = GitLabAPIClient(self.token, self.user, self.project) for note in mr.notes.list(all=True, per_page=DEFAULT_PER_PAGE): - if LINTLY_IDENTIFIER in note.body: + if (LINTLY_IDENTIFIER % comment_tag) in note.body: url = '/projects/{project_id}/merge_requests/{mr_id}/notes/{note_id}'.format( project_id=project.id, mr_id=mr.id, note_id=note.id ) client.delete(url) @translate_gitlab_exception - def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body): + def create_pull_request_review(self, pr, patch, all_violations, pr_review_action, has_body, comment_tag): raise NotSupportedError() @translate_gitlab_exception - def delete_pull_request_review_comments(self, pr): + def delete_pull_request_review_comments(self, pr, comment_tag): raise NotSupportedError() @translate_gitlab_exception diff --git a/lintly/builds.py b/lintly/builds.py index ace490b..ca136f4 100644 --- a/lintly/builds.py +++ b/lintly/builds.py @@ -90,10 +90,10 @@ def get_pr_patch(self, diff): def cleanup_previous_comments(self): logger.info('Deleting old PR review comments') - self.git_client.delete_pull_request_review_comments(self.config.pr) + self.git_client.delete_pull_request_review_comments(self.config.pr, self.config.comment_tag) logger.info('Deleting old PR comment') - self.git_client.delete_pull_request_comments(self.config.pr) + self.git_client.delete_pull_request_comments(self.config.pr, self.config.comment_tag) def find_diff_violations(self, patch): """ @@ -165,7 +165,8 @@ def submit_pr_review(self, patch, pr_review_action): patch, self._diff_violations, pr_review_action, - self.config.review_body + self.config.review_body, + self.config.comment_tag ) post_pr_comment = False except GitClientError as e: @@ -179,7 +180,7 @@ def submit_pr_review(self, patch, pr_review_action): if post_pr_comment and pr_review_action in (ACTION_REVIEW_COMMENT, ACTION_REVIEW_REQUEST_CHANGES): logger.info('Creating PR comment') - comment = build_pr_comment(self.config, self.violations) + comment = build_pr_comment(self.violations, self.config.comment_tag) self.git_client.create_pull_request_comment(self.config.pr, comment) def get_result_description(self): diff --git a/lintly/cli.py b/lintly/cli.py index 0b7d76c..c47716b 100644 --- a/lintly/cli.py +++ b/lintly/cli.py @@ -59,6 +59,9 @@ default=True, help=('Whether Lintly should post a PR review with a body. ' 'The body is not removed after a re-run.')) +@click.option('--comment-tag', + default='', + help='A tag used to identify comments from a previous run that should be deleted') @click.option('--exit-zero/--no-exit-zero', default=False, help=('Whether Lintly should exit with error code indicating ' 'amount of violations or not. Default false')) diff --git a/lintly/config.py b/lintly/config.py index d1a1ecc..9eb0e7e 100644 --- a/lintly/config.py +++ b/lintly/config.py @@ -63,6 +63,10 @@ def request_changes(self): def review_body(self): return self.cli_config['review_body'] + @property + def comment_tag(self): + return self.cli_config['comment_tag'] + @property def github_check_run_id(self): """The Check Run ID from GitHub Actions. diff --git a/lintly/constants.py b/lintly/constants.py index b3a0583..5117a85 100644 --- a/lintly/constants.py +++ b/lintly/constants.py @@ -4,7 +4,7 @@ # Identifies that a comment came from Lintly. This is used to aid in automatically # deleting old PR comments/reviews. This is valid Markdown that is hidden from # users in GitHub and GitLab. -LINTLY_IDENTIFIER = '' +LINTLY_IDENTIFIER = '' # These constants define the actions that lintly might take against a PR concerning reviews, ie. # not the commit status diff --git a/lintly/formatters.py b/lintly/formatters.py index fdeb274..e01e263 100644 --- a/lintly/formatters.py +++ b/lintly/formatters.py @@ -17,22 +17,22 @@ ) -def build_pr_comment(config, violations): +def build_pr_comment(violations, comment_tag): """ Creates a Markdown representation of the comment to be posted to a pull request. :return: The comment """ template = env.get_template('pr_comment.txt') - return template.render(violations=violations, LINTLY_IDENTIFIER=LINTLY_IDENTIFIER) + return template.render(violations=violations, LINTLY_IDENTIFIER=(LINTLY_IDENTIFIER % comment_tag)) -def build_pr_review_line_comment(violation): +def build_pr_review_line_comment(violation, comment_tag): """ Creates a Markdown representation of the comment to be posted to a pull request. :return: The comment """ template = env.get_template('pr_review_line_comment.txt') - return template.render(violation=violation, LINTLY_IDENTIFIER=LINTLY_IDENTIFIER) + return template.render(violation=violation, LINTLY_IDENTIFIER=(LINTLY_IDENTIFIER % comment_tag)) def build_check_line_comment(violation): @@ -40,6 +40,6 @@ def build_check_line_comment(violation): return template.render(violation=violation) -def build_pr_review_body(violations): +def build_pr_review_body(violations, comment_tag): template = env.get_template('pr_review_body.txt') - return template.render(violations=violations, LINTLY_IDENTIFIER=LINTLY_IDENTIFIER) + return template.render(violations=violations, LINTLY_IDENTIFIER=(LINTLY_IDENTIFIER % comment_tag))