From cf153540a612e4227cb8f2c74011e380a37957df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Fri, 14 Nov 2025 11:37:36 -0600 Subject: [PATCH 01/10] chore: update rubocop todo configuration Update rubocop todo file with latest offense counts and configurations --- test/lib/skunk/cli/options/argv_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/lib/skunk/cli/options/argv_test.rb b/test/lib/skunk/cli/options/argv_test.rb index 987b93b..4c8ee48 100644 --- a/test/lib/skunk/cli/options/argv_test.rb +++ b/test/lib/skunk/cli/options/argv_test.rb @@ -33,7 +33,6 @@ after do Skunk::Config.reset end - context "passing --formats option" do let(:argv) { ["--formats=json,html"] } From 49bc1e53a9170d703f0af4fc11ae5f648e096f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Fri, 14 Nov 2025 16:56:40 -0600 Subject: [PATCH 02/10] refactor(config): centralize output path configuration and simplify printing Move output path configuration to Skunk::Config and remove file output logic from Application#print Update tests and documentation to reflect changes in output path handling Even if the default path where the JSON and HTML reports are generated are `tmp/rubycritic` you can now modify them. --- CHANGELOG.md | 1 + README.md | 6 +- bin/console | 3 +- lib/skunk/cli/application.rb | 8 +-- lib/skunk/cli/options/argv.rb | 69 ++++++------------- lib/skunk/config.rb | 13 ++++ lib/skunk/generators/console_report.rb | 16 ++++- lib/skunk/generators/html/overview.rb | 4 ++ lib/skunk/generators/json/simple.rb | 4 +- test/lib/skunk/cli/options/argv_test.rb | 26 ++++--- test/lib/skunk/commands/help_test.rb | 4 +- test/lib/skunk/config_test.rb | 9 +++ .../skunk/generators/console_report_test.rb | 15 ++++ .../skunk/generators/html/overview_test.rb | 26 +++++++ 14 files changed, 127 insertions(+), 77 deletions(-) create mode 100644 test/lib/skunk/generators/html/overview_test.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 91c4480..eb65b86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## main [(unreleased)](https://github.com/fastruby/skunk/compare/v0.5.4...HEAD) +* [FEATURE: Indicate `--out PATH` location](https://github.com/fastruby/skunk/pull/131) * [ENHANCEMENT: Support SimpleCov 1.0](https://github.com/fastruby/skunk/pull/140) * BUGFIX: Pin path_expander < 2.0 for Ruby 2.7 compatibility * [FEATURE: Add `--formats` CLI flag to select report formats (json, html, console)](https://github.com/fastruby/skunk/pull/130) diff --git a/README.md b/README.md index 1792f04..21a93ca 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Run `skunk -h` to check out the help options: ``` Usage: skunk [options] [paths] -b, --branch BRANCH Set branch to compare - -o, --out FILE Output report to file + -o, --out PATH Output report path -v, --version Show gem's version -h, --help Show this message ``` @@ -127,7 +127,9 @@ To only run skunk on specific folders, pass a list of directories in the command ### Generate JSON report in background -When the Skunk command is run, it will generate a JSON report file in the `RubyCritic::Config.root` location. +When the Skunk command is run, it will generate a JSON report file in the configured output path. + +Skunk also writes the console report to `skunk_console.txt` under the same output path. ### Comparing feature branches diff --git a/bin/console b/bin/console index 00c2b0a..623d374 100755 --- a/bin/console +++ b/bin/console @@ -13,5 +13,6 @@ puts ARGV.inspect require "skunk/cli/application" require "skunk/config" -Skunk::Config.formats = %i[json console html] +Skunk::Config.formats = %i[json console html] # supported output formats +Skunk::Config.root = "tmp/rubycritic" # default path to store generated JSON and HTML reports. Skunk::Cli::Application.new(ARGV).execute diff --git a/lib/skunk/cli/application.rb b/lib/skunk/cli/application.rb index d7c00b4..482178d 100644 --- a/lib/skunk/cli/application.rb +++ b/lib/skunk/cli/application.rb @@ -50,14 +50,8 @@ def warn_coverage_info warn "warning: Having no coverage metrics will make your SkunkScore worse." end - # :reek:NilCheck def print(message) - filename = @parsed_options[:output_filename] - if filename.nil? - $stdout.puts(message) - else - File.open(filename, "a") { |file| file << message } - end + $stdout.puts(message) end end end diff --git a/lib/skunk/cli/options/argv.rb b/lib/skunk/cli/options/argv.rb index 26825cd..e43038e 100644 --- a/lib/skunk/cli/options/argv.rb +++ b/lib/skunk/cli/options/argv.rb @@ -10,59 +10,32 @@ class Options # Extends RubyCritic::Cli::Options::Argv to parse a subset of the # parameters accepted by RubyCritic class Argv < RubyCritic::Cli::Options::Argv - # :reek:Attribute - attr_accessor :output_filename - def parse parser.new do |opts| opts.banner = "Usage: skunk [options] [paths]\n" - add_branch_option(opts) - add_output_option(opts) - add_formats_option(opts) - add_tail_options(opts) + opts.on("-b", "--branch BRANCH", "Set branch to compare") do |branch| + self.base_branch = String(branch) + set_current_branch + self.mode = :compare_branches + end + + opts.on("-o", "--out PATH", "Output report path") do |path| + Skunk::Config.root = path + end + + opts.on("-f", "--formats json,html,console", Array, "Output formats: json,html,console") do |list| + Skunk::Config.formats = Array(list).map(&:to_sym) + end + + opts.on_tail("-v", "--version", "Show gem's version") do + self.mode = :version + end + + opts.on_tail("-h", "--help", "Show this message") do + self.mode = :help + end end.parse!(@argv) end - - def to_h - super.merge(output_filename: output_filename) - end - - private - - def add_branch_option(opts) - opts.on("-b", "--branch BRANCH", "Set branch to compare") do |branch| - self.base_branch = String(branch) - set_current_branch - self.mode = :compare_branches - end - end - - def add_output_option(opts) - opts.on("-o", "--out FILE", "Output report to file") do |filename| - self.output_filename = filename - end - end - - def add_formats_option(opts) - opts.on( - "-f", - "--formats json,html,console", - Array, - "Output formats: json,html,console (default: console)" - ) do |list| - Skunk::Config.formats = Array(list).map(&:to_sym) - end - end - - def add_tail_options(opts) - opts.on_tail("-v", "--version", "Show gem's version") do - self.mode = :version - end - - opts.on_tail("-h", "--help", "Show this message") do - self.mode = :help - end - end end end end diff --git a/lib/skunk/config.rb b/lib/skunk/config.rb index 769590d..aeec57b 100644 --- a/lib/skunk/config.rb +++ b/lib/skunk/config.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "rubycritic/configuration" + module Skunk # Utility module for format validation module FormatValidator @@ -28,10 +30,12 @@ class Configuration def initialize @formats = [DEFAULT_FORMAT] + @root = RubyCritic::Config.root end def set(options = {}) self.formats = options[:formats] if options.key?(:formats) + self.root = options[:root] if options.key?(:root) end # Get the configured formats @@ -46,6 +50,14 @@ def formats=(format_list) @formats = [DEFAULT_FORMAT] if @formats.empty? end + def root + @root || File.expand_path("tmp/rubycritic", Dir.pwd) + end + + def root=(path) + @root = path.nil? || path.to_s.empty? ? nil : File.expand_path(path.to_s) + end + # Add a format to the existing list # @param format [Symbol] Format to add def add_format(format) @@ -77,6 +89,7 @@ def supported_formats # Reset to default configuration def reset @formats = [DEFAULT_FORMAT] + @root = RubyCritic::Config.root end end diff --git a/lib/skunk/generators/console_report.rb b/lib/skunk/generators/console_report.rb index 3b1958e..2154f0e 100644 --- a/lib/skunk/generators/console_report.rb +++ b/lib/skunk/generators/console_report.rb @@ -2,8 +2,11 @@ require "erb" require "terminal-table" +require "pathname" +require "fileutils" require "skunk/generators/console/simple" +require "skunk/config" module Skunk module Generator @@ -14,7 +17,10 @@ def initialize(analysed_modules) end def generate_report - puts generator.render + content = generator.render + puts content + FileUtils.mkdir_p(file_directory) + File.write(file_pathname, content) end private @@ -22,6 +28,14 @@ def generate_report def generator @generator ||= Skunk::Generator::Console::Simple.new(@analysed_modules) end + + def file_directory + @file_directory ||= Pathname.new(Skunk::Config.root) + end + + def file_pathname + Pathname.new(file_directory).join("skunk_console.txt") + end end end end diff --git a/lib/skunk/generators/html/overview.rb b/lib/skunk/generators/html/overview.rb index 78e7d2b..a3c60f8 100644 --- a/lib/skunk/generators/html/overview.rb +++ b/lib/skunk/generators/html/overview.rb @@ -49,6 +49,10 @@ def files FileData.new(module_data) end end + + def root_directory + @root_directory ||= Pathname.new(Skunk::Config.root) + end end end end diff --git a/lib/skunk/generators/json/simple.rb b/lib/skunk/generators/json/simple.rb index 0a686ce..353d767 100644 --- a/lib/skunk/generators/json/simple.rb +++ b/lib/skunk/generators/json/simple.rb @@ -2,7 +2,7 @@ require "pathname" -require "rubycritic/configuration" +require "skunk/config" require "skunk/rubycritic/analysed_modules_collection" module Skunk @@ -25,7 +25,7 @@ def data end def file_directory - @file_directory ||= Pathname.new(RubyCritic::Config.root) + @file_directory ||= Pathname.new(Skunk::Config.root) end def file_pathname diff --git a/test/lib/skunk/cli/options/argv_test.rb b/test/lib/skunk/cli/options/argv_test.rb index 4c8ee48..bcc421e 100644 --- a/test/lib/skunk/cli/options/argv_test.rb +++ b/test/lib/skunk/cli/options/argv_test.rb @@ -5,23 +5,21 @@ require "skunk/cli/options/argv" describe Skunk::Cli::Options::Argv do - describe "#output_filename" do - context "passing --out=FILE options" do - let(:argv) { ["--out=file.txt"] } + describe "--out path" do + after do + Skunk::Config.reset + end - it "parses passed filename" do - parser = Skunk::Cli::Options::Argv.new(argv) - parser.parse - _(parser.output_filename).must_equal "file.txt" - end + it "sets Skunk::Config.root to the provided path" do + parser = Skunk::Cli::Options::Argv.new(["--out=tmp/custom"]) + parser.parse + _(Skunk::Config.root).must_match(/tmp\/custom$/) end - context "not passing the --out option" do - it "is nil" do - parser = Skunk::Cli::Options::Argv.new([]) - parser.parse - _(parser.output_filename).must_be_nil - end + it "defaults to tmp/rubycritic when not provided" do + parser = Skunk::Cli::Options::Argv.new([]) + parser.parse + _(Skunk::Config.root).must_match(/tmp\/rubycritic$/) end end diff --git a/test/lib/skunk/commands/help_test.rb b/test/lib/skunk/commands/help_test.rb index 4f25c0d..6ff3d24 100644 --- a/test/lib/skunk/commands/help_test.rb +++ b/test/lib/skunk/commands/help_test.rb @@ -11,8 +11,8 @@ <<~HELP Usage: skunk [options] [paths] -b, --branch BRANCH Set branch to compare - -o, --out FILE Output report to file - -f, --formats json,html,console Output formats: json,html,console (default: console) + -o, --out PATH Output report path + -f, --formats json,html,console Output formats: json,html,console -v, --version Show gem's version -h, --help Show this message HELP diff --git a/test/lib/skunk/config_test.rb b/test/lib/skunk/config_test.rb index e708eae..d79f438 100644 --- a/test/lib/skunk/config_test.rb +++ b/test/lib/skunk/config_test.rb @@ -85,5 +85,14 @@ def test_reset Config.reset assert_equal [:console], Config.formats end + + def test_default_root + assert_match(/tmp\/rubycritic$/, Config.root) + end + + def test_set_root_expands_path + Config.root = "tmp/custom" + assert_equal File.expand_path("tmp/custom", Dir.pwd), Config.root + end end end diff --git a/test/lib/skunk/generators/console_report_test.rb b/test/lib/skunk/generators/console_report_test.rb index 6f880de..39c98e9 100644 --- a/test/lib/skunk/generators/console_report_test.rb +++ b/test/lib/skunk/generators/console_report_test.rb @@ -187,6 +187,21 @@ def test_generate_report_calls_generator_render assert_equal "test output\n", output mock_generator.verify end + + def test_generate_report_writes_console_file + Skunk::Config.root = "tmp/console_report" + begin + path = File.join(Skunk::Config.root, "skunk_console.txt") + File.delete(path) if File.exist?(path) + + @console_report.generate_report + + assert File.exist?(path) + assert_includes File.read(path), "SkunkScore Total" + ensure + FileUtils.rm_rf(Skunk::Config.root) + end + end end end end diff --git a/test/lib/skunk/generators/html/overview_test.rb b/test/lib/skunk/generators/html/overview_test.rb new file mode 100644 index 0000000..5f5d018 --- /dev/null +++ b/test/lib/skunk/generators/html/overview_test.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require "minitest/autorun" +require "skunk/generators/html/overview" +require "skunk/config" + +module Skunk + module Generator + module Html + class OverviewTest < Minitest::Test + def teardown + Skunk::Config.reset + end + + def test_root_directory_uses_skunk_config_root + Skunk::Config.root = "tmp/custom_html" + analysed_modules = Minitest::Mock.new + generator = Overview.new(analysed_modules) + + root = generator.send(:root_directory) + assert_equal File.expand_path("tmp/custom_html", Dir.pwd), root.to_s + end + end + end + end +end \ No newline at end of file From d1f5b57f9bc67acd2fc01fdf2ebd42b6bb08cf50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Mon, 17 Nov 2025 15:20:17 -0600 Subject: [PATCH 03/10] Use same name on JSON, Console and HTML reports Skunk_report (txt,json,html) --- README.md | 2 +- lib/skunk/generators/console_report.rb | 2 +- lib/skunk/generators/html/overview.rb | 2 +- test/lib/skunk/generators/console_report_test.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 21a93ca..e16be5c 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ To only run skunk on specific folders, pass a list of directories in the command When the Skunk command is run, it will generate a JSON report file in the configured output path. -Skunk also writes the console report to `skunk_console.txt` under the same output path. +Skunk also writes the console report to `skunk_report.txt` under the same output path. ### Comparing feature branches diff --git a/lib/skunk/generators/console_report.rb b/lib/skunk/generators/console_report.rb index 2154f0e..774eae7 100644 --- a/lib/skunk/generators/console_report.rb +++ b/lib/skunk/generators/console_report.rb @@ -34,7 +34,7 @@ def file_directory end def file_pathname - Pathname.new(file_directory).join("skunk_console.txt") + Pathname.new(file_directory).join("skunk_report.txt") end end end diff --git a/lib/skunk/generators/html/overview.rb b/lib/skunk/generators/html/overview.rb index a3c60f8..fec1033 100644 --- a/lib/skunk/generators/html/overview.rb +++ b/lib/skunk/generators/html/overview.rb @@ -25,7 +25,7 @@ def initialize(analysed_modules) end def file_name - "skunk_overview.html" + "skunk_report.html" end def render diff --git a/test/lib/skunk/generators/console_report_test.rb b/test/lib/skunk/generators/console_report_test.rb index 39c98e9..c63e9d5 100644 --- a/test/lib/skunk/generators/console_report_test.rb +++ b/test/lib/skunk/generators/console_report_test.rb @@ -191,7 +191,7 @@ def test_generate_report_calls_generator_render def test_generate_report_writes_console_file Skunk::Config.root = "tmp/console_report" begin - path = File.join(Skunk::Config.root, "skunk_console.txt") + path = File.join(Skunk::Config.root, "skunk_report.txt") File.delete(path) if File.exist?(path) @console_report.generate_report From 9776e93c2cb7e10d1458d2bdbdbe867c5a31f7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Mon, 17 Nov 2025 15:57:13 -0600 Subject: [PATCH 04/10] test: fix share report sharing output --- lib/skunk/commands/status_sharer.rb | 6 ++++- test/lib/skunk/application_test.rb | 35 ++++++++++++++++------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lib/skunk/commands/status_sharer.rb b/lib/skunk/commands/status_sharer.rb index f46971a..653e21b 100644 --- a/lib/skunk/commands/status_sharer.rb +++ b/lib/skunk/commands/status_sharer.rb @@ -73,7 +73,11 @@ def share_enabled? # @return [Boolean] Check if share URL is empty def share_url_empty? - ENV["SHARE_URL"].to_s == "" + share_url == "" + end + + def share_url + ENV["SHARE_URL"].to_s end def payload diff --git a/test/lib/skunk/application_test.rb b/test/lib/skunk/application_test.rb index 8055646..5e2cc3f 100644 --- a/test/lib/skunk/application_test.rb +++ b/test/lib/skunk/application_test.rb @@ -2,6 +2,7 @@ require "test_helper" require "skunk/cli/application" +require "skunk/commands/default" require "rubycritic/core/analysed_module" require "minitest/stub_const" @@ -46,14 +47,15 @@ end context "when passing an environment variable SHARE=true" do - let(:argv) { ["--out=tmp/shared_report.txt", "samples/rubycritic"] } + let(:argv) { ["--out=tmp", "samples/rubycritic"] } let(:success_code) { 0 } - let(:shared_message) do - "Shared at: https://skunk.fastruby.io/j" - end + let(:generated_message) { "Generated with Skunk" } + let(:shared_message) { "Shared at: https://skunk.fastruby.io/j" } + let(:share_url) { "https://skunk.fastruby.io" } + let(:report_path) { "tmp/skunk_report.txt" } around do |example| - stub_request(:post, "https://skunk.fastruby.io/reports").to_return( + stub_request(:post, "#{share_url}/reports").to_return( status: 200, body: '{"id":"j"}', headers: { "Content-Type" => "application/json" } @@ -62,20 +64,21 @@ end it "share report to default server" do - FileUtils.rm("tmp/shared_report.txt", force: true) + FileUtils.rm(report_path, force: true) FileUtils.mkdir_p("tmp") - RubyCritic::AnalysedModule.stub_any_instance(:churn, 1) do - RubyCritic::AnalysedModule.stub_any_instance(:coverage, 100.0) do - Skunk::Command::Default.stub_any_instance(:share_enabled?, true) do - Skunk::Command::StatusSharer.stub_any_instance(:not_sharing?, false) do - Skunk::Command::StatusSharer.stub_any_instance(:share, "Shared at: https://skunk.fastruby.io/j") do - result = application.execute - _(result).must_equal success_code - output = File.read("tmp/shared_report.txt") - _(output).must_include(shared_message) - end + Skunk::Command::Default.stub_any_instance(:share_enabled?, true) do + Skunk::Command::StatusSharer.stub_any_instance(:share_url, share_url) do + Skunk::Command::StatusSharer.stub_any_instance(:share, "Shared at: #{share_url}/j") do + stdout = capture_stdout do + result = application.execute + _(result).must_equal success_code end + _(File.exist?(report_path)).must_equal true + file_output = File.read(report_path) + + _(file_output).must_include(generated_message) + _(stdout).must_include(shared_message) end end end From b66b365b3f0bd728c512e656090010d429783192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Thu, 5 Feb 2026 23:27:39 -0600 Subject: [PATCH 05/10] refactor: apply review feedback on --out flag - Write reporter output with $stdout.puts directly instead of a private print wrapper in the application - Memoize the SHARE_URL lookups in StatusSharer and use String#empty? - Simplify Skunk::Config#root= now that to_s covers the nil case - Assert the default root against an explicit RubyCritic::Config.root instead of a path regex, restoring the prior value afterwards --- lib/skunk/cli/application.rb | 8 ++------ lib/skunk/commands/status_sharer.rb | 6 +++--- lib/skunk/config.rb | 3 ++- samples/rubycritic/compare/skunk_report.txt | 1 + test/lib/skunk/cli/options/argv_test.rb | 17 +++++++++++++---- test/lib/skunk/config_test.rb | 9 ++++++++- test/lib/skunk/generators/html/overview_test.rb | 2 +- 7 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 samples/rubycritic/compare/skunk_report.txt diff --git a/lib/skunk/cli/application.rb b/lib/skunk/cli/application.rb index 482178d..06df963 100644 --- a/lib/skunk/cli/application.rb +++ b/lib/skunk/cli/application.rb @@ -31,10 +31,10 @@ def execute command = Skunk::CommandFactory.create(@parsed_options) reporter = command.execute - print(reporter.status_message) + $stdout.puts(reporter.status_message) if command.sharing? share_status_message = command.share(reporter) - print(share_status_message) + $stdout.puts(share_status_message) end reporter.status @@ -49,10 +49,6 @@ def warn_coverage_info warn "warning: Couldn't find coverage info at #{COVERAGE_FILE}." warn "warning: Having no coverage metrics will make your SkunkScore worse." end - - def print(message) - $stdout.puts(message) - end end end end diff --git a/lib/skunk/commands/status_sharer.rb b/lib/skunk/commands/status_sharer.rb index 653e21b..6e87d05 100644 --- a/lib/skunk/commands/status_sharer.rb +++ b/lib/skunk/commands/status_sharer.rb @@ -35,7 +35,7 @@ def share # :reek:UtilityFunction def base_url - ENV["SHARE_URL"] || DEFAULT_URL + @base_url ||= ENV["SHARE_URL"] || DEFAULT_URL end def json_summary @@ -73,11 +73,11 @@ def share_enabled? # @return [Boolean] Check if share URL is empty def share_url_empty? - share_url == "" + share_url.empty? end def share_url - ENV["SHARE_URL"].to_s + @share_url ||= ENV["SHARE_URL"].to_s end def payload diff --git a/lib/skunk/config.rb b/lib/skunk/config.rb index aeec57b..1cfb060 100644 --- a/lib/skunk/config.rb +++ b/lib/skunk/config.rb @@ -55,7 +55,8 @@ def root end def root=(path) - @root = path.nil? || path.to_s.empty? ? nil : File.expand_path(path.to_s) + path_str = path.to_s + @root = path_str.empty? ? nil : File.expand_path(path_str) end # Add a format to the existing list diff --git a/samples/rubycritic/compare/skunk_report.txt b/samples/rubycritic/compare/skunk_report.txt new file mode 100644 index 0000000..0866893 --- /dev/null +++ b/samples/rubycritic/compare/skunk_report.txt @@ -0,0 +1 @@ +test output \ No newline at end of file diff --git a/test/lib/skunk/cli/options/argv_test.rb b/test/lib/skunk/cli/options/argv_test.rb index bcc421e..04850fe 100644 --- a/test/lib/skunk/cli/options/argv_test.rb +++ b/test/lib/skunk/cli/options/argv_test.rb @@ -13,13 +13,22 @@ it "sets Skunk::Config.root to the provided path" do parser = Skunk::Cli::Options::Argv.new(["--out=tmp/custom"]) parser.parse - _(Skunk::Config.root).must_match(/tmp\/custom$/) + _(Skunk::Config.root).must_match(%r{tmp/custom$}) end it "defaults to tmp/rubycritic when not provided" do - parser = Skunk::Cli::Options::Argv.new([]) - parser.parse - _(Skunk::Config.root).must_match(/tmp\/rubycritic$/) + begin + prior_root = RubyCritic::Config.root + default_root = File.expand_path("tmp/rubycritic_default", Dir.pwd) + RubyCritic::Config.root = default_root + Skunk::Config.reset + parser = Skunk::Cli::Options::Argv.new([]) + parser.parse + _(Skunk::Config.root).must_equal default_root + ensure + RubyCritic::Config.root = prior_root || default_root + Skunk::Config.reset + end end end diff --git a/test/lib/skunk/config_test.rb b/test/lib/skunk/config_test.rb index d79f438..967e8e1 100644 --- a/test/lib/skunk/config_test.rb +++ b/test/lib/skunk/config_test.rb @@ -87,7 +87,14 @@ def test_reset end def test_default_root - assert_match(/tmp\/rubycritic$/, Config.root) + prior_root = RubyCritic::Config.root + default_root = File.expand_path("tmp/rubycritic_default", Dir.pwd) + RubyCritic::Config.root = default_root + Config.reset + assert_equal default_root, Config.root + ensure + RubyCritic::Config.root = prior_root || default_root + Config.reset end def test_set_root_expands_path diff --git a/test/lib/skunk/generators/html/overview_test.rb b/test/lib/skunk/generators/html/overview_test.rb index 5f5d018..05ecf5f 100644 --- a/test/lib/skunk/generators/html/overview_test.rb +++ b/test/lib/skunk/generators/html/overview_test.rb @@ -23,4 +23,4 @@ def test_root_directory_uses_skunk_config_root end end end -end \ No newline at end of file +end From 81f923a42c59b7f6d87ba01c7eb76cb78fc30ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Tue, 8 Sep 2026 12:18:57 -0600 Subject: [PATCH 06/10] style: restore RubyCritic root via an after hook in argv test RuboCop derives TargetRubyVersion from the gemspec's required_ruby_version (>= 2.4.0), so a begin/ensure spanning the whole block body trips Style/RedundantBegin on the RuboCop 1.31/1.50 resolved for Ruby 2.6 and 2.7, and the block level ensure that would replace it is 2.6+ syntax that RuboCop 1.81 rejects under the 2.4 parser. Move the restore into a minitest after hook, which is valid on every supported Ruby. --- test/lib/skunk/cli/options/argv_test.rb | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/test/lib/skunk/cli/options/argv_test.rb b/test/lib/skunk/cli/options/argv_test.rb index 04850fe..ba703d4 100644 --- a/test/lib/skunk/cli/options/argv_test.rb +++ b/test/lib/skunk/cli/options/argv_test.rb @@ -6,7 +6,12 @@ describe Skunk::Cli::Options::Argv do describe "--out path" do + before do + @prior_root = RubyCritic::Config.root + end + after do + RubyCritic::Config.root = @prior_root if @prior_root Skunk::Config.reset end @@ -17,18 +22,12 @@ end it "defaults to tmp/rubycritic when not provided" do - begin - prior_root = RubyCritic::Config.root - default_root = File.expand_path("tmp/rubycritic_default", Dir.pwd) - RubyCritic::Config.root = default_root - Skunk::Config.reset - parser = Skunk::Cli::Options::Argv.new([]) - parser.parse - _(Skunk::Config.root).must_equal default_root - ensure - RubyCritic::Config.root = prior_root || default_root - Skunk::Config.reset - end + default_root = File.expand_path("tmp/rubycritic_default", Dir.pwd) + RubyCritic::Config.root = default_root + Skunk::Config.reset + parser = Skunk::Cli::Options::Argv.new([]) + parser.parse + _(Skunk::Config.root).must_equal default_root end end From ab2a13e5e0b4c71353b2d055523373a48b43b922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Tue, 8 Sep 2026 12:32:23 -0600 Subject: [PATCH 07/10] build: pin rubocop and drop stray sample report Every CI job resolves its own Gemfile.lock, so an unpinned rubocop meant Ruby 2.7 linted with 1.31, 2.6 with 1.50 and 3.x with 1.81, and a cop whose behavior changed between them failed the build on the old rubies only. Pin the version so the matrix lints against one rubocop. Rubies older than 3.1 cannot install the pin: reek and rubycritic hold parser below 3.3 there, while rubocop 1.60 and up require it. The Gemfile leaves rubocop out on those rubies and the Rakefile drops the lint task when the require fails, so 2.6, 2.7 and 3.0 still run the tests and reek. The gemspec listed rubocop as an unpinned development dependency, which is what drove the resolution, so drop it and let the Gemfile hold the pin. It stays a Gemfile-only dev tool, like it already was in practice. Also drop samples/rubycritic/compare/skunk_report.txt, a stray "test output" file no test reads. --- Gemfile | 8 +++++++- Rakefile | 15 +++++++++++---- samples/rubycritic/compare/skunk_report.txt | 1 - skunk.gemspec | 1 - test/lib/skunk/generators/console_report_test.rb | 7 +++++++ 5 files changed, 25 insertions(+), 7 deletions(-) delete mode 100644 samples/rubycritic/compare/skunk_report.txt diff --git a/Gemfile b/Gemfile index 6d1cc79..be2e125 100644 --- a/Gemfile +++ b/Gemfile @@ -8,4 +8,10 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } gemspec gem "reek" -gem "rubocop" + +# Pinned so the CI matrix lints against one RuboCop instead of each Ruby +# resolving whatever version it happens to support. Rubies older than 3.1 cannot +# install it: reek and rubycritic hold parser below 3.3 there, while RuboCop +# 1.60 and up require it, so those rubies get no RuboCop and the Rakefile drops +# the lint task for them. They still run the tests and reek. +gem "rubocop", "~> 1.81.0" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.1") diff --git a/Rakefile b/Rakefile index 7d65feb..defea95 100644 --- a/Rakefile +++ b/Rakefile @@ -2,7 +2,6 @@ require "bundler/gem_tasks" require "rake/testtask" -require "rubocop/rake_task" require "reek/rake/task" require "rubycritic/rake_task" @@ -12,12 +11,20 @@ Rake::TestTask.new do |task| task.pattern = "test/**/*_test.rb" end -RuboCop::RakeTask.new - Reek::Rake::Task.new RubyCritic::RakeTask.new do |task| task.paths = FileList["lib/**/*.rb"] end -task default: %i[test reek rubocop] +lint_tasks = [] + +begin + require "rubocop/rake_task" + RuboCop::RakeTask.new + lint_tasks << :rubocop +rescue LoadError + # RuboCop is not installed on the rubies the Gemfile skips the pin for. +end + +task default: %i[test reek] + lint_tasks diff --git a/samples/rubycritic/compare/skunk_report.txt b/samples/rubycritic/compare/skunk_report.txt deleted file mode 100644 index 0866893..0000000 --- a/samples/rubycritic/compare/skunk_report.txt +++ /dev/null @@ -1 +0,0 @@ -test output \ No newline at end of file diff --git a/skunk.gemspec b/skunk.gemspec index ad8f919..78133d5 100644 --- a/skunk.gemspec +++ b/skunk.gemspec @@ -50,7 +50,6 @@ Gem::Specification.new do |spec| spec.add_development_dependency "minitest-stub-const", "~> 0.6" spec.add_development_dependency "rake", "~> 13.0" spec.add_development_dependency "reek" - spec.add_development_dependency "rubocop" spec.add_development_dependency "simplecov", ">= 0.18", "< 2" spec.add_development_dependency "simplecov-console", "0.5.0" spec.add_development_dependency "webmock", "~> 3.20.0" diff --git a/test/lib/skunk/generators/console_report_test.rb b/test/lib/skunk/generators/console_report_test.rb index c63e9d5..9ac51a8 100644 --- a/test/lib/skunk/generators/console_report_test.rb +++ b/test/lib/skunk/generators/console_report_test.rb @@ -170,6 +170,10 @@ def test_generator_returns_console_simple_instance end def test_generate_report_calls_generator_render + # Write the report file under tmp so the run does not leave one behind + # in samples/ + Skunk::Config.root = "tmp/console_report_render" + # Test that generate_report calls the generator's render method @console_report.send(:generator) @@ -186,6 +190,9 @@ def test_generate_report_calls_generator_render assert_equal "test output\n", output mock_generator.verify + ensure + FileUtils.rm_rf(Skunk::Config.root) + Skunk::Config.reset end def test_generate_report_writes_console_file From 25e90a73feecd291f7b1b1238bda3034b60a90ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Tue, 8 Sep 2026 12:53:53 -0600 Subject: [PATCH 08/10] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e16be5c..6003eb8 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ You can choose one or more formats from the command line: ``` skunk --formats=json -skunk --f json,html +skunk -f json,html skunk --formats console,json ``` From b6ec76c1e723458ac9c226ce902111e57c2745f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Mon, 12 Oct 2026 16:22:24 -0600 Subject: [PATCH 09/10] fix(cli): keep --out separate from RubyCritic root --out now sets only Skunk::Config.root. When it is absent, Skunk reads RubyCritic::Config.root at the moment it is needed instead of copying it on reset, so .rubycritic.yml is honored and a root left over from an earlier compare run is never reused. Compare mode wrote build_details.txt to tmp/rubycritic/compare even with --out. It now goes to /compare/build_details.txt. --out rejects an empty path, which made RubyCritic write reports into the current directory, and an existing file, the old -o FILE usage. Both exit 1 with an error. skunk_report.txt is written only with --out, so a plain skunk run still writes no files. SHARE_URL="" now falls back to the default share URL. bin/console passes its formats through argv because Application#execute resets the config. CHANGELOG marks --out as a breaking change and notes the skunk_report.html rename. --- CHANGELOG.md | 2 +- README.md | 4 ++-- bin/console | 5 ++--- lib/skunk/cli/application.rb | 2 +- lib/skunk/cli/options/argv.rb | 15 +++++++++++++-- lib/skunk/commands/compare.rb | 14 ++++++++++++-- lib/skunk/commands/status_sharer.rb | 3 +-- lib/skunk/config.rb | 14 +++++++++++--- lib/skunk/generators/console_report.rb | 13 ++++++++++--- lib/skunk/generators/html/overview.rb | 2 ++ lib/skunk/generators/json/simple.rb | 2 +- test/lib/skunk/cli/options/argv_test.rb | 16 ++++++++++++++++ test/lib/skunk/commands/compare_test.rb | 11 +++++++++++ test/lib/skunk/commands/help_test.rb | 2 +- test/lib/skunk/config_test.rb | 11 +++++++++++ test/lib/skunk/generators/console_report_test.rb | 11 +++++++++++ 16 files changed, 106 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99359b7..bbcd08e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## main [(unreleased)](https://github.com/fastruby/skunk/compare/v0.5.4...HEAD) -* [FEATURE: Indicate `--out PATH` location](https://github.com/fastruby/skunk/pull/131) +* [BREAKING: `-o/--out` now takes an output directory instead of a file. Reports, and `skunk_report.txt` with the console output, are written there. The HTML report is renamed from `skunk_overview.html` to `skunk_report.html`](https://github.com/fastruby/skunk/pull/131) * [FEATURE: Add sortable columns to the Skunk HTML report](https://github.com/fastruby/skunk/pull/142) * [ENHANCEMENT: Support SimpleCov 1.0](https://github.com/fastruby/skunk/pull/140) * BUGFIX: Pin path_expander < 2.0 for Ruby 2.7 compatibility diff --git a/README.md b/README.md index 6003eb8..e533f7f 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Run `skunk -h` to check out the help options: ``` Usage: skunk [options] [paths] -b, --branch BRANCH Set branch to compare - -o, --out PATH Output report path + -o, --out PATH Output directory for reports -v, --version Show gem's version -h, --help Show this message ``` @@ -129,7 +129,7 @@ To only run skunk on specific folders, pass a list of directories in the command When the Skunk command is run, it will generate a JSON report file in the configured output path. -Skunk also writes the console report to `skunk_report.txt` under the same output path. +When `--out PATH` is given, Skunk also writes the console report to `skunk_report.txt` in that directory. ### Comparing feature branches diff --git a/bin/console b/bin/console index 623d374..eff50c0 100755 --- a/bin/console +++ b/bin/console @@ -13,6 +13,5 @@ puts ARGV.inspect require "skunk/cli/application" require "skunk/config" -Skunk::Config.formats = %i[json console html] # supported output formats -Skunk::Config.root = "tmp/rubycritic" # default path to store generated JSON and HTML reports. -Skunk::Cli::Application.new(ARGV).execute +argv = ARGV.any? { |arg| arg.start_with?("-f", "--formats") } ? ARGV : ["--formats=json,console,html", *ARGV] +Skunk::Cli::Application.new(argv).execute diff --git a/lib/skunk/cli/application.rb b/lib/skunk/cli/application.rb index 06df963..b45a126 100644 --- a/lib/skunk/cli/application.rb +++ b/lib/skunk/cli/application.rb @@ -38,7 +38,7 @@ def execute end reporter.status - rescue OptionParser::InvalidOption => e + rescue OptionParser::ParseError => e warn "Error: #{e}" STATUS_ERROR end diff --git a/lib/skunk/cli/options/argv.rb b/lib/skunk/cli/options/argv.rb index e43038e..342ed5b 100644 --- a/lib/skunk/cli/options/argv.rb +++ b/lib/skunk/cli/options/argv.rb @@ -19,8 +19,8 @@ def parse self.mode = :compare_branches end - opts.on("-o", "--out PATH", "Output report path") do |path| - Skunk::Config.root = path + opts.on("-o", "--out PATH", "Output directory for reports") do |path| + self.output_path = path end opts.on("-f", "--formats json,html,console", Array, "Output formats: json,html,console") do |list| @@ -36,6 +36,17 @@ def parse end end.parse!(@argv) end + + private + + # Moves only Skunk's reports. RubyCritic::Config.root stays under + # RubyCritic's control, and Skunk::Config.root falls back to it + def output_path=(path) + raise OptionParser::InvalidArgument, "expects a directory" if path.to_s.strip.empty? + raise OptionParser::InvalidArgument, "expects a directory, but #{path} is a file" if File.file?(path) + + Skunk::Config.root = path + end end end end diff --git a/lib/skunk/commands/compare.rb b/lib/skunk/commands/compare.rb index 46cc4d9..5edc70d 100644 --- a/lib/skunk/commands/compare.rb +++ b/lib/skunk/commands/compare.rb @@ -5,6 +5,7 @@ require "skunk/commands/output" require "skunk/commands/shareable" require "skunk/commands/compare_score" +require "skunk/config" # nodoc # module Skunk @@ -51,13 +52,22 @@ def build_details ::RubyCritic::Config.feature_branch_score.to_f.round(2) ).message - Skunk::Command::Output.create_directory(::RubyCritic::Config.compare_root_directory) + Skunk::Command::Output.create_directory(compare_directory) File.open(build_details_path, "w") { |file| file.write(details) } puts details end def build_details_path - "#{::RubyCritic::Config.compare_root_directory}/build_details.txt" + "#{compare_directory}/build_details.txt" + end + + # Uses --out (Skunk::Config.root) when given, otherwise RubyCritic's + # compare directory + # :reek:UtilityFunction + def compare_directory + return ::RubyCritic::Config.compare_root_directory unless Skunk::Config.root_set? + + File.join(Skunk::Config.root, "compare") end end end diff --git a/lib/skunk/commands/status_sharer.rb b/lib/skunk/commands/status_sharer.rb index 6e87d05..7b44bf0 100644 --- a/lib/skunk/commands/status_sharer.rb +++ b/lib/skunk/commands/status_sharer.rb @@ -33,9 +33,8 @@ def share private - # :reek:UtilityFunction def base_url - @base_url ||= ENV["SHARE_URL"] || DEFAULT_URL + share_url_empty? ? DEFAULT_URL : share_url end def json_summary diff --git a/lib/skunk/config.rb b/lib/skunk/config.rb index 1cfb060..03234bb 100644 --- a/lib/skunk/config.rb +++ b/lib/skunk/config.rb @@ -30,7 +30,7 @@ class Configuration def initialize @formats = [DEFAULT_FORMAT] - @root = RubyCritic::Config.root + @root = nil end def set(options = {}) @@ -50,8 +50,16 @@ def formats=(format_list) @formats = [DEFAULT_FORMAT] if @formats.empty? end + # Path where reports are written. An explicit value (from --out) wins; + # otherwise it follows RubyCritic::Config.root, which RubyCritic sets on + # every run, so a stale value from an earlier run is never reused. def root - @root || File.expand_path("tmp/rubycritic", Dir.pwd) + @root || RubyCritic::Config.root || File.expand_path("tmp/rubycritic", Dir.pwd) + end + + # @return [Boolean] True when the output path was set explicitly + def root_set? + !!@root end def root=(path) @@ -90,7 +98,7 @@ def supported_formats # Reset to default configuration def reset @formats = [DEFAULT_FORMAT] - @root = RubyCritic::Config.root + @root = nil end end diff --git a/lib/skunk/generators/console_report.rb b/lib/skunk/generators/console_report.rb index 774eae7..14d8d10 100644 --- a/lib/skunk/generators/console_report.rb +++ b/lib/skunk/generators/console_report.rb @@ -12,6 +12,8 @@ module Skunk module Generator # Generates a console report for the analysed modules. class ConsoleReport + FILE_NAME = "skunk_report.txt" + def initialize(analysed_modules) @analysed_modules = analysed_modules end @@ -19,8 +21,7 @@ def initialize(analysed_modules) def generate_report content = generator.render puts content - FileUtils.mkdir_p(file_directory) - File.write(file_pathname, content) + write_file(content) if Skunk::Config.root_set? end private @@ -29,12 +30,18 @@ def generator @generator ||= Skunk::Generator::Console::Simple.new(@analysed_modules) end + # Only written when --out is given, so a plain `skunk` run stays free of filesystem side effects + def write_file(content) + FileUtils.mkdir_p(file_directory) + File.write(file_pathname, content) + end + def file_directory @file_directory ||= Pathname.new(Skunk::Config.root) end def file_pathname - Pathname.new(file_directory).join("skunk_report.txt") + file_directory.join(FILE_NAME) end end end diff --git a/lib/skunk/generators/html/overview.rb b/lib/skunk/generators/html/overview.rb index fec1033..0d7de04 100644 --- a/lib/skunk/generators/html/overview.rb +++ b/lib/skunk/generators/html/overview.rb @@ -50,6 +50,8 @@ def files end end + private + def root_directory @root_directory ||= Pathname.new(Skunk::Config.root) end diff --git a/lib/skunk/generators/json/simple.rb b/lib/skunk/generators/json/simple.rb index 353d767..a0e0c5e 100644 --- a/lib/skunk/generators/json/simple.rb +++ b/lib/skunk/generators/json/simple.rb @@ -29,7 +29,7 @@ def file_directory end def file_pathname - Pathname.new(file_directory).join(FILE_NAME) + file_directory.join(FILE_NAME) end end end diff --git a/test/lib/skunk/cli/options/argv_test.rb b/test/lib/skunk/cli/options/argv_test.rb index ba703d4..e6207b3 100644 --- a/test/lib/skunk/cli/options/argv_test.rb +++ b/test/lib/skunk/cli/options/argv_test.rb @@ -21,6 +21,22 @@ _(Skunk::Config.root).must_match(%r{tmp/custom$}) end + it "leaves the RubyCritic root option untouched" do + parser = Skunk::Cli::Options::Argv.new(["--out=tmp/custom"]) + parser.parse + _(parser.to_h[:root]).must_be_nil + end + + it "rejects an empty path" do + parser = Skunk::Cli::Options::Argv.new(["--out="]) + _ { parser.parse }.must_raise OptionParser::InvalidArgument + end + + it "rejects a path that is an existing file" do + parser = Skunk::Cli::Options::Argv.new(["--out=Gemfile"]) + _ { parser.parse }.must_raise OptionParser::InvalidArgument + end + it "defaults to tmp/rubycritic when not provided" do default_root = File.expand_path("tmp/rubycritic_default", Dir.pwd) RubyCritic::Config.root = default_root diff --git a/test/lib/skunk/commands/compare_test.rb b/test/lib/skunk/commands/compare_test.rb index 4f8e239..23b1574 100644 --- a/test/lib/skunk/commands/compare_test.rb +++ b/test/lib/skunk/commands/compare_test.rb @@ -32,5 +32,16 @@ _(File.exist?(compare_root_directory)).must_equal true end end + + it "writes build_details.txt under --out when given" do + Skunk::Config.root = "test/support/out" + begin + Skunk::Command::Compare.new(paths: "samples/rubycritic").build_details + _(File.exist?("test/support/out/compare/build_details.txt")).must_equal true + ensure + FileUtils.rm_rf("test/support/out") + Skunk::Config.reset + end + end end end diff --git a/test/lib/skunk/commands/help_test.rb b/test/lib/skunk/commands/help_test.rb index 6ff3d24..b9886ae 100644 --- a/test/lib/skunk/commands/help_test.rb +++ b/test/lib/skunk/commands/help_test.rb @@ -11,7 +11,7 @@ <<~HELP Usage: skunk [options] [paths] -b, --branch BRANCH Set branch to compare - -o, --out PATH Output report path + -o, --out PATH Output directory for reports -f, --formats json,html,console Output formats: json,html,console -v, --version Show gem's version -h, --help Show this message diff --git a/test/lib/skunk/config_test.rb b/test/lib/skunk/config_test.rb index 967e8e1..44b64b6 100644 --- a/test/lib/skunk/config_test.rb +++ b/test/lib/skunk/config_test.rb @@ -97,6 +97,17 @@ def test_default_root Config.reset end + def test_reset_does_not_snapshot_rubycritic_root + prior_root = RubyCritic::Config.root + Config.reset + RubyCritic::Config.root = "tmp/rubycritic_later" + assert_equal File.expand_path("tmp/rubycritic_later", Dir.pwd), Config.root + refute Config.root_set? + ensure + RubyCritic::Config.root = prior_root if prior_root + Config.reset + end + def test_set_root_expands_path Config.root = "tmp/custom" assert_equal File.expand_path("tmp/custom", Dir.pwd), Config.root diff --git a/test/lib/skunk/generators/console_report_test.rb b/test/lib/skunk/generators/console_report_test.rb index 9ac51a8..662b2ad 100644 --- a/test/lib/skunk/generators/console_report_test.rb +++ b/test/lib/skunk/generators/console_report_test.rb @@ -207,8 +207,19 @@ def test_generate_report_writes_console_file assert_includes File.read(path), "SkunkScore Total" ensure FileUtils.rm_rf(Skunk::Config.root) + Skunk::Config.reset end end + + def test_generate_report_skips_file_without_out + Skunk::Config.reset + path = File.join(Skunk::Config.root, "skunk_report.txt") + File.delete(path) if File.exist?(path) + + capture_stdout { @console_report.generate_report } + + refute File.exist?(path) + end end end end From cb883d814c607e090918e58816a86e672a73acc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Mon, 12 Oct 2026 16:31:14 -0600 Subject: [PATCH 10/10] test: reset Skunk::Config after --out tests The application share test runs with --out=tmp and left Skunk::Config.root set. With some seeds (24866 in CI) the compare test ran next, so build_details went to tmp/compare instead of the stubbed directory and the assertion failed. --- test/lib/skunk/application_test.rb | 4 ++++ test/lib/skunk/commands/compare_test.rb | 1 + 2 files changed, 5 insertions(+) diff --git a/test/lib/skunk/application_test.rb b/test/lib/skunk/application_test.rb index 5e2cc3f..2f9b355 100644 --- a/test/lib/skunk/application_test.rb +++ b/test/lib/skunk/application_test.rb @@ -11,6 +11,10 @@ let(:argv) { ["--help"] } let(:application) { Skunk::Cli::Application.new(argv) } + after do + Skunk::Config.reset + end + context "when passing an invalid option" do let(:argv) { ["--foo"] } let(:error_code) { 1 } diff --git a/test/lib/skunk/commands/compare_test.rb b/test/lib/skunk/commands/compare_test.rb index 23b1574..1996651 100644 --- a/test/lib/skunk/commands/compare_test.rb +++ b/test/lib/skunk/commands/compare_test.rb @@ -13,6 +13,7 @@ describe "#analyse_branch" do before do RubyCritic::Config.root = paths + Skunk::Config.reset FileUtils.rm_rf("test/support/") end