CopSource target Ruby version depends on the current directory #1226

Open
opened 2026-10-21 21:47:56 +00:00 by jared · 3 comments
Owner

Problem

OsSdlc::CopSource.target_version (plugins/os-sdlc/lib/os_sdlc/cop_source.rb:11) reads the Ruby version from the current directory when the path has no RuboCop config. RuboCop then defaults to 2.7. Ruby 2.7 cannot parse endless defs. Cop tests with tmpdir fixtures become flaky (seen in fast-batch-5, UnusedPrivateMethodTest).

Reproduce

ruby -I plugins/os-sdlc/lib -e 'require "os_sdlc"; p OsSdlc::CopSource.target_version("/tmp/x.rb")' — run it once from /tmp and once from plugins/os-sdlc. The values differ by directory.

Approach

Fix the version for paths with no config. cop_source.rb:11 stays the one place that picks the version. When no config file applies to the path, return one fixed version (the plugin's own TargetRubyVersion). Never read it from the current directory.

Required work:

  1. Remove the cwd-dependent lookup — check: absent Dir.pwd in plugins/os-sdlc/lib/os_sdlc/cop_source.rb

Acceptance criteria

  1. Given a path with no RuboCop config, when CopSource.target_version runs from any directory, then it returns the same version.
  2. Given a tmpdir fixture that uses an endless def, when CopSource.parse runs from any directory, then it parses without error.
  3. Given a path under a project with a RuboCop config, when CopSource.target_version runs, then it returns the version from that config.

Owner sketch

module OsSdlc
  class CopSource
    def self.target_version(path)
      config = RuboCop::ConfigStore.new.for_file(path)
      config.for_all_cops["TargetRubyVersion"] ? config.target_ruby_version : FALLBACK_VERSION
    end
  end
end

Origin

  • Trigger: fast-batch-5 saw flaky UnusedPrivateMethodTest with tmpdir fixtures.
  • Improvised this session: none
  • Chain: flaky parse of endless def <- RuboCop defaults to 2.7 <- target_version uses Dir.pwd for config-less paths <- DESIGN plugins/os-sdlc/lib/os_sdlc/cop_source.rb
  • Root candidate: none found; searched CopSource, target_version, Dir.pwd, TargetRubyVersion, tmpdir fixtures
  • Where: plugins/os-sdlc/lib/os_sdlc/cop_source.rb
  • Session: 03befa1b-ac60-4013-8433-1e4b189d9a85
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/03befa1b-ac60-4013-8433-1e4b189d9a85.jsonl

VERDICT: CREATE

## Problem `OsSdlc::CopSource.target_version` (`plugins/os-sdlc/lib/os_sdlc/cop_source.rb:11`) reads the Ruby version from the current directory when the path has no RuboCop config. RuboCop then defaults to 2.7. Ruby 2.7 cannot parse endless defs. Cop tests with tmpdir fixtures become flaky (seen in fast-batch-5, UnusedPrivateMethodTest). ## Reproduce `ruby -I plugins/os-sdlc/lib -e 'require "os_sdlc"; p OsSdlc::CopSource.target_version("/tmp/x.rb")'` — run it once from `/tmp` and once from `plugins/os-sdlc`. The values differ by directory. ## Approach Fix the version for paths with no config. `cop_source.rb:11` stays the one place that picks the version. When no config file applies to the path, return one fixed version (the plugin's own TargetRubyVersion). Never read it from the current directory. Required work: 1. Remove the cwd-dependent lookup — check: absent `Dir.pwd` in `plugins/os-sdlc/lib/os_sdlc/cop_source.rb` ## Acceptance criteria 1. Given a path with no RuboCop config, when `CopSource.target_version` runs from any directory, then it returns the same version. 2. Given a tmpdir fixture that uses an endless def, when `CopSource.parse` runs from any directory, then it parses without error. 3. Given a path under a project with a RuboCop config, when `CopSource.target_version` runs, then it returns the version from that config. ## Owner sketch ```ruby module OsSdlc class CopSource def self.target_version(path) config = RuboCop::ConfigStore.new.for_file(path) config.for_all_cops["TargetRubyVersion"] ? config.target_ruby_version : FALLBACK_VERSION end end end ``` ## Origin - Trigger: fast-batch-5 saw flaky UnusedPrivateMethodTest with tmpdir fixtures. - Improvised this session: none - Chain: flaky parse of endless def <- RuboCop defaults to 2.7 <- target_version uses Dir.pwd for config-less paths <- DESIGN plugins/os-sdlc/lib/os_sdlc/cop_source.rb - Root candidate: none found; searched CopSource, target_version, Dir.pwd, TargetRubyVersion, tmpdir fixtures - Where: plugins/os-sdlc/lib/os_sdlc/cop_source.rb - Session: 03befa1b-ac60-4013-8433-1e4b189d9a85 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/03befa1b-ac60-4013-8433-1e4b189d9a85.jsonl VERDICT: CREATE
Author
Owner

Occurrence: seen again in fast-batch-15 finding B (commit 2fea2e8a, parent #1330).

Occurrence: seen again in fast-batch-15 finding B (commit 2fea2e8a, parent #1330).
Author
Owner

Occurrence: Read the target Ruby version from the target root in Detector::CopSites
Seen: plugins/os-sdlc/lib/os_sdlc/detector (CopSites line 26 calls CopSource.target_version)
Run: Session 6c6b6eae-4ebd-4ac4-9b32-535875a6b39b, fast-batch-15 ruling R2
Adds: in-process, RuboCop memoizes the suite cwd (PathUtil.pwd, ConfigFinder.project_root), so CopSites returns an empty cop cell with no error. DetectorHoldersBinTest keeps one Open3 run with a constraint comment (2fea2e8a) until this is fixed; remove that run when it is.

Occurrence: Read the target Ruby version from the target root in Detector::CopSites Seen: plugins/os-sdlc/lib/os_sdlc/detector (CopSites line 26 calls CopSource.target_version) Run: Session 6c6b6eae-4ebd-4ac4-9b32-535875a6b39b, fast-batch-15 ruling R2 Adds: in-process, RuboCop memoizes the suite cwd (PathUtil.pwd, ConfigFinder.project_root), so CopSites returns an empty cop cell with no error. DetectorHoldersBinTest keeps one Open3 run with a constraint comment (2fea2e8a) until this is fixed; remove that run when it is.
Author
Owner

Occurrence: Parse files that cops read with the running cop's Ruby version, not the working directory's
Seen: plugins/os-sdlc/lib/os_sdlc/cops/structural/cop_source.rb (CopSource.from_file, CopSource.target_version)
Run: Session 3f3909e3-ad19-4d05-8792-564a9aa15708 (#1669 diagnosis)
Adds: Probe numbers. From the cc-os root, target_version(nil) gives 2.7 (TargetRuby::Default), and parse("module T\n def self.f = 1\nend\n") gives valid=false, ast=nil (unexpected token tEQL). From plugins/os-sdlc it gives 4.0 (TargetRuby::BundlerLockFile) and a valid AST. 12 cop tests in #1669 fail from the cc-os root for this reason. #1669 pins the version in test fixtures only. A file read through from_file (AdapterBuiltOutsideEntry::AdapterConstant.scanned) in a project with no .rubocop.yml is still parsed with the working directory's version.

Occurrence: Parse files that cops read with the running cop's Ruby version, not the working directory's Seen: plugins/os-sdlc/lib/os_sdlc/cops/structural/cop_source.rb (CopSource.from_file, CopSource.target_version) Run: Session 3f3909e3-ad19-4d05-8792-564a9aa15708 (#1669 diagnosis) Adds: Probe numbers. From the cc-os root, target_version(nil) gives 2.7 (TargetRuby::Default), and parse("module T\n def self.f = 1\nend\n") gives valid=false, ast=nil (unexpected token tEQL). From plugins/os-sdlc it gives 4.0 (TargetRuby::BundlerLockFile) and a valid AST. 12 cop tests in #1669 fail from the cc-os root for this reason. #1669 pins the version in test fixtures only. A file read through from_file (AdapterBuiltOutsideEntry::AdapterConstant.scanned) in a project with no .rubocop.yml is still parsed with the working directory's version.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#1226
No description provided.