|
2 | 2 | """ |
3 | 3 | Spell-check script for FORRT repository using codespell. |
4 | 4 | Checks for typos in pull requests and generates a formatted comment. |
| 5 | +
|
| 6 | +Modes: |
| 7 | +- PR mode: Only checks files changed in the pull request (CHANGED_FILES env var) |
| 8 | +- Full mode: Checks the default set of paths (content, scripts, .github, CONTRIBUTING.md, README.md) (CHECK_ALL=true env var) |
5 | 9 | """ |
6 | 10 |
|
7 | 11 | import os |
|
10 | 14 | import json |
11 | 15 | from pathlib import Path |
12 | 16 |
|
13 | | -def run_codespell(): |
| 17 | +# Default paths to check in full mode |
| 18 | +DEFAULT_PATHS = ['content', 'scripts', 'data', '.github', 'CONTRIBUTING.md', 'README.md'] |
| 19 | + |
| 20 | +# File extensions to check |
| 21 | +ALLOWED_EXTENSIONS = {'.md', '.txt', '.html', '.yaml', '.yml', '.py', '.js', '.json', '.toml'} |
| 22 | + |
| 23 | + |
| 24 | +def get_files_to_check(): |
| 25 | + """Determine which files to check based on environment variables. |
| 26 | +
|
| 27 | + Returns a tuple of (paths, is_full_mode). |
| 28 | + """ |
| 29 | + check_all = os.environ.get('CHECK_ALL', 'false').lower() == 'true' |
| 30 | + changed_files_env = os.environ.get('CHANGED_FILES') |
| 31 | + |
| 32 | + # If CHECK_ALL is explicitly requested, always run in full mode. |
| 33 | + if check_all: |
| 34 | + print("Running in full mode: checking default paths...", file=sys.stderr) |
| 35 | + return DEFAULT_PATHS, True |
| 36 | + |
| 37 | + # If CHANGED_FILES is not provided at all, fall back to full mode |
| 38 | + # (e.g., local runs or legacy workflows). |
| 39 | + if changed_files_env is None: |
| 40 | + print("Running in full mode: checking default paths (no CHANGED_FILES provided)...", file=sys.stderr) |
| 41 | + return DEFAULT_PATHS, True |
| 42 | + |
| 43 | + # CHANGED_FILES is provided but may be empty (no matching files). |
| 44 | + changed_files = changed_files_env.strip() |
| 45 | + if not changed_files: |
| 46 | + print("No spell-checkable files changed in this PR.", file=sys.stderr) |
| 47 | + return [], False |
| 48 | + |
| 49 | + # PR mode: only check changed files |
| 50 | + files = [f.strip() for f in changed_files.split('\n') if f.strip()] |
| 51 | + |
| 52 | + # Filter to only existing files with allowed extensions |
| 53 | + valid_files = [] |
| 54 | + for f in files: |
| 55 | + path = Path(f) |
| 56 | + if path.exists() and path.suffix.lower() in ALLOWED_EXTENSIONS: |
| 57 | + valid_files.append(f) |
| 58 | + |
| 59 | + if not valid_files: |
| 60 | + print("No spell-checkable files changed in this PR.", file=sys.stderr) |
| 61 | + return [], False |
| 62 | + print(f"Running in PR mode: checking {len(valid_files)} changed file(s)...", file=sys.stderr) |
| 63 | + return valid_files, False |
| 64 | + |
| 65 | + |
| 66 | +def run_codespell(paths): |
14 | 67 | """Run codespell and capture output.""" |
| 68 | + if not paths: |
| 69 | + return "", 0 |
| 70 | + |
15 | 71 | try: |
16 | | - # Run codespell on specific directories to avoid themes and other large dirs |
17 | | - # Focus on content, scripts, and GitHub workflows |
18 | | - paths = ['content', 'scripts', '.github', 'CONTRIBUTING.md', 'README.md'] |
19 | 72 |
|
20 | 73 | # Use repo root - GitHub Actions path or repo root directory |
21 | 74 | repo_root = os.environ.get('GITHUB_WORKSPACE') |
@@ -69,15 +122,20 @@ def parse_codespell_output(output): |
69 | 122 |
|
70 | 123 | return typos |
71 | 124 |
|
72 | | -def format_comment(typos): |
| 125 | +def format_comment(typos, is_full_mode=False, files_checked=None): |
73 | 126 | """Format typos as a GitHub comment.""" |
| 127 | + mode_info = "all content" if is_full_mode else f"{files_checked} changed file(s)" |
| 128 | + |
74 | 129 | if not typos: |
75 | 130 | comment = "## ✅ Spell Check Passed\n\n" |
76 | | - comment += "No spelling issues found in this PR! 🎉" |
| 131 | + if files_checked == 0: |
| 132 | + comment += "No spell-checkable files were changed in this PR." |
| 133 | + else: |
| 134 | + comment += f"No spelling issues found when checking {mode_info}! 🎉" |
77 | 135 | return comment |
78 | 136 |
|
79 | 137 | comment = "## 📝 Spell Check Results\n\n" |
80 | | - comment += f"Found {len(typos)} potential spelling issue(s) in this PR:\n\n" |
| 138 | + comment += f"Found {len(typos)} potential spelling issue(s) when checking {mode_info}:\n\n" |
81 | 139 |
|
82 | 140 | # Group typos by file |
83 | 141 | typos_by_file = {} |
@@ -111,14 +169,17 @@ def main(): |
111 | 169 | """Main function to run spell check and output comment.""" |
112 | 170 | print("Running spell check...", file=sys.stderr) |
113 | 171 |
|
| 172 | + # Determine which files to check |
| 173 | + paths, is_full_mode = get_files_to_check() |
| 174 | + |
114 | 175 | # Run codespell |
115 | | - output, returncode = run_codespell() |
| 176 | + output, returncode = run_codespell(paths) |
116 | 177 |
|
117 | 178 | # Parse output |
118 | 179 | typos = parse_codespell_output(output) |
119 | 180 |
|
120 | 181 | # Format comment |
121 | | - comment = format_comment(typos) |
| 182 | + comment = format_comment(typos, is_full_mode, len(paths) if not is_full_mode else None) |
122 | 183 |
|
123 | 184 | # Output comment for GitHub Actions |
124 | 185 | # Escape special characters for GitHub Actions output |
|
0 commit comments