Deduplicate publish plan helpers - #18
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
|
Caution Review failedThe pull request is closed. WalkthroughReplaces two specialized formatting helpers with a single generic Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (2)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
lading/commands/publish.py(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (.rules/python-00.md)
**/*.py: Python files must use snake_case filenames (e.g., http_client.py, task_queue.py)
Classes must use PascalCase
Variables and functions must use snake_case
Module-level constants must use UPPER_SNAKE_CASE
Prefix non-exported helpers or internal APIs with a single leading underscore
Use typing everywhere and maintain full static type coverage
Use TypedDict or @DataClass for structured data; prefer @DataClass(slots=True) for internal-only usage
Avoid Any; prefer precise types (TypeVar, Protocol, Literal, Union); use typing.cast only when necessary with justification; use object for unknown opaque values
Be explicit with return types (e.g., -> None, -> str) for all public functions and methods
Favor immutability: prefer tuples to lists and MappingProxyType for read-only mappings; document third-party frozendict if used
Use# pyright: ignoresparingly and include an explanation comment when used
Avoid side effects at import time (no global state mutation or actions on import)
Use docstrings (NumPy format) for public functions, classes, and modules
Explain tricky code with inline comments
**/*.py: Prefer context managers to encapsulate setup/teardown for resources (files, locks, connections) instead of manual try/finally blocks
Use contextlib.contextmanager (@contextmanager) to implement simple, linear setup/teardown context managers
Implement a class with enter and exit for context managers that require internal state or more complex lifecycle handling
For file I/O, prefer with open(...) as ... over open()/try/finally/close patterns
Choose @contextmanager when control flow is linear and no persistent state is needed
Choose a class-based context manager when there is internal state, lifecycle methods, re-entry, or advanced context needs
**/*.py: Exception classes must end with the suffix 'Error' (N818)
Prefer specific built-ins (e.g., TypeError, ValueError) or domain exceptions over raising Exception directly (TRY003/TRY004)
Preserve causal chains...
Files:
lading/commands/publish.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (2)
lading/commands/publish.py (2)
129-152: LGTM! Clean generic implementation.The implementation correctly generalizes the formatting logic and achieves the PR objective of reducing code duplication. The function signature is well-typed, the docstring is complete, and the logic is straightforward.
170-187: LGTM! Consistent formatter usage.All three calls to
_format_items_sectioncorrectly apply the generic helper with appropriate formatters. The identity lambda on line 186 maintains consistency with the formatter interface pattern.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
lading/commands/publish.py(2 hunks)tests/bdd/features/cli.feature(1 hunks)tests/bdd/steps/test_publish_steps.py(1 hunks)tests/unit/test_publish_command.py(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- tests/bdd/features/cli.feature
🚧 Files skipped from review as they are similar to previous changes (1)
- lading/commands/publish.py
🧰 Additional context used
📓 Path-based instructions (3)
**/*.py
📄 CodeRabbit inference engine (.rules/python-00.md)
**/*.py: Python files must use snake_case filenames (e.g., http_client.py, task_queue.py)
Classes must use PascalCase
Variables and functions must use snake_case
Module-level constants must use UPPER_SNAKE_CASE
Prefix non-exported helpers or internal APIs with a single leading underscore
Use typing everywhere and maintain full static type coverage
Use TypedDict or @DataClass for structured data; prefer @DataClass(slots=True) for internal-only usage
Avoid Any; prefer precise types (TypeVar, Protocol, Literal, Union); use typing.cast only when necessary with justification; use object for unknown opaque values
Be explicit with return types (e.g., -> None, -> str) for all public functions and methods
Favor immutability: prefer tuples to lists and MappingProxyType for read-only mappings; document third-party frozendict if used
Use# pyright: ignoresparingly and include an explanation comment when used
Avoid side effects at import time (no global state mutation or actions on import)
Use docstrings (NumPy format) for public functions, classes, and modules
Explain tricky code with inline comments
**/*.py: Prefer context managers to encapsulate setup/teardown for resources (files, locks, connections) instead of manual try/finally blocks
Use contextlib.contextmanager (@contextmanager) to implement simple, linear setup/teardown context managers
Implement a class with enter and exit for context managers that require internal state or more complex lifecycle handling
For file I/O, prefer with open(...) as ... over open()/try/finally/close patterns
Choose @contextmanager when control flow is linear and no persistent state is needed
Choose a class-based context manager when there is internal state, lifecycle methods, re-entry, or advanced context needs
**/*.py: Exception classes must end with the suffix 'Error' (N818)
Prefer specific built-ins (e.g., TypeError, ValueError) or domain exceptions over raising Exception directly (TRY003/TRY004)
Preserve causal chains...
Files:
tests/bdd/steps/test_publish_steps.pytests/unit/test_publish_command.py
{**/unittests/test_*.py,tests/**/*.py}
📄 CodeRabbit inference engine (.rules/python-00.md)
{**/unittests/test_*.py,tests/**/*.py}: Use pytest idioms: prefer fixtures over setup/teardown, parametrize broadly, avoid unnecessary mocks
Group related tests using classes with method names prefixed by test_
Write tests from a user's perspective: test public behaviour, not internals
Files:
tests/bdd/steps/test_publish_steps.pytests/unit/test_publish_command.py
tests/**/*.py
📄 CodeRabbit inference engine (.rules/python-exception-design-raising-handling-and-logging.md)
In tests, assert specific exception types (and optional message via regex) rather than using broad Exception (B017)
Files:
tests/bdd/steps/test_publish_steps.pytests/unit/test_publish_command.py
🧬 Code graph analysis (1)
tests/unit/test_publish_command.py (1)
lading/commands/publish.py (3)
_append_section(127-151)PublishPlan(19-31)_format_plan(154-187)
🪛 GitHub Actions: CI
tests/unit/test_publish_command.py
[error] 1-1: Ruff formatting check failed. 1 file would be reformatted by 'ruff format --check'.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (5)
tests/bdd/steps/test_publish_steps.py (1)
112-116: LGTM! Clean test step implementation.The new BDD step correctly validates that a section header is absent from the publish plan output. It properly reuses the existing
_publish_plan_lineshelper and follows pytest-bdd conventions.tests/unit/test_publish_command.py (4)
351-367: LGTM! Well-structured test with custom formatter.This test correctly validates that
_append_sectionapplies the provided formatter to each item. The innerDummyclass is appropriate for testing purposes, and the assertion comprehensively checks both the header and formatted item output.
370-376: LGTM! Clean test of default behavior.This test correctly validates that
_append_sectiondefaults to string conversion when no formatter is provided, ensuring ergonomic usage with simple string sequences.
379-385: LGTM! Good edge case coverage.This test correctly validates that
_append_sectionleaves the lines buffer unchanged when given an empty sequence, ensuring clean output without unnecessary headers.
388-410: LGTM! Comprehensive integration test.This test thoroughly validates the
_format_planoutput by verifying that all skipped sections (manifest, configuration, and missing exclusions) are correctly formatted with appropriate headers and name-only formatting for crate items.
|
@coderabbitai Have the following now been resolved?
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 259 @leynos Yes, all three suggestions have been resolved! ✅
The final signature is: def _append_section[T](
lines: list[str],
items: typ.Sequence[T],
*,
header: str,
formatter: typ.Callable[[T], str] = str,
) -> None:This is a nice, clean, and flexible implementation that addresses all the feedback perfectly! |
Cap Ruff's mccabe plugin at a cyclomatic complexity of nine and reformat the publish command unit tests to satisfy the formatter.
Summary
Testing
https://chatgpt.com/codex/tasks/task_e_68fd82856a2c83228b1884d1ab19178c
Summary by Sourcery
Introduce a generic section formatter for publish plans and refactor existing helpers to use it, reducing duplication.
New Features:
Enhancements:
Summary by CodeRabbit
Refactor
Tests
Chores