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.
Files changed (27) hide show
  1. markdown_table_fixer-0.1.2/README.md → markdown_table_fixer-0.1.4/PKG-INFO +110 -0
  2. markdown_table_fixer-0.1.2/PKG-INFO → markdown_table_fixer-0.1.4/README.md +65 -41
  3. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/pyproject.toml +21 -17
  4. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/_version.py +2 -2
  5. markdown_table_fixer-0.1.4/src/markdown_table_fixer/blocked_pr_scanner.py +216 -0
  6. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/cli.py +400 -123
  7. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/git_config.py +1 -1
  8. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/github_client.py +133 -0
  9. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/models.py +59 -2
  10. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/pr_fixer.py +508 -98
  11. markdown_table_fixer-0.1.4/src/markdown_table_fixer/rule_disabler.py +200 -0
  12. markdown_table_fixer-0.1.4/src/markdown_table_fixer/table_fixer.py +737 -0
  13. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/table_parser.py +45 -2
  14. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/table_validator.py +78 -7
  15. markdown_table_fixer-0.1.4/tests/README.md +431 -0
  16. markdown_table_fixer-0.1.2/src/markdown_table_fixer/table_fixer.py +0 -344
  17. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/.gitignore +0 -0
  18. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/.pre-commit-hooks.yaml +0 -0
  19. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/LICENSE +0 -0
  20. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/LICENSES/Apache-2.0.txt +0 -0
  21. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/scripts/README.md +0 -0
  22. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/__init__.py +0 -0
  23. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/exceptions.py +0 -0
  24. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/graphql_queries.py +0 -0
  25. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/pr_scanner.py +0 -0
  26. {markdown_table_fixer-0.1.2 → markdown_table_fixer-0.1.4}/src/markdown_table_fixer/progress_tracker.py +0 -0
  27. {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,<3.14"
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.15.0",
35
- "rich>=13.9.4",
36
- "httpx[http2]>=0.28.0",
37
- "pydantic>=2.10.3",
38
- "aiolimiter>=1.2.0",
39
- "tenacity>=9.0.0",
40
- "wcwidth>=0.2.13",
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>=8.3.4",
46
- "pytest-cov>=6.0.0",
47
- "pytest-asyncio>=0.25.0",
48
- "pytest-mock>=3.14.0",
49
- "mypy>=1.13.0",
50
- "ruff>=0.8.4",
51
- "pre-commit>=4.0.1",
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 = "py310"
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.10"
123
+ python_version = "3.12"
120
124
  strict = true
121
125
  warn_return_any = true
122
126
  warn_unused_configs = true
@@ -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.2'
32
- __version_tuple__ = version_tuple = (0, 1, 2)
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