Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Warning Rate limit exceeded@leynos has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 40 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
Summary by CodeRabbit
WalkthroughRefactor the diagram rendering workflow in Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant _render_diagram
participant FileSystem
participant MermaidCLI
Caller->>_render_diagram: Call with block, paths, semaphore, timeout
_render_diagram->>FileSystem: Write .mmd file
_render_diagram->>MermaidCLI: Invoke CLI with semaphore (async)
MermaidCLI-->>_render_diagram: Return result or error
_render_diagram-->>Caller: Complete or raise error
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~18 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Reviewer's GuideRefactor diagram rendering by merging file writing and CLI invocation into a single helper, updating render_block to use it, and adjusting tests accordingly. Class diagram for consolidated Mermaid rendering helpersclassDiagram
class _render_diagram {
+async __call__(block: str, tmpdir: Path, cfg_path: Path, path: Path, idx: int, sem: asyncio.Semaphore, timeout: float) None
"""Write block to disk and invoke mermaid-cli."""
}
class render_block {
+async __call__(block: str, tmpdir: Path, cfg_path: Path, path: Path, idx: int, semaphore: asyncio.Semaphore, timeout: float = 30.0) bool
"""Render a single mermaid block using the CLI asynchronously."""
}
render_block --> _render_diagram : uses
%% Removed helpers
class _write_diagram_file {
-__call__(block: str, tmpdir: Path, path: Path, idx: int) -> tuple[Path, Path]
}
class _run_mermaid_cli {
-async __call__(cmd: list[str], semaphore: asyncio.Semaphore, path: Path, idx: int, timeout: float) None
}
%% _render_diagram replaces _write_diagram_file and _run_mermaid_cli
_render_diagram <.. _write_diagram_file : replaces
_render_diagram <.. _run_mermaid_cli : replaces
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey @leynos - I've reviewed your changes and found some issues that need to be addressed.
- Extend the semaphore context in _render_diagram to cover the wait_for_proc call so that the concurrency limit truly applies to the entire rendering process, not just the subprocess spawn.
- Removing the verbose parameter from render_block changes its public signature—consider bumping the version or providing a compatibility shim if downstream code relies on it.
- Consider replacing the direct print in the FileNotFoundError handler with logger.error to keep CLI error reporting consistent.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Extend the semaphore context in _render_diagram to cover the wait_for_proc call so that the concurrency limit truly applies to the entire rendering process, not just the subprocess spawn.
- Removing the verbose parameter from render_block changes its public signature—consider bumping the version or providing a compatibility shim if downstream code relies on it.
- Consider replacing the direct print in the FileNotFoundError handler with logger.error to keep CLI error reporting consistent.
## Individual Comments
### Comment 1
<location> `nixie/cli.py:110` </location>
<code_context>
- block: str, tmpdir: Path, path: Path, idx: int
-) -> tuple[Path, Path]:
- """Write ``block`` to a temporary ``.mmd`` file.
+async def _render_diagram(
+ block: str,
+ tmpdir: Path,
</code_context>
<issue_to_address>
Consider splitting _render_diagram into two focused helpers for file writing and CLI invocation to keep each function small and testable.
Consider restoring the two focused helpers and let _render_diagram only orchestrate them. This keeps each piece easy to test and the signature of _render_diagram small:
```python
# isolate file I/O
def _write_diagram_file(
block: str, tmpdir: Path, path: Path, idx: int
) -> tuple[Path, Path]:
mmd = tmpdir / f"{path.stem}_{idx}.mmd"
mmd.write_text(block)
return mmd, mmd.with_suffix(".svg")
# isolate CLI invocation
async def _run_mermaid_cli(
mmd: Path,
svg: Path,
cfg_path: Path,
sem: asyncio.Semaphore,
path: Path,
idx: int,
timeout: float,
) -> None:
cmd = get_mmdc_cmd(mmd, svg, cfg_path)
logging.getLogger(__name__).info(shlex.join(cmd))
async with sem:
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
success, stderr = await wait_for_proc(proc, path, idx, timeout)
if not success:
raise RuntimeError(f"Error running {shlex.join(cmd)} for {path}")
# only orchestration
async def _render_diagram(
block: str,
tmpdir: Path,
cfg_path: Path,
path: Path,
idx: int,
sem: asyncio.Semaphore,
timeout: float,
) -> None:
mmd, svg = _write_diagram_file(block, tmpdir, path, idx)
await _run_mermaid_cli(mmd, svg, cfg_path, sem, path, idx, timeout)
```
This way:
- _write_diagram_file and _run_mermaid_cli stay small and unit-testable.
- _render_diagram’s signature remains the same but its body is a single “call two helpers” step.
- All behavior is unchanged.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
nixie/cli.py (1)
1-3: Add module-level docstring.Add a triple-quoted docstring after the shebang to explain the module's purpose, utility, and usage as required by the coding guidelines.
#!/usr/bin/env python3 +"""Command-line interface for validating Mermaid diagrams in Markdown files. + +This module provides functionality to parse Markdown files, extract Mermaid +diagram blocks, and validate them using the mermaid-cli tool. It supports +concurrent processing of multiple diagrams and handles various CLI backends +(mmdc, npx, bun). + +Usage: + nixie [--concurrency N] [--verbose] path1.md [path2.md ...] +""" from __future__ import annotations
♻️ Duplicate comments (1)
nixie/cli.py (1)
110-171: Split _render_diagram into focused helpers to maintain single responsibility.The function violates the single responsibility principle by handling both file I/O and CLI invocation. Split it into two focused functions as previously suggested to improve testability and maintainability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
nixie/cli.py(4 hunks)nixie/unittests/test_render_diagram.py(3 hunks)nixie/unittests/test_write_diagram_file.py(0 hunks)
💤 Files with no reviewable changes (1)
- nixie/unittests/test_write_diagram_file.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
⚙️ CodeRabbit Configuration File
**/*.py: How about the following?- Keep cyclomatic complexity ≤ 12 - Follow single responsibility and CQRS (command/query segregation) - Docstrings must follow the `numpy` style guide. Use a single-line summary for private functions and methods, and full structured docs for all public interfaces. - Move conditionals with >2 branches to predicate/helper functions - Avoid `eval`, `exec`, `pickle`, monkey-patching, `ctypes`, unsafe shell - Every module must begin with a triple-quoted docstring explaining its purpose, utility, and usage, including example calls if appropriate. - Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar - Lint suppressions: - Blanket `# noqa`, file-level skips, and categories are **forbidden** - Only narrow in-line disables (`# noqa: XYZ`) are permitted, and must be accompanied by `FIXME:` or a ticket link, and used only as a last resort. - Use `pytest` fixtures for shared setup (`conftest.py` or `fixtures/`) - Replace duplicate tests with `@pytest.mark.parametrize` - Prefer `pytest-mock` or `unittest.mock` for stubs/mocks - Use `assert …, "message"` over bare asserts - Reflect all API/behaviour changes in `docs/` and update roadmap on completion - Files must not exceed 400 logical lines: - Decompose large modules into subpackages - Split large `match/case` or dispatch tables by domain and collocate with targets if appropriate - Move bulky data (fixtures, templates) to external files for parsing at runtime - Mutable defaults and shadowed built-ins are forbidden - All code must have clear type hints using modern style (`A | B`, `list[str]`, `class Foo[A]:`, `type Bar = int`, etc.), with ABC imports drawn from the correct stdlib module.
Files:
nixie/unittests/test_render_diagram.pynixie/cli.py
🪛 Ruff (0.12.2)
nixie/unittests/test_render_diagram.py
16-16: Trailing comma missing
Add trailing comma
(COM812)
48-48: Trailing comma missing
Add trailing comma
(COM812)
nixie/cli.py
117-117: Async function definition with a timeout parameter
(ASYNC109)
206-206: Trailing comma missing
Add trailing comma
(COM812)
🔇 Additional comments (1)
nixie/cli.py (1)
205-207: Add trailing comma after the format string.Add a trailing comma to maintain consistency with Python formatting conventions.
print( "Error: '{0}' not found. Install Node.js with npx or Bun to use @mermaid-js/mermaid-cli.".format( cli - ), + ), file=sys.stderr, )Likely an incorrect or invalid review comment.
|
@coderabbitai Have the following now been resolved?
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain@leynos Let me check each of these issues: Issue 1: Semaphore context in _render_diagram async with sem:
proc = await asyncio.create_subprocess_exec(*cmd, ...)
await wait_for_proc(proc, path, idx, timeout)The semaphore is released before waiting for the process to complete, meaning multiple processes can run concurrently beyond the intended limit. Issue 2: Verbose parameter removal from render_block Issue 3: FileNotFoundError handler using logger.error except FileNotFoundError as e:
print(f"ERROR: {filename} not found. Is mermaid-cli installed?")Summary: None of the three issues have been resolved in the current implementation. The PR still has:
These issues should be addressed before merging to ensure proper concurrency control, API compatibility, and consistent logging practices. 🏁 Script executed: Length of output: 62 🏁 Script executed: Length of output: 62 🏁 Script executed: Length of output: 794 🏁 Script executed: Length of output: 9187 @leynos After examining the current implementation, I can confirm that none of the three issues have been resolved: 1. Semaphore context issue - ❌ NOT RESOLVED async with sem:
proc = await asyncio.create_subprocess_exec(...)
# Semaphore is released here
success, stderr = await wait_for_proc(proc, path, idx, timeout)This means the concurrency limit only applies to starting processes, not to the entire rendering process. Multiple processes can run simultaneously beyond the intended limit. 2. Breaking API change - ❌ NOT ADDRESSED async def render_block(
block: str,
tmpdir: Path,
cfg_path: Path,
path: Path,
idx: int,
semaphore: asyncio.Semaphore,
*,
timeout: float = 30.0,
) -> bool:This is a breaking change that could affect downstream code. No version bump or compatibility shim has been implemented. 3. Inconsistent error logging - ❌ NOT RESOLVED except FileNotFoundError as exc:
cli = exc.filename or "mmdc"
print(
"Error: '{0}' not found. Install Node.js with npx or Bun to use @mermaid-js/mermaid-cli.".format(
cli
),
file=sys.stderr,
)This is inconsistent with the logging approach used elsewhere in the codebase. Recommendation: Address these issues before merging to ensure proper concurrency control, maintain API compatibility, and achieve consistent error reporting. |
Summary
_render_diagramrender_blockto use_render_diagram_render_diagramTesting
make check-fmtmake lintmake typecheckmake testhttps://chatgpt.com/codex/tasks/task_e_6894ef7712f88322b33b7dc4fe9285b9
Summary by Sourcery
Consolidate Mermaid diagram rendering by merging file creation and CLI invocation into a single helper and updating render_block accordingly.
Enhancements:
Tests: