Skip to content

Staged RuboCop configuration improvements #197

@justin808

Description

@justin808

Overview

This issue tracks a staged migration plan to improve RuboCop configuration following the initial setup in PR #193. The goal is to incrementally enhance code quality through small, focused, reviewable PRs.

Context

PR #193 (#193) added initial RuboCop support with:

  • Basic RuboCop configuration with extensions (rubocop-rake, rubocop-rspec)
  • Rake tasks for linting and newline checking
  • Pre-commit hook support
  • GitHub Actions CI integration

This issue outlines the next steps to improve the RuboCop configuration systematically.

Guiding Principles

  1. Small, focused PRs - Each PR should address one category of changes
  2. Easy to review - Changes should be straightforward to understand and validate
  3. Incremental improvement - Build on previous work, avoid breaking changes
  4. Team alignment - Ensure team agrees with style decisions before enforcement

Staged Migration Plan

Stage 1: Enable High-Value, Low-Controversy Cops (Priority: HIGH)

Estimated effort: Small
Risk: Low

Enable cops that catch common bugs and improve code quality with minimal style impact:

  • Style/RedundantReturn - Remove unnecessary explicit returns
  • Style/RedundantSelf - Remove unnecessary self receivers
  • Lint/UnreachableCode - Detect unreachable code (potential bugs)
  • Lint/DuplicateMethods - Detect duplicate method definitions
  • Lint/UselessAssignment - Detect variables assigned but never used
  • Performance/StringInclude? - Use String#include? instead of regex when possible

Pros:

  • Catches actual bugs and performance issues
  • Minimal code style debate
  • Quick wins for code quality

Cons:

  • May require some code changes
  • Need to review each auto-fix

Stage 2: Standardize String and Collection Literals (Priority: MEDIUM)

Estimated effort: Small to Medium
Risk: Low

Enforce consistent quote styles and collection syntax:

  • Style/StringLiterals - Enforce single quotes for non-interpolated strings
  • Style/StringLiteralsInInterpolation - Enforce quotes within interpolation
  • Style/SymbolArray - Use %i[] for symbol arrays
  • Style/WordArray - Use %w[] for word arrays
  • Style/HashSyntax - Enforce modern hash syntax (key: value)

Pros:

  • Improves consistency across codebase
  • Most can be auto-fixed
  • Aligns with Ruby community standards

Cons:

  • Creates large diffs (but mechanical changes)
  • May trigger debates about quote style preference

Stage 3: Enable Layout and Formatting Cops (Priority: MEDIUM)

Estimated effort: Small
Risk: Very Low

Enforce consistent code formatting:

  • Layout/TrailingWhitespace - Remove trailing whitespace
  • Layout/EmptyLineAfterGuardClause - Add empty line after guard clauses
  • Layout/SpaceAroundOperators - Consistent spacing around operators
  • Layout/LineLength - Set maximum line length (suggest 120)
  • Layout/EmptyLinesAroundClassBody - Consistent empty lines in classes
  • Layout/EmptyLinesAroundModuleBody - Consistent empty lines in modules

Pros:

  • Purely formatting, no logic changes
  • Almost entirely auto-fixable
  • Improves readability

Cons:

  • Large diff potential
  • May require configuring max line length threshold

Stage 4: RSpec-Specific Improvements (Priority: MEDIUM)

Estimated effort: Medium
Risk: Medium

Enhance test quality and consistency:

  • RSpec/ExampleLength - Enforce maximum example length
  • RSpec/MultipleExpectations - Limit expectations per example
  • RSpec/DescribeClass - Ensure describe blocks reference classes
  • RSpec/ContextWording - Enforce "when/with" context naming
  • RSpec/ExpectChange - Prefer block form of expect change
  • RSpec/LetBeforeExamples - Ensure let declarations before examples

Pros:

  • Improves test readability and maintainability
  • Encourages better test practices
  • Catches common RSpec antipatterns

Cons:

  • May require test refactoring (splitting large examples)
  • Some rules may be controversial (e.g., multiple expectations)
  • Team alignment needed on test style

Stage 5: Naming Conventions (Priority: LOW)

Estimated effort: Small
Risk: Medium

Enforce consistent naming conventions:

  • Naming/MethodName - Enforce snake_case for methods
  • Naming/VariableName - Enforce snake_case for variables
  • Naming/PredicateName - Enforce ? suffix for boolean methods
  • Naming/AccessorMethodName - Enforce get/set naming patterns

Pros:

  • Improves code consistency
  • Aligns with Ruby conventions
  • Some auto-fixable

Cons:

  • May require API changes if public methods renamed
  • Could be controversial for established naming patterns
  • Needs careful review to avoid breaking changes

Stage 6: Metrics and Complexity (Priority: LOW)

Estimated effort: Large
Risk: High

Enable cops that enforce code complexity limits:

  • Metrics/MethodLength - Limit method length
  • Metrics/ClassLength - Limit class length
  • Metrics/ModuleLength - Limit module length
  • Metrics/CyclomaticComplexity - Limit cyclomatic complexity
  • Metrics/AbcSize - Limit assignment/branch/condition size

Pros:

  • Encourages better code design
  • Identifies refactoring opportunities
  • Reduces code complexity over time

Cons:

  • Large refactoring effort required
  • Many legitimate exceptions needed
  • Team must agree on thresholds
  • Not auto-fixable - requires manual refactoring
  • May slow down development initially

Recommendation: Consider this stage optional or very long-term. Start with high thresholds and gradually tighten.

Implementation Checklist

For each stage:

  • Create feature branch
  • Enable cops in .rubocop.yml
  • Run bundle exec rubocop -a to auto-fix
  • Manually review and adjust auto-fixes
  • Run tests to ensure no breakage
  • Create PR with clear description of changes
  • Get team review and approval
  • Merge and monitor CI

Success Metrics

  • All stages completed within 6-8 weeks
  • No CI breakage from RuboCop changes
  • Team adoption of pre-commit hooks
  • Reduction in code review comments about style
  • Improved code consistency scores

Notes

  • Each stage should be a separate PR
  • Auto-fix capabilities reduce manual effort significantly
  • Team input welcomed on priorities and specific cop configurations
  • Can adjust stage order based on team feedback

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions