markdown-table-fixer 0.1.2__tar.gz → 0.1.4__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.
- markdown_table_fixer-0.1.2/README.md → markdown_table_fixer-0.1.4/PKG-INFO +110 -0
- markdown_table_fixer-0.1.2/PKG-INFO → markdown_table_fixer-0.1.4/README.md +65 -41
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/pyproject.toml +21 -17
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/_version.py +2 -2
- markdown_table_fixer-0.1.4/src/markdown_table_fixer/blocked_pr_scanner.py +216 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/cli.py +400 -123
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/git_config.py +1 -1
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/github_client.py +133 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/models.py +59 -2
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/pr_fixer.py +508 -98
- markdown_table_fixer-0.1.4/src/markdown_table_fixer/rule_disabler.py +200 -0
- markdown_table_fixer-0.1.4/src/markdown_table_fixer/table_fixer.py +737 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/table_parser.py +45 -2
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/table_validator.py +78 -7
- markdown_table_fixer-0.1.4/tests/README.md +431 -0
- markdown_table_fixer-0.1.2/src/markdown_table_fixer/table_fixer.py +0 -344
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/.gitignore +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/.pre-commit-hooks.yaml +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/LICENSE +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/LICENSES/Apache-2.0.txt +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/scripts/README.md +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/__init__.py +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/exceptions.py +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/graphql_queries.py +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/pr_scanner.py +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/progress_tracker.py +0 -0
- {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/py.typed +0 -0
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: markdown-table-fixer
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: Markdown table formatter and linter with GitHub integration
|
|
5
|
+
Project-URL: Homepage, https://github.com/lfit/markdown-table-fixer
|
|
6
|
+
Project-URL: Repository, https://github.com/lfit/markdown-table-fixer.git
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/lfit/markdown-table-fixer/issues
|
|
8
|
+
Author-email: The Linux Foundation <releng@linuxfoundation.org>
|
|
9
|
+
License: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: formatter,github,linter,markdown,pre-commit,table
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
24
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
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: pyyaml>=6.0.3
|
|
31
|
+
Requires-Dist: rich>=14.2.0
|
|
32
|
+
Requires-Dist: tenacity>=9.1.2
|
|
33
|
+
Requires-Dist: typer>=0.20.0
|
|
34
|
+
Requires-Dist: wcwidth>=0.2.14
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: mypy>=1.17.1; extra == 'dev'
|
|
37
|
+
Requires-Dist: pre-commit>=4.5.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-asyncio>=1.1.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest>=9.0.2; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff>=0.14.8; extra == 'dev'
|
|
43
|
+
Requires-Dist: types-pyyaml>=6.0.12.20250915; extra == 'dev'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
1
46
|
<!--
|
|
2
47
|
SPDX-License-Identifier: Apache-2.0
|
|
3
48
|
SPDX-FileCopyrightText: 2025 The Linux Foundation
|
|
@@ -56,6 +101,54 @@ Auto-fix issues found:
|
|
|
56
101
|
markdown-table-fixer lint --auto-fix
|
|
57
102
|
```
|
|
58
103
|
|
|
104
|
+
#### Respecting Markdownlint Disable Comments
|
|
105
|
+
|
|
106
|
+
The tool automatically respects markdownlint disable/enable comments in your
|
|
107
|
+
markdown files. Violations within disabled sections are not reported:
|
|
108
|
+
|
|
109
|
+
```markdown
|
|
110
|
+
<!-- markdownlint-disable MD013 -->
|
|
111
|
+
| Long table that exceeds line length... |
|
|
112
|
+
<!-- markdownlint-enable MD013 -->
|
|
113
|
+
|
|
114
|
+
<!-- markdownlint-disable MD013 MD060 -->
|
|
115
|
+
| Table with both line length and formatting issues disabled |
|
|
116
|
+
<!-- markdownlint-enable MD013 MD060 -->
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This behavior is consistent across both `lint` and `github` commands,
|
|
120
|
+
ensuring that locally suppressed violations are not reported or fixed when
|
|
121
|
+
processing pull requests.
|
|
122
|
+
|
|
123
|
+
#### Violation Reporting
|
|
124
|
+
|
|
125
|
+
The lint command provides detailed violation reporting by markdownlint rule code:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
$ markdown-table-fixer lint .
|
|
129
|
+
🔍 Scanning: .
|
|
130
|
+
|
|
131
|
+
Summary:
|
|
132
|
+
Files scanned: 10
|
|
133
|
+
Files with issues: 1
|
|
134
|
+
Total violations: 66
|
|
135
|
+
|
|
136
|
+
Files with issues:
|
|
137
|
+
README.md [66 Errors: MD013 (61), MD060 (5)]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The tool reports violations categorized by markdownlint rule:
|
|
141
|
+
|
|
142
|
+
- **MD013**: Line length exceeds limit (auto-detected from `.markdownlintrc`)
|
|
143
|
+
- **MD060**: Table formatting issues (misaligned pipes, spacing, etc.)
|
|
144
|
+
|
|
145
|
+
**Note:** Violations in sections with markdownlint disable comments are
|
|
146
|
+
automatically filtered out and not reported.
|
|
147
|
+
|
|
148
|
+
The line length limit is automatically detected from your markdownlint
|
|
149
|
+
configuration file (`.markdownlint.json`, `.markdownlint.yaml`, etc.). If no
|
|
150
|
+
configuration file exists, the default is 80 characters.
|
|
151
|
+
|
|
59
152
|
### GitHub Mode
|
|
60
153
|
|
|
61
154
|
The `github` command intelligently handles both individual pull requests and
|
|
@@ -110,6 +203,23 @@ markdown-table-fixer github https://github.com/owner/repo/pull/123 \
|
|
|
110
203
|
- Requires Git operations (clone, amend, push)
|
|
111
204
|
- Use when you need to amend commits or use sync strategies
|
|
112
205
|
|
|
206
|
+
#### Scope Control
|
|
207
|
+
|
|
208
|
+
By default, both methods scan and fix **all markdown files** in the
|
|
209
|
+
repository. To limit processing to files changed in the PR, use the
|
|
210
|
+
`--pr-changes-only` flag:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
markdown-table-fixer github https://github.com/owner/repo/pull/123 \
|
|
214
|
+
--pr-changes-only
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Benefits of limiting scope to PR changes:
|
|
218
|
+
|
|
219
|
+
- Faster processing (fewer files to check)
|
|
220
|
+
- Useful when you want to fix tables in modified files without touching others
|
|
221
|
+
- Avoids touching unrelated markdown files
|
|
222
|
+
|
|
113
223
|
#### Fix PRs Across an Organization
|
|
114
224
|
|
|
115
225
|
Scan and fix tables in PRs across an entire GitHub organization:
|
|
@@ -1,44 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: markdown-table-fixer
|
|
3
|
-
Version: 0.1.2
|
|
4
|
-
Summary: Markdown table formatter and linter with GitHub integration
|
|
5
|
-
Project-URL: Homepage, https://github.com/lfit/markdown-table-fixer
|
|
6
|
-
Project-URL: Repository, https://github.com/lfit/markdown-table-fixer.git
|
|
7
|
-
Project-URL: Bug Tracker, https://github.com/lfit/markdown-table-fixer/issues
|
|
8
|
-
Author-email: The Linux Foundation <releng@linuxfoundation.org>
|
|
9
|
-
License: Apache-2.0
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Keywords: formatter,github,linter,markdown,pre-commit,table
|
|
12
|
-
Classifier: Development Status :: 4 - Beta
|
|
13
|
-
Classifier: Environment :: Console
|
|
14
|
-
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
-
Classifier: Operating System :: OS Independent
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
|
-
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
|
|
31
|
-
Requires-Dist: wcwidth>=0.2.13
|
|
32
|
-
Provides-Extra: dev
|
|
33
|
-
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
34
|
-
Requires-Dist: pre-commit>=4.0.1; extra == 'dev'
|
|
35
|
-
Requires-Dist: pytest-asyncio>=0.25.0; extra == 'dev'
|
|
36
|
-
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
37
|
-
Requires-Dist: pytest-mock>=3.14.0; extra == 'dev'
|
|
38
|
-
Requires-Dist: pytest>=8.3.4; extra == 'dev'
|
|
39
|
-
Requires-Dist: ruff>=0.8.4; extra == 'dev'
|
|
40
|
-
Description-Content-Type: text/markdown
|
|
41
|
-
|
|
42
1
|
<!--
|
|
43
2
|
SPDX-License-Identifier: Apache-2.0
|
|
44
3
|
SPDX-FileCopyrightText: 2025 The Linux Foundation
|
|
@@ -97,6 +56,54 @@ Auto-fix issues found:
|
|
|
97
56
|
markdown-table-fixer lint --auto-fix
|
|
98
57
|
```
|
|
99
58
|
|
|
59
|
+
#### Respecting Markdownlint Disable Comments
|
|
60
|
+
|
|
61
|
+
The tool automatically respects markdownlint disable/enable comments in your
|
|
62
|
+
markdown files. Violations within disabled sections are not reported:
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
<!-- markdownlint-disable MD013 -->
|
|
66
|
+
| Long table that exceeds line length... |
|
|
67
|
+
<!-- markdownlint-enable MD013 -->
|
|
68
|
+
|
|
69
|
+
<!-- markdownlint-disable MD013 MD060 -->
|
|
70
|
+
| Table with both line length and formatting issues disabled |
|
|
71
|
+
<!-- markdownlint-enable MD013 MD060 -->
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This behavior is consistent across both `lint` and `github` commands,
|
|
75
|
+
ensuring that locally suppressed violations are not reported or fixed when
|
|
76
|
+
processing pull requests.
|
|
77
|
+
|
|
78
|
+
#### Violation Reporting
|
|
79
|
+
|
|
80
|
+
The lint command provides detailed violation reporting by markdownlint rule code:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
$ markdown-table-fixer lint .
|
|
84
|
+
🔍 Scanning: .
|
|
85
|
+
|
|
86
|
+
Summary:
|
|
87
|
+
Files scanned: 10
|
|
88
|
+
Files with issues: 1
|
|
89
|
+
Total violations: 66
|
|
90
|
+
|
|
91
|
+
Files with issues:
|
|
92
|
+
README.md [66 Errors: MD013 (61), MD060 (5)]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The tool reports violations categorized by markdownlint rule:
|
|
96
|
+
|
|
97
|
+
- **MD013**: Line length exceeds limit (auto-detected from `.markdownlintrc`)
|
|
98
|
+
- **MD060**: Table formatting issues (misaligned pipes, spacing, etc.)
|
|
99
|
+
|
|
100
|
+
**Note:** Violations in sections with markdownlint disable comments are
|
|
101
|
+
automatically filtered out and not reported.
|
|
102
|
+
|
|
103
|
+
The line length limit is automatically detected from your markdownlint
|
|
104
|
+
configuration file (`.markdownlint.json`, `.markdownlint.yaml`, etc.). If no
|
|
105
|
+
configuration file exists, the default is 80 characters.
|
|
106
|
+
|
|
100
107
|
### GitHub Mode
|
|
101
108
|
|
|
102
109
|
The `github` command intelligently handles both individual pull requests and
|
|
@@ -151,6 +158,23 @@ markdown-table-fixer github https://github.com/owner/repo/pull/123 \
|
|
|
151
158
|
- Requires Git operations (clone, amend, push)
|
|
152
159
|
- Use when you need to amend commits or use sync strategies
|
|
153
160
|
|
|
161
|
+
#### Scope Control
|
|
162
|
+
|
|
163
|
+
By default, both methods scan and fix **all markdown files** in the
|
|
164
|
+
repository. To limit processing to files changed in the PR, use the
|
|
165
|
+
`--pr-changes-only` flag:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
markdown-table-fixer github https://github.com/owner/repo/pull/123 \
|
|
169
|
+
--pr-changes-only
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Benefits of limiting scope to PR changes:
|
|
173
|
+
|
|
174
|
+
- Faster processing (fewer files to check)
|
|
175
|
+
- Useful when you want to fix tables in modified files without touching others
|
|
176
|
+
- Avoids touching unrelated markdown files
|
|
177
|
+
|
|
154
178
|
#### Fix PRs Across an Organization
|
|
155
179
|
|
|
156
180
|
Scan and fix tables in PRs across an entire GitHub organization:
|
|
@@ -10,7 +10,7 @@ name = "markdown-table-fixer"
|
|
|
10
10
|
dynamic = ["version"]
|
|
11
11
|
description = "Markdown table formatter and linter with GitHub integration"
|
|
12
12
|
readme = "README.md"
|
|
13
|
-
requires-python = ">=3.10
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
14
|
license = {text = "Apache-2.0"}
|
|
15
15
|
authors = [
|
|
16
16
|
{name = "The Linux Foundation", email = "releng@linuxfoundation.org"},
|
|
@@ -27,28 +27,32 @@ classifiers = [
|
|
|
27
27
|
"Programming Language :: Python :: 3.11",
|
|
28
28
|
"Programming Language :: Python :: 3.12",
|
|
29
29
|
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
30
31
|
"Topic :: Software Development :: Quality Assurance",
|
|
31
32
|
"Topic :: Text Processing :: Markup :: Markdown",
|
|
32
33
|
]
|
|
33
34
|
dependencies = [
|
|
34
|
-
"typer>=0.
|
|
35
|
-
"rich>=
|
|
36
|
-
"httpx[http2]>=0.28.
|
|
37
|
-
"pydantic>=2.
|
|
38
|
-
"aiolimiter>=1.2.
|
|
39
|
-
"tenacity>=9.
|
|
40
|
-
"wcwidth>=0.2.
|
|
35
|
+
"typer>=0.20.0",
|
|
36
|
+
"rich>=14.2.0",
|
|
37
|
+
"httpx[http2]>=0.28.1",
|
|
38
|
+
"pydantic>=2.12.5",
|
|
39
|
+
"aiolimiter>=1.2.1",
|
|
40
|
+
"tenacity>=9.1.2",
|
|
41
|
+
"wcwidth>=0.2.14",
|
|
42
|
+
"pyyaml>=6.0.3",
|
|
43
|
+
"dependamerge>=0.1.19",
|
|
41
44
|
]
|
|
42
45
|
|
|
43
46
|
[project.optional-dependencies]
|
|
44
47
|
dev = [
|
|
45
|
-
"pytest>=
|
|
46
|
-
"pytest-cov>=
|
|
47
|
-
"pytest-asyncio>=
|
|
48
|
-
"pytest-mock>=3.
|
|
49
|
-
"mypy>=1.
|
|
50
|
-
"ruff>=0.8
|
|
51
|
-
"pre-commit>=4.0
|
|
48
|
+
"pytest>=9.0.2",
|
|
49
|
+
"pytest-cov>=7.0.0",
|
|
50
|
+
"pytest-asyncio>=1.1.0",
|
|
51
|
+
"pytest-mock>=3.15.1",
|
|
52
|
+
"mypy>=1.17.1",
|
|
53
|
+
"ruff>=0.14.8",
|
|
54
|
+
"pre-commit>=4.5.0",
|
|
55
|
+
"types-PyYAML>=6.0.12.20250915",
|
|
52
56
|
]
|
|
53
57
|
|
|
54
58
|
[project.urls]
|
|
@@ -72,7 +76,7 @@ packages = ["src/markdown_table_fixer"]
|
|
|
72
76
|
include = ["src", "README.md", "LICENSE*", "pyproject.toml", ".pre-commit-hooks.yaml"]
|
|
73
77
|
|
|
74
78
|
[tool.ruff]
|
|
75
|
-
target-version = "
|
|
79
|
+
target-version = "py312"
|
|
76
80
|
line-length = 80
|
|
77
81
|
exclude = [
|
|
78
82
|
"src/markdown_table_fixer/_version.py",
|
|
@@ -116,7 +120,7 @@ skip-magic-trailing-comma = false
|
|
|
116
120
|
line-ending = "auto"
|
|
117
121
|
|
|
118
122
|
[tool.mypy]
|
|
119
|
-
python_version = "3.
|
|
123
|
+
python_version = "3.12"
|
|
120
124
|
strict = true
|
|
121
125
|
warn_return_any = true
|
|
122
126
|
warn_unused_configs = true
|
{markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/_version.py
RENAMED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 4)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# SPDX-FileCopyrightText: 2025 The Linux Foundation
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Blocked PR scanner using dependamerge's GitHubService.
|
|
6
|
+
|
|
7
|
+
This module wraps dependamerge's PR scanning functionality to provide
|
|
8
|
+
consistent blocked PR detection across both tools.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
from collections.abc import AsyncIterator
|
|
13
|
+
import logging
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from dependamerge.github_service import GitHubService
|
|
17
|
+
from dependamerge.models import UnmergeablePR
|
|
18
|
+
|
|
19
|
+
from .progress_tracker import ProgressTracker
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BlockedPRScanner:
|
|
23
|
+
"""Scanner for blocked/unmergeable pull requests using dependamerge logic."""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
token: str,
|
|
28
|
+
progress_tracker: ProgressTracker | None = None,
|
|
29
|
+
max_repo_tasks: int = 10,
|
|
30
|
+
):
|
|
31
|
+
"""Initialize the blocked PR scanner.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
token: GitHub authentication token
|
|
35
|
+
progress_tracker: Optional progress tracker for UI updates
|
|
36
|
+
max_repo_tasks: Maximum number of repositories to process concurrently
|
|
37
|
+
"""
|
|
38
|
+
self.token = token
|
|
39
|
+
self.progress_tracker = progress_tracker
|
|
40
|
+
self.max_repo_tasks = max_repo_tasks
|
|
41
|
+
self.logger = logging.getLogger(__name__)
|
|
42
|
+
|
|
43
|
+
# Initialize the dependamerge GitHubService
|
|
44
|
+
self.service = GitHubService(
|
|
45
|
+
token=token,
|
|
46
|
+
progress_tracker=progress_tracker,
|
|
47
|
+
max_repo_tasks=max_repo_tasks,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
async def close(self) -> None:
|
|
51
|
+
"""Close the underlying HTTP client."""
|
|
52
|
+
await self.service.close()
|
|
53
|
+
|
|
54
|
+
async def scan_organization_for_blocked_prs(
|
|
55
|
+
self,
|
|
56
|
+
organization: str,
|
|
57
|
+
include_drafts: bool = False,
|
|
58
|
+
) -> AsyncIterator[tuple[str, str, dict[str, Any], UnmergeablePR]]:
|
|
59
|
+
"""Scan an organization for blocked/unmergeable pull requests.
|
|
60
|
+
|
|
61
|
+
This method uses dependamerge's GitHubService to analyze PRs and only
|
|
62
|
+
yields those that are truly blocked (have merge conflicts, failing checks,
|
|
63
|
+
behind base, etc.). This ensures consistency with dependamerge's reporting.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
organization: Organization name to scan
|
|
67
|
+
include_drafts: Whether to include draft PRs (default False)
|
|
68
|
+
|
|
69
|
+
Yields:
|
|
70
|
+
Tuples of (owner, repo_name, pr_data, unmergeable_pr) where:
|
|
71
|
+
- owner: Repository owner
|
|
72
|
+
- repo_name: Repository name
|
|
73
|
+
- pr_data: Raw PR data dict from GraphQL
|
|
74
|
+
- unmergeable_pr: UnmergeablePR model with blocking reasons
|
|
75
|
+
"""
|
|
76
|
+
self.logger.debug(
|
|
77
|
+
f"Starting blocked PR scan of organization: {organization}"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Start progress tracker if available
|
|
81
|
+
if self.progress_tracker:
|
|
82
|
+
self.progress_tracker.start()
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
# Use dependamerge's scan_organization which already:
|
|
86
|
+
# 1. Counts repositories
|
|
87
|
+
# 2. Paginates through PRs
|
|
88
|
+
# 3. Analyzes blocking conditions
|
|
89
|
+
# 4. Tracks progress correctly
|
|
90
|
+
scan_result = await self.service.scan_organization(
|
|
91
|
+
organization, include_drafts=include_drafts
|
|
92
|
+
)
|
|
93
|
+
finally:
|
|
94
|
+
# Stop progress tracker before yielding results
|
|
95
|
+
if self.progress_tracker:
|
|
96
|
+
self.progress_tracker.stop()
|
|
97
|
+
|
|
98
|
+
# Display summary
|
|
99
|
+
if self.progress_tracker:
|
|
100
|
+
from rich.console import Console
|
|
101
|
+
|
|
102
|
+
console = Console()
|
|
103
|
+
console.print(
|
|
104
|
+
f"\n✅ Scan completed\n"
|
|
105
|
+
f"📊 Found {len(scan_result.unmergeable_prs)} blocked PRs "
|
|
106
|
+
f"out of {scan_result.total_prs} total PRs across {scan_result.scanned_repositories} repositories"
|
|
107
|
+
)
|
|
108
|
+
else:
|
|
109
|
+
self.logger.info(
|
|
110
|
+
f"Scan complete: found {len(scan_result.unmergeable_prs)} blocked PRs "
|
|
111
|
+
f"out of {scan_result.total_prs} total PRs across {scan_result.scanned_repositories} repositories"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Now we need to fetch the full PR data for each unmergeable PR
|
|
115
|
+
# to provide it in the same format as the old scanner
|
|
116
|
+
for unmergeable_pr in scan_result.unmergeable_prs:
|
|
117
|
+
# Split repository name
|
|
118
|
+
parts = unmergeable_pr.repository.split("/", 1)
|
|
119
|
+
if len(parts) != 2:
|
|
120
|
+
self.logger.warning(
|
|
121
|
+
f"Invalid repository format: {unmergeable_pr.repository}"
|
|
122
|
+
)
|
|
123
|
+
continue
|
|
124
|
+
|
|
125
|
+
owner, repo_name = parts
|
|
126
|
+
|
|
127
|
+
# Create a minimal pr_data dict that matches what the old scanner returned
|
|
128
|
+
# This is primarily for compatibility with existing code
|
|
129
|
+
pr_data = {
|
|
130
|
+
"number": unmergeable_pr.pr_number,
|
|
131
|
+
"title": unmergeable_pr.title,
|
|
132
|
+
"author": {"login": unmergeable_pr.author},
|
|
133
|
+
"url": unmergeable_pr.url,
|
|
134
|
+
"createdAt": unmergeable_pr.created_at,
|
|
135
|
+
"updatedAt": unmergeable_pr.updated_at,
|
|
136
|
+
# Include blocking information for backward compatibility
|
|
137
|
+
"_unmergeable_reasons": [
|
|
138
|
+
{
|
|
139
|
+
"type": reason.type,
|
|
140
|
+
"description": reason.description,
|
|
141
|
+
"details": reason.details,
|
|
142
|
+
}
|
|
143
|
+
for reason in unmergeable_pr.reasons
|
|
144
|
+
],
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
yield owner, repo_name, pr_data, unmergeable_pr
|
|
148
|
+
|
|
149
|
+
async def scan_organization_all_prs(
|
|
150
|
+
self,
|
|
151
|
+
organization: str,
|
|
152
|
+
include_drafts: bool = False,
|
|
153
|
+
) -> AsyncIterator[tuple[str, str, dict[str, Any], bool]]:
|
|
154
|
+
"""Scan an organization for ALL pull requests, marking which are blocked.
|
|
155
|
+
|
|
156
|
+
This is useful when you want to process all PRs but need to know which
|
|
157
|
+
ones are blocked.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
organization: Organization name to scan
|
|
161
|
+
include_drafts: Whether to include draft PRs
|
|
162
|
+
|
|
163
|
+
Yields:
|
|
164
|
+
Tuples of (owner, repo_name, pr_data, is_blocked) where:
|
|
165
|
+
- owner: Repository owner
|
|
166
|
+
- repo_name: Repository name
|
|
167
|
+
- pr_data: Raw PR data dict from GraphQL
|
|
168
|
+
- is_blocked: Boolean indicating if PR is blocked
|
|
169
|
+
"""
|
|
170
|
+
# For this use case, we need to fetch ALL PRs, not just blocked ones
|
|
171
|
+
# This requires using the lower-level iteration methods
|
|
172
|
+
# For now, we'll note this is a TODO and focus on the blocked-only case
|
|
173
|
+
raise NotImplementedError(
|
|
174
|
+
"Scanning all PRs (not just blocked) is not yet implemented. "
|
|
175
|
+
"Use scan_organization_for_blocked_prs() for blocked-only scanning."
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
def is_pr_blocked(self, pr: dict[str, Any]) -> tuple[bool, list[str]]:
|
|
179
|
+
"""Check if a PR is blocked from merging (synchronous wrapper).
|
|
180
|
+
|
|
181
|
+
This method provides backward compatibility with the old scanner interface.
|
|
182
|
+
It uses the same logic as dependamerge's _analyze_pr_node.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
pr: PR data from GraphQL
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Tuple of (is_blocked, list of blocking reasons as strings)
|
|
189
|
+
"""
|
|
190
|
+
# Use asyncio to call the async version
|
|
191
|
+
return asyncio.run(self._is_pr_blocked_async(pr))
|
|
192
|
+
|
|
193
|
+
async def _is_pr_blocked_async(
|
|
194
|
+
self, pr: dict[str, Any]
|
|
195
|
+
) -> tuple[bool, list[str]]:
|
|
196
|
+
"""Async version of is_pr_blocked.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
pr: PR data from GraphQL
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Tuple of (is_blocked, list of blocking reasons as strings)
|
|
203
|
+
"""
|
|
204
|
+
# Use dependamerge's _analyze_pr_node to check if PR is blocked
|
|
205
|
+
result = await self.service._analyze_pr_node(
|
|
206
|
+
repo_full_name="temp/repo", # Not used for just checking blocked status
|
|
207
|
+
pr=pr,
|
|
208
|
+
include_drafts=False,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
if result is None:
|
|
212
|
+
return False, []
|
|
213
|
+
|
|
214
|
+
# Extract reason descriptions
|
|
215
|
+
reasons = [reason.description for reason in result.reasons]
|
|
216
|
+
return True, reasons
|