diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 91c31651da..51f71af501 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -610,17 +610,8 @@ module Bundler end desc "doctor [OPTIONS]", "Checks the bundle for common problems" - long_desc <<-D - Doctor scans the OS dependencies of each of the gems requested in the Gemfile. If - missing dependencies are detected, Bundler prints them and exits status 1. - Otherwise, Bundler prints a success message and exits with a status of 0. - D - method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile" - method_option "quiet", type: :boolean, banner: "Only output warnings and errors." - def doctor - require_relative "cli/doctor" - Doctor.new(options).run - end + require_relative "cli/doctor" + subcommand("doctor", Doctor) desc "issue", "Learn how to report an issue in Bundler" def issue diff --git a/lib/bundler/cli/doctor.rb b/lib/bundler/cli/doctor.rb new file mode 100644 index 0000000000..21437fc89f --- /dev/null +++ b/lib/bundler/cli/doctor.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Bundler + class CLI::Doctor < Thor + default_command(:diagnose) + + desc "diagnose [OPTIONS]", "Checks the bundle for common problems" + long_desc <<-D + Doctor scans the OS dependencies of each of the gems requested in the Gemfile. If + missing dependencies are detected, Bundler prints them and exits status 1. + Otherwise, Bundler prints a success message and exits with a status of 0. + D + method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile" + method_option "quiet", type: :boolean, banner: "Only output warnings and errors." + def diagnose + require_relative "doctor/diagnose" + Diagnose.new(options).run + end + end +end diff --git a/lib/bundler/cli/doctor/diagnose.rb b/lib/bundler/cli/doctor/diagnose.rb index 160ad13b99..c32a1b5369 100644 --- a/lib/bundler/cli/doctor/diagnose.rb +++ b/lib/bundler/cli/doctor/diagnose.rb @@ -65,7 +65,7 @@ module Bundler end def check! - require_relative "check" + require_relative "../check" Bundler::CLI::Check.new({}).run end diff --git a/lib/bundler/cli/issue.rb b/lib/bundler/cli/issue.rb index e16c9b0e39..fbe9184d12 100644 --- a/lib/bundler/cli/issue.rb +++ b/lib/bundler/cli/issue.rb @@ -34,8 +34,8 @@ module Bundler end def doctor - require_relative "doctor" - Bundler::CLI::Doctor.new({}).run + require_relative "doctor/diagnose" + Bundler::CLI::Doctor::Diagnose.new({}).run end end end diff --git a/spec/bundler/commands/doctor_spec.rb b/spec/bundler/commands/doctor_spec.rb index 7c30d0e91b..456fb4ec78 100644 --- a/spec/bundler/commands/doctor_spec.rb +++ b/spec/bundler/commands/doctor_spec.rb @@ -4,6 +4,7 @@ require "find" require "stringio" require "bundler/cli" require "bundler/cli/doctor" +require "bundler/cli/doctor/diagnose" RSpec.describe "bundle doctor" do before(:each) do @@ -46,14 +47,14 @@ RSpec.describe "bundle doctor" do end it "exits with a success message if the installed gem has no C extensions" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) allow(doctor).to receive(:lookup_with_fiddle).and_return(false) expect { doctor.run }.not_to raise_error expect(@stdout.string).to include("No issues") end it "exits with a success message if the installed gem's C extension dylib breakage is fine" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/myrack/myrack.bundle"] expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/lib/libSystem.dylib"] allow(doctor).to receive(:lookup_with_fiddle).with("/usr/lib/libSystem.dylib").and_return(false) @@ -62,7 +63,7 @@ RSpec.describe "bundle doctor" do end it "exits with a message if one of the linked libraries is missing" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/myrack/myrack.bundle"] expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"] allow(doctor).to receive(:lookup_with_fiddle).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_return(true) @@ -84,7 +85,7 @@ RSpec.describe "bundle doctor" do end it "exits with an error if home contains files that are not readable/writable" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) allow(doctor).to receive(:lookup_with_fiddle).and_return(false) expect { doctor.run }.not_to raise_error expect(@stdout.string).to include( @@ -106,7 +107,7 @@ RSpec.describe "bundle doctor" do end it "exits with an error if home contains files that are not readable" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) allow(doctor).to receive(:lookup_with_fiddle).and_return(false) allow(@stat).to receive(:uid) { Process.uid } allow(File).to receive(:writable?).with(@unwritable_file) { false } @@ -119,7 +120,7 @@ RSpec.describe "bundle doctor" do end it "exits without an error if home contains files that are not writable" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) allow(doctor).to receive(:lookup_with_fiddle).and_return(false) allow(@stat).to receive(:uid) { Process.uid } allow(File).to receive(:writable?).with(@unwritable_file) { false } @@ -137,7 +138,7 @@ RSpec.describe "bundle doctor" do end it "exits with an error if home contains files that are not readable/writable and are not owned by the current user" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) allow(doctor).to receive(:lookup_with_fiddle).and_return(false) allow(File).to receive(:writable?).with(@unwritable_file) { false } allow(File).to receive(:readable?).with(@unwritable_file) { false } @@ -149,7 +150,7 @@ RSpec.describe "bundle doctor" do end it "exits with a warning if home contains files that are read/write but not owned by current user" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) allow(doctor).to receive(:lookup_with_fiddle).and_return(false) allow(File).to receive(:writable?).with(@unwritable_file) { true } allow(File).to receive(:readable?).with(@unwritable_file) { true } @@ -164,7 +165,7 @@ RSpec.describe "bundle doctor" do context "when home contains filenames with special characters" do it "escape filename before command execute" do - doctor = Bundler::CLI::Doctor.new({}) + doctor = Bundler::CLI::Doctor::Diagnose.new({}) expect(doctor).to receive(:`).with("/usr/bin/otool -L \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string") doctor.dylibs_darwin('$(date) "\'\.bundle') expect(doctor).to receive(:`).with("/usr/bin/ldd \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string")