-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Checking scripts #136829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Checking scripts #136829
Conversation
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-backend-directx @llvm/pr-subscribers-backend-amdgpu Author: None (blazie2004) ChangesPatch is 75.64 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136829.diff 4551 Files Affected:
diff --git a/check_remote_class_check.py b/check_remote_class_check.py
new file mode 100644
index 0000000000000..2bd8f75ee9084
--- /dev/null
+++ b/check_remote_class_check.py
@@ -0,0 +1,86 @@
+import subprocess
+import sys
+import re
+import requests
+import yaml
+
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+
+
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+# GitHub API to fetch the PR diff
+url = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}"
+diff_url = f"{url}.diff"
+
+# Fetch the diff from GitHub API
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER} from GitHub...")
+response = requests.get(diff_url, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff or no changes found. Status Code: {response.status_code}")
+ sys.exit(1)
+
+# Get the diff content (only .cpp and .h files)
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# Get the list of modified .cpp and .h files in the PR
+pr_files = [line.split(" ")[1][2:] for line in diff_text.splitlines() if line.startswith("+++")]
+pr_files = [file for file in pr_files if file.endswith(".cpp") or file.endswith(".h")]
+
+if not pr_files:
+ print("❌ No relevant .cpp or .h files to check in PR #$PR_NUMBER.")
+ sys.exit(0)
+
+# Initialize a list to store missing documentation info
+missing_docs = []
+
+# Process each file in the diff
+for file in pr_files:
+ # Check if the file is a .cpp or .h file
+ if file.endswith(".cpp") or file.endswith(".h"):
+ # Get the diff for the modified file
+ file_diff = "\n".join(
+ [line[1:] for line in diff_text.splitlines() if line.startswith(('+', '-')) and line[2:].startswith(file)]
+ )
+
+ # Loop through each modified line in the file
+ for line in file_diff.splitlines():
+ # Check if the line creates a class (i.e., contains "class ")
+ if "class " in line:
+ # Check the previous line to see if it has Doxygen documentation
+ prev_line = None
+ lines = file_diff.splitlines()
+ idx = lines.index(line)
+ if idx > 0:
+ prev_line = lines[idx - 1]
+
+ # If the previous line is not a Doxygen comment, it's missing documentation
+ if prev_line and not prev_line.strip().startswith("/**"):
+ missing_docs.append((file, line))
+ print(f"The following class is missing documentation: {file}")
+ print(f"Before: {prev_line}")
+ print(f"After: {line}")
+ print("Action: Please add a Doxygen comment above this class explaining its purpose and functionality.")
+ print("Example:")
+ print(" /**")
+ print(" * @brief Class description: What this class does.")
+ print(" * @details More detailed explanation if needed.")
+ print(" */")
+ print()
+
+# If missing documentation was found, exit with status 1
+if missing_docs:
+ sys.exit(1)
+else:
+ print("All modified classes are properly documented.")
+
+print("LLVM CLASS CHECK COMPLETE")
diff --git a/check_remote_llvmheader.py b/check_remote_llvmheader.py
new file mode 100644
index 0000000000000..91ef567e166ad
--- /dev/null
+++ b/check_remote_llvmheader.py
@@ -0,0 +1,83 @@
+import sys
+import subprocess
+import re
+import yaml
+import requests
+
+# === Load config.yaml ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+# === Configuration ===
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+LLVM_HEADER_TEMPLATE = "//===----------------------------------------------------------------------===//"
+LLVM_LICENSE = "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception"
+FILE_EXTENSIONS = (".cpp", ".h")
+
+# === GitHub PR Diff URL ===
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Extract Modified .cpp/.h Files ===
+pr_files = [
+ line.split(" ")[1][2:] for line in diff_text.splitlines()
+ if line.startswith("+++ b/") and line.endswith(FILE_EXTENSIONS)
+]
+
+if not pr_files:
+ print("✅ No .cpp or .h files modified in this PR.")
+ sys.exit(0)
+
+print("\n🔍 Checking headers in the following modified files:")
+for file in pr_files:
+ print(" •", file)
+
+# === Check Each File for LLVM Header in Modified Lines ===
+missing_header_files = []
+
+for file in pr_files:
+ raw_url = f"https://raw.githubusercontent.com/{OWNER}/{REPO}/pull/{PR_NUMBER}/head/{file}"
+ file_response = requests.get(raw_url)
+
+ if file_response.status_code != 200:
+ continue # Skip without printing a message if file is not found in PR head
+
+ content = file_response.text
+ # Extract modified lines from the diff
+ modified_lines = [
+ line[1:] for line in diff_text.splitlines() if line.startswith("+") and line[1:] not in content
+ ]
+
+ # Check only the modified lines for the header
+ header_found = any(
+ LLVM_HEADER_TEMPLATE in line or LLVM_LICENSE in line for line in modified_lines
+ )
+
+ if not header_found:
+ print(f"\n❌ Missing or incorrect LLVM-style header in the modified lines of: {file}")
+ print("Expected header must include:")
+ print(f" {LLVM_HEADER_TEMPLATE}")
+ print(f" {LLVM_LICENSE}")
+ missing_header_files.append(file)
+
+# === Final Report ===
+if missing_header_files:
+ print(f"\n❌ {len(missing_header_files)} file(s) missing proper LLVM-style headers in modified lines.")
+ sys.exit(1)
+else:
+ print("\n✅ All modified files contain correct LLVM-style headers in modified lines!")
+ sys.exit(0)
diff --git a/check_remote_naming_conventions.py b/check_remote_naming_conventions.py
new file mode 100644
index 0000000000000..10b68b83a7ef3
--- /dev/null
+++ b/check_remote_naming_conventions.py
@@ -0,0 +1,182 @@
+import sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is inimport sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is in the exempted list
+ if func_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Function '{func_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := enum_pattern.search(code_line)):
+ enum_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum '{enum_name}' should start with an uppercase letter."))
+
+ if (m := enum_kind_pattern.search(code_line)):
+ enum_kind_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum type '{enum_kind_name}' should end with 'Kind' if used as a discriminator."))
+
+ elif line.startswith("-") or line.startswith(" "):
+ line_number += 1
+
+# === Report Violations ===
+if violations:
+ print("\n❌ Naming convention violations found:\n")
+ for file, line, code, message in violations:
+ print(f"🔸 File: {file}, Line: {line}")
+ print(f"🔹 Code: {code.strip()}")
+ print(f"⚠️ {message}\n")
+ sys.exit(1)
+else:
+ print("\n✅ All modified lines follow naming conventions.")
+ sys.exit(0)
diff --git a/check_remote_pr_format.py b/check_remote_pr_format.py
new file mode 100644
index 0000000000000..10b68b83a7ef3
--- /dev/null
+++ b/check_remote_pr_format.py
@@ -0,0 +1,182 @@
+import sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is inimport sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is in the exempted list
+ if func_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Function '{func_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := enum_pattern.search(code_line)):
+ enum_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum '{enum_name}' should start with an uppercase letter."))
+
+ if (m := enum_kind_pattern.search(code_line)):
+ enum_kind_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum type '{enum_kind_name}' should end with 'Kind' if used as a discriminator."))
+
+ elif line.startswith("-") or line.startswith(" "):
+ line_number += 1
+
+# === Report Violations ===
+if violations:
+ print("\n❌ Naming convention violations found:\n")
+ for file, line, code, message in violations:
+ print(f"🔸 File: {file}, Line: {line}")
+ print(f"🔹 Code: {code.strip()}")
+ print(f"⚠️ {message}\n")
+ sys.exit(1)
+else:
+ print("\n✅ All modified lines follow naming conventions.")
+ sys.exit(0)
diff --git a/check_remote_tidy_format.py b/check_remote_tidy_format.py
new file mode 100644
index 0000000000000..b4d7c4dfdd048
--- /dev/null
+++ b/check_remote_tidy_format.py
@@ -0,0 +1,64 @@
+import subprocess
+import sys
+import re
+import requests
+import yaml
+
+# === Load config.yaml ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+# === Configuration ===
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+headers = {
+ "Accept": "application/vnd.github.v3.diff"
+}
+
+# === Fetch PR Diff ===
+url = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}"
+diff_url = f"{url}.diff"
+
+print(f"📥 F...
[truncated]
|
|
@llvm/pr-subscribers-clang Author: None (blazie2004) ChangesPatch is 75.64 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136829.diff 4551 Files Affected:
diff --git a/check_remote_class_check.py b/check_remote_class_check.py
new file mode 100644
index 0000000000000..2bd8f75ee9084
--- /dev/null
+++ b/check_remote_class_check.py
@@ -0,0 +1,86 @@
+import subprocess
+import sys
+import re
+import requests
+import yaml
+
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+
+
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+# GitHub API to fetch the PR diff
+url = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}"
+diff_url = f"{url}.diff"
+
+# Fetch the diff from GitHub API
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER} from GitHub...")
+response = requests.get(diff_url, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff or no changes found. Status Code: {response.status_code}")
+ sys.exit(1)
+
+# Get the diff content (only .cpp and .h files)
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# Get the list of modified .cpp and .h files in the PR
+pr_files = [line.split(" ")[1][2:] for line in diff_text.splitlines() if line.startswith("+++")]
+pr_files = [file for file in pr_files if file.endswith(".cpp") or file.endswith(".h")]
+
+if not pr_files:
+ print("❌ No relevant .cpp or .h files to check in PR #$PR_NUMBER.")
+ sys.exit(0)
+
+# Initialize a list to store missing documentation info
+missing_docs = []
+
+# Process each file in the diff
+for file in pr_files:
+ # Check if the file is a .cpp or .h file
+ if file.endswith(".cpp") or file.endswith(".h"):
+ # Get the diff for the modified file
+ file_diff = "\n".join(
+ [line[1:] for line in diff_text.splitlines() if line.startswith(('+', '-')) and line[2:].startswith(file)]
+ )
+
+ # Loop through each modified line in the file
+ for line in file_diff.splitlines():
+ # Check if the line creates a class (i.e., contains "class ")
+ if "class " in line:
+ # Check the previous line to see if it has Doxygen documentation
+ prev_line = None
+ lines = file_diff.splitlines()
+ idx = lines.index(line)
+ if idx > 0:
+ prev_line = lines[idx - 1]
+
+ # If the previous line is not a Doxygen comment, it's missing documentation
+ if prev_line and not prev_line.strip().startswith("/**"):
+ missing_docs.append((file, line))
+ print(f"The following class is missing documentation: {file}")
+ print(f"Before: {prev_line}")
+ print(f"After: {line}")
+ print("Action: Please add a Doxygen comment above this class explaining its purpose and functionality.")
+ print("Example:")
+ print(" /**")
+ print(" * @brief Class description: What this class does.")
+ print(" * @details More detailed explanation if needed.")
+ print(" */")
+ print()
+
+# If missing documentation was found, exit with status 1
+if missing_docs:
+ sys.exit(1)
+else:
+ print("All modified classes are properly documented.")
+
+print("LLVM CLASS CHECK COMPLETE")
diff --git a/check_remote_llvmheader.py b/check_remote_llvmheader.py
new file mode 100644
index 0000000000000..91ef567e166ad
--- /dev/null
+++ b/check_remote_llvmheader.py
@@ -0,0 +1,83 @@
+import sys
+import subprocess
+import re
+import yaml
+import requests
+
+# === Load config.yaml ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+# === Configuration ===
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+LLVM_HEADER_TEMPLATE = "//===----------------------------------------------------------------------===//"
+LLVM_LICENSE = "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception"
+FILE_EXTENSIONS = (".cpp", ".h")
+
+# === GitHub PR Diff URL ===
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Extract Modified .cpp/.h Files ===
+pr_files = [
+ line.split(" ")[1][2:] for line in diff_text.splitlines()
+ if line.startswith("+++ b/") and line.endswith(FILE_EXTENSIONS)
+]
+
+if not pr_files:
+ print("✅ No .cpp or .h files modified in this PR.")
+ sys.exit(0)
+
+print("\n🔍 Checking headers in the following modified files:")
+for file in pr_files:
+ print(" •", file)
+
+# === Check Each File for LLVM Header in Modified Lines ===
+missing_header_files = []
+
+for file in pr_files:
+ raw_url = f"https://raw.githubusercontent.com/{OWNER}/{REPO}/pull/{PR_NUMBER}/head/{file}"
+ file_response = requests.get(raw_url)
+
+ if file_response.status_code != 200:
+ continue # Skip without printing a message if file is not found in PR head
+
+ content = file_response.text
+ # Extract modified lines from the diff
+ modified_lines = [
+ line[1:] for line in diff_text.splitlines() if line.startswith("+") and line[1:] not in content
+ ]
+
+ # Check only the modified lines for the header
+ header_found = any(
+ LLVM_HEADER_TEMPLATE in line or LLVM_LICENSE in line for line in modified_lines
+ )
+
+ if not header_found:
+ print(f"\n❌ Missing or incorrect LLVM-style header in the modified lines of: {file}")
+ print("Expected header must include:")
+ print(f" {LLVM_HEADER_TEMPLATE}")
+ print(f" {LLVM_LICENSE}")
+ missing_header_files.append(file)
+
+# === Final Report ===
+if missing_header_files:
+ print(f"\n❌ {len(missing_header_files)} file(s) missing proper LLVM-style headers in modified lines.")
+ sys.exit(1)
+else:
+ print("\n✅ All modified files contain correct LLVM-style headers in modified lines!")
+ sys.exit(0)
diff --git a/check_remote_naming_conventions.py b/check_remote_naming_conventions.py
new file mode 100644
index 0000000000000..10b68b83a7ef3
--- /dev/null
+++ b/check_remote_naming_conventions.py
@@ -0,0 +1,182 @@
+import sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is inimport sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is in the exempted list
+ if func_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Function '{func_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := enum_pattern.search(code_line)):
+ enum_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum '{enum_name}' should start with an uppercase letter."))
+
+ if (m := enum_kind_pattern.search(code_line)):
+ enum_kind_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum type '{enum_kind_name}' should end with 'Kind' if used as a discriminator."))
+
+ elif line.startswith("-") or line.startswith(" "):
+ line_number += 1
+
+# === Report Violations ===
+if violations:
+ print("\n❌ Naming convention violations found:\n")
+ for file, line, code, message in violations:
+ print(f"🔸 File: {file}, Line: {line}")
+ print(f"🔹 Code: {code.strip()}")
+ print(f"⚠️ {message}\n")
+ sys.exit(1)
+else:
+ print("\n✅ All modified lines follow naming conventions.")
+ sys.exit(0)
diff --git a/check_remote_pr_format.py b/check_remote_pr_format.py
new file mode 100644
index 0000000000000..10b68b83a7ef3
--- /dev/null
+++ b/check_remote_pr_format.py
@@ -0,0 +1,182 @@
+import sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is inimport sys
+import requests
+import re
+import yaml
+
+# === Load Configuration ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+EXTENSIONS = (".cpp", ".h")
+DIFF_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}.diff"
+
+# === Fetch PR Diff ===
+print(f"📥 Fetching PR diff for PR #{PR_NUMBER}...")
+response = requests.get(DIFF_URL, headers={"Accept": "application/vnd.github.v3.diff"})
+
+if response.status_code != 200:
+ print(f"❌ Failed to fetch PR diff. Status: {response.status_code}")
+ sys.exit(1)
+
+diff_text = response.text
+if not diff_text.strip():
+ print("✅ No changes in the PR.")
+ sys.exit(0)
+
+# === Regex Patterns ===
+class_pattern = re.compile(r"\bclass\s+([a-z]\w*)")
+var_pattern = re.compile(r"\b(?:int|float|double|char|bool)\s+([A-Z]\w*)")
+func_pattern = re.compile(r"\bvoid\s+([A-Z]\w*)\s*\(")
+enum_pattern = re.compile(r"\benum\s+([a-z]\w*)")
+enum_kind_pattern = re.compile(r"\benum\s+(?!.*Kind\b)(\w+)\b")
+
+# === Exempted Names ===
+EXEMPT_NAMES = {'RecursiveASTVisitor'} # Add any class or function names that you want to exempt
+
+violations = []
+current_file = None
+line_number = 0
+
+# === Process Diff ===
+for line in diff_text.splitlines():
+ if line.startswith("+++ b/") and line.endswith(EXTENSIONS):
+ current_file = line[6:]
+ line_number = 0
+ continue
+
+ if not current_file:
+ continue
+
+ if line.startswith("@@"):
+ match = re.search(r"\+(\d+)", line)
+ if match:
+ line_number = int(match.group(1)) - 1
+ continue
+
+ if line.startswith("+") and not line.startswith("+++"):
+
+ line_number += 1
+ code_line = line[1:]
+
+ if (m := class_pattern.search(code_line)):
+ class_name = m.group(1)
+ # Skip if the class is in the exempted list
+ if class_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Class '{class_name}' should start with an uppercase letter."))
+
+ if (m := var_pattern.search(code_line)):
+ var_name = m.group(1)
+ # Skip if the variable is in the exempted list
+ if var_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Variable '{var_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := func_pattern.search(code_line)):
+ func_name = m.group(1)
+ # Skip if the function is in the exempted list
+ if func_name not in EXEMPT_NAMES:
+ violations.append((current_file, line_number, code_line, f"Function '{func_name}' should start with a lowercase letter in camelCase."))
+
+ if (m := enum_pattern.search(code_line)):
+ enum_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum '{enum_name}' should start with an uppercase letter."))
+
+ if (m := enum_kind_pattern.search(code_line)):
+ enum_kind_name = m.group(1)
+ violations.append((current_file, line_number, code_line, f"Enum type '{enum_kind_name}' should end with 'Kind' if used as a discriminator."))
+
+ elif line.startswith("-") or line.startswith(" "):
+ line_number += 1
+
+# === Report Violations ===
+if violations:
+ print("\n❌ Naming convention violations found:\n")
+ for file, line, code, message in violations:
+ print(f"🔸 File: {file}, Line: {line}")
+ print(f"🔹 Code: {code.strip()}")
+ print(f"⚠️ {message}\n")
+ sys.exit(1)
+else:
+ print("\n✅ All modified lines follow naming conventions.")
+ sys.exit(0)
diff --git a/check_remote_tidy_format.py b/check_remote_tidy_format.py
new file mode 100644
index 0000000000000..b4d7c4dfdd048
--- /dev/null
+++ b/check_remote_tidy_format.py
@@ -0,0 +1,64 @@
+import subprocess
+import sys
+import re
+import requests
+import yaml
+
+# === Load config.yaml ===
+with open("config.yaml", "r") as f:
+ config = yaml.safe_load(f)
+
+# === Configuration ===
+PR_NUMBER = str(config["project"]["pr_number"])
+OWNER = config["project"]["owner"]
+REPO = config["project"]["repo"]
+
+headers = {
+ "Accept": "application/vnd.github.v3.diff"
+}
+
+# === Fetch PR Diff ===
+url = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{PR_NUMBER}"
+diff_url = f"{url}.diff"
+
+print(f"📥 F...
[truncated]
|
No description provided.