Fix duplicated cycle detection with consistent error handling#42
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughConsolidates cycle detection into DependencyResolver, changes CyclicDependencyError to carry the ordered cycle path, updates Workflow.dependency_order() to use the resolver, and strengthens tests to assert the new error attributes and message. ChangesUnified Cycle Detection and Error Handling
sequenceDiagram
participant Workflow
participant DependencyResolver
participant CyclicDependencyError
Workflow->>DependencyResolver: build graph (add_job / add_edge(filtered needs))
Workflow->>DependencyResolver: resolve()
DependencyResolver->>DependencyResolver: DFS with path tracking
alt cycle detected
DependencyResolver->>CyclicDependencyError: raise with ordered cycle list
CyclicDependencyError-->>Workflow: exception with cycle and message
else no cycle
DependencyResolver-->>Workflow: return ordered job list
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cli/tests/test_queue.py (1)
124-129: ⚡ Quick winStrengthen cycle-path assertions to enforce ordering contract.
Current checks only verify membership and delimiter presence, so an incorrectly ordered path could still pass. Assert cycle closure and expected sequence for this fixed 2-node cycle.
Proposed test tightening
- assert exc.cycle - assert "a" in exc.cycle - assert "b" in exc.cycle - assert "a" in str(exc) - assert "b" in str(exc) - assert " -> " in str(exc) + assert exc.cycle in (["a", "b", "a"], ["b", "a", "b"]) + assert exc.cycle[0] == exc.cycle[-1] + assert " -> ".join(exc.cycle) in str(exc)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cli/tests/test_queue.py` around lines 124 - 129, The test currently only checks membership and delimiter presence for exc.cycle and str(exc), which allows wrong ordering; update the assertions to enforce the exact sequence and closure for the 2-node cycle by asserting exc.cycle == ["a","b","a"] (or the canonical cyclic path expected) and that str(exc) contains the ordered string "a -> b -> a" (or the exact formatted representation your exception uses), ensuring both the cycle list and its string representation preserve the required ordering and closure; update assertions referencing exc.cycle and str(exc) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@cli/tests/test_queue.py`:
- Around line 124-129: The test currently only checks membership and delimiter
presence for exc.cycle and str(exc), which allows wrong ordering; update the
assertions to enforce the exact sequence and closure for the 2-node cycle by
asserting exc.cycle == ["a","b","a"] (or the canonical cyclic path expected) and
that str(exc) contains the ordered string "a -> b -> a" (or the exact formatted
representation your exception uses), ensuring both the cycle list and its string
representation preserve the required ordering and closure; update assertions
referencing exc.cycle and str(exc) accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6f5762c3-b768-43f5-9503-9ae0c3b668b2
📒 Files selected for processing (6)
cli/localci/core/queue.pycli/localci/core/workflow.pycli/localci/errors.pycli/tests/test_errors.pycli/tests/test_queue.pycli/tests/test_workflow.py
|
@coderabbitai |
|
✅ Actions performedFull review triggered. |
|
Actionable comments posted: 0 |
Summary
DependencyResolver.resolve()incli/localci/core/queue.py.Workflow.dependency_order()delegate toDependencyResolverinstead of running its own DFS that logged a warning and returned a partial order on cycles.CyclicDependencyErrorwith acycle: list[str]attribute and a message that shows the full cycle path (e.g.a -> b -> a) for easier debugging.What changed
cli/localci/errors.pyCyclicDependencyErrornow acceptscycle: list[str]; message uses" -> ".join(cycle);job_idretained ascycle[0]for compatibilitycli/localci/core/queue.pyDependencyResolver.resolve()builds the cycle path on detection and raisesCyclicDependencyError(cycle)cli/localci/core/workflow.pydependency_order()populates aDependencyResolver, filters unknownneeds(with existing warning), and callsresolve()Behavior change
Cyclic job dependencies now always raise
CyclicDependencyErrorwith a cycle path, whether detected viaDependencyResolver.resolve()orWorkflow.dependency_order(). Previously,dependency_order()could silently return a partial topological order.Test plan
pytest tests/test_queue.py::TestDependencyResolver::test_cyclic_dependency— cycle detected,cyclepopulated, path in messagepytest tests/test_workflow.py::TestDependencyOrder::test_cyclic_dependency_raises— workflow path delegates and raises same error typepytest tests/test_errors.py::TestErrorAttributes::test_cyclic_dependency_error_attributes—cycle, message,WorkflowErrorhierarchytest_workflow.py,test_full_workflow.py)cd cli && pytest --cov=localci --cov-report=term-missing(490 passed)Out of scope
PriorityJobQueue(still usesall_dependencies_met()only; not required by w4_issue_03)Related issue
close #40
Summary by CodeRabbit
Bug Fixes
Tests