pull-request-fixer 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/.gitignore +1 -0
  2. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/PKG-INFO +265 -30
  3. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/README.md +248 -15
  4. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/pyproject.toml +92 -16
  5. pull_request_fixer-0.1.2/src/pull_request_fixer/_version.py +24 -0
  6. pull_request_fixer-0.1.2/src/pull_request_fixer/blocked_pr_scanner.py +216 -0
  7. pull_request_fixer-0.1.2/src/pull_request_fixer/cli.py +1855 -0
  8. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/exceptions.py +6 -0
  9. pull_request_fixer-0.1.2/src/pull_request_fixer/file_fixer.py +245 -0
  10. pull_request_fixer-0.1.2/src/pull_request_fixer/git_config.py +258 -0
  11. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/github_client.py +292 -4
  12. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/models.py +31 -0
  13. pull_request_fixer-0.1.2/src/pull_request_fixer/pr_file_fixer.py +896 -0
  14. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/pr_scanner.py +122 -5
  15. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/progress_tracker.py +8 -8
  16. pull_request_fixer-0.1.0/src/pull_request_fixer/_version.py +0 -34
  17. pull_request_fixer-0.1.0/src/pull_request_fixer/cli.py +0 -1059
  18. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/.pre-commit-hooks.yaml +0 -0
  19. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/LICENSE +0 -0
  20. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/LICENSES/Apache-2.0.txt +0 -0
  21. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/scripts/README.md +0 -0
  22. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/__init__.py +0 -0
  23. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/graphql_queries.py +0 -0
  24. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/pr_fixer.py +0 -0
  25. {pull_request_fixer-0.1.0 → pull_request_fixer-0.1.2}/src/pull_request_fixer/py.typed +0 -0
@@ -64,3 +64,4 @@ src/markdown_table_fixer/_version.py
64
64
 
65
65
  # Test output directory (created by integration tests)
66
66
  test_output/
67
+ write-good
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pull-request-fixer
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Pull request formatter and fixer with GitHub integration
5
5
  Project-URL: Homepage, https://github.com/lfit/pull-request-fixer
6
6
  Project-URL: Repository, https://github.com/lfit/pull-request-fixer.git
@@ -19,23 +19,25 @@ Classifier: Programming Language :: Python :: 3.10
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
22
23
  Classifier: Topic :: Software Development :: Quality Assurance
23
24
  Classifier: Topic :: Text Processing :: Markup :: Markdown
24
- Requires-Python: <3.14,>=3.10
25
- Requires-Dist: aiolimiter>=1.2.0
26
- Requires-Dist: httpx[http2]>=0.28.0
27
- Requires-Dist: pydantic>=2.10.3
28
- Requires-Dist: rich>=13.9.4
29
- Requires-Dist: tenacity>=9.0.0
30
- Requires-Dist: typer>=0.15.0
25
+ Requires-Python: >=3.10
26
+ Requires-Dist: aiolimiter>=1.2.1
27
+ Requires-Dist: dependamerge>=0.1.19
28
+ Requires-Dist: httpx[http2]>=0.28.1
29
+ Requires-Dist: pydantic>=2.12.5
30
+ Requires-Dist: rich>=14.2.0
31
+ Requires-Dist: tenacity>=9.1.2
32
+ Requires-Dist: typer>=0.20.0
31
33
  Provides-Extra: dev
32
- Requires-Dist: mypy>=1.13.0; extra == 'dev'
33
- Requires-Dist: pre-commit>=4.0.1; extra == 'dev'
34
- Requires-Dist: pytest-asyncio>=0.25.0; extra == 'dev'
35
- Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
36
- Requires-Dist: pytest-mock>=3.14.0; extra == 'dev'
37
- Requires-Dist: pytest>=8.3.4; extra == 'dev'
38
- Requires-Dist: ruff>=0.8.4; extra == 'dev'
34
+ Requires-Dist: mypy>=1.19.0; extra == 'dev'
35
+ Requires-Dist: pre-commit>=4.5.0; extra == 'dev'
36
+ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
37
+ Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
38
+ Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
39
+ Requires-Dist: pytest>=9.0.2; extra == 'dev'
40
+ Requires-Dist: ruff>=0.14.8; extra == 'dev'
39
41
  Description-Content-Type: text/markdown
40
42
 
41
43
  <!--
@@ -56,6 +58,10 @@ commit messages.
56
58
  - **✍️ Title Fixing**: Set PR titles to match the first commit's subject line
57
59
  - **📝 Body Fixing**: Set PR descriptions to match commit message bodies
58
60
  (excluding trailers)
61
+ - **📄 File Fixing**: Apply regex-based search/replace to files in PRs (clones,
62
+ modifies, amends commit, and force-pushes changes)
63
+ - **🚫 Blocked PR Filtering**: Option to process PRs that cannot merge
64
+ (failing checks, conflicts, etc.)
59
65
  - **🚀 Parallel Processing**: Process PRs concurrently for
60
66
  performance
61
67
  - **🔄 Dry Run Mode**: Preview changes before applying them
@@ -88,23 +94,46 @@ pull-request-fixer lfreleng-actions --fix-title
88
94
  # Fix both titles and bodies
89
95
  pull-request-fixer lfreleng-actions --fix-title --fix-body
90
96
 
97
+ # Show help (includes version)
98
+ pull-request-fixer --help
99
+
100
+ # Fix files in a specific PR using regex
101
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
102
+ --fix-files \
103
+ --file-pattern './action.yaml' \
104
+ --search-pattern '^\s+type:\s+\S' \
105
+ --remove-lines \
106
+ --context-start 'inputs:' \
107
+ --context-end 'runs:' \
108
+ --dry-run \
109
+ --show-diff
110
+
91
111
  # Preview changes without applying (dry run)
92
112
  pull-request-fixer lfreleng-actions --fix-title --fix-body --dry-run
93
113
  ```
94
114
 
95
115
  ## Usage
96
116
 
97
- ### Basic Command
117
+ ### Basic Commands
118
+
119
+ **Scan and fix an organization:**
98
120
 
99
121
  ```bash
100
122
  pull-request-fixer ORGANIZATION [OPTIONS]
101
123
  ```
102
124
 
103
- You can specify the organization as:
125
+ **Fix a specific PR:**
126
+
127
+ ```bash
128
+ pull-request-fixer PR_URL [OPTIONS]
129
+ ```
130
+
131
+ You can specify the target as:
104
132
 
105
133
  - Organization name: `myorg`
106
134
  - GitHub URL: `https://github.com/myorg`
107
135
  - GitHub URL with path: `https://github.com/myorg/`
136
+ - Specific PR URL: `https://github.com/owner/repo/pull/123`
108
137
 
109
138
  ### Fix Options
110
139
 
@@ -144,6 +173,94 @@ log in with special characters in passwords.
144
173
 
145
174
  The `Signed-off-by:` trailer is automatically removed.
146
175
 
176
+ #### `--fix-files`
177
+
178
+ Fixes files in pull requests using regex-based search and replace. This feature:
179
+
180
+ 1. Clones the PR branch
181
+ 2. Finds files matching `--file-pattern` (regex)
182
+ 3. Applies search/replace using `--search-pattern` and `--replacement`
183
+ 4. Amends the last commit with the changes
184
+ 5. Force-pushes the updated commit back to the PR
185
+
186
+ **Required options when using `--fix-files`:**
187
+
188
+ - `--file-pattern`: Regex to match file paths (e.g., `'./action.yaml'` or
189
+ `'.*\.yaml$'`)
190
+ - `--search-pattern`: Regex pattern to find in matched files
191
+ - Either `--replacement` (text to replace matches) or `--remove-lines` (to
192
+ delete matching lines)
193
+
194
+ **Optional context options (for line removal):**
195
+
196
+ - `--context-start`: Regex to define where the removal context begins (e.g., `'inputs:'`)
197
+ - `--context-end`: Regex to define where the removal context ends (e.g., `'runs:'`)
198
+
199
+ **Optional display options:**
200
+
201
+ - `--show-diff`: Show unified diff output for file changes
202
+
203
+ #### Update Methods (for `--fix-files` only)
204
+
205
+ The tool supports two methods for applying file fixes:
206
+
207
+ **API Method (default)** - Uses GitHub API to create new commits:
208
+
209
+ ```bash
210
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
211
+ --fix-files \
212
+ --file-pattern './action.yaml' \
213
+ --search-pattern 'pattern'
214
+ ```
215
+
216
+ - Creates new commits via GitHub API
217
+ - Shows as "Verified" by GitHub
218
+ - No Git operations required
219
+ - Faster and simpler
220
+ - Default method for ease of use
221
+
222
+ **Git Method** - Clones repo, amends commit, force-pushes:
223
+
224
+ ```bash
225
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
226
+ --fix-files \
227
+ --update-method git \
228
+ --file-pattern './action.yaml' \
229
+ --search-pattern 'pattern'
230
+ ```
231
+
232
+ - Respects your local Git signing configuration
233
+ - Amends the existing commit (preserves commit history)
234
+ - Requires Git operations (clone, amend, push)
235
+ - Use when you need to amend commits or use your own signature
236
+
237
+ **Example - Remove type definitions from GitHub Actions:**
238
+
239
+ ```bash
240
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
241
+ --fix-files \
242
+ --file-pattern './action.yaml' \
243
+ --search-pattern '^\s+type:\s+\S' \
244
+ --remove-lines \
245
+ --context-start 'inputs:' \
246
+ --context-end 'runs:' \
247
+ --dry-run \
248
+ --show-diff
249
+ ```
250
+
251
+ This will remove lines containing `type:` that appear between `inputs:` and `runs:`
252
+ sections in `action.yaml` files.
253
+
254
+ **Example - Replace text with regex:**
255
+
256
+ ```bash
257
+ pull-request-fixer https://github.com/owner/repo/pull/456 \
258
+ --fix-files \
259
+ --file-pattern '.*\.py$' \
260
+ --search-pattern 'old_function_name' \
261
+ --replacement 'new_function_name'
262
+ ```
263
+
147
264
  ### Common Usage Patterns
148
265
 
149
266
  **Fix titles:**
@@ -182,6 +299,38 @@ pull-request-fixer myorg --fix-title --workers 16
182
299
  pull-request-fixer myorg --fix-title --quiet
183
300
  ```
184
301
 
302
+ **Verbose mode for debugging:**
303
+
304
+ ```bash
305
+ pull-request-fixer myorg --fix-files --file-pattern '*.yaml' \
306
+ --search-pattern '^\s+type:\s+\S' --remove-lines \
307
+ --verbose # Shows detailed DEBUG logs including file operations
308
+ ```
309
+
310
+ **Process blocked PRs:**
311
+
312
+ <!-- write-good-disable -->
313
+ ```bash
314
+ pull-request-fixer myorg --fix-title --blocked-only
315
+ ```
316
+ <!-- write-good-enable -->
317
+
318
+ **Fix files across PRs:**
319
+
320
+ <!-- write-good-disable -->
321
+ ```bash
322
+ pull-request-fixer myorg \
323
+ --fix-files \
324
+ --file-pattern './action.yaml' \
325
+ --search-pattern '^\s+type:\s+\S' \
326
+ --remove-lines \
327
+ --context-start 'inputs:' \
328
+ --context-end 'runs:' \
329
+ --blocked-only \
330
+ --dry-run
331
+ ```
332
+ <!-- write-good-enable -->
333
+
185
334
  ## PR Comments
186
335
 
187
336
  When the tool applies fixes (not in dry-run mode), it automatically adds a
@@ -207,19 +356,34 @@ comment.
207
356
 
208
357
  ## Options
209
358
 
210
- | Flag | Short | Default | Description |
211
- |------|-------|---------|-------------|
212
- | `--token` | `-t` | `$GITHUB_TOKEN` | GitHub personal access token |
213
- | `--fix-title` | | `false` | Fix PR title to match first commit subject |
214
- | `--fix-body` | | `false` | Fix PR body to match commit message body |
215
- | `--include-drafts` | | `false` | Include draft PRs in scan |
216
- | `--dry-run` | | `false` | Preview changes without applying them |
217
- | `--workers` | `-j` | `4` | Number of parallel workers (1-32) |
218
- | `--verbose` | `-v` | `false` | Enable verbose output |
219
- | `--quiet` | `-q` | `false` | Suppress output except errors |
220
- | `--log-level` | | `INFO` | Set logging level |
221
- | `--version` | | | Show version and exit |
222
- | `--help` | | | Show help message |
359
+ <!-- markdownlint-disable MD013 -->
360
+ <!-- write-good-disable -->
361
+
362
+ | Flag | Short | Default | Description |
363
+ | ------------------ | ----- | --------------- | ----------------------------------------------------- |
364
+ | `--help` | `-h` | | Show help message and exit (displays version) |
365
+ | `--token` | `-t` | `$GITHUB_TOKEN` | GitHub personal access token |
366
+ | `--fix-title` | | `false` | Fix PR title to match first commit subject |
367
+ | `--fix-body` | | `false` | Fix PR body to match commit message body |
368
+ | `--fix-files` | | `false` | Fix files in PR using regex search/replace |
369
+ | `--file-pattern` | | | Regex to match file paths (required w/ `--fix-files`) |
370
+ | `--search-pattern` | | | Regex to search in files (required w/ `--fix-files`) |
371
+ | `--replacement` | | | Replacement string for matched patterns |
372
+ | `--remove-lines` | | `false` | Remove matching lines instead of replacing |
373
+ | `--context-start` | | | Regex pattern for context start (for line removal) |
374
+ | `--context-end` | | | Regex pattern for context end (for line removal) |
375
+ | `--show-diff` | | `false` | Show unified diff output for file changes |
376
+ | `--include-drafts` | | `false` | Include draft PRs in scan |
377
+ | `--blocked-only` | | `false` | Process PRs that cannot merge |
378
+ | `--dry-run` | | `false` | Preview changes without applying them |
379
+ | `--workers` | `-j` | `4` | Number of parallel workers (1-32) |
380
+ | `--verbose` | `-v` | `false` | Enable verbose output (DEBUG logs) |
381
+ | `--quiet` | `-q` | `false` | Suppress output except errors |
382
+ | `--log-level` | | `INFO` | Set logging level |
383
+ | `--version` | | | Show version and exit |
384
+
385
+ <!-- write-good-enable -->
386
+ <!-- markdownlint-enable MD013 -->
223
387
 
224
388
  ## How It Works
225
389
 
@@ -343,6 +507,77 @@ Example timing for 100 repositories with 50 blocked PRs using 8 workers:
343
507
  - PR processing: ~20-30 seconds
344
508
  - **Total: ~50-90 seconds**
345
509
 
510
+ ### Example 4: Fix Files in a Blocked PR
511
+
512
+ This example removes invalid `type:` definitions from a GitHub composite action:
513
+
514
+ ```bash
515
+ pull-request-fixer https://github.com/lfreleng-actions/make-action/pull/40 \
516
+ --fix-files \
517
+ --file-pattern './action.yaml' \
518
+ --search-pattern '^\s+type:\s+\S' \
519
+ --remove-lines \
520
+ --context-start 'inputs:' \
521
+ --context-end 'runs:' \
522
+ --dry-run \
523
+ --show-diff
524
+ ```
525
+
526
+ Output:
527
+
528
+ ```text
529
+ 🔍 Processing PR: https://github.com/lfreleng-actions/make-action/pull/40
530
+ 🔧 Will fix: files
531
+ 🏃 Dry run mode: the tool will not apply changes
532
+
533
+ 📝 Fixing files in PR...
534
+ ```
535
+
536
+ ✅ Would fix 1 file
537
+ 📂 action.yaml
538
+ --- action.yaml
539
+ +++ action.yaml
540
+ @@ -10,7 +10,6 @@
541
+ repository:
542
+ description: 'Remote Git repository URL'
543
+ required: false
544
+
545
+ - type: 'string'
546
+ debug:
547
+ description: 'Enable debug mode'
548
+ required: false
549
+ - type: 'boolean'
550
+
551
+ Dry-run completed!
552
+
553
+ ```text
554
+
555
+ Without `--dry-run`, the output would show:
556
+
557
+ ```text
558
+ ✅ Updated 1 file
559
+ 🔀 action.yaml
560
+ --- action.yaml
561
+ +++ action.yaml
562
+ @@ -10,7 +10,6 @@
563
+ repository:
564
+ description: 'Remote Git repository URL'
565
+ required: false
566
+ - type: 'string'
567
+ debug:
568
+ description: 'Enable debug mode'
569
+ required: false
570
+ - type: 'boolean'
571
+ ```
572
+
573
+ This would:
574
+
575
+ 1. Clone the PR branch
576
+ 2. Remove all lines containing `type:` from the `inputs:` section of `action.yaml`
577
+ 3. Amend the last commit with the changes
578
+ 4. Force-push the updated commit
579
+ 5. Add a comment to the PR explaining the fix
580
+
346
581
  ## Troubleshooting
