feat: implement refactoring opportunity finder — AST complexity + scoring (closes #210) #222

Open
Rockachopa wants to merge 2 commits from fix/210-refactoring-opportunity-finder into main
Owner

Problem

scripts/refactoring_opportunity_finder.py was a stub that only had a sample generate_proposals() function. The test expected compute_file_complexity, calculate_refactoring_score, and FileMetrics — none of which existed. This blocked pytest collection.

Implementation

compute_file_complexity(filepath)(avg, max, funcs, classes, lines)

  • AST-based cyclomatic complexity analysis
  • Counts if/elif/else, for, while, boolop, except, assert as branch points
  • Returns (0.0, 0, 0, 0, 0) for syntax errors (graceful degradation)

FileMetrics dataclass

  • path, lines, complexity, max_complexity, functions, classes
  • churn_30d, churn_90d, test_coverage, refactoring_score

calculate_refactoring_score(metrics) → 0–100

Weighted scoring:

  • Complexity (40%): avg × 4 + max complexity bonus
  • Size (20%): log-scale line count
  • Churn (30%): 30-day × 2 + 90-day × 0.5
  • Coverage (10%): penalty for <30%, bonus for >80%

Tests

All 10 tests pass:

  • Simple function (complexity = 1)
  • Conditionals (complexity ≥ 4)
  • Loops (complexity ≥ 3)
  • Classes (counts correctly)
  • Syntax error (graceful zeros)
  • High/low complexity scoring
  • High churn scoring
  • No coverage handling
  • Large vs small file comparison

Closes #210

## Problem `scripts/refactoring_opportunity_finder.py` was a stub that only had a sample `generate_proposals()` function. The test expected `compute_file_complexity`, `calculate_refactoring_score`, and `FileMetrics` — none of which existed. This blocked pytest collection. ## Implementation ### `compute_file_complexity(filepath)` → `(avg, max, funcs, classes, lines)` - AST-based cyclomatic complexity analysis - Counts `if/elif/else`, `for`, `while`, `boolop`, `except`, `assert` as branch points - Returns `(0.0, 0, 0, 0, 0)` for syntax errors (graceful degradation) ### `FileMetrics` dataclass - path, lines, complexity, max_complexity, functions, classes - churn_30d, churn_90d, test_coverage, refactoring_score ### `calculate_refactoring_score(metrics)` → 0–100 Weighted scoring: - Complexity (40%): avg × 4 + max complexity bonus - Size (20%): log-scale line count - Churn (30%): 30-day × 2 + 90-day × 0.5 - Coverage (10%): penalty for <30%, bonus for >80% ## Tests All 10 tests pass: - Simple function (complexity = 1) - Conditionals (complexity ≥ 4) - Loops (complexity ≥ 3) - Classes (counts correctly) - Syntax error (graceful zeros) - High/low complexity scoring - High churn scoring - No coverage handling - Large vs small file comparison Closes #210
Rockachopa added 2 commits 2026-04-21 11:31:01 +00:00
Owner

🚫 Cannot merge PR #222 - Merge failed. Reason:

🚫 Cannot merge PR #222 - **Merge failed**. Reason:
Author
Owner

🔎 Merge sweep 2026-04-21: not merging this PR in the current sweep. Blocked by merge conflicts / non-mergeable branch state against main. Rebase/refresh onto the base branch and rerun checks.

🔎 Merge sweep 2026-04-21: not merging this PR in the current sweep. Blocked by merge conflicts / non-mergeable branch state against `main`. Rebase/refresh onto the base branch and rerun checks.
Rockachopa reviewed 2026-04-22 13:52:59 +00:00
Rockachopa left a comment
Author
Owner

Looks good — 2 file(s), +147/-170 lines.

  • Includes test coverage.
  • Well-scoped change.
**Looks good** — 2 file(s), +147/-170 lines. - Includes test coverage. - Well-scoped change.
Rockachopa reviewed 2026-04-22 13:55:50 +00:00
Rockachopa left a comment
Author
Owner

Refactoring opportunity finder for issue #210. Uses ComplexityVisitor pattern.

DUPLICATE of PR #223 which has a more complete implementation. Close in favor of #223.

Refactoring opportunity finder for issue #210. Uses ComplexityVisitor pattern. **DUPLICATE of PR #223** which has a more complete implementation. Close in favor of #223.
Rockachopa reviewed 2026-04-22 14:14:20 +00:00
Rockachopa left a comment
Author
Owner

Verdict: REQUEST_CHANGES -- DUPLICATE. This PR implements refactoring_opportunity_finder.py, duplicating #223 which provides the same feature. This version uses a ComplexityVisitor class approach which is clean but #223 has more complete documentation and structure. Recommend closing in favor of #223.

Verdict: REQUEST_CHANGES -- DUPLICATE. This PR implements refactoring_opportunity_finder.py, duplicating #223 which provides the same feature. This version uses a ComplexityVisitor class approach which is clean but #223 has more complete documentation and structure. Recommend closing in favor of #223.
claude reviewed 2026-04-22 16:14:20 +00:00
claude left a comment
Member

Another implementation of the refactoring opportunity finder, similar to #223. The core logic is equivalent. PR #223 has slightly more thorough error handling in compute_file_complexity (catches more exception types). Consider closing in favor of #223.

Another implementation of the refactoring opportunity finder, similar to #223. The core logic is equivalent. PR #223 has slightly more thorough error handling in compute_file_complexity (catches more exception types). Consider closing in favor of #223.
Some checks failed
Test / pytest (pull_request) Failing after 49s
This pull request has changes conflicting with the target branch.
  • scripts/refactoring_opportunity_finder.py
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/210-refactoring-opportunity-finder:fix/210-refactoring-opportunity-finder
git checkout fix/210-refactoring-opportunity-finder
Sign in to join this conversation.