aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-14 06:01:35 +0000
committerhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-14 06:01:35 +0000
commit68ddd4d300e9a88737c4f37af74e1a0312949b2f (patch)
tree787e1e83d76934ce039eb336995a8d5bb53a89e6 /lib
parentd636809c057432e8d42abe30c6c6785eb0721d77 (diff)
downloadruby-68ddd4d300e9a88737c4f37af74e1a0312949b2f.tar.gz
Merge Bundler 2.1.0.pre.1 as developed version from upstream.
https://github.com/bundler/bundler/commit/a53709556b95a914e874b22ed2116a46b0528852 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler.rb75
-rw-r--r--lib/bundler/bundler.gemspec15
-rw-r--r--lib/bundler/capistrano.rb2
-rw-r--r--lib/bundler/cli.rb174
-rw-r--r--lib/bundler/cli/cache.rb2
-rw-r--r--lib/bundler/cli/common.rb12
-rw-r--r--lib/bundler/cli/config.rb247
-rw-r--r--lib/bundler/cli/console.rb4
-rw-r--r--lib/bundler/cli/doctor.rb4
-rw-r--r--lib/bundler/cli/gem.rb6
-rw-r--r--lib/bundler/cli/info.rb22
-rw-r--r--lib/bundler/cli/init.rb2
-rw-r--r--lib/bundler/cli/install.rb19
-rw-r--r--lib/bundler/cli/issue.rb4
-rw-r--r--lib/bundler/cli/outdated.rb8
-rw-r--r--lib/bundler/cli/package.rb2
-rw-r--r--lib/bundler/cli/plugin.rb9
-rw-r--r--lib/bundler/cli/pristine.rb2
-rw-r--r--lib/bundler/cli/show.rb2
-rw-r--r--lib/bundler/cli/update.rb2
-rw-r--r--lib/bundler/compact_index_client.rb30
-rw-r--r--lib/bundler/compact_index_client/updater.rb6
-rw-r--r--lib/bundler/compatibility_guard.rb5
-rw-r--r--lib/bundler/definition.rb20
-rw-r--r--lib/bundler/deployment.rb2
-rw-r--r--lib/bundler/dsl.rb51
-rw-r--r--lib/bundler/env.rb10
-rw-r--r--lib/bundler/feature_flag.rb11
-rw-r--r--lib/bundler/fetcher.rb10
-rw-r--r--lib/bundler/fetcher/compact_index.rb32
-rw-r--r--lib/bundler/fetcher/downloader.rb4
-rw-r--r--lib/bundler/friendly_errors.rb5
-rw-r--r--lib/bundler/gem_helper.rb48
-rw-r--r--lib/bundler/gem_helpers.rb2
-rw-r--r--lib/bundler/gem_version_promoter.rb2
-rw-r--r--lib/bundler/graph.rb4
-rw-r--r--lib/bundler/injector.rb14
-rw-r--r--lib/bundler/inline.rb1
-rw-r--r--lib/bundler/installer.rb11
-rw-r--r--lib/bundler/installer/gem_installer.rb6
-rw-r--r--lib/bundler/installer/parallel_installer.rb8
-rw-r--r--lib/bundler/lazy_specification.rb2
-rw-r--r--lib/bundler/lockfile_parser.rb24
-rw-r--r--lib/bundler/plugin.rb44
-rw-r--r--lib/bundler/plugin/api/source.rb2
-rw-r--r--lib/bundler/plugin/index.rb13
-rw-r--r--lib/bundler/plugin/installer.rb39
-rw-r--r--lib/bundler/resolver.rb90
-rw-r--r--lib/bundler/resolver/spec_group.rb4
-rw-r--r--lib/bundler/retry.rb4
-rw-r--r--lib/bundler/ruby_version.rb4
-rw-r--r--lib/bundler/rubygems_ext.rb15
-rw-r--r--lib/bundler/rubygems_gem_installer.rb2
-rw-r--r--lib/bundler/rubygems_integration.rb59
-rw-r--r--lib/bundler/runtime.rb2
-rw-r--r--lib/bundler/settings.rb40
-rw-r--r--lib/bundler/setup.rb7
-rw-r--r--lib/bundler/shared_helpers.rb49
-rw-r--r--lib/bundler/similarity_detector.rb2
-rw-r--r--lib/bundler/source/git.rb17
-rw-r--r--lib/bundler/source/git/git_proxy.rb2
-rw-r--r--lib/bundler/source/metadata.rb6
-rw-r--r--lib/bundler/source/path.rb8
-rw-r--r--lib/bundler/source/rubygems.rb14
-rw-r--r--lib/bundler/source_list.rb21
-rw-r--r--lib/bundler/spec_set.rb1
-rw-r--r--lib/bundler/ssl_certs/.document1
-rw-r--r--lib/bundler/ssl_certs/certificate_manager.rb66
-rw-r--r--lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem21
-rw-r--r--lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem23
-rw-r--r--lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem25
-rw-r--r--lib/bundler/stub_specification.rb42
-rw-r--r--lib/bundler/templates/Executable.bundler2
-rw-r--r--lib/bundler/templates/newgem/README.md.tt2
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt23
-rw-r--r--lib/bundler/templates/newgem/test/test_helper.rb.tt2
-rw-r--r--lib/bundler/templates/newgem/travis.yml.tt1
-rw-r--r--lib/bundler/vendor/fileutils/lib/fileutils.rb199
-rw-r--r--lib/bundler/vendor/fileutils/lib/fileutils/version.rb5
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb38
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions.rb18
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb13
-rw-r--r--lib/bundler/vendor/thor/lib/thor/base.rb9
-rw-r--r--lib/bundler/vendor/thor/lib/thor/error.rb82
-rw-r--r--lib/bundler/vendor/thor/lib/thor/group.rb4
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/options.rb9
-rw-r--r--lib/bundler/vendor/thor/lib/thor/runner.rb4
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/basic.rb59
-rw-r--r--lib/bundler/vendor/thor/lib/thor/util.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/version.rb2
-rw-r--r--lib/bundler/version.rb5
-rw-r--r--lib/bundler/version_ranges.rb56
-rw-r--r--lib/bundler/vlad.rb2
-rw-r--r--lib/bundler/worker.rb4
-rw-r--r--lib/bundler/yaml_serializer.rb5
96 files changed, 1242 insertions, 850 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index cf3a289df2..f792a3bc98 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -5,7 +5,6 @@ require "bundler/compatibility_guard"
require "bundler/vendored_fileutils"
require "pathname"
require "rbconfig"
-require "thread"
require "bundler/errors"
require "bundler/environment_preserver"
@@ -119,7 +118,7 @@ module Bundler
end
def environment
- SharedHelpers.major_deprecation 3, "Bundler.environment has been removed in favor of Bundler.load"
+ SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load"
load
end
@@ -280,10 +279,19 @@ EOF
ORIGINAL_ENV.clone
end
- # @deprecated Use `original_env` instead
- # @return [Hash] Environment with all bundler-related variables removed
+ # @deprecated Use `unbundled_env` instead
def clean_env
- Bundler::SharedHelpers.major_deprecation(3, "`Bundler.clean_env` has weird edge cases, use `.original_env` instead")
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.clean_env` has been deprecated in favor of `Bundler.unbundled_env`. " \
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env`"
+ )
+
+ unbundled_env
+ end
+
+ # @return [Hash] Environment with all bundler-related variables removed
+ def unbundled_env
env = original_env
if env.key?("BUNDLER_ORIG_MANPATH")
@@ -305,20 +313,67 @@ EOF
env
end
+ # Run block with environment present before Bundler was activated
def with_original_env
with_env(original_env) { yield }
end
+ # @deprecated Use `with_unbundled_env` instead
def with_clean_env
- with_env(clean_env) { yield }
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. " \
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`"
+ )
+
+ with_env(unbundled_env) { yield }
+ end
+
+ # Run block with all bundler-related variables removed
+ def with_unbundled_env
+ with_env(unbundled_env) { yield }
+ end
+
+ # Run subcommand with the environment present before Bundler was activated
+ def original_system(*args)
+ with_original_env { Kernel.system(*args) }
end
+ # @deprecated Use `unbundled_system` instead
def clean_system(*args)
- with_clean_env { Kernel.system(*args) }
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.clean_system` has been deprecated in favor of `Bundler.unbundled_system`. " \
+ "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`"
+ )
+
+ with_env(unbundled_env) { Kernel.system(*args) }
end
+ # Run subcommand in an environment with all bundler related variables removed
+ def unbundled_system(*args)
+ with_unbundled_env { Kernel.system(*args) }
+ end
+
+ # Run a `Kernel.exec` to a subcommand with the environment present before Bundler was activated
+ def original_exec(*args)
+ with_original_env { Kernel.exec(*args) }
+ end
+
+ # @deprecated Use `unbundled_exec` instead
def clean_exec(*args)
- with_clean_env { Kernel.exec(*args) }
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.clean_exec` has been deprecated in favor of `Bundler.unbundled_exec`. " \
+ "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`"
+ )
+
+ with_env(unbundled_env) { Kernel.exec(*args) }
+ end
+
+ # Run a `Kernel.exec` to a subcommand in an environment with all bundler related variables removed
+ def unbundled_exec(*args)
+ with_env(unbundled_env) { Kernel.exec(*args) }
end
def local_platform
@@ -343,7 +398,7 @@ EOF
# system binaries. If you put '-n foo' in your .gemrc, RubyGems will
# install binstubs there instead. Unfortunately, RubyGems doesn't expose
# that directory at all, so rather than parse .gemrc ourselves, we allow
- # the directory to be set as well, via `bundle config bindir foo`.
+ # the directory to be set as well, via `bundle config set bindir foo`.
Bundler.settings[:system_bindir] || Bundler.rubygems.gem_bindir
end
@@ -523,7 +578,7 @@ EOF
rescue ScriptError, StandardError => e
msg = "There was an error while loading `#{path.basename}`: #{e.message}"
- if e.is_a?(LoadError) && RUBY_VERSION >= "1.9"
+ if e.is_a?(LoadError)
msg += "\nDoes it try to require a relative path? That's been removed in Ruby 1.9"
end
diff --git a/lib/bundler/bundler.gemspec b/lib/bundler/bundler.gemspec
index b229ab224d..d8abb2b16f 100644
--- a/lib/bundler/bundler.gemspec
+++ b/lib/bundler/bundler.gemspec
@@ -1,4 +1,3 @@
-# coding: utf-8
# frozen_string_literal: true
begin
@@ -19,16 +18,16 @@ Gem::Specification.new do |s|
"Yehuda Katz"
]
s.email = ["team@bundler.io"]
- s.homepage = "http://bundler.io"
+ s.homepage = "https://bundler.io"
s.summary = "The best way to manage your application's dependencies"
s.description = "Bundler manages an application's dependencies through its entire life, across many machines, systematically and repeatably"
if s.respond_to?(:metadata=)
s.metadata = {
- "bug_tracker_uri" => "http://github.com/bundler/bundler/issues",
+ "bug_tracker_uri" => "https://github.com/bundler/bundler/issues",
"changelog_uri" => "https://github.com/bundler/bundler/blob/master/CHANGELOG.md",
"homepage_uri" => "https://bundler.io/",
- "source_code_uri" => "http://github.com/bundler/bundler/",
+ "source_code_uri" => "https://github.com/bundler/bundler/",
}
end
@@ -41,14 +40,12 @@ Gem::Specification.new do |s|
end
s.add_development_dependency "automatiek", "~> 0.1.0"
- s.add_development_dependency "mustache", "0.99.6"
- s.add_development_dependency "rake", "~> 10.0"
- s.add_development_dependency "rdiscount", "~> 2.2"
+ s.add_development_dependency "rake", "~> 12.0"
s.add_development_dependency "ronn", "~> 0.7.3"
s.add_development_dependency "rspec", "~> 3.6"
+ s.add_development_dependency "rubocop", "= 0.65.0"
- # base_dir = File.dirname(__FILE__).gsub(%r{([^A-Za-z0-9_\-.,:\/@\n])}, "\\\\\\1")
- # s.files = IO.popen("git -C #{base_dir} ls-files -z", &:read).split("\x0").select {|f| f.match(%r{^(lib|exe)/}) }
+ # s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
# we don't check in man pages, but we need to ship them because
# we use them to generate the long-form help for each command.
diff --git a/lib/bundler/capistrano.rb b/lib/bundler/capistrano.rb
index 40e2e5dbe8..1b7145b72b 100644
--- a/lib/bundler/capistrano.rb
+++ b/lib/bundler/capistrano.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "bundler/shared_helpers"
-Bundler::SharedHelpers.major_deprecation 3,
+Bundler::SharedHelpers.major_deprecation 2,
"The Bundler task for Capistrano. Please use http://github.com/capistrano/bundler"
# Capistrano task for Bundler.
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 3efe193613..4e3735847e 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -16,7 +16,7 @@ module Bundler
def self.start(*)
super
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
Bundler.ui = UI::Shell.new
raise e
ensure
@@ -61,11 +61,6 @@ module Bundler
end
end
- def self.deprecated_option(*args, &blk)
- return if Bundler.feature_flag.forget_cli_options?
- method_option(*args, &blk)
- end
-
check_unknown_options!(:except => [:config, :exec])
stop_on_unknown_option! :exec
@@ -142,7 +137,7 @@ module Bundler
Gemfile to a gem with a gemspec, the --gemspec option will automatically add each
dependency listed in the gemspec file to the newly created Gemfile.
D
- deprecated_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
+ method_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
def init
require "bundler/cli/init"
Init.new(options.dup).run
@@ -188,13 +183,13 @@ module Bundler
If the bundle has already been installed, bundler will tell you so and then exit.
D
- deprecated_option "binstubs", :type => :string, :lazy_default => "bin", :banner =>
+ method_option "binstubs", :type => :string, :lazy_default => "bin", :banner =>
"Generate bin stubs for bundled gems to ./bin"
- deprecated_option "clean", :type => :boolean, :banner =>
+ method_option "clean", :type => :boolean, :banner =>
"Run bundle clean automatically after install"
- deprecated_option "deployment", :type => :boolean, :banner =>
+ method_option "deployment", :type => :boolean, :banner =>
"Install using defaults tuned for deployment environments"
- deprecated_option "frozen", :type => :boolean, :banner =>
+ method_option "frozen", :type => :boolean, :banner =>
"Do not allow the Gemfile.lock to be updated after this install"
method_option "full-index", :type => :boolean, :banner =>
"Fall back to using the single-file index of all gems"
@@ -204,32 +199,37 @@ module Bundler
"Specify the number of jobs to run in parallel"
method_option "local", :type => :boolean, :banner =>
"Do not attempt to fetch gems remotely and use the gem cache instead"
- deprecated_option "no-cache", :type => :boolean, :banner =>
+ method_option "no-cache", :type => :boolean, :banner =>
"Don't update the existing gem cache."
method_option "redownload", :type => :boolean, :aliases => "--force", :banner =>
"Force downloading every gem."
- deprecated_option "no-prune", :type => :boolean, :banner =>
+ method_option "no-prune", :type => :boolean, :banner =>
"Don't remove stale gems from the cache."
- deprecated_option "path", :type => :string, :banner =>
+ method_option "path", :type => :string, :banner =>
"Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME). Bundler will remember this value for future installs on this machine"
method_option "quiet", :type => :boolean, :banner =>
"Only output warnings and errors."
- deprecated_option "shebang", :type => :string, :banner =>
+ method_option "shebang", :type => :string, :banner =>
"Specify a different shebang executable name than the default (usually 'ruby')"
method_option "standalone", :type => :array, :lazy_default => [], :banner =>
"Make a bundle that can work without the Bundler runtime"
- deprecated_option "system", :type => :boolean, :banner =>
+ method_option "system", :type => :boolean, :banner =>
"Install to the system location ($BUNDLE_PATH or $GEM_HOME) even if the bundle was previously installed somewhere else for this application"
method_option "trust-policy", :alias => "P", :type => :string, :banner =>
"Gem trust policy (like gem install -P). Must be one of " +
Bundler.rubygems.security_policy_keys.join("|")
- deprecated_option "without", :type => :array, :banner =>
+ method_option "without", :type => :array, :banner =>
"Exclude gems that are part of the specified named group."
- deprecated_option "with", :type => :array, :banner =>
+ method_option "with", :type => :array, :banner =>
"Include gems that are part of the specified named group."
map "i" => "install"
def install
- SharedHelpers.major_deprecation(3, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
+ SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
+
+ %w[clean deployment frozen no-cache no-prune path shebang system without with].each do |option|
+ remembered_flag_deprecation(option)
+ end
+
require "bundler/cli/install"
Bundler.settings.temporary(:no_install => false) do
Install.new(options.dup).run
@@ -275,57 +275,60 @@ module Bundler
method_option "all", :type => :boolean, :banner =>
"Update everything."
def update(*gems)
- SharedHelpers.major_deprecation(3, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
+ SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
require "bundler/cli/update"
- Update.new(options, gems).run
+ Bundler.settings.temporary(:no_install => false) do
+ Update.new(options, gems).run
+ end
end
- desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
- long_desc <<-D
- Show lists the names and versions of all gems that are required by your Gemfile.
- Calling show with [GEM] will list the exact location of that gem on your machine.
- D
- method_option "paths", :type => :boolean,
- :banner => "List the paths of all gems that are required by your Gemfile."
- method_option "outdated", :type => :boolean,
- :banner => "Show verbose output including whether gems are outdated."
- def show(gem_name = nil)
- if ARGV[0] == "show"
- rest = ARGV[1..-1]
-
- new_command = rest.find {|arg| !arg.start_with?("--") } ? "info" : "list"
-
- new_arguments = rest.map do |arg|
- next arg if arg != "--paths"
- next "--path" if new_command == "info"
+ unless Bundler.feature_flag.bundler_3_mode?
+ desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
+ long_desc <<-D
+ Show lists the names and versions of all gems that are required by your Gemfile.
+ Calling show with [GEM] will list the exact location of that gem on your machine.
+ D
+ method_option "paths", :type => :boolean,
+ :banner => "List the paths of all gems that are required by your Gemfile."
+ method_option "outdated", :type => :boolean,
+ :banner => "Show verbose output including whether gems are outdated."
+ def show(gem_name = nil)
+ if ARGV[0] == "show"
+ rest = ARGV[1..-1]
+
+ if flag = rest.find{|arg| ["--verbose", "--outdated"].include?(arg) }
+ Bundler::SharedHelpers.major_deprecation(2, "the `#{flag}` flag to `bundle show` was undocumented and will be removed without replacement")
+ else
+ new_command = rest.find {|arg| !arg.start_with?("--") } ? "info" : "list"
+
+ new_arguments = rest.map do |arg|
+ next arg if arg != "--paths"
+ next "--path" if new_command == "info"
+ end
+
+ old_argv = ARGV.join(" ")
+ new_argv = [new_command, *new_arguments.compact].join(" ")
+
+ Bundler::SharedHelpers.major_deprecation(2, "use `bundle #{new_argv}` instead of `bundle #{old_argv}`")
+ end
end
-
- old_argv = ARGV.join(" ")
- new_argv = [new_command, *new_arguments.compact].join(" ")
-
- Bundler::SharedHelpers.major_deprecation(3, "use `bundle #{new_argv}` instead of `bundle #{old_argv}`")
- end
- require "bundler/cli/show"
- Show.new(options, gem_name).run
- end
- # TODO: 2.0 remove `bundle show`
-
- if Bundler.feature_flag.list_command?
- desc "list", "List all gems in the bundle"
- method_option "name-only", :type => :boolean, :banner => "print only the gem names"
- method_option "only-group", :type => :string, :banner => "print gems from a particular group"
- method_option "without-group", :type => :string, :banner => "print all gems expect from a group"
- method_option "paths", :type => :boolean, :banner => "print the path to each gem in the bundle"
- def list
- require "bundler/cli/list"
- List.new(options).run
+ require "bundler/cli/show"
+ Show.new(options, gem_name).run
end
+ end
- map %w[ls] => "list"
- else
- map %w[list] => "show"
+ desc "list", "List all gems in the bundle"
+ method_option "name-only", :type => :boolean, :banner => "print only the gem names"
+ method_option "only-group", :type => :string, :banner => "print gems from a particular group"
+ method_option "without-group", :type => :string, :banner => "print all gems except from a group"
+ method_option "paths", :type => :boolean, :banner => "print the path to each gem in the bundle"
+ def list
+ require "bundler/cli/list"
+ List.new(options).run
end
+ map %w[ls] => "list"
+
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)
@@ -386,9 +389,10 @@ module Bundler
"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 =>
+ strict_is_update = Bundler.feature_flag.forget_cli_options?
+ method_option "filter-strict", :type => :boolean, :aliases => strict_is_update ? [] : %w[--strict], :banner =>
"Only list newer versions allowed by your Gemfile requirements"
- method_option "update-strict", :type => :boolean, :banner =>
+ method_option "update-strict", :type => :boolean, :aliases => strict_is_update ? %w[--strict] : [], :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)"
@@ -475,11 +479,8 @@ module Bundler
will show the current value, as well as any superceded values and
where they were specified.
D
- method_option "parseable", :type => :boolean, :banner => "Use minimal formatting for more parseable output"
- def config(*args)
- require "bundler/cli/config"
- Config.new(options, args, self).run
- end
+ require "bundler/cli/config"
+ subcommand "config", Config
desc "open GEM", "Opens the source directory of the given bundled gem"
def open(name)
@@ -487,7 +488,7 @@ module Bundler
Open.new(options, name).run
end
- if Bundler.feature_flag.console_command?
+ unless Bundler.feature_flag.bundler_3_mode?
desc "console [GROUP]", "Opens an IRB session with the bundle pre-loaded"
def console(group = nil)
require "bundler/cli/console"
@@ -524,7 +525,7 @@ module Bundler
end
end
- if Bundler.feature_flag.viz_command?
+ unless Bundler.feature_flag.bundler_3_mode?
desc "viz [OPTIONS]", "Generates a visual dependency graph", :hide => true
long_desc <<-D
Viz generates a PNG file of the current Gemfile as a dependency graph.
@@ -537,7 +538,7 @@ module Bundler
method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version."
method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group."
def viz
- SharedHelpers.major_deprecation 3, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/bundler/bundler-viz"
+ SharedHelpers.major_deprecation 2, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/bundler/bundler-viz"
require "bundler/cli/viz"
Viz.new(options.dup).run
end
@@ -547,14 +548,14 @@ module Bundler
desc "gem NAME [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`."
+ method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config set gem.coc true`."
method_option :edit, :type => :string, :aliases => "-e", :required => false, :banner => "EDITOR",
:lazy_default => [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? },
:desc => "Open generated gemspec in the specified editor (defaults to $EDITOR or $BUNDLER_EDITOR)"
method_option :ext, :type => :boolean, :default => false, :desc => "Generate the boilerplate for C extension code"
- method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config gem.mit true`."
+ method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set gem.mit true`."
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`."
+ :desc => "Generate a test directory for your library, either rspec or minitest. Set a default with `bundle config set gem.test rspec`."
def gem(name)
end
@@ -608,7 +609,7 @@ module Bundler
method_option "group", :type => :string, :banner =>
"Install gem into a bundler group"
def inject(name, version)
- SharedHelpers.major_deprecation 3, "The `inject` command has been replaced by the `add` command"
+ SharedHelpers.major_deprecation 2, "The `inject` command has been replaced by the `add` command"
require "bundler/cli/inject"
Inject.new(options.dup, name, version).run
end
@@ -620,6 +621,8 @@ module Bundler
"do not attempt to fetch remote gemspecs and use the local gem cache only"
method_option "print", :type => :boolean, :default => false, :banner =>
"print the lockfile to STDOUT instead of writing to the file system"
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
method_option "lockfile", :type => :string, :default => nil, :banner =>
"the path the lockfile should be written to"
method_option "full-index", :type => :boolean, :default => false, :banner =>
@@ -714,7 +717,7 @@ module Bundler
# Automatically invoke `bundle install` and resume if
# Bundler.settings[:auto_install] exists. This is set through config cmd
- # `bundle config auto_install 1`.
+ # `bundle config set auto_install 1`.
#
# Note that this method `nil`s out the global Definition object, so it
# should be called first, before you instantiate anything like an
@@ -786,5 +789,22 @@ module Bundler
rescue RuntimeError
nil
end
+
+ def remembered_flag_deprecation(name)
+ option = current_command.options[name]
+ flag_name = option.switch_name
+
+ name_index = ARGV.find {|arg| flag_name == arg }
+ return unless name_index
+
+ value = options[name]
+ value = value.join(" ").to_s if option.type == :array
+
+ Bundler::SharedHelpers.major_deprecation 2,\
+ "The `#{flag_name}` flag is deprecated because it relies on being " \
+ "remembered accross bundler invokations, which bundler will no longer " \
+ "do in future versions. Instead please use `bundle config #{name} " \
+ "'#{value}'`, and stop using this flag"
+ end
end
end
diff --git a/lib/bundler/cli/cache.rb b/lib/bundler/cli/cache.rb
index 9d2ba87d34..cb7958e5d0 100644
--- a/lib/bundler/cli/cache.rb
+++ b/lib/bundler/cli/cache.rb
@@ -29,7 +29,7 @@ module Bundler
if Bundler.definition.has_local_dependencies? && !Bundler.feature_flag.cache_all?
Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
"to package them as well, please pass the --all flag. This will be the default " \
- "on Bundler 2.0."
+ "on Bundler 3.0."
end
end
end
diff --git a/lib/bundler/cli/common.rb b/lib/bundler/cli/common.rb
index 9d40ee9dfd..9ea52baa6b 100644
--- a/lib/bundler/cli/common.rb
+++ b/lib/bundler/cli/common.rb
@@ -23,7 +23,7 @@ module Bundler
groups = Bundler.settings[:without]
group_list = [groups[0...-1].join(", "), groups[-1..-1]].
reject {|s| s.to_s.empty? }.join(" and ")
- group_str = (groups.size == 1) ? "group" : "groups"
+ group_str = groups.size == 1 ? "group" : "groups"
"Gems in the #{group_str} #{group_list} were not installed."
end
@@ -49,10 +49,6 @@ module Bundler
end
def self.ask_for_spec_from(specs)
- if !$stdout.tty? && ENV["BUNDLE_SPEC_RUN"].nil?
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
- end
-
specs.each_with_index do |spec, index|
Bundler.ui.info "#{index.succ} : #{spec.name}", true
end
@@ -72,7 +68,7 @@ module Bundler
end
def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems)
- locked_names = locked_gems.specs.map(&:name)
+ locked_names = locked_gems.specs.map(&:name).uniq
names.-(locked_names).each do |g|
raise GemNotFound, gem_not_found_message(g, locked_names)
end
@@ -80,10 +76,12 @@ module Bundler
def self.configure_gem_version_promoter(definition, options)
patch_level = patch_level_options(options)
+ patch_level << :patch if patch_level.empty? && Bundler.settings[:prefer_patch]
raise InvalidOption, "Provide only one of the following options: #{patch_level.join(", ")}" unless patch_level.length <= 1
+
definition.gem_version_promoter.tap do |gvp|
gvp.level = patch_level.first || :major
- gvp.strict = options[:strict] || options["update-strict"]
+ gvp.strict = options[:strict] || options["update-strict"] || options["filter-strict"]
end
end
diff --git a/lib/bundler/cli/config.rb b/lib/bundler/cli/config.rb
index 12f71ea8fe..1df2a55d9a 100644
--- a/lib/bundler/cli/config.rb
+++ b/lib/bundler/cli/config.rb
@@ -1,119 +1,194 @@
# frozen_string_literal: true
module Bundler
- class CLI::Config
- attr_reader :name, :options, :scope, :thor
- attr_accessor :args
-
- def initialize(options, args, thor)
- @options = options
- @args = args
- @thor = thor
- @name = peek = args.shift
- @scope = "global"
- return unless peek && peek.start_with?("--")
- @name = args.shift
- @scope = peek[2..-1]
+ class CLI::Config < Thor
+ class_option :parseable, :type => :boolean, :banner => "Use minimal formatting for more parseable output"
+
+ def self.scope_options
+ method_option :global, :type => :boolean, :banner => "Only change the global config"
+ method_option :local, :type => :boolean, :banner => "Only change the local config"
end
+ private_class_method :scope_options
- def run
- unless name
- confirm_all
- return
- end
+ desc "base NAME [VALUE]", "The Bundler 1 config interface", :hide => true
+ scope_options
+ method_option :delete, :type => :boolean, :banner => "delete"
+ def base(name = nil, *value)
+ new_args =
+ if ARGV.size == 1
+ ["config", "list"]
+ elsif ARGV.include?("--delete")
+ ARGV.map {|arg| arg == "--delete" ? "unset" : arg }
+ elsif ARGV.include?("--global") || ARGV.include?("--local") || ARGV.size == 3
+ ["config", "set", *ARGV[1..-1]]
+ else
+ ["config", "get", ARGV[1]]
+ end
- unless valid_scope?(scope)
- Bundler.ui.error "Invalid scope --#{scope} given. Please use --local or --global."
- exit 1
- end
+ SharedHelpers.major_deprecation 2,
+ "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead."
+
+ Base.new(options, name, value, self).run
+ end
+
+ desc "list", "List out all configured settings"
+ def list
+ Base.new(options, nil, nil, self).run
+ end
+
+ desc "get NAME", "Returns the value for the given key"
+ def get(name)
+ Base.new(options, name, nil, self).run
+ end
+
+ desc "set NAME VALUE", "Sets the given value for the given key"
+ scope_options
+ def set(name, value, *value_)
+ Base.new(options, name, value_.unshift(value), self).run
+ end
- if scope == "delete"
- Bundler.settings.set_local(name, nil)
- Bundler.settings.set_global(name, nil)
- return
+ desc "unset NAME", "Unsets the value for the given key"
+ scope_options
+ def unset(name)
+ options[:delete] = true
+ Base.new(options, name, nil, self).run
+ end
+
+ default_task :base
+
+ class Base
+ attr_reader :name, :value, :options, :scope, :thor
+
+ def initialize(options, name, value, thor)
+ @options = options
+ @name = name
+ value = Array(value)
+ @value = value.empty? ? nil : value.join(" ")
+ @thor = thor
+ validate_scope!
end
- if args.empty?
- if options[:parseable]
- if value = Bundler.settings[name]
- Bundler.ui.info("#{name}=#{value}")
+ def run
+ unless name
+ warn_unused_scope "Ignoring --#{scope}"
+ confirm_all
+ return
+ end
+
+ if options[:delete]
+ if !explicit_scope? || scope != "global"
+ Bundler.settings.set_local(name, nil)
+ end
+ if !explicit_scope? || scope != "local"
+ Bundler.settings.set_global(name, nil)
end
return
end
- confirm(name)
- return
- end
+ if value.nil?
+ warn_unused_scope "Ignoring --#{scope} since no value to set was given"
- Bundler.ui.info(message) if message
- Bundler.settings.send("set_#{scope}", name, new_value)
- end
+ if options[:parseable]
+ if value = Bundler.settings[name]
+ Bundler.ui.info("#{name}=#{value}")
+ end
+ return
+ end
- private
+ confirm(name)
+ return
+ end
- def confirm_all
- if @options[:parseable]
- thor.with_padding do
+ Bundler.ui.info(message) if message
+ Bundler.settings.send("set_#{scope}", name, new_value)
+ end
+
+ def confirm_all
+ if @options[:parseable]
+ thor.with_padding do
+ Bundler.settings.all.each do |setting|
+ val = Bundler.settings[setting]
+ Bundler.ui.info "#{setting}=#{val}"
+ end
+ end
+ else
+ Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n"
Bundler.settings.all.each do |setting|
- val = Bundler.settings[setting]
- Bundler.ui.info "#{setting}=#{val}"
+ Bundler.ui.confirm "#{setting}"
+ show_pretty_values_for(setting)
+ Bundler.ui.confirm ""
end
end
- else
- Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n"
- Bundler.settings.all.each do |setting|
- Bundler.ui.confirm "#{setting}"
- show_pretty_values_for(setting)
- Bundler.ui.confirm ""
- end
end
- end
- def confirm(name)
- Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used"
- show_pretty_values_for(name)
- end
+ def confirm(name)
+ Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used"
+ show_pretty_values_for(name)
+ end
- def new_value
- pathname = Pathname.new(args.join(" "))
- if name.start_with?("local.") && pathname.directory?
- pathname.expand_path.to_s
- else
- args.join(" ")
+ def new_value
+ pathname = Pathname.new(value)
+ if name.start_with?("local.") && pathname.directory?
+ pathname.expand_path.to_s
+ else
+ value
+ end
end
- end
- def message
- locations = Bundler.settings.locations(name)
- if @options[:parseable]
- "#{name}=#{new_value}" if new_value
- elsif scope == "global"
- if locations[:local]
- "Your application has set #{name} to #{locations[:local].inspect}. " \
- "This will override the global value you are currently setting"
- elsif locations[:env]
- "You have a bundler environment variable for #{name} set to " \
- "#{locations[:env].inspect}. This will take precedence over the global value you are setting"
- elsif locations[:global] && locations[:global] != args.join(" ")
- "You are replacing the current global value of #{name}, which is currently " \
- "#{locations[:global].inspect}"
+ def message
+ locations = Bundler.settings.locations(name)
+ if @options[:parseable]
+ "#{name}=#{new_value}" if new_value
+ elsif scope == "global"
+ if !locations[:local].nil?
+ "Your application has set #{name} to #{locations[:local].inspect}. " \
+ "This will override the global value you are currently setting"
+ elsif locations[:env]
+ "You have a bundler environment variable for #{name} set to " \
+ "#{locations[:env].inspect}. This will take precedence over the global value you are setting"
+ elsif !locations[:global].nil? && locations[:global] != value
+ "You are replacing the current global value of #{name}, which is currently " \
+ "#{locations[:global].inspect}"
+ end
+ elsif scope == "local" && !locations[:local].nil? && locations[:local] != value
+ "You are replacing the current local value of #{name}, which is currently " \
+ "#{locations[:local].inspect}"
end
- elsif scope == "local" && locations[:local] != args.join(" ")
- "You are replacing the current local value of #{name}, which is currently " \
- "#{locations[:local].inspect}"
end
- end
- def show_pretty_values_for(setting)
- thor.with_padding do
- Bundler.settings.pretty_values_for(setting).each do |line|
- Bundler.ui.info line
+ def show_pretty_values_for(setting)
+ thor.with_padding do
+ Bundler.settings.pretty_values_for(setting).each do |line|
+ Bundler.ui.info line
+ end
end
end
- end
- def valid_scope?(scope)
- %w[delete local global].include?(scope)
+ def explicit_scope?
+ @explicit_scope
+ end
+
+ def warn_unused_scope(msg)
+ return unless explicit_scope?
+ return if options[:parseable]
+
+ Bundler.ui.warn(msg)
+ end
+
+ def validate_scope!
+ @explicit_scope = true
+ scopes = %w[global local].select {|s| options[s] }
+ case scopes.size
+ when 0
+ @scope = "global"
+ @explicit_scope = false
+ when 1
+ @scope = scopes.first
+ else
+ raise InvalidOption,
+ "The options #{scopes.join " and "} were specified. Please only use one of the switches at a time."
+ end
+ end
end
end
end
diff --git a/lib/bundler/cli/console.rb b/lib/bundler/cli/console.rb
index d45f30cdcf..6e0dfe28af 100644
--- a/lib/bundler/cli/console.rb
+++ b/lib/bundler/cli/console.rb
@@ -9,10 +9,10 @@ module Bundler
end
def run
- Bundler::SharedHelpers.major_deprecation 3, "bundle console will be replaced " \
+ Bundler::SharedHelpers.major_deprecation 2, "bundle console will be replaced " \
"by `bin/console` generated by `bundle gem <name>`"
- group ? Bundler.require(:default, *(group.split.map!(&:to_sym))) : Bundler.require
+ group ? Bundler.require(:default, *group.split.map!(&:to_sym)) : Bundler.require
ARGV.clear
console = get_console(Bundler.settings[:console] || "irb")
diff --git a/lib/bundler/cli/doctor.rb b/lib/bundler/cli/doctor.rb
index 3e0898ff8a..6d038937c0 100644
--- a/lib/bundler/cli/doctor.rb
+++ b/lib/bundler/cli/doctor.rb
@@ -4,8 +4,8 @@ require "rbconfig"
module Bundler
class CLI::Doctor
- DARWIN_REGEX = /\s+(.+) \(compatibility /
- LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/
+ DARWIN_REGEX = /\s+(.+) \(compatibility /.freeze
+ LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/.freeze
attr_reader :options
diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb
index 58e2f8a3fd..3db1ec7843 100644
--- a/lib/bundler/cli/gem.rb
+++ b/lib/bundler/cli/gem.rb
@@ -11,7 +11,7 @@ module Bundler
class CLI::Gem
TEST_FRAMEWORK_VERSIONS = {
"rspec" => "3.0",
- "minitest" => "5.0"
+ "minitest" => "5.0",
}.freeze
attr_reader :options, :gem_name, :thor, :name, :target
@@ -57,7 +57,7 @@ module Bundler
:ext => options[:ext],
:exe => options[:exe],
:bundler_version => bundler_dependency_version,
- :github_username => github_username.empty? ? "[USERNAME]" : github_username
+ :github_username => github_username.empty? ? "[USERNAME]" : github_username,
}
ensure_safe_gem_name(name, constant_array)
@@ -69,7 +69,7 @@ module Bundler
"Rakefile.tt" => "Rakefile",
"README.md.tt" => "README.md",
"bin/console.tt" => "bin/console",
- "bin/setup.tt" => "bin/setup"
+ "bin/setup.tt" => "bin/setup",
}
executables = %w[
diff --git a/lib/bundler/cli/info.rb b/lib/bundler/cli/info.rb
index 958b525067..4733675e8c 100644
--- a/lib/bundler/cli/info.rb
+++ b/lib/bundler/cli/info.rb
@@ -9,18 +9,24 @@ module Bundler
end
def run
+ Bundler.ui.silence do
+ Bundler.definition.validate_runtime!
+ Bundler.load.lock
+ end
+
spec = spec_for_gem(gem_name)
- spec_not_found(gem_name) unless spec
- return print_gem_path(spec) if @options[:path]
- print_gem_info(spec)
+ if spec
+ return print_gem_path(spec) if @options[:path]
+ print_gem_info(spec)
+ end
end
private
def spec_for_gem(gem_name)
spec = Bundler.definition.specs.find {|s| s.name == gem_name }
- spec || default_gem_spec(gem_name)
+ spec || default_gem_spec(gem_name) || Bundler::CLI::Common.select_spec(gem_name, :regex_match)
end
def default_gem_spec(gem_name)
@@ -34,7 +40,13 @@ module Bundler
end
def print_gem_path(spec)
- Bundler.ui.info spec.full_gem_path
+ path = if spec.name == "bundler"
+ File.expand_path("../../../..", __FILE__)
+ else
+ spec.full_gem_path
+ end
+
+ Bundler.ui.info path
end
def print_gem_info(spec)
diff --git a/lib/bundler/cli/init.rb b/lib/bundler/cli/init.rb
index 40df797269..65dd08dfe9 100644
--- a/lib/bundler/cli/init.rb
+++ b/lib/bundler/cli/init.rb
@@ -41,7 +41,7 @@ module Bundler
private
def gemfile
- @gemfile ||= Bundler.feature_flag.init_gems_rb? ? "gems.rb" : "Gemfile"
+ @gemfile ||= Bundler.settings[:init_gems_rb] ? "gems.rb" : "Gemfile"
end
end
end
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index 55e90ead0e..03edc7fbd2 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -53,7 +53,7 @@ module Bundler
Bundler::Fetcher.disable_endpoint = options["full-index"]
if options["binstubs"]
- Bundler::SharedHelpers.major_deprecation 3,
+ Bundler::SharedHelpers.major_deprecation 2,
"The --binstubs option will be removed in favor of `bundle binstubs`"
end
@@ -202,15 +202,16 @@ module Bundler
end
def warn_ambiguous_gems
+ # TODO: remove this when we drop Bundler 1.x support
Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris|
- Bundler.ui.error "Warning: the gem '#{name}' was found in multiple sources."
- Bundler.ui.error "Installed from: #{installed_from_uri}"
- Bundler.ui.error "Also found in:"
- also_found_in_uris.each {|uri| Bundler.ui.error " * #{uri}" }
- Bundler.ui.error "You should add a source requirement to restrict this gem to your preferred source."
- Bundler.ui.error "For example:"
- Bundler.ui.error " gem '#{name}', :source => '#{installed_from_uri}'"
- Bundler.ui.error "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
+ Bundler.ui.warn "Warning: the gem '#{name}' was found in multiple sources."
+ Bundler.ui.warn "Installed from: #{installed_from_uri}"
+ Bundler.ui.warn "Also found in:"
+ also_found_in_uris.each {|uri| Bundler.ui.warn " * #{uri}" }
+ Bundler.ui.warn "You should add a source requirement to restrict this gem to your preferred source."
+ Bundler.ui.warn "For example:"
+ Bundler.ui.warn " gem '#{name}', :source => '#{installed_from_uri}'"
+ Bundler.ui.warn "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
end
end
end
diff --git a/lib/bundler/cli/issue.rb b/lib/bundler/cli/issue.rb
index 91f827ea99..bba1619340 100644
--- a/lib/bundler/cli/issue.rb
+++ b/lib/bundler/cli/issue.rb
@@ -13,10 +13,10 @@ module Bundler
https://github.com/bundler/bundler/blob/master/doc/TROUBLESHOOTING.md
2. Instructions for common Bundler uses can be found on the documentation
- site: http://bundler.io/
+ site: https://bundler.io/
3. Information about each Bundler command can be found in the Bundler
- man pages: http://bundler.io/man/bundle.1.html
+ man pages: https://bundler.io/man/bundle.1.html
Hopefully the troubleshooting steps above resolved your problem! If things
still aren't working the way you expect them to, please let us know so
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
index 2ca90293db..3a0521de1e 100644
--- a/lib/bundler/cli/outdated.rb
+++ b/lib/bundler/cli/outdated.rb
@@ -41,7 +41,7 @@ module Bundler
# the patch level options imply strict is also true. It wouldn't make
# sense otherwise.
- strict = options[:strict] ||
+ strict = options["filter-strict"] ||
Bundler::CLI::Common.patch_level_options(options).any?
filter_options_patch = options.keys &
@@ -124,7 +124,7 @@ module Bundler
[nil, ordered_groups].flatten.each do |groups|
gems = outdated_gems_by_groups[groups]
contains_group = if groups
- groups.split(",").include?(options[:group])
+ groups.split(", ").include?(options[:group])
else
options[:group] == "group"
end
@@ -221,9 +221,9 @@ module Bundler
def check_for_deployment_mode
return unless Bundler.frozen_bundle?
suggested_command = if Bundler.settings.locations("frozen")[:global]
- "bundle config --delete frozen"
+ "bundle config unset frozen"
elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
- "bundle config --delete deployment"
+ "bundle config unset deployment"
else
"bundle install --no-deployment"
end
diff --git a/lib/bundler/cli/package.rb b/lib/bundler/cli/package.rb
index 2dcd0e1e29..cd01ce422e 100644
--- a/lib/bundler/cli/package.rb
+++ b/lib/bundler/cli/package.rb
@@ -42,7 +42,7 @@ module Bundler
if Bundler.definition.has_local_dependencies? && !Bundler.feature_flag.cache_all?
Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
"to package them as well, please pass the --all flag. This will be the default " \
- "on Bundler 2.0."
+ "on Bundler 3.0."
end
end
end
diff --git a/lib/bundler/cli/plugin.rb b/lib/bundler/cli/plugin.rb
index 5488a9f28d..b5dd5b6d4b 100644
--- a/lib/bundler/cli/plugin.rb
+++ b/lib/bundler/cli/plugin.rb
@@ -5,7 +5,7 @@ module Bundler
class CLI::Plugin < Thor
desc "install PLUGINS", "Install the plugin from the source"
long_desc <<-D
- Install plugins either from the rubygems source provided (with --source option) or from a git source provided with (--git option). If no sources are provided, it uses Gem.sources
+ Install plugins either from the rubygems source provided (with --source option) or from a git source provided with --git (for remote repos) or --local_git (for local repos). If no sources are provided, it uses Gem.sources
D
method_option "source", :type => :string, :default => nil, :banner =>
"URL of the RubyGems source to fetch the plugin from"
@@ -13,6 +13,8 @@ module Bundler
"The version of the plugin to fetch"
method_option "git", :type => :string, :default => nil, :banner =>
"URL of the git repo to fetch from"
+ method_option "local_git", :type => :string, :default => nil, :banner =>
+ "Path of the local git repo to fetch from"
method_option "branch", :type => :string, :default => nil, :banner =>
"The git branch to checkout"
method_option "ref", :type => :string, :default => nil, :banner =>
@@ -20,5 +22,10 @@ module Bundler
def install(*plugins)
Bundler::Plugin.install(plugins, options)
end
+
+ desc "list", "List the installed plugins and available commands"
+ def list
+ Bundler::Plugin.list
+ end
end
end
diff --git a/lib/bundler/cli/pristine.rb b/lib/bundler/cli/pristine.rb
index 4a411a83fc..532b3e0b5b 100644
--- a/lib/bundler/cli/pristine.rb
+++ b/lib/bundler/cli/pristine.rb
@@ -33,7 +33,7 @@ module Bundler
if extension_cache_path = source.extension_cache_path(spec)
FileUtils.rm_rf extension_cache_path
end
- FileUtils.rm_rf spec.extension_dir if spec.respond_to?(:extension_dir)
+ FileUtils.rm_rf spec.extension_dir
FileUtils.rm_rf spec.full_gem_path
else
Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
diff --git a/lib/bundler/cli/show.rb b/lib/bundler/cli/show.rb
index 61756801b2..3748c25b89 100644
--- a/lib/bundler/cli/show.rb
+++ b/lib/bundler/cli/show.rb
@@ -24,7 +24,7 @@ module Bundler
return unless spec
path = spec.full_gem_path
unless File.directory?(path)
- Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at:"
+ return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}"
end
end
return Bundler.ui.info(path)
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
index bf300a8437..b088853768 100644
--- a/lib/bundler/cli/update.rb
+++ b/lib/bundler/cli/update.rb
@@ -22,7 +22,7 @@ module Bundler
if Bundler.feature_flag.update_requires_all_flag?
raise InvalidOption, "To update everything, pass the `--all` flag."
end
- SharedHelpers.major_deprecation 3, "Pass --all to `bundle update` to update everything"
+ SharedHelpers.major_deprecation 2, "Pass --all to `bundle update` to update everything"
elsif !full_update && options[:all]
raise InvalidOption, "Cannot specify --all along with specific options."
end
diff --git a/lib/bundler/compact_index_client.rb b/lib/bundler/compact_index_client.rb
index 6c241ca07a..2f713041c8 100644
--- a/lib/bundler/compact_index_client.rb
+++ b/lib/bundler/compact_index_client.rb
@@ -18,11 +18,6 @@ module Bundler
attr_reader :directory
- # @return [Lambda] A lambda that takes an array of inputs and a block, and
- # maps the inputs with the block in parallel.
- #
- attr_accessor :in_parallel
-
def initialize(directory, fetcher)
@directory = Pathname.new(directory)
@updater = Updater.new(fetcher)
@@ -31,7 +26,28 @@ module Bundler
@info_checksums_by_name = {}
@parsed_checksums = false
@mutex = Mutex.new
- @in_parallel = lambda do |inputs, &blk|
+ end
+
+ def execution_mode=(block)
+ Bundler::CompactIndexClient.debug { "execution_mode=" }
+ @endpoints = Set.new
+
+ @execution_mode = block
+ end
+
+ # @return [Lambda] A lambda that takes an array of inputs and a block, and
+ # maps the inputs with the block in parallel.
+ #
+ def execution_mode
+ @execution_mode || sequentially
+ end
+
+ def sequential_execution_mode!
+ self.execution_mode = sequentially
+ end
+
+ def sequentially
+ @sequentially ||= lambda do |inputs, &blk|
inputs.map(&blk)
end
end
@@ -51,7 +67,7 @@ module Bundler
def dependencies(names)
Bundler::CompactIndexClient.debug { "dependencies(#{names})" }
- in_parallel.call(names) do |name|
+ execution_mode.call(names) do |name|
update_info(name)
@cache.dependencies(name).map {|d| d.unshift(name) }
end.flatten(1)
diff --git a/lib/bundler/compact_index_client/updater.rb b/lib/bundler/compact_index_client/updater.rb
index 4d6eb80044..d77285072c 100644
--- a/lib/bundler/compact_index_client/updater.rb
+++ b/lib/bundler/compact_index_client/updater.rb
@@ -95,11 +95,7 @@ module Bundler
end
def slice_body(body, range)
- if body.respond_to?(:byteslice)
- body.byteslice(range)
- else # pre-1.9.3
- body.unpack("@#{range.first}a#{range.end + 1}").first
- end
+ body.byteslice(range)
end
def checksum_for_file(path)
diff --git a/lib/bundler/compatibility_guard.rb b/lib/bundler/compatibility_guard.rb
index 750a1db04f..958116ce55 100644
--- a/lib/bundler/compatibility_guard.rb
+++ b/lib/bundler/compatibility_guard.rb
@@ -1,14 +1,9 @@
# frozen_string_literal: false
-require "rubygems"
require "bundler/version"
if Bundler::VERSION.split(".").first.to_i >= 2
if Gem::Version.new(Object::RUBY_VERSION.dup) < Gem::Version.new("2.3")
abort "Bundler 2 requires Ruby 2.3 or later. Either install bundler 1 or update to a supported Ruby version."
end
-
- if Gem::Version.new(Gem::VERSION.dup) < Gem::Version.new("2.5")
- abort "Bundler 2 requires RubyGems 2.5 or later. Either install bundler 1 or update to a supported RubyGems version."
- end
end
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index c5e94c7123..f9daae067c 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -331,7 +331,7 @@ module Bundler
# i.e., Windows with `git config core.autocrlf=true`
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
- if @locked_bundler_version && Bundler.feature_flag.lockfile_upgrade_warning?
+ if @locked_bundler_version
locked_major = @locked_bundler_version.segments.first
current_major = Gem::Version.create(Bundler::VERSION).segments.first
@@ -397,9 +397,9 @@ module Bundler
unless explicit_flag
suggested_command = if Bundler.settings.locations("frozen")[:global]
- "bundle config --delete frozen"
+ "bundle config unset frozen"
elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
- "bundle config --delete deployment"
+ "bundle config unset deployment"
else
"bundle install --no-deployment"
end
@@ -643,7 +643,7 @@ module Bundler
end
def converge_rubygems_sources
- return false if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
+ return false if Bundler.feature_flag.disable_multisource?
changes = false
@@ -855,8 +855,8 @@ module Bundler
concat_ruby_version_requirements(locked_ruby_version_object) unless @unlock[:ruby]
end
[
- Dependency.new("ruby\0", ruby_versions),
- Dependency.new("rubygems\0", Gem::VERSION),
+ Dependency.new("Ruby\0", ruby_versions),
+ Dependency.new("RubyGems\0", Gem::VERSION),
]
end
end
@@ -915,7 +915,7 @@ module Bundler
# look for that gemspec (or its dependencies)
default = sources.default_source
source_requirements = { :default => default }
- default = nil unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
+ default = nil unless Bundler.feature_flag.disable_multisource?
dependencies.each do |dep|
next unless source = dep.source || default
source_requirements[dep.name] = source
@@ -929,7 +929,7 @@ module Bundler
def pinned_spec_names(skip = nil)
pinned_names = []
- default = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? && sources.default_source
+ default = Bundler.feature_flag.disable_multisource? && sources.default_source
@dependencies.each do |dep|
next unless dep_source = dep.source || default
next if dep_source == skip
@@ -977,7 +977,9 @@ module Bundler
dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
name = locked_spec.name
- next requirements if @locked_gems.dependencies[name] != dependencies_by_name[name]
+ dependency = dependencies_by_name[name]
+ next requirements if @locked_gems.dependencies[name] != dependency
+ next requirements if dependency && dependency.source.is_a?(Source::Path)
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
requirements[name] = DepProxy.new(dep, locked_spec.platform)
requirements
diff --git a/lib/bundler/deployment.rb b/lib/bundler/deployment.rb
index 4c8f48d405..291e158ca0 100644
--- a/lib/bundler/deployment.rb
+++ b/lib/bundler/deployment.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "bundler/shared_helpers"
-Bundler::SharedHelpers.major_deprecation 3, "Bundler no longer integrates with " \
+Bundler::SharedHelpers.major_deprecation 2, "Bundler no longer integrates with " \
"Capistrano, but Capistrano provides its own integration with " \
"Bundler via the capistrano-bundler gem. Use it instead."
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 90ac073c36..7424a5c8a4 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -45,7 +45,7 @@ module Bundler
@gemfiles << expanded_gemfile_path
contents ||= Bundler.read_file(@gemfile.to_s)
instance_eval(contents.dup.untaint, gemfile.to_s, 1)
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
message = "There was an error " \
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
"`#{File.basename gemfile.to_s}`: #{e.message}"
@@ -194,7 +194,7 @@ module Bundler
" end\n\n"
raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource?
- SharedHelpers.major_deprecation(3, msg.strip)
+ SharedHelpers.major_deprecation(2, msg.strip)
end
source_options = normalize_hash(options).merge(
@@ -290,37 +290,21 @@ module Bundler
warn_deprecated_git_source(:github, <<-'RUBY'.strip, 'Change any "reponame" :github sources to "username/reponame".')
"https://github.com/#{repo_name}.git"
RUBY
- # It would be better to use https instead of the git protocol, but this
- # can break deployment of existing locked bundles when switching between
- # different versions of Bundler. The change will be made in 2.0, which
- # does not guarantee compatibility with the 1.x series.
- #
- # See https://github.com/bundler/bundler/pull/2569 for discussion
- #
- # This can be overridden by adding this code to your Gemfiles:
- #
- # git_source(:github) do |repo_name|
- # repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
- # "https://github.com/#{repo_name}.git"
- # end
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
- # TODO: 2.0 upgrade this setting to the default
- if Bundler.settings["github.https"]
- Bundler::SharedHelpers.major_deprecation 3, "The `github.https` setting will be removed"
+ if Bundler.feature_flag.github_https?
"https://github.com/#{repo_name}.git"
else
+ Bundler::SharedHelpers.major_deprecation 2, "Setting `github.https` to false is deprecated and won't be supported in the future."
"git://github.com/#{repo_name}.git"
end
end
- # TODO: 2.0 remove this deprecated git source
git_source(:gist) do |repo_name|
warn_deprecated_git_source(:gist, '"https://gist.github.com/#{repo_name}.git"')
"https://gist.github.com/#{repo_name}.git"
end
- # TODO: 2.0 remove this deprecated git source
git_source(:bitbucket) do |repo_name|
warn_deprecated_git_source(:bitbucket, <<-'RUBY'.strip)
user_name, repo_name = repo_name.split("/")
@@ -363,9 +347,7 @@ repo_name ||= user_name
if name =~ /\s/
raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace)
end
- if name.empty?
- raise GemfileError, %(an empty gem name is not valid)
- end
+ raise GemfileError, %(an empty gem name is not valid) if name.empty?
normalize_hash(opts)
@@ -443,10 +425,10 @@ repo_name ||= user_name
message = String.new
message << "You passed #{invalid_keys.map {|k| ":" + k }.join(", ")} "
message << if invalid_keys.size > 1
- "as options for #{command}, but they are invalid."
- else
- "as an option for #{command}, but it is invalid."
- end
+ "as options for #{command}, but they are invalid."
+ else
+ "as an option for #{command}, but it is invalid."
+ end
message << " Valid options are: #{valid_keys.join(", ")}."
message << " You may be able to resolve this by upgrading Bundler to the newest version."
@@ -456,7 +438,7 @@ repo_name ||= user_name
def normalize_source(source)
case source
when :gemcutter, :rubygems, :rubyforge
- Bundler::SharedHelpers.major_deprecation 3, "The source :#{source} is deprecated because HTTP " \
+ Bundler::SharedHelpers.major_deprecation 2, "The source :#{source} is deprecated because HTTP " \
"requests are insecure.\nPlease change your source to 'https://" \
"rubygems.org' if possible, or 'http://rubygems.org' if not."
"http://rubygems.org"
@@ -474,23 +456,22 @@ repo_name ||= user_name
msg = "This Gemfile contains multiple primary sources. " \
"Each source after the first must include a block to indicate which gems " \
"should come from that source"
- unless Bundler.feature_flag.bundler_3_mode?
+ unless Bundler.feature_flag.bundler_2_mode?
msg += ". To downgrade this error to a warning, run " \
- "`bundle config --delete disable_multisource`"
+ "`bundle config unset disable_multisource`"
end
raise GemfileEvalError, msg
else
- Bundler::SharedHelpers.major_deprecation 3, "Your Gemfile contains multiple primary sources. " \
+ Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source. " \
- "To upgrade this warning to an error, run `bundle config " \
+ "To upgrade this warning to an error, run `bundle config set " \
"disable_multisource true`."
end
end
def warn_deprecated_git_source(name, replacement, additional_message = nil)
- # TODO: 2.0 remove deprecation
additional_message &&= " #{additional_message}"
replacement = if replacement.count("\n").zero?
"{|repo_name| #{replacement} }"
@@ -499,7 +480,7 @@ repo_name ||= user_name
end
Bundler::SharedHelpers.major_deprecation 3, <<-EOS
-The :#{name} git source is deprecated, and will be removed in Bundler 3.0.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
+The :#{name} git source is deprecated, and will be removed in the future.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
git_source(:#{name}) #{replacement}
@@ -601,7 +582,7 @@ The :#{name} git source is deprecated, and will be removed in Bundler 3.0.#{addi
description = self.description
if dsl_path && description =~ /((#{Regexp.quote File.expand_path(dsl_path)}|#{Regexp.quote dsl_path.to_s}):\d+)/
trace_line = Regexp.last_match[1]
- description = description.sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
+ description = description.sub(/\n.*\n(\.\.\.)? *\^~+$/, "").sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
end
[trace_line, description]
end
diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb
index 51738139fa..9cd9b8baca 100644
--- a/lib/bundler/env.rb
+++ b/lib/bundler/env.rb
@@ -70,14 +70,8 @@ module Bundler
def self.ruby_version
str = String.new("#{RUBY_VERSION}")
- if RUBY_VERSION < "1.9"
- str << " (#{RUBY_RELEASE_DATE}"
- str << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
- str << ") [#{RUBY_PLATFORM}]"
- else
- str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
- str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]"
- end
+ str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
+ str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]"
end
def self.git_version
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index e5b4e84063..982f0fa540 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -19,7 +19,7 @@ module Bundler
def self.settings_method(name, key, &default)
define_method(name) do
value = Bundler.settings[key]
- value = instance_eval(&default) if value.nil? && !default.nil?
+ value = instance_eval(&default) if value.nil?
value
end
end
@@ -33,7 +33,6 @@ module Bundler
settings_flag(:auto_config_jobs) { bundler_3_mode? }
settings_flag(:cache_all) { bundler_3_mode? }
settings_flag(:cache_command_is_package) { bundler_3_mode? }
- settings_flag(:console_command) { !bundler_3_mode? }
settings_flag(:default_install_uses_path) { bundler_3_mode? }
settings_flag(:deployment_means_frozen) { bundler_3_mode? }
settings_flag(:disable_multisource) { bundler_3_mode? }
@@ -41,23 +40,17 @@ module Bundler
settings_flag(:forget_cli_options) { bundler_3_mode? }
settings_flag(:global_path_appends_ruby_scope) { bundler_3_mode? }
settings_flag(:global_gem_cache) { bundler_3_mode? }
- settings_flag(:init_gems_rb) { bundler_3_mode? }
- settings_flag(:list_command) { bundler_3_mode? }
- settings_flag(:lockfile_uses_separate_rubygems_sources) { bundler_3_mode? }
- settings_flag(:lockfile_upgrade_warning) { bundler_3_mode? }
settings_flag(:only_update_to_newer_versions) { bundler_3_mode? }
settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
- settings_flag(:prefer_gems_rb) { bundler_3_mode? }
settings_flag(:print_only_version_number) { bundler_3_mode? }
settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
- settings_flag(:skip_default_git_sources) { bundler_3_mode? }
+ settings_flag(:skip_default_git_sources) { bundler_4_mode? }
settings_flag(:specific_platform) { bundler_3_mode? }
settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? }
settings_flag(:update_requires_all_flag) { bundler_3_mode? }
settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? }
- settings_flag(:viz_command) { !bundler_3_mode? }
settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install }
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb
index 4dd42e42ff..8397f7b72b 100644
--- a/lib/bundler/fetcher.rb
+++ b/lib/bundler/fetcher.rb
@@ -4,6 +4,7 @@ require "bundler/vendored_persistent"
require "cgi"
require "securerandom"
require "zlib"
+require "rubygems/request"
module Bundler
# Handles all the fetching with the rubygems server
@@ -15,6 +16,8 @@ module Bundler
# This error is raised when it looks like the network is down
class NetworkDownError < HTTPError; end
+ # This error is raised if we should rate limit our requests to the API
+ class TooManyRequestsError < HTTPError; end
# This error is raised if the API returns a 413 (only printed in verbose)
class FallbackError < HTTPError; end
# This is the error raised if OpenSSL fails the cert verification
@@ -44,7 +47,7 @@ module Bundler
remote_uri = filter_uri(remote_uri)
super "Authentication is required for #{remote_uri}.\n" \
"Please supply credentials for this source. You can do this by running:\n" \
- " bundle config #{remote_uri} username:password"
+ " bundle config set #{remote_uri} username:password"
end
end
# This error is raised if HTTP authentication is provided, but incorrect.
@@ -226,7 +229,7 @@ module Bundler
"GO_SERVER_URL" => "go",
"SNAP_CI" => "snap",
"CI_NAME" => ENV["CI_NAME"],
- "CI" => "ci"
+ "CI" => "ci",
}
env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci }
end
@@ -293,8 +296,7 @@ module Bundler
end
else
store.set_default_paths
- certs = File.expand_path("../ssl_certs/*/*.pem", __FILE__)
- Dir.glob(certs).each {|c| store.add_file c }
+ Gem::Request.get_cert_files.each {|c| store.add_file c }
end
store
end
diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb
index cfc74d642c..a117af72fa 100644
--- a/lib/bundler/fetcher/compact_index.rb
+++ b/lib/bundler/fetcher/compact_index.rb
@@ -39,7 +39,13 @@ module Bundler
until remaining_gems.empty?
log_specs "Looking up gems #{remaining_gems.inspect}"
- deps = compact_index_client.dependencies(remaining_gems)
+ deps = begin
+ parallel_compact_index_client.dependencies(remaining_gems)
+ rescue TooManyRequestsError
+ @bundle_worker.stop if @bundle_worker
+ @bundle_worker = nil # reset it. Not sure if necessary
+ serial_compact_index_client.dependencies(remaining_gems)
+ end
next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
deps.each {|dep| gem_info << dep }
complete_gems.concat(deps.map(&:first)).uniq!
@@ -80,18 +86,26 @@ module Bundler
private
def compact_index_client
- @compact_index_client ||= begin
+ @compact_index_client ||=
SharedHelpers.filesystem_access(cache_path) do
CompactIndexClient.new(cache_path, client_fetcher)
- end.tap do |client|
- client.in_parallel = lambda do |inputs, &blk|
- func = lambda {|object, _index| blk.call(object) }
- worker = bundle_worker(func)
- inputs.each {|input| worker.enq(input) }
- inputs.map { worker.deq }
- end
end
+ end
+
+ def parallel_compact_index_client
+ compact_index_client.execution_mode = lambda do |inputs, &blk|
+ func = lambda {|object, _index| blk.call(object) }
+ worker = bundle_worker(func)
+ inputs.each {|input| worker.enq(input) }
+ inputs.map { worker.deq }
end
+
+ compact_index_client
+ end
+
+ def serial_compact_index_client
+ compact_index_client.sequential_execution_mode!
+ compact_index_client
end
def bundle_worker(func = nil)
diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb
index e0e0cbf1c9..2aeb9962c4 100644
--- a/lib/bundler/fetcher/downloader.rb
+++ b/lib/bundler/fetcher/downloader.rb
@@ -34,10 +34,12 @@ module Bundler
fetch(uri, new_headers)
when Net::HTTPRequestEntityTooLarge
raise FallbackError, response.body
+ when Net::HTTPTooManyRequests
+ raise TooManyRequestsError, response.body
when Net::HTTPUnauthorized
raise AuthenticationRequiredError, uri.host
when Net::HTTPNotFound
- raise FallbackError, "Net::HTTPNotFound"
+ raise FallbackError, "Net::HTTPNotFound: #{URICredentialsFilter.credential_filtered_uri(uri)}"
else
raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
end
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
index ae3299a7c8..dd9b847f10 100644
--- a/lib/bundler/friendly_errors.rb
+++ b/lib/bundler/friendly_errors.rb
@@ -1,4 +1,3 @@
-# encoding: utf-8
# frozen_string_literal: true
require "cgi"
@@ -45,7 +44,7 @@ module Bundler
"Alternatively, you can increase the amount of memory the JVM is able to use by running Bundler with jruby -J-Xmx1024m -S bundle (JRuby defaults to 500MB)."
else request_issue_report_for(error)
end
- rescue
+ rescue StandardError
raise error
end
@@ -124,7 +123,7 @@ module Bundler
yield
rescue SignalException
raise
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
FriendlyErrors.log_error(e)
exit FriendlyErrors.exit_status(e)
end
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb
index 55f484f723..e9ee03b8a2 100644
--- a/lib/bundler/gem_helper.rb
+++ b/lib/bundler/gem_helper.rb
@@ -2,6 +2,7 @@
require "bundler/vendored_thor" unless defined?(Thor)
require "bundler"
+require "shellwords"
module Bundler
class GemHelper
@@ -75,7 +76,7 @@ module Bundler
def build_gem
file_name = nil
gem = ENV["BUNDLE_GEM"] ? ENV["BUNDLE_GEM"] : "gem"
- sh("#{gem} build -V '#{spec_path}'") do
+ sh(%W[#{gem} build -V #{spec_path}]) do
file_name = File.basename(built_gem_path)
SharedHelpers.filesystem_access(File.join(base, "pkg")) {|p| FileUtils.mkdir_p(p) }
FileUtils.mv(built_gem_path, "pkg")
@@ -87,17 +88,21 @@ module Bundler
def install_gem(built_gem_path = nil, local = false)
built_gem_path ||= build_gem
gem = ENV["BUNDLE_GEM"] ? ENV["BUNDLE_GEM"] : "gem"
- out, _ = sh_with_code("#{gem} install '#{built_gem_path}'#{" --local" if local}")
- raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
+ cmd = %W[#{gem} install #{built_gem_path}]
+ cmd << "--local" if local
+ out, status = sh_with_status(cmd)
+ unless status.success? && out[/Successfully installed/]
+ raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output"
+ end
Bundler.ui.confirm "#{name} (#{version}) installed."
end
protected
def rubygem_push(path)
- gem_command = "gem push '#{path}'"
- gem_command += " --key #{gem_key}" if gem_key
- gem_command += " --host #{allowed_push_host}" if allowed_push_host
+ gem_command = %W[gem push #{path}]
+ gem_command << "--key" << gem_key if gem_key
+ gem_command << "--host" << allowed_push_host if allowed_push_host
unless allowed_push_host || Bundler.user_home.join(".gem/credentials").file?
raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
end
@@ -129,12 +134,14 @@ module Bundler
def perform_git_push(options = "")
cmd = "git push #{options}"
- out, code = sh_with_code(cmd)
- raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
+ out, status = sh_with_status(cmd)
+ return if status.success?
+ cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
+ raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n"
end
def already_tagged?
- return false unless sh("git tag").split(/\n/).include?(version_tag)
+ return false unless sh(%w[git tag]).split(/\n/).include?(version_tag)
Bundler.ui.confirm "Tag #{version_tag} has already been created."
true
end
@@ -144,20 +151,20 @@ module Bundler
end
def clean?
- sh_with_code("git diff --exit-code")[1] == 0
+ sh_with_status(%w[git diff --exit-code])[1].success?
end
def committed?
- sh_with_code("git diff-index --quiet --cached HEAD")[1] == 0
+ sh_with_status(%w[git diff-index --quiet --cached HEAD])[1].success?
end
def tag_version
- sh "git tag -m \"Version #{version}\" #{version_tag}"
+ sh %W[git tag -m Version\ #{version} #{version_tag}]
Bundler.ui.confirm "Tagged #{version_tag}."
yield if block_given?
rescue RuntimeError
Bundler.ui.error "Untagging #{version_tag} due to error."
- sh_with_code "git tag -d #{version_tag}"
+ sh_with_status %W[git tag -d #{version_tag}]
raise
end
@@ -174,21 +181,20 @@ module Bundler
end
def sh(cmd, &block)
- out, code = sh_with_code(cmd, &block)
- unless code.zero?
+ out, status = sh_with_status(cmd, &block)
+ unless status.success?
+ cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
end
out
end
- def sh_with_code(cmd, &block)
- cmd += " 2>&1"
- outbuf = String.new
+ def sh_with_status(cmd, &block)
Bundler.ui.debug(cmd)
SharedHelpers.chdir(base) do
- outbuf = `#{cmd}`
- status = $?.exitstatus
- block.call(outbuf) if status.zero? && block
+ outbuf = IO.popen(cmd, :err => [:child, :out], &:read)
+ status = $?
+ block.call(outbuf) if status.success? && block
[outbuf, status]
end
end
diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb
index 019ae10c66..9d35169b99 100644
--- a/lib/bundler/gem_helpers.rb
+++ b/lib/bundler/gem_helpers.rb
@@ -10,7 +10,7 @@ module Bundler
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
[Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
- [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")]
+ [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
].freeze
def generic(p)
diff --git a/lib/bundler/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb
index adb951a7a0..ed950ad28b 100644
--- a/lib/bundler/gem_version_promoter.rb
+++ b/lib/bundler/gem_version_promoter.rb
@@ -109,7 +109,7 @@ module Bundler
must_match = minor? ? [0] : [0, 1]
matches = must_match.map {|idx| gsv.segments[idx] == lsv.segments[idx] }
- (matches.uniq == [true]) ? (gsv >= lsv) : false
+ matches.uniq == [true] ? (gsv >= lsv) : false
else
true
end
diff --git a/lib/bundler/graph.rb b/lib/bundler/graph.rb
index de6bba0214..5644e41079 100644
--- a/lib/bundler/graph.rb
+++ b/lib/bundler/graph.rb
@@ -117,7 +117,7 @@ module Bundler
:style => "filled",
:fillcolor => "#B9B9D5",
:shape => "box3d",
- :fontsize => 16
+ :fontsize => 16,
}.merge(@node_options[group])
)
end
@@ -142,7 +142,7 @@ module Bundler
g.output @output_format.to_sym => "#{@output_file}.#{@output_format}"
Bundler.ui.info "#{@output_file}.#{@output_format}"
rescue ArgumentError => e
- $stderr.puts "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
+ warn "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
raise e
end
end
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
index 1bb29f0b36..e67469f2dd 100644
--- a/lib/bundler/injector.rb
+++ b/lib/bundler/injector.rb
@@ -123,7 +123,7 @@ module Bundler
end
end
- # evalutes a gemfile to remove the specified gem
+ # evaluates a gemfile to remove the specified gem
# from it.
def remove_deps(gemfile_path)
initial_gemfile = IO.readlines(gemfile_path)
@@ -136,8 +136,8 @@ module Bundler
removed_deps = remove_gems_from_dependencies(builder, @deps, gemfile_path)
- # abort the opertion if no gems were removed
- # no need to operate on gemfile furthur
+ # abort the operation if no gems were removed
+ # no need to operate on gemfile further
return [] if removed_deps.empty?
cleaned_gemfile = remove_gems_from_gemfile(@deps, gemfile_path)
@@ -153,8 +153,8 @@ module Bundler
# @param [Dsl] builder Dsl object of current Gemfile.
# @param [Array] gems Array of names of gems to be removed.
- # @param [Pathname] path of the Gemfile
- # @return [Array] removed_deps Array of removed dependencies.
+ # @param [Pathname] gemfile_path Path of the Gemfile.
+ # @return [Array] Array of removed dependencies.
def remove_gems_from_dependencies(builder, gems, gemfile_path)
removed_deps = []
@@ -206,7 +206,7 @@ module Bundler
nested_blocks -= 1
gemfile.each_with_index do |line, index|
- next unless !line.nil? && line.include?(block_name)
+ next unless !line.nil? && line.strip.start_with?(block_name)
if gemfile[index + 1] =~ /^\s*end\s*$/
gemfile[index] = nil
gemfile[index + 1] = nil
@@ -222,7 +222,7 @@ module Bundler
# @param [Array] removed_deps Array of removed dependencies.
# @param [Array] initial_gemfile Contents of original Gemfile before any operation.
def cross_check_for_errors(gemfile_path, original_deps, removed_deps, initial_gemfile)
- # evalute the new gemfile to look for any failure cases
+ # evaluate the new gemfile to look for any failure cases
builder = Dsl.new
builder.eval_gemfile(gemfile_path)
diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb
index 9d25f3261a..93355c9460 100644
--- a/lib/bundler/inline.rb
+++ b/lib/bundler/inline.rb
@@ -36,6 +36,7 @@ def gemfile(install = false, options = {}, &gemfile)
opts = options.dup
ui = opts.delete(:ui) { Bundler::UI::Shell.new }
+ ui.level = "silent" if opts.delete(:quiet)
raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
old_root = Bundler.method(:root)
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index b49cfb6703..49143b38f9 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -221,7 +221,7 @@ module Bundler
def processor_count
require "etc"
Etc.nprocessors
- rescue
+ rescue StandardError
1
end
@@ -275,14 +275,7 @@ module Bundler
end
def can_install_in_parallel?
- if Bundler.rubygems.provides?(">= 2.1.0")
- true
- else
- Bundler.ui.warn "RubyGems #{Gem::VERSION} is not threadsafe, so your "\
- "gems will be installed one at a time. Upgrade to RubyGems 2.1.0 " \
- "or higher to enable parallel gem installation."
- false
- end
+ true
end
def install_in_parallel(size, standalone, force = false)
diff --git a/lib/bundler/installer/gem_installer.rb b/lib/bundler/installer/gem_installer.rb
index e5e245f970..9689911d6c 100644
--- a/lib/bundler/installer/gem_installer.rb
+++ b/lib/bundler/installer/gem_installer.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "shellwords"
+
module Bundler
class GemInstaller
attr_reader :spec, :standalone, :worker, :force, :installer
@@ -56,7 +58,9 @@ module Bundler
def spec_settings
# Fetch the build settings, if there are any
- Bundler.settings["build.#{spec.name}"]
+ if settings = Bundler.settings["build.#{spec.name}"]
+ Shellwords.shellsplit(settings)
+ end
end
def install
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index f8a849ccfc..469b15b96c 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -91,10 +91,6 @@ module Bundler
end
def call
- # Since `autoload` has the potential for threading issues on 1.8.7
- # TODO: remove in bundler 2.0
- require "bundler/gem_remote_fetcher" if RUBY_VERSION < "1.9"
-
check_for_corrupt_lockfile
if @size > 1
@@ -115,7 +111,7 @@ module Bundler
s,
s.missing_lockfile_dependencies(@specs.map(&:name)),
]
- end.reject { |a| a.last.empty? }
+ end.reject {|a| a.last.empty? }
return if missing_dependencies.empty?
warning = []
@@ -150,7 +146,7 @@ module Bundler
end
def worker_pool
- @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
+ @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda {|spec_install, worker_num|
do_install(spec_install, worker_num)
}
end
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index d9cb01f810..69a721c120 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -77,7 +77,7 @@ module Bundler
if search && Gem::Platform.new(search.platform) != Gem::Platform.new(platform) && !search.runtime_dependencies.-(dependencies.reject {|d| d.type == :development }).empty?
Bundler.ui.warn "Unable to use the platform-specific (#{search.platform}) version of #{name} (#{version}) " \
"because it has different dependencies from the #{platform} version. " \
- "To use the platform-specific version of the gem, run `bundle config specific_platform true` and install again."
+ "To use the platform-specific version of the gem, run `bundle config set specific_platform true` and install again."
search = source.specs.search(self).last
end
search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index ff706fca1d..50dc1381fe 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -23,16 +23,14 @@ module Bundler
PATH = "PATH".freeze
PLUGIN = "PLUGIN SOURCE".freeze
SPECS = " specs:".freeze
- OPTIONS = /^ ([a-z]+): (.*)$/i
+ OPTIONS = /^ ([a-z]+): (.*)$/i.freeze
SOURCE = [GIT, GEM, PATH, PLUGIN].freeze
SECTIONS_BY_VERSION_INTRODUCED = {
- # The strings have to be dup'ed for old RG on Ruby 2.3+
- # TODO: remove dup in Bundler 2.0
- Gem::Version.create("1.0".dup) => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
- Gem::Version.create("1.10".dup) => [BUNDLED].freeze,
- Gem::Version.create("1.12".dup) => [RUBY].freeze,
- Gem::Version.create("1.13".dup) => [PLUGIN].freeze,
+ Gem::Version.create("1.0") => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
+ Gem::Version.create("1.10") => [BUNDLED].freeze,
+ Gem::Version.create("1.12") => [RUBY].freeze,
+ Gem::Version.create("1.13") => [PLUGIN].freeze,
}.freeze
KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze
@@ -90,7 +88,7 @@ module Bundler
send("parse_#{@state}", line)
end
end
- @sources << @rubygems_aggregate unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
+ @sources << @rubygems_aggregate unless Bundler.feature_flag.disable_multisource?
@specs = @specs.values.sort_by(&:identifier)
warn_for_outdated_bundler_version
rescue ArgumentError => e
@@ -109,9 +107,9 @@ module Bundler
when 0
if current_version < bundler_version
Bundler.ui.warn "Warning: the running version of Bundler (#{current_version}) is older " \
- "than the version that created the lockfile (#{bundler_version}). We suggest you " \
- "upgrade to the latest version of Bundler by running `gem " \
- "install bundler#{prerelease_text}`.\n"
+ "than the version that created the lockfile (#{bundler_version}). We suggest you to " \
+ "upgrade to the version that created the lockfile by running `gem install " \
+ "bundler:#{bundler_version}#{prerelease_text}`.\n"
end
end
end
@@ -141,7 +139,7 @@ module Bundler
@sources << @current_source
end
when GEM
- if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
+ if Bundler.feature_flag.disable_multisource?
@opts["remotes"] = @opts.delete("remote")
@current_source = TYPES[@type].from_lock(@opts)
@sources << @current_source
@@ -185,7 +183,7 @@ module Bundler
(?:-(.*))?\))? # Optional platform
(!)? # Optional pinned marker
$ # Line end
- /xo
+ /xo.freeze
def parse_dependency(line)
return unless line =~ NAME_VERSION
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index 53f9806b73..996d29aafb 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -47,26 +47,48 @@ module Bundler
Bundler.ui.error "Failed to install plugin #{name}: #{e.message}\n #{e.backtrace.join("\n ")}"
end
+ # List installed plugins and commands
+ #
+ def list
+ installed_plugins = index.installed_plugins
+ if installed_plugins.any?
+ output = String.new
+ installed_plugins.each do |plugin|
+ output << "#{plugin}\n"
+ output << "-----\n"
+ index.plugin_commands(plugin).each do |command|
+ output << " #{command}\n"
+ end
+ output << "\n"
+ end
+ else
+ output = "No plugins installed"
+ end
+ Bundler.ui.info output
+ end
+
# Evaluates the Gemfile with a limited DSL and installs the plugins
# specified by plugin method
#
# @param [Pathname] gemfile path
# @param [Proc] block that can be evaluated for (inline) Gemfile
def gemfile_install(gemfile = nil, &inline)
- builder = DSL.new
- if block_given?
- builder.instance_eval(&inline)
- else
- builder.eval_gemfile(gemfile)
- end
- definition = builder.to_definition(nil, true)
+ Bundler.settings.temporary(:frozen => false, :deployment => false) do
+ builder = DSL.new
+ if block_given?
+ builder.instance_eval(&inline)
+ else
+ builder.eval_gemfile(gemfile)
+ end
+ definition = builder.to_definition(nil, true)
- return if definition.dependencies.empty?
+ return if definition.dependencies.empty?
- plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p }
- installed_specs = Installer.new.install_definition(definition)
+ plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p }
+ installed_specs = Installer.new.install_definition(definition)
- save_plugins plugins, installed_specs, builder.inferred_plugins
+ save_plugins plugins, installed_specs, builder.inferred_plugins
+ end
rescue RuntimeError => e
unless e.is_a?(GemfileError)
Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}"
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
index 586477efb5..b33926a181 100644
--- a/lib/bundler/plugin/api/source.rb
+++ b/lib/bundler/plugin/api/source.rb
@@ -37,7 +37,7 @@ module Bundler
#
# @!attribute [rw] dependency_names
# @return [Array<String>] Names of dependencies that the source should
- # try to resolve. It is not necessary to use this list intenally. This
+ # try to resolve. It is not necessary to use this list internally. This
# is present to be compatible with `Definition` and is used by
# rubygems source.
module Source
diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb
index f09587dfda..faabf3a8d1 100644
--- a/lib/bundler/plugin/index.rb
+++ b/lib/bundler/plugin/index.rb
@@ -58,7 +58,10 @@ module Bundler
raise SourceConflict.new(name, common) unless common.empty?
sources.each {|k| @sources[k] = name }
- hooks.each {|e| (@hooks[e] ||= []) << name }
+ hooks.each do |event|
+ event_hooks = (@hooks[event] ||= []) << name
+ event_hooks.uniq!
+ end
@plugin_paths[name] = path
@load_paths[name] = load_paths
@@ -100,6 +103,14 @@ module Bundler
@plugin_paths[name]
end
+ def installed_plugins
+ @plugin_paths.keys
+ end
+
+ def plugin_commands(plugin)
+ @commands.find_all {|_, n| n == plugin }.map(&:first)
+ end
+
def source?(source)
@sources.key? source
end
diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb
index 5379c38979..4a262efac2 100644
--- a/lib/bundler/plugin/installer.rb
+++ b/lib/bundler/plugin/installer.rb
@@ -12,10 +12,15 @@ module Bundler
autoload :Git, "bundler/plugin/installer/git"
def install(names, options)
+ check_sources_consistency!(options)
+
version = options[:version] || [">= 0"]
- Bundler.settings.temporary(:lockfile_uses_separate_rubygems_sources => false, :disable_multisource => false) do
+
+ Bundler.settings.temporary(:disable_multisource => false) do
if options[:git]
install_git(names, version, options)
+ elsif options[:local_git]
+ install_local_git(names, version, options)
else
sources = options[:source] || Bundler.rubygems.sources
install_rubygems(names, version, sources)
@@ -38,22 +43,24 @@ module Bundler
private
+ def check_sources_consistency!(options)
+ if options.key?(:git) && options.key?(:local_git)
+ raise InvalidOption, "Remote and local plugin git sources can't be both specified"
+ end
+ end
+
def install_git(names, version, options)
uri = options.delete(:git)
options["uri"] = uri
- source_list = SourceList.new
- source_list.add_git_source(options)
-
- # To support both sources
- if options[:source]
- source_list.add_rubygems_source("remotes" => options[:source])
- end
+ install_all_sources(names, version, options, options[:source])
+ end
- deps = names.map {|name| Dependency.new name, version }
+ def install_local_git(names, version, options)
+ uri = options.delete(:local_git)
+ options["uri"] = uri
- definition = Definition.new(nil, deps, source_list, true)
- install_definition(definition)
+ install_all_sources(names, version, options, options[:source])
end
# Installs the plugin from rubygems source and returns the path where the
@@ -65,10 +72,16 @@ module Bundler
#
# @return [Hash] map of names to the specs of plugins installed
def install_rubygems(names, version, sources)
- deps = names.map {|name| Dependency.new name, version }
+ install_all_sources(names, version, nil, sources)
+ end
+ def install_all_sources(names, version, git_source_options, rubygems_source)
source_list = SourceList.new
- source_list.add_rubygems_source("remotes" => sources)
+
+ source_list.add_git_source(git_source_options) if git_source_options
+ source_list.add_rubygems_source("remotes" => rubygems_source) if rubygems_source
+
+ deps = names.map {|name| Dependency.new name, version }
definition = Definition.new(nil, deps, source_list, true)
install_definition(definition)
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 545b4cc88a..90f833bef1 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -38,8 +38,8 @@ module Bundler
@platforms = platforms
@gem_version_promoter = gem_version_promoter
@allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
- @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
+ @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
end
def start(requirements)
@@ -48,9 +48,12 @@ module Bundler
verify_gemfile_dependencies_are_found!(requirements)
dg = @resolver.resolve(requirements, @base_dg)
- dg.map(&:payload).
+ dg.
+ tap {|resolved| validate_resolved_specs!(resolved) }.
+ map(&:payload).
reject {|sg| sg.name.end_with?("\0") }.
- map(&:to_specs).flatten
+ map(&:to_specs).
+ flatten
rescue Molinillo::VersionConflict => e
message = version_conflict_message(e)
raise VersionConflict.new(e.conflicts.keys.uniq, message)
@@ -169,13 +172,13 @@ module Bundler
def name_for_explicit_dependency_source
Bundler.default_gemfile.basename.to_s
- rescue
+ rescue StandardError
"Gemfile"
end
def name_for_locking_dependency_source
Bundler.default_lockfile.basename.to_s
- rescue
+ rescue StandardError
"Gemfile.lock"
end
@@ -276,10 +279,10 @@ module Bundler
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
message << if versions_with_platforms.any?
- "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
- else
- "The source does not contain any versions of '#{name}'"
- end
+ "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
+ else
+ "The source does not contain any versions of '#{name}'"
+ end
else
message = "Could not find gem '#{requirement}' in any of the gem sources " \
"listed in your Gemfile#{cache_message}."
@@ -300,9 +303,19 @@ module Bundler
end
def version_conflict_message(e)
+ # only show essential conflicts, if possible
+ conflicts = e.conflicts.dup
+ conflicts.delete_if do |_name, conflict|
+ deps = conflict.requirement_trees.map(&:last).flatten(1)
+ !Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
+ end
+ e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
+
+ solver_name = "Bundler"
+ possibility_type = "gem"
e.message_with_trees(
- :solver_name => "Bundler",
- :possibility_type => "gem",
+ :solver_name => solver_name,
+ :possibility_type => possibility_type,
:reduce_trees => lambda do |trees|
# called first, because we want to reduce the amount of work required to find maximal empty sets
trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
@@ -314,10 +327,8 @@ module Bundler
end.flatten(1).select do |deps|
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
end.min_by(&:size)
- trees.reject! {|t| !maximal.include?(t.last) } if maximal
- trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
- trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
+ trees.reject! {|t| !maximal.include?(t.last) } if maximal
trees.sort_by {|t| t.reverse.map(&:name) }
end,
@@ -325,7 +336,7 @@ module Bundler
:additional_message_for_conflict => lambda do |o, name, conflict|
if name == "bundler"
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
- other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
+ other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
end
if name == "bundler" && other_bundler_required
@@ -352,7 +363,11 @@ module Bundler
[]
end.compact.map(&:to_s).uniq.sort
- o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
+ metadata_requirement = name.end_with?("\0")
+
+ o << "Could not find gem '" unless metadata_requirement
+ o << SharedHelpers.pretty_dependency(conflict.requirement)
+ o << "'" unless metadata_requirement
if conflict.requirement_trees.first.size > 1
o << ", which is required by "
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
@@ -360,14 +375,47 @@ module Bundler
o << " "
o << if relevant_sources.empty?
- "in any of the sources.\n"
- else
- "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
- end
+ "in any of the sources.\n"
+ elsif metadata_requirement
+ "is not available in #{relevant_sources.join(" or ")}"
+ else
+ "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
+ end
end
end,
- :version_for_spec => lambda {|spec| spec.version }
+ :version_for_spec => lambda {|spec| spec.version },
+ :incompatible_version_message_for_conflict => lambda do |name, _conflict|
+ if name.end_with?("\0")
+ %(#{solver_name} found conflicting requirements for the #{name} version:)
+ else
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
+ end
+ end
)
end
+
+ def validate_resolved_specs!(resolved_specs)
+ resolved_specs.each do |v|
+ name = v.name
+ next unless sources = relevant_sources_for_vertex(v)
+ sources.compact!
+ if default_index = sources.index(@source_requirements[:default])
+ sources.delete_at(default_index)
+ end
+ sources.reject! {|s| s.specs[name].empty? }
+ sources.uniq!
+ next if sources.size <= 1
+
+ multisource_disabled = Bundler.feature_flag.disable_multisource?
+
+ msg = ["The gem '#{name}' was found in multiple relevant sources."]
+ msg.concat sources.map {|s| " * #{s}" }.sort
+ msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
+ msg = msg.join("\n")
+
+ raise SecurityError, msg if multisource_disabled
+ Bundler.ui.warn "Warning: #{msg}"
+ end
+ end
end
end
diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb
index 34d043aed7..119f63b5c8 100644
--- a/lib/bundler/resolver/spec_group.rb
+++ b/lib/bundler/resolver/spec_group.rb
@@ -94,10 +94,10 @@ module Bundler
return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
dependencies = []
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
- dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
+ dependencies << DepProxy.new(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
end
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
- dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
+ dependencies << DepProxy.new(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
end
dependencies
end
diff --git a/lib/bundler/retry.rb b/lib/bundler/retry.rb
index 244606dcc9..d64958ba70 100644
--- a/lib/bundler/retry.rb
+++ b/lib/bundler/retry.rb
@@ -35,10 +35,10 @@ module Bundler
private
def run(&block)
- @failed = false
+ @failed = false
@current_run += 1
@result = block.call
- rescue => e
+ rescue StandardError => e
fail_attempt(e)
end
diff --git a/lib/bundler/ruby_version.rb b/lib/bundler/ruby_version.rb
index e6c31a94c9..80dc444f93 100644
--- a/lib/bundler/ruby_version.rb
+++ b/lib/bundler/ruby_version.rb
@@ -49,7 +49,7 @@ module Bundler
([\d.]+) # ruby version
(?:p(-?\d+))? # optional patchlevel
(?:\s\((\S+)\s(.+)\))? # optional engine info
- /xo
+ /xo.freeze
# Returns a RubyVersion from the given string.
# @param [String] the version string to match.
@@ -74,7 +74,7 @@ module Bundler
@host ||= [
RbConfig::CONFIG["host_cpu"],
RbConfig::CONFIG["host_vendor"],
- RbConfig::CONFIG["host_os"]
+ RbConfig::CONFIG["host_os"],
].join("-")
end
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index e9f0eac355..ccf71c8c00 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -2,12 +2,6 @@
require "pathname"
-if defined?(Gem::QuickLoader)
- # Gem Prelude makes me a sad panda :'(
- Gem::QuickLoader.load_full_rubygems_library
-end
-
-require "rubygems"
require "rubygems/specification"
begin
@@ -27,14 +21,16 @@ module Gem
class Specification
attr_accessor :remote, :location, :relative_loaded_from
- if instance_methods(false).map(&:to_sym).include?(:source)
+ if instance_methods(false).include?(:source)
remove_method :source
attr_writer :source
def source
(defined?(@source) && @source) || Gem::Source::Installed.new
end
else
+ # rubocop:disable Lint/DuplicateMethods
attr_accessor :source
+ # rubocop:enable Lint/DuplicateMethods
end
alias_method :rg_full_gem_path, :full_gem_path
@@ -85,10 +81,7 @@ module Gem
end
end
- # RubyGems 1.8+ used only.
- methods = instance_methods(false)
- gem_dir = methods.first.is_a?(String) ? "gem_dir" : :gem_dir
- remove_method :gem_dir if methods.include?(gem_dir)
+ remove_method :gem_dir if instance_methods(false).include?(:gem_dir)
def gem_dir
full_gem_path
end
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb
index 2b7fa8e0f6..b1076b4554 100644
--- a/lib/bundler/rubygems_gem_installer.rb
+++ b/lib/bundler/rubygems_gem_installer.rb
@@ -66,7 +66,7 @@ module Bundler
If you wish to continue installing the downloaded gem, and are certain it does not pose a \
security issue despite the mismatching checksum, do the following:
- 1. run `bundle config disable_checksum_validation true` to turn off checksum verification
+ 1. run `bundle config set disable_checksum_validation true` to turn off checksum verification
2. run `bundle install`
(More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index f088c2fdfb..a4519246a9 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
require "monitor"
-require "rubygems"
-require "rubygems/config_file"
module Bundler
class RubygemsIntegration
@@ -307,7 +305,7 @@ module Bundler
gem_from_path(path, security_policies[policy]).spec
rescue Gem::Package::FormatError
raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
- rescue Exception, Gem::Exception, Gem::Security::Exception => e
+ rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
if e.is_a?(Gem::Security::Exception) ||
e.message =~ /unknown trust policy|unsigned gem/i ||
e.message =~ /couldn't verify (meta)?data signature/i
@@ -436,40 +434,42 @@ module Bundler
# Used to make bin stubs that are not created by bundler work
# under bundler. The new Gem.bin_path only considers gems in
# +specs+
- def replace_bin_path(specs, specs_by_name)
+ def replace_bin_path(specs_by_name)
gem_class = (class << Gem; self; end)
redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
exec_name = args.first
+ raise ArgumentError, "you must supply exec_name" unless exec_name
spec_with_name = specs_by_name[gem_name]
- spec = if exec_name
- if spec_with_name && spec_with_name.executables.include?(exec_name)
- spec_with_name
- else
- specs.find {|s| s.executables.include?(exec_name) }
- end
- else
- spec_with_name
- end
+ matching_specs_by_exec_name = specs_by_name.values.select {|s| s.executables.include?(exec_name) }
+ spec = matching_specs_by_exec_name.delete(spec_with_name)
- unless spec
+ unless spec || !matching_specs_by_exec_name.empty?
message = "can't find executable #{exec_name} for gem #{gem_name}"
- if !exec_name || spec_with_name.nil?
+ if spec_with_name.nil?
message += ". #{gem_name} is not currently included in the bundle, " \
"perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?"
end
raise Gem::Exception, message
end
- raise Gem::Exception, "no default executable for #{spec.full_name}" unless exec_name ||= spec.default_executable
-
- unless spec.name == gem_name
- Bundler::SharedHelpers.major_deprecation 3,
+ unless spec
+ spec = matching_specs_by_exec_name.shift
+ warn \
"Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \
"You should run `bundle binstub #{gem_name}` " \
"to work around a system/bundle conflict."
end
+
+ unless matching_specs_by_exec_name.empty?
+ conflicting_names = matching_specs_by_exec_name.map(&:name).join(", ")
+ warn \
+ "The `#{exec_name}` executable in the `#{spec.name}` gem is being loaded, but it's also present in other gems (#{conflicting_names}).\n" \
+ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
+ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
+ end
+
spec
end
@@ -514,9 +514,18 @@ module Bundler
h
end
+ Bundler.rubygems.default_stubs.each do |stub|
+ default_spec = stub.to_spec
+ default_spec_name = default_spec.name
+ next if specs_by_name.key?(default_spec_name)
+
+ specs << default_spec
+ specs_by_name[default_spec_name] = default_spec
+ end
+
replace_gem(specs, specs_by_name)
stub_rubygems(specs)
- replace_bin_path(specs, specs_by_name)
+ replace_bin_path(specs_by_name)
replace_refresh
Gem.clear_paths
@@ -850,6 +859,16 @@ module Bundler
end
end
+ if Gem::Specification.respond_to?(:default_stubs)
+ def default_stubs
+ Gem::Specification.default_stubs("*.gemspec")
+ end
+ else
+ def default_stubs
+ Gem::Specification.send(:default_stubs, "*.gemspec")
+ end
+ end
+
def use_gemdeps(gemfile)
ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
require "bundler/gemdeps"
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
index 762e7b3ec6..83945868f9 100644
--- a/lib/bundler/runtime.rb
+++ b/lib/bundler/runtime.rb
@@ -163,7 +163,7 @@ module Bundler
gem_dirs = Dir["#{Gem.dir}/gems/*"]
gem_files = Dir["#{Gem.dir}/cache/*.gem"]
gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"]
- extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"]
+ extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"] + Dir["#{Gem.dir}/bundler/gems/extensions/*/*/*"]
spec_gem_paths = []
# need to keep git sources around
spec_git_paths = @definition.spec_git_paths
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 66af31dab2..5bc190865f 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -18,7 +18,6 @@ module Bundler
cache_all
cache_all_platforms
cache_command_is_package
- console_command
default_install_uses_path
deployment
deployment_means_frozen
@@ -35,23 +34,21 @@ module Bundler
frozen
gem.coc
gem.mit
+ github.https
global_path_appends_ruby_scope
global_gem_cache
ignore_messages
init_gems_rb
- list_command
- lockfile_upgrade_warning
- lockfile_uses_separate_rubygems_sources
- major_deprecations
no_install
no_prune
only_update_to_newer_versions
path_relative_to_cwd
path.system
plugins
- prefer_gems_rb
+ prefer_patch
print_only_version_number
setup_makes_kernel_gem_public
+ silence_deprecations
silence_root_warning
skip_default_git_sources
specific_platform
@@ -59,7 +56,6 @@ module Bundler
unlock_source_unlocks_spec
update_requires_all_flag
use_gem_version_promoter_for_major_updates
- viz_command
].freeze
NUMBER_KEYS = %w[
@@ -76,7 +72,9 @@ module Bundler
].freeze
DEFAULT_CONFIG = {
+ :silence_deprecations => false,
:disable_version_check => true,
+ :prefer_patch => false,
:redirect => 5,
:retry => 3,
:timeout => 10,
@@ -107,18 +105,6 @@ module Bundler
temporary(key => value)
value
else
- command = if value.nil?
- "bundle config --delete #{key}"
- else
- "bundle config #{key} #{Array(value).join(":")}"
- end
-
- Bundler::SharedHelpers.major_deprecation 3,\
- "flags passed to commands " \
- "will no longer be automatically remembered. Instead please set flags " \
- "you want remembered between commands using `bundle config " \
- "<setting name> <setting value>`, i.e. `#{command}`"
-
set_local(key, value)
end
end
@@ -407,20 +393,6 @@ module Bundler
Pathname.new(@root).join("config") if @root
end
- CONFIG_REGEX = %r{ # rubocop:disable Style/RegexpLiteral
- ^
- (BUNDLE_.+):\s # the key
- (?: !\s)? # optional exclamation mark found with ruby 1.9.3
- (['"]?) # optional opening quote
- (.* # contents of the value
- (?: # optionally, up until the next key
- (\n(?!BUNDLE).+)*
- )
- )
- \2 # matching closing quote
- $
- }xo
-
def load_config(config_file)
return {} if !config_file || ignore_config?
SharedHelpers.filesystem_access(config_file, :read) do |file|
@@ -442,7 +414,7 @@ module Bundler
(https?.*?) # URI
(\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key
\z
- /ix
+ /ix.freeze
# TODO: duplicates Rubygems#normalize_uri
# TODO: is this the correct place to validate mirror URIs?
diff --git a/lib/bundler/setup.rb b/lib/bundler/setup.rb
index ac6a5bf861..52a5b8889a 100644
--- a/lib/bundler/setup.rb
+++ b/lib/bundler/setup.rb
@@ -6,13 +6,14 @@ if Bundler::SharedHelpers.in_bundle?
require "bundler"
if STDOUT.tty? || ENV["BUNDLER_FORCE_TTY"]
+ Bundler.ui = Bundler::UI::Shell.new
begin
Bundler.setup
rescue Bundler::BundlerError => e
- puts "\e[31m#{e.message}\e[0m"
- puts e.backtrace.join("\n") if ENV["DEBUG"]
+ Bundler.ui.warn "\e[31m#{e.message}\e[0m"
+ Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
if e.is_a?(Bundler::GemNotFound)
- puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
+ Bundler.ui.warn "\e[33mRun `bundle install` to install missing gems.\e[0m"
end
exit e.status_code
end
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index d6ef25dc95..1b703c5cbc 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -3,6 +3,7 @@
require "bundler/compatibility_guard"
require "pathname"
+require "rbconfig"
require "rubygems"
require "bundler/version"
@@ -10,17 +11,6 @@ require "bundler/constants"
require "bundler/rubygems_integration"
require "bundler/current_ruby"
-module Gem
- class Dependency
- # This is only needed for RubyGems < 1.4
- unless method_defined? :requirement
- def requirement
- version_requirements
- end
- end
- end
-end
-
module Bundler
module SharedHelpers
def root
@@ -140,33 +130,28 @@ module Bundler
end
def major_deprecation(major_version, message)
- if Bundler.bundler_major_version >= major_version
+ bundler_major_version = Bundler.bundler_major_version
+ if bundler_major_version > major_version
require "bundler/errors"
- raise DeprecatedError, "[REMOVED FROM #{major_version}.0] #{message}"
+ raise DeprecatedError, "[REMOVED] #{message}"
end
- return unless prints_major_deprecations?
+ return unless bundler_major_version >= major_version && prints_major_deprecations?
@major_deprecation_ui ||= Bundler::UI::Shell.new("no-color" => true)
ui = Bundler.ui.is_a?(@major_deprecation_ui.class) ? Bundler.ui : @major_deprecation_ui
- ui.warn("[DEPRECATED FOR #{major_version}.0] #{message}")
+ ui.warn("[DEPRECATED] #{message}")
end
def print_major_deprecations!
multiple_gemfiles = search_up(".") do |dir|
gemfiles = gemfile_names.select {|gf| File.file? File.expand_path(gf, dir) }
next if gemfiles.empty?
- break false if gemfiles.size == 1
+ break gemfiles.size != 1
end
- if multiple_gemfiles && Bundler.bundler_major_version == 2
- Bundler::SharedHelpers.major_deprecation 3, \
- "gems.rb and gems.locked will be preferred to Gemfile and Gemfile.lock."
- end
-
- if RUBY_VERSION < "2"
- major_deprecation(2, "Bundler will only support ruby >= 2.0, you are running #{RUBY_VERSION}")
- end
- return if Bundler.rubygems.provides?(">= 2")
- major_deprecation(2, "Bundler will only support rubygems >= 2.0, you are running #{Bundler.rubygems.version}")
+ return unless multiple_gemfiles
+ message = "Multiple gemfiles (gems.rb and Gemfile) detected. " \
+ "Make sure you remove Gemfile and Gemfile.lock since bundler is ignoring them in favor of gems.rb and gems.rb.locked."
+ Bundler.ui.warn message
end
def trap(signal, override = false, &block)
@@ -246,13 +231,11 @@ module Bundler
def find_gemfile(order_matters = false)
given = ENV["BUNDLE_GEMFILE"]
return given if given && !given.empty?
- names = gemfile_names
- names.reverse! if order_matters && Bundler.feature_flag.prefer_gems_rb?
- find_file(*names)
+ find_file(*gemfile_names)
end
def gemfile_names
- ["Gemfile", "gems.rb"]
+ ["gems.rb", "Gemfile"]
end
def find_file(*names)
@@ -349,9 +332,6 @@ module Bundler
end
def clean_load_path
- # handle 1.9 where system gems are always on the load path
- return unless defined?(::Gem)
-
bundler_lib = bundler_ruby_lib
loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
@@ -372,8 +352,7 @@ module Bundler
def prints_major_deprecations?
require "bundler"
- deprecation_release = Bundler::VERSION.split(".").drop(1).include?("99")
- return false if !deprecation_release && !Bundler.settings[:major_deprecations]
+ return false if Bundler.settings[:silence_deprecations]
require "bundler/deprecate"
return false if Bundler::Deprecate.skip
true
diff --git a/lib/bundler/similarity_detector.rb b/lib/bundler/similarity_detector.rb
index b7f3ee7afa..f698f46a4c 100644
--- a/lib/bundler/similarity_detector.rb
+++ b/lib/bundler/similarity_detector.rb
@@ -51,7 +51,7 @@ module Bundler
dm[i][j] = [
dm[i - 1][j - 1] + (this[j - 1] == that[i - 1] ? 0 : sub),
dm[i][j - 1] + ins,
- dm[i - 1][j] + del
+ dm[i - 1][j] + del,
].min
end
end
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
index 0b00608bdd..a8afb341d8 100644
--- a/lib/bundler/source/git.rb
+++ b/lib/bundler/source/git.rb
@@ -118,18 +118,19 @@ module Bundler
def local_override!(path)
return false if local?
+ original_path = path
path = Pathname.new(path)
path = path.expand_path(Bundler.root) unless path.relative?
unless options["branch"] || Bundler.settings[:disable_local_branch_check]
raise GitError, "Cannot use local override for #{name} at #{path} because " \
- ":branch is not specified in Gemfile. Specify a branch or use " \
- "`bundle config --delete` to remove the local override"
+ ":branch is not specified in Gemfile. Specify a branch or run " \
+ "`bundle config unset local.#{override_for(original_path)}` to remove the local override"
end
unless path.exist?
raise GitError, "Cannot use local override for #{name} because #{path} " \
- "does not exist. Check `bundle config --delete` to remove the local override"
+ "does not exist. Run `bundle config unset local.#{override_for(original_path)}` to remove the local override"
end
set_local!(path)
@@ -260,7 +261,11 @@ module Bundler
end
def requires_checkout?
- allow_git_ops? && !local?
+ allow_git_ops? && !local? && !cached_revision_checked_out?
+ end
+
+ def cached_revision_checked_out?
+ cached_revision && cached_revision == revision && install_path.exist?
end
def base_name
@@ -324,6 +329,10 @@ module Bundler
def extension_cache_slug(_)
extension_dir_name
end
+
+ def override_for(path)
+ Bundler.settings.local_overrides.key(path)
+ end
end
end
end
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb
index cd964f7e56..3db31f0237 100644
--- a/lib/bundler/source/git/git_proxy.rb
+++ b/lib/bundler/source/git/git_proxy.rb
@@ -253,7 +253,7 @@ module Bundler
ensure
STDERR.reopen backup_stderr
end
- $stderr.puts URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
+ Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
return_value
end
end
diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb
index d9c93bfb67..559b912ffd 100644
--- a/lib/bundler/source/metadata.rb
+++ b/lib/bundler/source/metadata.rb
@@ -5,8 +5,10 @@ module Bundler
class Metadata < Source
def specs
@specs ||= Index.build do |idx|
- idx << Gem::Specification.new("ruby\0", RubyVersion.system.to_gem_version_with_patchlevel)
- idx << Gem::Specification.new("rubygems\0", Gem::VERSION)
+ idx << Gem::Specification.new("Ruby\0", RubyVersion.system.to_gem_version_with_patchlevel)
+ idx << Gem::Specification.new("RubyGems\0", Gem::VERSION) do |s|
+ s.required_rubygems_version = Gem::Requirement.default
+ end
idx << Gem::Specification.new do |s|
s.name = "bundler"
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index ed734bf549..5f3f1bc2e4 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -191,10 +191,10 @@ module Bundler
else
message = String.new("The path `#{expanded_path}` ")
message << if File.exist?(expanded_path)
- "is not a directory."
- else
- "does not exist."
- end
+ "is not a directory."
+ else
+ "does not exist."
+ end
raise PathError, message
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 485b388a32..86fd329089 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -51,7 +51,7 @@ module Bundler
end
def can_lock?(spec)
- return super if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
+ return super if Bundler.feature_flag.disable_multisource?
spec.source.is_a?(Rubygems)
end
@@ -106,7 +106,7 @@ module Bundler
end
end
- if installed?(spec) && !force
+ if (installed?(spec) || Plugin.installed?(spec.name)) && !force
print_using_message "Using #{version_message(spec)}"
return nil # no post-install message
end
@@ -120,8 +120,14 @@ module Bundler
uris.uniq!
Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
- s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
- spec.__swap__(s)
+ path = fetch_gem(spec)
+ begin
+ s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"])
+ spec.__swap__(s)
+ rescue StandardError
+ Bundler.rm_rf(path)
+ raise
+ end
end
unless Bundler.settings[:no_install]
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index ac2adacb3d..d3f649a12c 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "set"
+
module Bundler
class SourceList
attr_reader :path_sources,
@@ -41,17 +43,14 @@ module Bundler
end
def global_rubygems_source=(uri)
- if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
+ if Bundler.feature_flag.disable_multisource?
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
end
add_rubygems_remote(uri)
end
def add_rubygems_remote(uri)
- if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
- return if Bundler.feature_flag.disable_multisource?
- raise InvalidOption, "`lockfile_uses_separate_rubygems_sources` cannot be set without `disable_multisource` being set"
- end
+ return if Bundler.feature_flag.disable_multisource?
@rubygems_aggregate.add_remote(uri)
@rubygems_aggregate
end
@@ -77,12 +76,10 @@ module Bundler
end
def lock_sources
- if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
- [[default_source], @rubygems_sources, git_sources, path_sources, plugin_sources].map do |sources|
- sources.sort_by(&:to_s)
- end.flatten(1)
+ lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
+ if Bundler.feature_flag.disable_multisource?
+ lock_sources + rubygems_sources.sort_by(&:to_s)
else
- lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
lock_sources << combine_rubygems_sources
end
end
@@ -97,7 +94,7 @@ module Bundler
end
end
- replacement_rubygems = !Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? &&
+ replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
@rubygems_aggregate = replacement_rubygems if replacement_rubygems
@@ -150,7 +147,7 @@ module Bundler
if source.uri =~ /^git\:/
Bundler.ui.warn "The git source `#{source.uri}` uses the `git` protocol, " \
"which transmits data without encryption. Disable this warning with " \
- "`bundle config git.allow_insecure true`, or switch to the `https` " \
+ "`bundle config set git.allow_insecure true`, or switch to the `https` " \
"protocol to keep your data secure."
end
end
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index bbdf04a7d6..2c5d9e6580 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -60,7 +60,6 @@ module Bundler
@specs << value
@lookup = nil
@sorted = nil
- value
end
def sort!
diff --git a/lib/bundler/ssl_certs/.document b/lib/bundler/ssl_certs/.document
deleted file mode 100644
index fb66f13c33..0000000000
--- a/lib/bundler/ssl_certs/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Ignore all files in this directory
diff --git a/lib/bundler/ssl_certs/certificate_manager.rb b/lib/bundler/ssl_certs/certificate_manager.rb
deleted file mode 100644
index 26fc38ec18..0000000000
--- a/lib/bundler/ssl_certs/certificate_manager.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/vendored_fileutils"
-require "net/https"
-require "openssl"
-
-module Bundler
- module SSLCerts
- class CertificateManager
- attr_reader :bundler_cert_path, :bundler_certs, :rubygems_certs
-
- def self.update_from!(rubygems_path)
- new(rubygems_path).update!
- end
-
- def initialize(rubygems_path = nil)
- if rubygems_path
- rubygems_cert_path = File.join(rubygems_path, "lib/rubygems/ssl_certs")
- @rubygems_certs = certificates_in(rubygems_cert_path)
- end
-
- @bundler_cert_path = File.expand_path("..", __FILE__)
- @bundler_certs = certificates_in(bundler_cert_path)
- end
-
- def up_to_date?
- rubygems_certs.all? do |rc|
- bundler_certs.find do |bc|
- File.basename(bc) == File.basename(rc) && FileUtils.compare_file(bc, rc)
- end
- end
- end
-
- def update!
- return if up_to_date?
-
- FileUtils.rm bundler_certs
- FileUtils.cp rubygems_certs, bundler_cert_path
- end
-
- def connect_to(host)
- http = Net::HTTP.new(host, 443)
- http.use_ssl = true
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
- http.cert_store = store
- http.head("/")
- end
-
- private
-
- def certificates_in(path)
- Dir[File.join(path, "**/*.pem")].sort
- end
-
- def store
- @store ||= begin
- store = OpenSSL::X509::Store.new
- bundler_certs.each do |cert|
- store.add_file cert
- end
- store
- end
- end
- end
- end
-end
diff --git a/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem b/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem
deleted file mode 100644
index f4ce4ca43d..0000000000
--- a/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
-MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
-aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
-jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
-xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
-1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
-snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
-U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
-9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
-AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
-yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
-38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
-AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
-DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
-HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
------END CERTIFICATE-----
diff --git a/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem b/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem
deleted file mode 100644
index 9e6810ab70..0000000000
--- a/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----
diff --git a/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem b/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem
deleted file mode 100644
index 20585f1c01..0000000000
--- a/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem
+++ /dev/null
@@ -1,25 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb
index 0dd024024a..bef94b505e 100644
--- a/lib/bundler/stub_specification.rb
+++ b/lib/bundler/stub_specification.rb
@@ -13,17 +13,13 @@ module Bundler
attr_accessor :stub, :ignored
- # Pre 2.2.0 did not include extension_dir
- # https://github.com/rubygems/rubygems/commit/9485ca2d101b82a946d6f327f4bdcdea6d4946ea
- if Bundler.rubygems.provides?(">= 2.2.0")
- def source=(source)
- super
- # Stub has no concept of source, which means that extension_dir may be wrong
- # This is the case for git-based gems. So, instead manually assign the extension dir
- return unless source.respond_to?(:extension_dir_name)
- path = File.join(stub.extensions_dir, source.extension_dir_name)
- stub.extension_dir = File.expand_path(path)
- end
+ def source=(source)
+ super
+ # Stub has no concept of source, which means that extension_dir may be wrong
+ # This is the case for git-based gems. So, instead manually assign the extension dir
+ return unless source.respond_to?(:extension_dir_name)
+ path = File.join(stub.extensions_dir, source.extension_dir_name)
+ stub.extension_dir = File.expand_path(path)
end
def to_yaml
@@ -32,11 +28,9 @@ module Bundler
# @!group Stub Delegates
- if Bundler.rubygems.provides?(">= 2.3")
- # This is defined directly to avoid having to load every installed spec
- def missing_extensions?
- stub.missing_extensions?
- end
+ # This is defined directly to avoid having to load every installed spec
+ def missing_extensions?
+ stub.missing_extensions?
end
def activated
@@ -57,16 +51,14 @@ module Bundler
stub.full_gem_path || method_missing(:full_gem_path)
end
- if Bundler.rubygems.provides?(">= 2.2.0")
- def full_require_paths
- stub.full_require_paths
- end
+ def full_require_paths
+ stub.full_require_paths
+ end
- # This is what we do in bundler/rubygems_ext
- # full_require_paths is always implemented in >= 2.2.0
- def load_paths
- full_require_paths
- end
+ # This is what we do in bundler/rubygems_ext
+ # full_require_paths is always implemented
+ def load_paths
+ full_require_paths
end
def loaded_from
diff --git a/lib/bundler/templates/Executable.bundler b/lib/bundler/templates/Executable.bundler
index eeda90b584..3adac41e74 100644
--- a/lib/bundler/templates/Executable.bundler
+++ b/lib/bundler/templates/Executable.bundler
@@ -11,7 +11,7 @@
require "rubygems"
m = Module.new do
- module_function
+ module_function
def invoked_as_script?
File.expand_path($0) == File.expand_path(__FILE__)
diff --git a/lib/bundler/templates/newgem/README.md.tt b/lib/bundler/templates/newgem/README.md.tt
index 868a0afe67..22ddeaa91a 100644
--- a/lib/bundler/templates/newgem/README.md.tt
+++ b/lib/bundler/templates/newgem/README.md.tt
@@ -14,7 +14,7 @@ gem '<%= config[:name] %>'
And then execute:
- $ bundle
+ $ bundle install
Or install it yourself as:
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index faf6f7bbc5..5505540b9e 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -1,8 +1,4 @@
-<%- if RUBY_VERSION < "2.0.0" -%>
-# coding: utf-8
-<%- end -%>
-
-lib = File.expand_path("../lib", __FILE__)
+lib = File.expand_path("lib", __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "<%= config[:namespaced_path] %>/version"
@@ -19,18 +15,11 @@ Gem::Specification.new do |spec|
spec.license = "MIT"
<%- end -%>
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
- # to allow pushing to a single host or delete this section to allow pushing to any host.
- if spec.respond_to?(:metadata)
- spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
+ spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
- spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
- else
- raise "RubyGems 2.0 or newer is required to protect against " \
- "public gem pushes."
- end
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
+ spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -45,7 +34,7 @@ Gem::Specification.new do |spec|
<%- end -%>
spec.add_development_dependency "bundler", "~> <%= config[:bundler_version] %>"
- spec.add_development_dependency "rake", "~> 10.0"
+ spec.add_development_dependency "rake", "~> 12.0"
<%- if config[:ext] -%>
spec.add_development_dependency "rake-compiler"
<%- end -%>
diff --git a/lib/bundler/templates/newgem/test/test_helper.rb.tt b/lib/bundler/templates/newgem/test/test_helper.rb.tt
index 725e3e4647..7d7db165ec 100644
--- a/lib/bundler/templates/newgem/test/test_helper.rb.tt
+++ b/lib/bundler/templates/newgem/test/test_helper.rb.tt
@@ -1,4 +1,4 @@
-$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
+$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
require "<%= config[:namespaced_path] %>"
require "minitest/autorun"
diff --git a/lib/bundler/templates/newgem/travis.yml.tt b/lib/bundler/templates/newgem/travis.yml.tt
index 7a3381a889..eab16addca 100644
--- a/lib/bundler/templates/newgem/travis.yml.tt
+++ b/lib/bundler/templates/newgem/travis.yml.tt
@@ -1,5 +1,4 @@
---
-sudo: false
language: ruby
cache: bundler
rvm:
diff --git a/lib/bundler/vendor/fileutils/lib/fileutils.rb b/lib/bundler/vendor/fileutils/lib/fileutils.rb
index cc69740845..fb7777eb49 100644
--- a/lib/bundler/vendor/fileutils/lib/fileutils.rb
+++ b/lib/bundler/vendor/fileutils/lib/fileutils.rb
@@ -1,4 +1,13 @@
# frozen_string_literal: true
+
+begin
+ require 'rbconfig'
+rescue LoadError
+ # for make mjit-headers
+end
+
+require "bundler/vendor/fileutils/lib/fileutils/version"
+
#
# = fileutils.rb
#
@@ -56,7 +65,7 @@
#
# There are some `low level' methods, which do not accept any option:
#
-# Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference = false)
+# Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
# Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
# Bundler::FileUtils.copy_stream(srcstream, deststream)
# Bundler::FileUtils.remove_entry(path, force = false)
@@ -84,7 +93,6 @@
# files/directories. This equates to passing the <tt>:noop</tt> and
# <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
#
-
module Bundler::FileUtils
def self.private_module_function(name) #:nodoc:
@@ -106,19 +114,22 @@ module Bundler::FileUtils
#
# Changes the current directory to the directory +dir+.
#
- # If this method is called with block, resumes to the old
- # working directory after the block execution finished.
+ # If this method is called with block, resumes to the previous
+ # working directory after the block execution has finished.
#
- # Bundler::FileUtils.cd('/', :verbose => true) # chdir and report it
+ # Bundler::FileUtils.cd('/') # change directory
#
- # Bundler::FileUtils.cd('/') do # chdir
+ # Bundler::FileUtils.cd('/', :verbose => true) # change directory and report it
+ #
+ # Bundler::FileUtils.cd('/') do # change directory
# # ... # do something
# end # return to original directory
#
def cd(dir, verbose: nil, &block) # :yield: dir
fu_output_message "cd #{dir}" if verbose
- Dir.chdir(dir, &block)
+ result = Dir.chdir(dir, &block)
fu_output_message 'cd -' if verbose and block
+ result
end
module_function :cd
@@ -245,15 +256,15 @@ module Bundler::FileUtils
fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
return if noop
list.each do |dir|
- begin
- Dir.rmdir(dir = remove_trailing_slash(dir))
- if parents
+ Dir.rmdir(dir = remove_trailing_slash(dir))
+ if parents
+ begin
until (parent = File.dirname(dir)) == '.' or parent == dir
dir = parent
Dir.rmdir(dir)
end
+ rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
end
- rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
end
end
end
@@ -295,6 +306,39 @@ module Bundler::FileUtils
#
# :call-seq:
+ # Bundler::FileUtils.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
+ #
+ # Hard link +src+ to +dest+. If +src+ is a directory, this method links
+ # all its contents recursively. If +dest+ is a directory, links
+ # +src+ to +dest/src+.
+ #
+ # +src+ can be a list of files.
+ #
+ # # Installing the library "mylib" under the site_ruby directory.
+ # Bundler::FileUtils.rm_r site_ruby + '/mylib', :force => true
+ # Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
+ #
+ # # Examples of linking several files to target directory.
+ # Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
+ # Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true
+ #
+ # # If you want to link all contents of a directory instead of the
+ # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
+ # # use the following code.
+ # Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
+ #
+ def cp_lr(src, dest, noop: nil, verbose: nil,
+ dereference_root: true, remove_destination: false)
+ fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest(src, dest) do |s, d|
+ link_entry s, d, dereference_root, remove_destination
+ end
+ end
+ module_function :cp_lr
+
+ #
+ # :call-seq:
# Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
# Bundler::FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
# Bundler::FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
@@ -340,6 +384,26 @@ module Bundler::FileUtils
module_function :ln_sf
#
+ # Hard links a file system entry +src+ to +dest+.
+ # If +src+ is a directory, this method links its contents recursively.
+ #
+ # Both of +src+ and +dest+ must be a path name.
+ # +src+ must exist, +dest+ must not exist.
+ #
+ # If +dereference_root+ is true, this method dereferences the tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
+ def link_entry(src, dest, dereference_root = false, remove_destination = false)
+ Entry_.new(src, nil, dereference_root).traverse do |ent|
+ destent = Entry_.new(dest, ent.rel, false)
+ File.unlink destent.path if remove_destination && File.file?(destent.path)
+ ent.link destent.path
+ end
+ end
+ module_function :link_entry
+
+ #
# Copies a file content +src+ to +dest+. If +dest+ is a directory,
# copies +src+ to +dest/src+.
#
@@ -412,7 +476,7 @@ module Bundler::FileUtils
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
- File.unlink destent.path if remove_destination && File.file?(destent.path)
+ File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
ent.copy destent.path
end, proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
@@ -461,13 +525,12 @@ module Bundler::FileUtils
if destent.exist?
if destent.directory?
raise Errno::EEXIST, d
- else
- destent.remove_file if rename_cannot_overwrite_file?
end
end
begin
File.rename s, d
- rescue Errno::EXDEV
+ rescue Errno::EXDEV,
+ Errno::EPERM # move from unencrypted to encrypted dir (ext4)
copy_entry s, d, true
if secure
remove_entry_secure s, force
@@ -485,11 +548,6 @@ module Bundler::FileUtils
alias move mv
module_function :move
- def rename_cannot_overwrite_file? #:nodoc:
- /emx/ =~ RUBY_PLATFORM
- end
- private_module_function :rename_cannot_overwrite_file?
-
#
# Remove file(s) specified in +list+. This method cannot remove directories.
# All StandardErrors are ignored when the :force option is set.
@@ -601,8 +659,8 @@ module Bundler::FileUtils
#
# For details of this security vulnerability, see Perl's case:
#
- # * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
- # * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
#
# For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
#
@@ -626,22 +684,38 @@ module Bundler::FileUtils
unless parent_st.sticky?
raise ArgumentError, "parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
end
+
# freeze tree root
euid = Process.euid
- File.open(fullpath + '/.') {|f|
- unless fu_stat_identical_entry?(st, f.stat)
- # symlink (TOC-to-TOU attack?)
- File.unlink fullpath
- return
- end
- f.chown euid, -1
- f.chmod 0700
- unless fu_stat_identical_entry?(st, File.lstat(fullpath))
- # TOC-to-TOU attack?
- File.unlink fullpath
- return
- end
- }
+ dot_file = fullpath + "/."
+ begin
+ File.open(dot_file) {|f|
+ unless fu_stat_identical_entry?(st, f.stat)
+ # symlink (TOC-to-TOU attack?)
+ File.unlink fullpath
+ return
+ end
+ f.chown euid, -1
+ f.chmod 0700
+ }
+ rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
+ File.lstat(dot_file).tap {|fstat|
+ unless fu_stat_identical_entry?(st, fstat)
+ # symlink (TOC-to-TOU attack?)
+ File.unlink fullpath
+ return
+ end
+ File.chown euid, -1, dot_file
+ File.chmod 0700, dot_file
+ }
+ end
+
+ unless fu_stat_identical_entry?(st, File.lstat(fullpath))
+ # TOC-to-TOU attack?
+ File.unlink fullpath
+ return
+ end
+
# ---- tree root is frozen ----
root = Entry_.new(path)
root.preorder_traverse do |ent|
@@ -742,8 +816,15 @@ module Bundler::FileUtils
#
def compare_stream(a, b)
bsize = fu_stream_blksize(a, b)
- sa = String.new(capacity: bsize)
- sb = String.new(capacity: bsize)
+
+ if RUBY_VERSION > "2.4"
+ sa = String.new(capacity: bsize)
+ sb = String.new(capacity: bsize)
+ else
+ sa = String.new
+ sb = String.new
+ end
+
begin
a.read(bsize, sa)
b.read(bsize, sb)
@@ -1001,11 +1082,6 @@ module Bundler::FileUtils
end
module_function :chown_R
- begin
- require 'etc'
- rescue LoadError # rescue LoadError for miniruby
- end
-
def fu_get_uid(user) #:nodoc:
return nil unless user
case user
@@ -1014,6 +1090,7 @@ module Bundler::FileUtils
when /\A\d+\z/
user.to_i
else
+ require 'etc'
Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
end
end
@@ -1027,6 +1104,7 @@ module Bundler::FileUtils
when /\A\d+\z/
group.to_i
else
+ require 'etc'
Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
end
end
@@ -1067,8 +1145,11 @@ module Bundler::FileUtils
module StreamUtils_
private
- def fu_windows?
- /mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
+ case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
+ when /mswin|mingw/
+ def fu_windows?; true end
+ else
+ def fu_windows?; false end
end
def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
@@ -1193,9 +1274,15 @@ module Bundler::FileUtils
def entries
opts = {}
opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
- Dir.entries(path(), opts)\
- .reject {|n| n == '.' or n == '..' }\
- .map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
+
+ files = if Dir.respond_to?(:children)
+ Dir.children(path, opts)
+ else
+ Dir.entries(path(), opts)
+ .reject {|n| n == '.' or n == '..' }
+ end
+
+ files.map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
end
def stat
@@ -1250,6 +1337,22 @@ module Bundler::FileUtils
end
end
+ def link(dest)
+ case
+ when directory?
+ if !File.exist?(dest) and descendant_directory?(dest, path)
+ raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
+ end
+ begin
+ Dir.mkdir dest
+ rescue
+ raise unless File.directory?(dest)
+ end
+ else
+ File.link path(), dest
+ end
+ end
+
def copy(dest)
lstat
case
diff --git a/lib/bundler/vendor/fileutils/lib/fileutils/version.rb b/lib/bundler/vendor/fileutils/lib/fileutils/version.rb
new file mode 100644
index 0000000000..6d8504ccd5
--- /dev/null
+++ b/lib/bundler/vendor/fileutils/lib/fileutils/version.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module Bundler::FileUtils
+ VERSION = "1.2.0"
+end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
index 7ecdc4b65a..41bc013143 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
@@ -50,14 +50,25 @@ module Bundler::Molinillo
incoming_edges.map(&:origin)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is a
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
# {#descendent?}
def recursive_predecessors
- vertices = predecessors
- vertices += Compatibility.flat_map(vertices, &:recursive_predecessors)
- vertices.uniq!
+ _recursive_predecessors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the predecessors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
+ # {#descendent?}
+ def _recursive_predecessors(vertices = Set.new)
+ incoming_edges.each do |edge|
+ vertex = edge.origin
+ next unless vertices.add?(vertex)
+ vertex._recursive_predecessors(vertices)
+ end
+
vertices
end
+ protected :_recursive_predecessors
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
# `self` as their {Edge#origin}
@@ -65,14 +76,25 @@ module Bundler::Molinillo
outgoing_edges.map(&:destination)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is an
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
# {#ancestor?}
def recursive_successors
- vertices = successors
- vertices += Compatibility.flat_map(vertices, &:recursive_successors)
- vertices.uniq!
+ _recursive_successors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the successors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
+ # {#ancestor?}
+ def _recursive_successors(vertices = Set.new)
+ outgoing_edges.each do |edge|
+ vertex = edge.destination
+ next unless vertices.add?(vertex)
+ vertex._recursive_successors(vertices)
+ end
+
vertices
end
+ protected :_recursive_successors
# @return [String] a string suitable for debugging
def inspect
diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb
index e6698572a9..b06feac2a0 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions.rb
@@ -113,8 +113,10 @@ class Bundler::Thor
# the script started).
#
def relative_to_original_destination_root(path, remove_dot = true)
- path = path.dup
- if path.gsub!(@destination_stack[0], ".")
+ root = @destination_stack[0]
+ if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
+ path = path.dup
+ path[0...root.size] = '.'
remove_dot ? (path[2..-1] || "") : path
else
path
@@ -217,6 +219,7 @@ class Bundler::Thor
shell.padding += 1 if verbose
contents = if is_uri
+ require "open-uri"
open(path, "Accept" => "application/x-thor-template", &:read)
else
open(path, &:read)
@@ -252,9 +255,16 @@ class Bundler::Thor
say_status :run, desc, config.fetch(:verbose, true)
- unless options[:pretend]
- config[:capture] ? `#{command}` : system(command.to_s)
+ return if options[:pretend]
+
+ result = config[:capture] ? `#{command}` : system(command.to_s)
+
+ if config[:abort_on_failure]
+ success = config[:capture] ? $?.success? : result
+ abort unless success
end
+
+ result
end
# Executes a ruby script (taking into account WIN32 platform quirks).
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
index 4c83bebc86..cc29db05a8 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
@@ -60,6 +60,9 @@ class Bundler::Thor
# destination. If a block is given instead of destination, the content of
# the url is yielded and used as location.
#
+ # +get+ relies on open-uri, so passing application user input would provide
+ # a command injection attack vector.
+ #
# ==== Parameters
# source<String>:: the address of the given content.
# destination<String>:: the relative path to the destination root.
@@ -117,7 +120,13 @@ class Bundler::Thor
context = config.delete(:context) || instance_eval("binding")
create_file destination, nil, config do
- content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").tap do |erb|
+ match = ERB.version.match(/(\d+\.\d+\.\d+)/)
+ capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+
+ CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer")
+ else
+ CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer")
+ end
+ content = capturable_erb.tap do |erb|
erb.filename = source
end.result(context)
content = yield(content) if block
@@ -301,7 +310,7 @@ class Bundler::Thor
def comment_lines(path, flag, *args)
flag = flag.respond_to?(:source) ? flag.source : flag
- gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
+ gsub_file(path, /^(\s*)([^#\n]*#{flag})/, '\1# \2', *args)
end
# Removes a file at the given location.
diff --git a/lib/bundler/vendor/thor/lib/thor/base.rb b/lib/bundler/vendor/thor/lib/thor/base.rb
index 9bd1077170..e79d03d087 100644
--- a/lib/bundler/vendor/thor/lib/thor/base.rb
+++ b/lib/bundler/vendor/thor/lib/thor/base.rb
@@ -113,7 +113,7 @@ class Bundler::Thor
end
# Whenever a class inherits from Bundler::Thor or Bundler::Thor::Group, we should track the
- # class and the file on Bundler::Thor::Base. This is the method responsable for it.
+ # class and the file on Bundler::Thor::Base. This is the method responsible for it.
#
def register_klass_file(klass) #:nodoc:
file = caller[1].match(/(.*):\d+/)[1]
@@ -466,13 +466,13 @@ class Bundler::Thor
dispatch(nil, given_args.dup, nil, config)
rescue Bundler::Thor::Error => e
config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
- exit(1) if exit_on_failure?
+ exit(false) if exit_on_failure?
rescue Errno::EPIPE
# This happens if a thor command is piped to something like `head`,
# which closes the pipe when it's done reading. This will also
# mean that if the pipe is closed, further unnecessary
# computation will not occur.
- exit(0)
+ exit(true)
end
# Allows to use private methods from parent in child classes as commands.
@@ -493,8 +493,7 @@ class Bundler::Thor
alias_method :public_task, :public_command
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
- raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." if has_namespace
- raise UndefinedCommandError, "Could not find command #{command.inspect}."
+ raise UndefinedCommandError.new(command, all_commands.keys, (namespace if has_namespace))
end
alias_method :handle_no_task_error, :handle_no_command_error
diff --git a/lib/bundler/vendor/thor/lib/thor/error.rb b/lib/bundler/vendor/thor/lib/thor/error.rb
index 2f816081f3..16c68294e4 100644
--- a/lib/bundler/vendor/thor/lib/thor/error.rb
+++ b/lib/bundler/vendor/thor/lib/thor/error.rb
@@ -1,4 +1,23 @@
class Bundler::Thor
+ Correctable =
+ begin
+ require 'did_you_mean'
+
+ # In order to support versions of Ruby that don't have keyword
+ # arguments, we need our own spell checker class that doesn't take key
+ # words. Even though this code wouldn't be hit because of the check
+ # above, it's still necessary because the interpreter would otherwise be
+ # unable to parse the file.
+ class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
+ def initialize(dictionary)
+ @dictionary = dictionary
+ end
+ end
+
+ DidYouMean::Correctable
+ rescue LoadError, NameError
+ end
+
# Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those
# errors have their backtrace suppressed and are nicely shown to the user.
#
@@ -10,6 +29,35 @@ class Bundler::Thor
# Raised when a command was not found.
class UndefinedCommandError < Error
+ class SpellChecker
+ attr_reader :error
+
+ def initialize(error)
+ @error = error
+ end
+
+ def corrections
+ @corrections ||= spell_checker.correct(error.command).map(&:inspect)
+ end
+
+ def spell_checker
+ NoKwargSpellChecker.new(error.all_commands)
+ end
+ end
+
+ attr_reader :command, :all_commands
+
+ def initialize(command, all_commands, namespace)
+ @command = command
+ @all_commands = all_commands
+
+ message = "Could not find command #{command.inspect}"
+ message = namespace ? "#{message} in #{namespace.inspect} namespace." : "#{message}."
+
+ super(message)
+ end
+
+ prepend Correctable if Correctable
end
UndefinedTaskError = UndefinedCommandError
@@ -22,6 +70,33 @@ class Bundler::Thor
end
class UnknownArgumentError < Error
+ class SpellChecker
+ attr_reader :error
+
+ def initialize(error)
+ @error = error
+ end
+
+ def corrections
+ @corrections ||=
+ error.unknown.flat_map { |unknown| spell_checker.correct(unknown) }.uniq.map(&:inspect)
+ end
+
+ def spell_checker
+ @spell_checker ||= NoKwargSpellChecker.new(error.switches)
+ end
+ end
+
+ attr_reader :switches, :unknown
+
+ def initialize(switches, unknown)
+ @switches = switches
+ @unknown = unknown
+
+ super("Unknown switches #{unknown.map(&:inspect).join(', ')}")
+ end
+
+ prepend Correctable if Correctable
end
class RequiredArgumentMissingError < InvocationError
@@ -29,4 +104,11 @@ class Bundler::Thor
class MalformattedArgumentError < InvocationError
end
+
+ if Correctable
+ DidYouMean::SPELL_CHECKERS.merge!(
+ 'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker,
+ 'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker
+ )
+ end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/group.rb b/lib/bundler/vendor/thor/lib/thor/group.rb
index 05ddc10cd3..30db46529e 100644
--- a/lib/bundler/vendor/thor/lib/thor/group.rb
+++ b/lib/bundler/vendor/thor/lib/thor/group.rb
@@ -61,7 +61,7 @@ class Bundler::Thor::Group
invocations[name] = false
invocation_blocks[name] = block if block_given?
- class_eval <<-METHOD, __FILE__, __LINE__
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
def _invoke_#{name.to_s.gsub(/\W/, '_')}
klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
@@ -120,7 +120,7 @@ class Bundler::Thor::Group
invocations[name] = true
invocation_blocks[name] = block if block_given?
- class_eval <<-METHOD, __FILE__, __LINE__
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
return unless options[#{name.inspect}]
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/options.rb b/lib/bundler/vendor/thor/lib/thor/parser/options.rb
index 70f6366842..179f4fa015 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/options.rb
@@ -44,6 +44,7 @@ class Bundler::Thor
@shorts = {}
@switches = {}
@extra = []
+ @stopped_parsing_after_extra_index = nil
options.each do |option|
@switches[option.switch_name] = option
@@ -66,6 +67,7 @@ class Bundler::Thor
if result == OPTS_END
shift
@parsing_options = false
+ @stopped_parsing_after_extra_index ||= @extra.size
super
else
result
@@ -99,6 +101,7 @@ class Bundler::Thor
elsif @stop_on_unknown
@parsing_options = false
@extra << shifted
+ @stopped_parsing_after_extra_index ||= @extra.size
@extra << shift while peek
break
elsif match
@@ -120,9 +123,11 @@ class Bundler::Thor
end
def check_unknown!
+ to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra
+
# an unknown option starts with - or -- and has no more --'s afterward.
- unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
- raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
+ unknown = to_check.select { |str| str =~ /^--?(?:(?!--).)*$/ }
+ raise UnknownArgumentError.new(@switches.keys, unknown) unless unknown.empty?
end
protected
diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb
index b110b8d478..65ae422d7f 100644
--- a/lib/bundler/vendor/thor/lib/thor/runner.rb
+++ b/lib/bundler/vendor/thor/lib/thor/runner.rb
@@ -3,7 +3,7 @@ require "bundler/vendor/thor/lib/thor/group"
require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
require "yaml"
-require "digest"
+require "digest/md5"
require "pathname"
class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength
@@ -90,7 +90,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
end
thor_yaml[as] = {
- :filename => Digest(:MD5).hexdigest(name + as),
+ :filename => Digest::MD5.hexdigest(name + as),
:location => location,
:namespaces => Bundler::Thor::Util.namespaces_in_content(contents, base)
}
diff --git a/lib/bundler/vendor/thor/lib/thor/shell.rb b/lib/bundler/vendor/thor/lib/thor/shell.rb
index e945549324..a68cdf8a98 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell.rb
@@ -55,7 +55,7 @@ class Bundler::Thor
# Common methods that are delegated to the shell.
SHELL_DELEGATED_METHODS.each do |method|
- module_eval <<-METHOD, __FILE__, __LINE__
+ module_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{method}(*args,&block)
shell.#{method}(*args,&block)
end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
index 5162390efd..52648fee8f 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
@@ -1,6 +1,8 @@
class Bundler::Thor
module Shell
class Basic
+ DEFAULT_TERMINAL_WIDTH = 80
+
attr_accessor :base
attr_reader :padding
@@ -45,6 +47,10 @@ class Bundler::Thor
# Asks something to the user and receives a response.
#
+ # If a default value is specified it will be presented to the user
+ # and allows them to select that value with an empty response. This
+ # option is ignored when limited answers are supplied.
+ #
# If asked to limit the correct responses, you can pass in an
# array of acceptable answers. If one of those is not supplied,
# they will be shown a message stating that one of those answers
@@ -61,6 +67,8 @@ class Bundler::Thor
# ==== Example
# ask("What is your name?")
#
+ # ask("What is the planet furthest from the sun?", :default => "Pluto")
+ #
# ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
#
# ask("What is your password?", :echo => false)
@@ -222,8 +230,20 @@ class Bundler::Thor
paras = message.split("\n\n")
paras.map! do |unwrapped|
- unwrapped.strip.tr("\n", " ").squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
- end
+ counter = 0
+ unwrapped.split(" ").inject do |memo, word|
+ word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
+ counter = 0 if word.include? "\n"
+ if (counter + word.length + 1) < width
+ memo = "#{memo} #{word}"
+ counter += (word.length + 1)
+ else
+ memo = "#{memo}\n#{word}"
+ counter = word.length
+ end
+ memo
+ end
+ end.compact!
paras.each do |para|
para.split("\n").each do |line|
@@ -239,11 +259,11 @@ class Bundler::Thor
#
# ==== Parameters
# destination<String>:: the destination file to solve conflicts
- # block<Proc>:: an optional block that returns the value to be used in diff
+ # block<Proc>:: an optional block that returns the value to be used in diff and merge
#
def file_collision(destination)
return true if @always_force
- options = block_given? ? "[Ynaqdh]" : "[Ynaqh]"
+ options = block_given? ? "[Ynaqdhm]" : "[Ynaqh]"
loop do
answer = ask(
@@ -267,6 +287,13 @@ class Bundler::Thor
when is?(:diff)
show_diff(destination, yield) if block_given?
say "Retrying..."
+ when is?(:merge)
+ if block_given? && !merge_tool.empty?
+ merge(destination, yield)
+ return nil
+ end
+
+ say "Please specify merge tool to `THOR_MERGE` env."
else
say file_collision_help
end
@@ -279,11 +306,11 @@ class Bundler::Thor
result = if ENV["THOR_COLUMNS"]
ENV["THOR_COLUMNS"].to_i
else
- unix? ? dynamic_width : 80
+ unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
end
- result < 10 ? 80 : result
+ result < 10 ? DEFAULT_TERMINAL_WIDTH : result
rescue
- 80
+ DEFAULT_TERMINAL_WIDTH
end
# Called if something goes wrong during the execution. This is used by Bundler::Thor
@@ -344,6 +371,7 @@ class Bundler::Thor
q - quit, abort
d - diff, show the differences between the old and the new
h - help, show this help
+ m - merge, run merge tool
HELP
end
@@ -432,6 +460,23 @@ class Bundler::Thor
end
correct_answer
end
+
+ def merge(destination, content) #:nodoc:
+ require "tempfile"
+ Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp|
+ temp.write content
+ temp.rewind
+ system %(#{merge_tool} "#{temp.path}" "#{destination}")
+ end
+ end
+
+ def merge_tool #:nodoc:
+ @merge_tool ||= ENV["THOR_MERGE"] || git_merge_tool
+ end
+
+ def git_merge_tool #:nodoc:
+ `git config merge.tool`.rstrip rescue ""
+ end
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/util.rb b/lib/bundler/vendor/thor/lib/thor/util.rb
index 5d03177a28..0fe7d4d859 100644
--- a/lib/bundler/vendor/thor/lib/thor/util.rb
+++ b/lib/bundler/vendor/thor/lib/thor/util.rb
@@ -27,7 +27,7 @@ class Bundler::Thor
end
# Receives a constant and converts it to a Bundler::Thor namespace. Since Bundler::Thor
- # commands can be added to a sandbox, this method is also responsable for
+ # commands can be added to a sandbox, this method is also responsible for
# removing the sandbox namespace.
#
# This method should not be used in general because it's used to deal with
diff --git a/lib/bundler/vendor/thor/lib/thor/version.rb b/lib/bundler/vendor/thor/lib/thor/version.rb
index df8f18821a..98f2b79081 100644
--- a/lib/bundler/vendor/thor/lib/thor/version.rb
+++ b/lib/bundler/vendor/thor/lib/thor/version.rb
@@ -1,3 +1,3 @@
class Bundler::Thor
- VERSION = "0.20.0"
+ VERSION = "0.20.3"
end
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index 401f62447c..cfd6300950 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,13 +1,10 @@
# frozen_string_literal: false
-# Ruby 1.9.3 and old RubyGems don't play nice with frozen version strings
-# rubocop:disable MutableConstant
-
module Bundler
# We're doing this because we might write tests that deal
# with other versions of bundler and we are unsure how to
# handle this better.
- VERSION = "2.0.1" unless defined?(::Bundler::VERSION)
+ VERSION = "2.1.0.pre.1".freeze unless defined?(::Bundler::VERSION)
def self.overwrite_loaded_gem_version
begin
diff --git a/lib/bundler/version_ranges.rb b/lib/bundler/version_ranges.rb
index ec25716cde..12a956d6a0 100644
--- a/lib/bundler/version_ranges.rb
+++ b/lib/bundler/version_ranges.rb
@@ -5,11 +5,42 @@ module Bundler
NEq = Struct.new(:version)
ReqR = Struct.new(:left, :right)
class ReqR
- Endpoint = Struct.new(:version, :inclusive)
+ Endpoint = Struct.new(:version, :inclusive) do
+ def <=>(other)
+ if version.equal?(INFINITY)
+ return 0 if other.version.equal?(INFINITY)
+ return 1
+ elsif other.version.equal?(INFINITY)
+ return -1
+ end
+
+ comp = version <=> other.version
+ return comp unless comp.zero?
+
+ if inclusive && !other.inclusive
+ 1
+ elsif !inclusive && other.inclusive
+ -1
+ else
+ 0
+ end
+ end
+ end
+
def to_s
"#{left.inclusive ? "[" : "("}#{left.version}, #{right.version}#{right.inclusive ? "]" : ")"}"
end
- INFINITY = Object.new.freeze
+ INFINITY = begin
+ inf = Object.new
+ def inf.to_s
+ "∞"
+ end
+ def inf.<=>(other)
+ return 0 if other.equal?(self)
+ 1
+ end
+ inf.freeze
+ end
ZERO = Gem::Version.new("0.a")
def cover?(v)
@@ -32,6 +63,15 @@ module Bundler
left.version == right.version
end
+ def <=>(other)
+ return -1 if other.equal?(INFINITY)
+
+ comp = left <=> other.left
+ return comp unless comp.zero?
+
+ right <=> other.right
+ end
+
UNIVERSAL = ReqR.new(ReqR::Endpoint.new(Gem::Version.new("0.a"), true), ReqR::Endpoint.new(ReqR::INFINITY, false)).freeze
end
@@ -57,7 +97,7 @@ module Bundler
end.uniq
ranges, neqs = ranges.partition {|r| !r.is_a?(NEq) }
- [ranges.sort_by {|range| [range.left.version, range.left.inclusive ? 0 : 1] }, neqs.map(&:version)]
+ [ranges.sort, neqs.map(&:version)]
end
def self.empty?(ranges, neqs)
@@ -66,8 +106,14 @@ module Bundler
next false if curr_range.single? && neqs.include?(curr_range.left.version)
next curr_range if last_range.right.version == ReqR::INFINITY
case last_range.right.version <=> curr_range.left.version
- when 1 then next curr_range
- when 0 then next(last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version) && curr_range)
+ # higher
+ when 1 then next ReqR.new(curr_range.left, last_range.right)
+ # equal
+ when 0
+ if last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version)
+ ReqR.new(curr_range.left, [curr_range.right, last_range.right].max)
+ end
+ # lower
when -1 then next false
end
end
diff --git a/lib/bundler/vlad.rb b/lib/bundler/vlad.rb
index a6b13435c9..68181e7db8 100644
--- a/lib/bundler/vlad.rb
+++ b/lib/bundler/vlad.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "bundler/shared_helpers"
-Bundler::SharedHelpers.major_deprecation 3,
+Bundler::SharedHelpers.major_deprecation 2,
"The Bundler task for Vlad"
# Vlad task for Bundler.
diff --git a/lib/bundler/worker.rb b/lib/bundler/worker.rb
index e91cfa7805..3471654b43 100644
--- a/lib/bundler/worker.rb
+++ b/lib/bundler/worker.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require "thread"
-
module Bundler
class Worker
POISON = Object.new
@@ -62,7 +60,7 @@ module Bundler
def apply_func(obj, i)
@func.call(obj, i)
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
WrappedException.new(e)
end
diff --git a/lib/bundler/yaml_serializer.rb b/lib/bundler/yaml_serializer.rb
index 0fd81c40ef..374b3bb5e3 100644
--- a/lib/bundler/yaml_serializer.rb
+++ b/lib/bundler/yaml_serializer.rb
@@ -32,7 +32,7 @@ module Bundler
(.*) # value
\1 # matching closing quote
$
- /xo
+ /xo.freeze
HASH_REGEX = /
^
@@ -40,12 +40,11 @@ module Bundler
(.+) # key
(?::(?=(?:\s|$))) # : (without the lookahead the #key includes this when : is present in value)
[ ]?
- (?: !\s)? # optional exclamation mark found with ruby 1.9.3
(['"]?) # optional opening quote
(.*) # value
\3 # matching closing quote
$
- /xo
+ /xo.freeze
def load(str)
res = {}