347
582
 
348
583
  ### No PRs Found
@@ -16,6 +16,10 @@ commit messages.
16
16
  - **✍️ Title Fixing**: Set PR titles to match the first commit's subject line
17
17
  - **📝 Body Fixing**: Set PR descriptions to match commit message bodies
18
18
  (excluding trailers)
19
+ - **📄 File Fixing**: Apply regex-based search/replace to files in PRs (clones,
20
+ modifies, amends commit, and force-pushes changes)
21
+ - **🚫 Blocked PR Filtering**: Option to process PRs that cannot merge
22
+ (failing checks, conflicts, etc.)
19
23
  - **🚀 Parallel Processing**: Process PRs concurrently for
20
24
  performance
21
25
  - **🔄 Dry Run Mode**: Preview changes before applying them
@@ -48,23 +52,46 @@ pull-request-fixer lfreleng-actions --fix-title
48
52
  # Fix both titles and bodies
49
53
  pull-request-fixer lfreleng-actions --fix-title --fix-body
50
54
 
55
+ # Show help (includes version)
56
+ pull-request-fixer --help
57
+
58
+ # Fix files in a specific PR using regex
59
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
60
+ --fix-files \
61
+ --file-pattern './action.yaml' \
62
+ --search-pattern '^\s+type:\s+\S' \
63
+ --remove-lines \
64
+ --context-start 'inputs:' \
65
+ --context-end 'runs:' \
66
+ --dry-run \
67
+ --show-diff
68
+
51
69
  # Preview changes without applying (dry run)
