diff options
Diffstat (limited to 'lib/bundler/cli.rb')
-rw-r--r-- | lib/bundler/cli.rb | 153 |
1 files changed, 111 insertions, 42 deletions
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 3bdc3db9e9..cf75c52733 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -13,6 +13,7 @@ module Bundler Bundler.ui = UI::Shell.new raise e ensure + warn_on_outdated_bundler Bundler::SharedHelpers.print_major_deprecations! end @@ -22,10 +23,12 @@ module Bundler def initialize(*args) super - Bundler.reset! custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile] - ENV["BUNDLE_GEMFILE"] = File.expand_path(custom_gemfile) if custom_gemfile && !custom_gemfile.empty? + if custom_gemfile && !custom_gemfile.empty? + ENV["BUNDLE_GEMFILE"] = File.expand_path(custom_gemfile) + Bundler.reset_paths! + end Bundler.settings[:retry] = options[:retry] if options[:retry] @@ -36,8 +39,10 @@ module Bundler ensure self.options ||= {} Bundler.settings.cli_flags_given = !options.empty? + unprinted_warnings = Bundler.ui.unprinted_warnings Bundler.ui = UI::Shell.new(options) Bundler.ui.level = "debug" if options["verbose"] + unprinted_warnings.each {|w| Bundler.ui.warn(w) } if ENV["RUBYGEMS_GEMDEPS"] && !ENV["RUBYGEMS_GEMDEPS"].empty? Bundler.ui.warn( @@ -59,30 +64,21 @@ module Bundler def help(cli = nil) case cli - when "gemfile" then command = "gemfile.5" + when "gemfile" then command = "gemfile" when nil then command = "bundle" else command = "bundle-#{cli}" end - manpages = %w( - bundle - bundle-config - bundle-exec - bundle-gem - bundle-install - bundle-package - bundle-update - bundle-platform - gemfile.5 - ) - - if manpages.include?(command) - root = File.expand_path("../man", __FILE__) - - if Bundler.which("man") && root !~ %r{^file:/.+!/META-INF/jruby.home/.+} - Kernel.exec "man #{root}/#{command}" + man_path = File.expand_path("../../../man", __FILE__) + man_pages = Hash[Dir.glob(File.join(man_path, "*")).grep(/.*\.\d*\Z/).collect do |f| + [File.basename(f, ".*"), f] + end] + + if man_pages.include?(command) + if Bundler.which("man") && man_path !~ %r{^file:/.+!/META-INF/jruby.home/.+} + Kernel.exec "man #{man_pages[command]}" else - puts File.read("#{root}/#{command}.txt") + puts File.read("#{man_path}/#{File.basename(man_pages[command])}.txt") end elsif command_path = Bundler.which("bundler-#{cli}") Kernel.exec(command_path, "--help") @@ -91,6 +87,9 @@ module Bundler end end + # Ensure `bundle help --no-color` is valid + all_commands["help"].disable_class_options = false + def self.handle_no_command_error(command, has_namespace = $thor_runner) if Bundler.feature_flag.plugins? && Bundler::Plugin.command?(command) return Bundler::Plugin.exec_command(command, ARGV[1..-1]) @@ -184,11 +183,9 @@ module Bundler map "i" => "install" def install require "bundler/cli/install" - no_install = Bundler.settings[:no_install] - Bundler.settings[:no_install] = false if no_install == true - Install.new(options.dup).run - ensure - Bundler.settings[:no_install] = no_install unless no_install.nil? + Bundler.settings.temporary(:no_install => false) do + Install.new(options.dup).run + end end desc "update [OPTIONS]", "update the current environment" @@ -215,14 +212,16 @@ module Bundler "Update ruby specified in Gemfile.lock" method_option "bundler", :type => :string, :lazy_default => "> 0.a", :banner => "Update the locked version of bundler" - method_option "patch", :type => :boolean, :hide => true, :banner => + method_option "patch", :type => :boolean, :banner => "Prefer updating only to next patch version" - method_option "minor", :type => :boolean, :hide => true, :banner => + method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version" - method_option "major", :type => :boolean, :hide => true, :banner => + method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)" - method_option "strict", :type => :boolean, :hide => true, :banner => - "Do not allow any gem to be updated past latest --patch/--minor/--major" + method_option "strict", :type => :boolean, :banner => + "Do not allow any gem to be updated past latest --patch | --minor | --major" + method_option "conservative", :type => :boolean, :banner => + "Use bundle install conservative update behavior and do not allow shared dependencies to be updated." def update(*gems) require "bundler/cli/update" Update.new(options, gems).run @@ -245,6 +244,13 @@ module Bundler # TODO: 2.0 remove `bundle list` map %w(list) => "show" + desc "info GEM [OPTIONS]", "Show information for the given gem" + method_option "path", :type => :boolean, :banner => "Print full path to gem" + def info(gem_name) + require "bundler/cli/info" + Info.new(options, gem_name).run + end + desc "binstubs GEM [OPTIONS]", "Install the binstubs of the listed gem" long_desc <<-D Generate binstubs for executables in [GEM]. Binstubs are put into bin, @@ -268,16 +274,26 @@ module Bundler in the given source. Calling outdated with [GEM [GEM]] will only check for newer versions of the given gems. Prerelease gems are ignored by default. If your gems are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1. + + For more information on patch level options (--major, --minor, --patch, + --update-strict) see documentation on the same options on the update command. D + method_option "group", :aliases => "--group", :type => :string, :banner => "List gems from a specific group" + method_option "groups", :aliases => "--groups", :type => :boolean, :banner => "List gems organized by groups" method_option "local", :type => :boolean, :banner => "Do not attempt to fetch gems remotely and use the gem cache instead" method_option "pre", :type => :boolean, :banner => "Check for newer pre-release gems" method_option "source", :type => :array, :banner => "Check against a specific source" method_option "strict", :type => :boolean, :banner => "Only list newer versions allowed by your Gemfile requirements" - method_option "major", :type => :boolean, :banner => "Only list major newer versions" - method_option "minor", :type => :boolean, :banner => "Only list minor newer versions" - method_option "patch", :type => :boolean, :banner => "Only list patch newer versions" + method_option "update-strict", :type => :boolean, :banner => + "Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major" + method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version" + method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)" + method_option "patch", :type => :boolean, :banner => "Prefer updating only to next patch version" + method_option "filter-major", :type => :boolean, :banner => "Only list major newer versions" + method_option "filter-minor", :type => :boolean, :banner => "Only list minor newer versions" + method_option "filter-patch", :type => :boolean, :banner => "Only list patch newer versions" method_option "parseable", :aliases => "--porcelain", :type => :boolean, :banner => "Use minimal formatting for more parseable output" def outdated(*gems) @@ -399,6 +415,8 @@ module Bundler Viz.new(options.dup).run end + old_gem = instance_method(:gem) + desc "gem GEM [OPTIONS]", "Creates a skeleton for creating a rubygem" method_option :exe, :type => :boolean, :default => false, :aliases => ["--bin", "-b"], :desc => "Generate a binary executable for your library." method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config gem.coc true`." @@ -410,10 +428,30 @@ module Bundler method_option :test, :type => :string, :lazy_default => "rspec", :aliases => "-t", :banner => "rspec", :desc => "Generate a test directory for your library, either rspec or minitest. Set a default with `bundle config gem.test rspec`." def gem(name) - require "bundler/cli/gem" - Gem.new(options, name, self).run end + commands["gem"].tap do |gem_command| + def gem_command.run(instance, args = []) + arity = 1 # name + + require "bundler/cli/gem" + cmd_args = args + [instance] + cmd_args.unshift(instance.options) + + cmd = begin + Gem.new(*cmd_args) + rescue ArgumentError => e + instance.class.handle_argument_error(self, e, args, arity) + end + + cmd.run + end + end + + undef_method(:gem) + define_method(:gem, old_gem) + private :gem + def self.source_root File.expand_path(File.join(File.dirname(__FILE__), "templates")) end @@ -436,15 +474,15 @@ module Bundler Platform.new(options).run end - desc "inject GEM VERSION ...", "Add the named gem(s), with version requirements, to the resolved Gemfile" - def inject(name, version, *gems) + desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile" + def inject(name, version) SharedHelpers.major_deprecation "The `inject` command has been replaced by the `add` command" require "bundler/cli/inject" - Inject.new(options, name, version, gems).run + Inject.new(options, name, version).run end desc "lock", "Creates a lockfile without installing" - method_option "update", :type => :array, :lazy_default => [], :banner => + method_option "update", :type => :array, :lazy_default => true, :banner => "ignore the existing lockfile, update all gems by default, or update list of given gems" method_option "local", :type => :boolean, :default => false, :banner => "do not attempt to fetch remote gemspecs and use the local gem cache only" @@ -455,9 +493,19 @@ module Bundler method_option "full-index", :type => :boolean, :default => false, :banner => "Fall back to using the single-file index of all gems" method_option "add-platform", :type => :array, :default => [], :banner => - "add a new platform to the lockfile" + "Add a new platform to the lockfile" method_option "remove-platform", :type => :array, :default => [], :banner => - "remove a platform from the lockfile" + "Remove a platform from the lockfile" + method_option "patch", :type => :boolean, :banner => + "If updating, prefer updating only to next patch version" + method_option "minor", :type => :boolean, :banner => + "If updating, prefer updating only to next minor version" + method_option "major", :type => :boolean, :banner => + "If updating, prefer updating to next major version (default)" + method_option "strict", :type => :boolean, :banner => + "If updating, do not allow any gem to be updated past latest --patch | --minor | --major" + method_option "conservative", :type => :boolean, :banner => + "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated" def lock require "bundler/cli/lock" Lock.new(options).run @@ -545,5 +593,26 @@ module Bundler command.reject!(&:empty?) Bundler.ui.info "Running `#{command * " "}` with bundler #{Bundler::VERSION}" end + + def self.warn_on_outdated_bundler + return if Bundler.settings[:disable_version_check] + + latest = Fetcher::CompactIndex. + new(nil, Source::Rubygems::Remote.new(URI("https://rubygems.org")), nil). + send(:compact_index_client). + instance_variable_get(:@cache). + dependencies("bundler"). + map {|d| Gem::Version.new(d.first) }. + max + return unless latest + + current = Gem::Version.new(VERSION) + return if current >= latest + + Bundler.ui.warn "The latest bundler is #{latest}, but you are currently running #{current}.\nTo update, run `gem install bundler#{" --pre" if latest.prerelease?}`" + rescue + nil + end + private_class_method :warn_on_outdated_bundler end end |