[llvm] [Workflow] Add new code format helper. (PR #66684)

Louis Dionne via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 19 06:54:57 PDT 2023


================
@@ -0,0 +1,236 @@
+#!/usr/bin/env python3
+#
+# ====- code-format-helper, runs code formatters from the ci --*- python -*--==#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ==-------------------------------------------------------------------------==#
+
+import argparse
+import os
+import subprocess
+import sys
+from functools import cached_property
+
+import github
+from github import IssueComment, PullRequest
+
+
+class FormatHelper:
+    COMMENT_TAG = "<!--LLVM CODE FORMAT COMMENT: {fmt}-->"
+    name = "unknown"
+
+    @property
+    def comment_tag(self) -> str:
+        return self.COMMENT_TAG.replace("fmt", self.name)
+
+    def format_run(self, changed_files: [str], args: argparse.Namespace) -> str | None:
+        pass
+
+    def pr_comment_text(self, diff: str) -> str:
+        return f"""
+{self.comment_tag}
+
+:warning: {self.friendly_name}, {self.name} found issues in your code. :warning:
+
+<details>
+<summary>
+You can test this locally with the following command:
+</summary>
+
+``````````bash
+{self.instructions}
+``````````
+
+</details>
+
+<details>
+<summary>
+View the diff from {self.name} here.
+</summary>
+
+``````````diff
+{diff}
+``````````
+
+</details>
+"""
+
+    def find_comment(
+        self, pr: PullRequest.PullRequest
+    ) -> IssueComment.IssueComment | None:
+        for comment in pr.as_issue().get_comments():
+            if self.comment_tag in comment.body:
+                return comment
+        return None
+
+    def update_pr(self, diff: str, args: argparse.Namespace):
+        repo = github.Github(args.token).get_repo(args.repo)
+        pr = repo.get_issue(args.issue_number).as_pull_request()
+
+        existing_comment = self.find_comment(pr)
+        pr_text = self.pr_comment_text(diff)
+
+        if existing_comment:
+            existing_comment.edit(pr_text)
+        else:
+            pr.as_issue().create_comment(pr_text)
+
+    def update_pr_success(self, args: argparse.Namespace):
+        repo = github.Github(args.token).get_repo(args.repo)
+        pr = repo.get_issue(args.issue_number).as_pull_request()
+
+        existing_comment = self.find_comment(pr)
+        if existing_comment:
+            existing_comment.edit(
+                f"""
+{self.comment_tag}
+:white_check_mark: With the latest revision this PR passed the {self.friendly_name}.
+"""
+            )
+
+    def run(self, changed_files: [str], args: argparse.Namespace):
+        diff = self.format_run(changed_files, args)
+        if diff:
+            self.update_pr(diff, args)
+            return False
+        else:
+            self.update_pr_success(args)
+            return True
+
+
+class ClangFormatHelper(FormatHelper):
+    name = "clang-format"
+    friendly_name = "C/C++ code formatter"
+
+    @property
+    def instructions(self):
+        return " ".join(self.cf_cmd)
+
+    @cached_property
+    def libcxx_excluded_files(self):
+        with open("libcxx/utils/data/ignore_format.txt", "r") as ifd:
+            return [excl.strip() for excl in ifd.readlines()]
+
+    def should_be_excluded(self, path: str) -> bool:
+        for excl in self.libcxx_excluded_files:
+            if path == excl:
+                print(f"Excluding file {path}")
+                return True
+        return False
+
+    def filter_changed_files(self, changed_files: [str]) -> [str]:
+        filtered_files = []
+        for path in changed_files:
+            _, ext = os.path.splitext(path)
+            if ext in (".cpp", ".c", ".h", ".hpp", ".hxx", ".cxx"):
----------------
ldionne wrote:

The rule is just "all files inside `libcxx/include`".

I know it's a real pain, but we don't have a choice here because the name of these headers is mandated by the Standard. Sometimes I wish the Standard had used an extension like everybody else, but they don't and it creates these small (but annoying) complexities.

https://github.com/llvm/llvm-project/pull/66684


More information about the llvm-commits mailing list