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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions