Skip to content

Preserve ENV["TESTOPTS"] when verbose is enabled#723

Merged
hsbt merged 2 commits intomasterfrom
fix/testopts-preserve-existing-value
Apr 16, 2026
Merged

Preserve ENV["TESTOPTS"] when verbose is enabled#723
hsbt merged 2 commits intomasterfrom
fix/testopts-preserve-existing-value

Conversation

@hsbt
Copy link
Copy Markdown
Member

@hsbt hsbt commented Apr 16, 2026

Rake 13.4.0 made FileUtilsExt.verbose(true) set ENV["TESTOPTS"] = "-v" unconditionally so that rake -v test would propagate verbosity to the test runner. The unconditional assignment also overwrote values set by other tools such as ci_reporter_minitest, breaking any workflow that relied on TESTOPTS being populated before TestTask ran.

Move the -v injection out of FileUtilsExt.verbose and into Rake::TestTask#option_list. The task block now computes an effective verbose flag from @verbose or the global FileUtilsExt.verbose_flag, passes it to option_list(verbose:), and the option list appends -v to the existing TESTOPTS only when it is not already present. This keeps the PR #394 behavior for rake -v and t.verbose = true while no longer clobbering pre-set TESTOPTS values.

Fixes #722.

Rake 13.4.0 made `FileUtilsExt.verbose(true)` set `ENV["TESTOPTS"] = "-v"`
unconditionally so that `rake -v test` would propagate verbosity to the
test runner. The unconditional assignment also overwrote values set by
other tools such as `ci_reporter_minitest`, breaking any workflow that
relied on `TESTOPTS` being populated before `TestTask` ran.

Move the `-v` injection out of `FileUtilsExt.verbose` and into
`Rake::TestTask#option_list`. The task block now computes an effective
verbose flag from `@verbose` or the global `FileUtilsExt.verbose_flag`,
passes it to `option_list(verbose:)`, and the option list appends `-v`
to the existing `TESTOPTS` only when it is not already present. This
keeps the PR #394 behavior for `rake -v` and `t.verbose = true` while
no longer clobbering pre-set `TESTOPTS` values.

Fixes #722.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 16, 2026 04:15
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a regression where enabling verbose mode (rake -v / t.verbose = true) could clobber a pre-existing ENV["TESTOPTS"] (e.g., set by ci_reporter_minitest). It does this by removing TESTOPTS mutation from FileUtilsExt.verbose and instead computing/appending -v within Rake::TestTask’s option handling.

Changes:

  • Stop setting ENV["TESTOPTS"] inside Rake::FileUtilsExt.verbose.
  • Compute an “effective verbose” flag in Rake::TestTask#define (task-local verbose OR global -v) and pass it into option_list.
  • Update/add tests to validate option_list appends -v without overwriting existing TESTOPTS.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
lib/rake/testtask.rb Moves -v injection into option_list(verbose:) and uses an effective verbose flag during task execution.
lib/rake/file_utils_ext.rb Removes the unconditional ENV["TESTOPTS"] = "-v" side effect from verbose.
test/test_rake_test_task.rb Adds coverage for option_list behavior with/without TESTOPTS and duplicate -v handling.
test/test_rake_file_utils.rb Removes assertions/cleanup tied to FileUtilsExt.verbose mutating TESTOPTS.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +194 to +196
def test_option_list_verbose_without_testopts
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v", tt.option_list
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_option_list_verbose_without_testopts assumes ENV["TESTOPTS"] is unset; if a developer/CI environment has TESTOPTS pre-populated, this assertion will fail. Consider saving the original value and clearing/restoring TESTOPTS within this test (similar to the other tests here).

Suggested change
def test_option_list_verbose_without_testopts
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v", tt.option_list
def test_option_list_verbose_without_testopts
testopts = ENV["TESTOPTS"]
ENV.delete "TESTOPTS"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v", tt.option_list
ensure
if testopts
ENV["TESTOPTS"] = testopts
else
ENV.delete "TESTOPTS"
end

Copilot uses AI. Check for mistakes.
Comment thread test/test_rake_test_task.rb Outdated
Comment on lines +200 to +220
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
ENV.delete "TESTOPTS"
end

def test_option_list_not_verbose_with_testopts
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
end