52
70
  pull-request-fixer lfreleng-actions --fix-title --fix-body --dry-run
53
71
  ```
54
72
 
55
73
  ## Usage
56
74
 
57
- ### Basic Command
75
+ ### Basic Commands
76
+
77
+ **Scan and fix an organization:**
58
78
 
59
79
  ```bash
60
80
  pull-request-fixer ORGANIZATION [OPTIONS]
61
81
  ```
62
82
 
63
- You can specify the organization as:
83
+ **Fix a specific PR:**
84
+
85
+ ```bash
86
+ pull-request-fixer PR_URL [OPTIONS]
87
+ ```
88
+
89
+ You can specify the target as:
64
90
 
65
91
  - Organization name: `myorg`
66
92
  - GitHub URL: `https://github.com/myorg`
67
93
  - GitHub URL with path: `https://github.com/myorg/`
94
+ - Specific PR URL: `https://github.com/owner/repo/pull/123`
68
95
 
69
96
  ### Fix Options
70
97
 
@@ -104,6 +131,94 @@ log in with special characters in passwords.
104
131
 
105
132
  The `Signed-off-by:` trailer is automatically removed.
106
133
 
134
+ #### `--fix-files`
135
+
136
+ Fixes files in pull requests using regex-based search and replace. This feature:
137
+
138
+ 1. Clones the PR branch
139
+ 2. Finds files matching `--file-pattern` (regex)
140
+ 3. Applies search/replace using `--search-pattern` and `--replacement`
141
+ 4. Amends the last commit with the changes
142
+ 5. Force-pushes the updated commit back to the PR
143
+
144
+ **Required options when using `--fix-files`:**
145
+
146
+ - `--file-pattern`: Regex to match file paths (e.g., `'./action.yaml'` or
147
+ `'.*\.yaml$'`)
148
+ - `--search-pattern`: Regex pattern to find in matched files
149
+ - Either `--replacement` (text to replace matches) or `--remove-lines` (to
150
+ delete matching lines)
151
+
152
+ **Optional context options (for line removal):**
153
+
154
+ - `--context-start`: Regex to define where the removal context begins (e.g., `'inputs:'`)
155
+ - `--context-end`: Regex to define where the removal context ends (e.g., `'runs:'`)
156
+
157
+ **Optional display options:**
158
+
159
+ - `--show-diff`: Show unified diff output for file changes
160
+
161
+ #### Update Methods (for `--fix-files` only)
162
+
163
+ The tool supports two methods for applying file fixes:
164
+
165
+ **API Method (default)** - Uses GitHub API to create new commits:
166
+
167
+ ```bash
168
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
169
+ --fix-files \
170
+ --file-pattern './action.yaml' \
171
+ --search-pattern 'pattern'
172
+ ```
173
+
174
+ - Creates new commits via GitHub API
175
+ - Shows as "Verified" by GitHub
176
+ - No Git operations required
177
+ - Faster and simpler
178
+ - Default method for ease of use
179
+
180
+ **Git Method** - Clones repo, amends commit, force-pushes:
181
+
182
+ ```bash
183
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
184
+ --fix-files \
185
+ --update-method git \
186
+ --file-pattern './action.yaml' \
187
+ --search-pattern 'pattern'
188
+ ```
189
+
190
+ - Respects your local Git signing configuration
191
+ - Amends the existing commit (preserves commit history)
192
+ - Requires Git operations (clone, amend, push)
193
+ - Use when you need to amend commits or use your own signature
194
+
195
+ **Example - Remove type definitions from GitHub Actions:**
196
+
197
+ ```bash
198
+ pull-request-fixer https://github.com/owner/repo/pull/123 \
199
+ --fix-files \
200
+ --file-pattern './action.yaml' \
201
+ --search-pattern '^\s+type:\s+\S' \
202
+ --remove-lines \
203
+ --context-start 'inputs:' \
204
+ --context-end 'runs:' \
205
+ --dry-run \
206
+ --show-diff
207
+ ```
208
+
209
+ This will remove lines containing `type:` that appear between `inputs:` and `runs:`
210
+ sections in `action.yaml` files.
211
+
212
+ **Example - Replace text with regex:**
213
+
214
+ ```bash
215
+ pull-request-fixer https://github.com/owner/repo/pull/456 \
216
+ --fix-files \
217
+ --file-pattern '.*\.py$' \
218
+ --search-pattern 'old_function_name' \
219
+ --replacement 'new_function_name'
220
+ ```
221
+
107
222
  ### Common Usage Patterns
108
223
 
109
224
  **Fix titles:**
@@ -142,6 +257,38 @@ pull-request-fixer myorg --fix-title --workers 16
142
257
  pull-request-fixer myorg --fix-title --quiet
143
258
  ```
144
259
 
260
+ **Verbose mode for debugging:**
261
+
262
+ ```bash
263
+ pull-request-fixer myorg --fix-files --file-pattern '*.yaml' \
264
+ --search-pattern '^\s+type:\s+\S' --remove-lines \
265
+ --verbose # Shows detailed DEBUG logs including file operations
266
+ ```
267
+
268
+ **Process blocked PRs:**
269
+
270
+ <!-- write-good-disable -->
271
+ ```bash
272
+ pull-request-fixer myorg --fix-title --blocked-only
273
+ ```
274
+ <!-- write-good-enable -->
275
+
276
+ **Fix files across PRs:**
277
+
278
+ <!-- write-good-disable -->
279
+ ```bash
280
+ pull-request-fixer myorg \
281
+ --fix-files \
282
+ --file-pattern './action.yaml' \
283
+ --search-pattern '^\s+type:\s+\S' \
284
+ --remove-lines \
285
+ --context-start 'inputs:' \
286
+ --context-end 'runs:' \
287
+ --blocked-only \
288
+ --dry-run
289
+ ```
290
+ <!-- write-good-enable -->
291
+
145
292
  ## PR Comments
146
293
 
147
294
  When the tool applies fixes (not in dry-run mode), it automatically adds a
@@ -167,19 +314,34 @@ comment.
167
314
 
168
315
  ## Options
169
316
 
170
- | Flag | Short | Default | Description |
171
- |------|-------|---------|-------------|
172
- | `--token` | `-t` | `$GITHUB_TOKEN` | GitHub personal access token |
173
- | `--fix-title` | | `false` | Fix PR title to match first commit subject |
174
- | `--fix-body` | | `false` | Fix PR body to match commit message body |
175
- | `--include-drafts` | | `false` | Include draft PRs in scan |
176
- | `--dry-run` | | `false` | Preview changes without applying them |
177
- | `--workers` | `-j` | `4` | Number of parallel workers (1-32) |
178
- | `--verbose` | `-v` | `false` | Enable verbose output |
179
- | `--quiet` | `-q` | `false` | Suppress output except errors |
180
- | `--log-level` | | `INFO` | Set logging level |
181
- | `--version` | | | Show version and exit |
182
- | `--help` | | | Show help message |
317
+ <!-- markdownlint-disable MD013 -->
318
+ <!-- write-good-disable -->
319
+
320
+ | Flag | Short | Default | Description |
321
+ | ------------------ | ----- | --------------- | ----------------------------------------------------- |
322
+ | `--help` | `-h` | | Show help message and exit (displays version) |
323
+ | `--token` | `-t` | `$GITHUB_TOKEN` | GitHub personal access token |
324
+ | `--fix-title` | | `false` | Fix PR title to match first commit subject |
325
+ | `--fix-body` | | `false` | Fix PR body to match commit message body |
326
+ | `--fix-files` | | `false` | Fix files in PR using regex search/replace |
327
+ | `--file-pattern` | | | Regex to match file paths (required w/ `--fix-files`) |
328
+ | `--search-pattern` | | | Regex to search in files (required w/ `--fix-files`) |
329
+ | `--replacement` | | | Replacement string for matched patterns |
330
+ | `--remove-lines` | | `false` | Remove matching lines instead of replacing |
331
+ | `--context-start` | | | Regex pattern for context start (for line removal) |
332
+ | `--context-end` | | | Regex pattern for context end (for line removal) |
333
+ | `--show-diff` | | `false` | Show unified diff output for file changes |
334
+ | `--include-drafts` | | `false` | Include draft PRs in scan |
335
+ | `--blocked-only` | | `false` | Process PRs that cannot merge |
336
+ | `--dry-run` | | `false` | Preview changes without applying them |
337
+ | `--workers` | `-j` | `4` | Number of parallel workers (1-32) |
338
+ | `--verbose` | `-v` | `false` | Enable verbose output (DEBUG logs) |
339
+ | `--quiet` | `-q` | `false` | Suppress output except errors |
340
+ | `--log-level` | | `INFO` | Set logging level |
341
+ | `--version` | | | Show version and exit |
342
+
343
+ <!-- write-good-enable -->
344
+ <!-- markdownlint-enable MD013 -->
183
345
 
184
346
  ## How It Works
185
347
 
@@ -303,6 +465,77 @@ Example timing for 100 repositories with 50 blocked PRs using 8 workers:
303
465
  - PR processing: ~20-30 seconds
304
466
  - **Total: ~50-90 seconds**
305
467
 
468
+ ### Example 4: Fix Files in a Blocked PR
469
+
470
+ This example removes invalid `type:` definitions from a GitHub composite action:
471
+
472
+ ```bash
473
+ pull-request-fixer https://github.com/lfreleng-actions/make-action/pull/40 \
474
+ --fix-files \
475
+ --file-pattern './action.yaml' \
476
+ --search-pattern '^\s+type:\s+\S' \
477
+ --remove-lines \
478
+ --context-start 'inputs:' \
479
+ --context-end 'runs:' \
480
+ --dry-run \
481
+ --show-diff
482
+ ```
483
+
484
+ Output:
485
+
486
+ ```text
487
+ 🔍 Processing PR: https://github.com/lfreleng-actions/make-action/pull/40
488
+ 🔧 Will fix: files
489
+ 🏃 Dry run mode: the tool will not apply changes
490
+
491
+ 📝 Fixing files in PR...
492
+ ```
493
+
494
+ ✅ Would fix 1 file
495
+ 📂 action.yaml
496
+ --- action.yaml
497
+ +++ action.yaml
498
+ @@ -10,7 +10,6 @@
499
+ repository:
500
+ description: 'Remote Git repository URL'
501
+ required: false
502
+
503
+ - type: 'string'
504
+ debug:
505
+ description: 'Enable debug mode'
506
+ required: false
507
+ - type: 'boolean'
508
+
509
+ Dry-run completed!
510
+
511
+ ```text
512
+
513
+ Without `--dry-run`, the output would show:
514
+
515
+ ```text
516
+ ✅ Updated 1 file
517
+ 🔀 action.yaml
518
+ --- action.yaml
519
+ +++ action.yaml
520
+ @@ -10,7 +10,6 @@
521
+ repository:
522
+ description: 'Remote Git repository URL'
523
+ required: false
524
+ - type: 'string'
525
+ debug:
526
+ description: 'Enable debug mode'
527
+ required: false
528
+ - type: 'boolean'
529
+ ```
530
+
531
+ This would:
532
+
533
+ 1. Clone the PR branch
534
+ 2. Remove all lines containing `type:` from the `inputs:` section of `action.yaml`
535
+ 3. Amend the last commit with the changes
536
+ 4. Force-push the updated commit
537
+ 5. Add a comment to the PR explaining the fix
538
+
306
539
  ## Troubleshooting
307
540
 
308
541
  ### No PRs Found