def test_option_list_skips_duplicate_v
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test unconditionally ENV.delete "TESTOPTS" in ensure. If TESTOPTS was already set in the process environment, this will clobber it for subsequent tests. Prefer capturing the previous value and restoring it in ensure (set it back or delete only if it was originally absent).

Suggested change
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
ENV.delete "TESTOPTS"
end
def test_option_list_not_verbose_with_testopts
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
end
def test_option_list_skips_duplicate_v
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
old_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
if old_testopts
ENV["TESTOPTS"] = old_testopts
else
ENV.delete "TESTOPTS"
end
end
def test_option_list_not_verbose_with_testopts
old_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
if old_testopts
ENV["TESTOPTS"] = old_testopts
else
ENV.delete "TESTOPTS"
end
end
def test_option_list_skips_duplicate_v
old_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
if old_testopts
ENV["TESTOPTS"] = old_testopts
else
ENV.delete "TESTOPTS"
end

Copilot uses AI. Check for mistakes.
Comment thread test/test_rake_test_task.rb Outdated
Comment on lines +200 to +220
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
ENV.delete "TESTOPTS"
end

def test_option_list_not_verbose_with_testopts
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
end

def test_option_list_skips_duplicate_v
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test unconditionally ENV.delete "TESTOPTS" in ensure. If TESTOPTS was already set in the process environment, this will clobber it for subsequent tests. Prefer capturing the previous value and restoring it in ensure (set it back or delete only if it was originally absent).

Suggested change
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
ENV.delete "TESTOPTS"
end
def test_option_list_not_verbose_with_testopts
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
end
def test_option_list_skips_duplicate_v
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
previous_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
if previous_testopts.nil?
ENV.delete "TESTOPTS"
else
ENV["TESTOPTS"] = previous_testopts
end
end
def test_option_list_not_verbose_with_testopts
previous_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
if previous_testopts.nil?
ENV.delete "TESTOPTS"
else
ENV["TESTOPTS"] = previous_testopts
end
end
def test_option_list_skips_duplicate_v
previous_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
if previous_testopts.nil?
ENV.delete "TESTOPTS"
else
ENV["TESTOPTS"] = previous_testopts
end

Copilot uses AI. Check for mistakes.
Comment thread test/test_rake_test_task.rb Outdated
Comment on lines +200 to +220
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
ENV.delete "TESTOPTS"
end

def test_option_list_not_verbose_with_testopts
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
end

def test_option_list_skips_duplicate_v
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test unconditionally ENV.delete "TESTOPTS" in ensure. If TESTOPTS was already set in the process environment, this will clobber it for subsequent tests. Prefer capturing the previous value and restoring it in ensure (set it back or delete only if it was originally absent).

Suggested change
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
ENV.delete "TESTOPTS"
end
def test_option_list_not_verbose_with_testopts
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
end
def test_option_list_skips_duplicate_v
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
ENV.delete "TESTOPTS"
original_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "--ci-reporter -v", tt.option_list
ensure
if original_testopts.nil?
ENV.delete "TESTOPTS"
else
ENV["TESTOPTS"] = original_testopts
end
end
def test_option_list_not_verbose_with_testopts
original_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "--ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = false }
assert_equal "--ci-reporter", tt.option_list
ensure
if original_testopts.nil?
ENV.delete "TESTOPTS"
else
ENV["TESTOPTS"] = original_testopts
end
end
def test_option_list_skips_duplicate_v
original_testopts = ENV["TESTOPTS"]
ENV["TESTOPTS"] = "-v --ci-reporter"
tt = Rake::TestTask.new { |t| t.verbose = true }
assert_equal "-v --ci-reporter", tt.option_list
ensure
if original_testopts.nil?
ENV.delete "TESTOPTS"
else
ENV["TESTOPTS"] = original_testopts
end

Copilot uses AI. Check for mistakes.
Copilot review on #723 pointed out that the new option_list tests
either assumed TESTOPTS was unset or unconditionally deleted it in
ensure, which would clobber a pre-existing TESTOPTS and leak state
across tests. Save and restore the previous value from setup/teardown
so each test starts from a clean slate without losing the process
environment value, and drop the now-redundant ensure blocks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hsbt hsbt merged commit 46038e7 into master Apr 16, 2026
79 checks passed
@hsbt hsbt deleted the fix/testopts-preserve-existing-value branch April 16, 2026 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ENV["TESTOPTS"] overwritten in rake 13.4.0+, breaking ci_reporter_minitest

2 participants