summaryrefslogtreecommitdiff
path: root/lib/bundler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bundler')
-rw-r--r--lib/bundler/build_metadata.rb36
-rw-r--r--lib/bundler/capistrano.rb22
-rw-r--r--lib/bundler/cli.rb746
-rw-r--r--lib/bundler/cli/add.rb25
-rw-r--r--lib/bundler/cli/binstubs.rb43
-rw-r--r--lib/bundler/cli/cache.rb36
-rw-r--r--lib/bundler/cli/check.rb38
-rw-r--r--lib/bundler/cli/clean.rb25
-rw-r--r--lib/bundler/cli/common.rb102
-rw-r--r--lib/bundler/cli/config.rb119
-rw-r--r--lib/bundler/cli/console.rb43
-rw-r--r--lib/bundler/cli/doctor.rb94
-rw-r--r--lib/bundler/cli/exec.rb105
-rw-r--r--lib/bundler/cli/gem.rb249
-rw-r--r--lib/bundler/cli/info.rb50
-rw-r--r--lib/bundler/cli/init.rb42
-rw-r--r--lib/bundler/cli/inject.rb60
-rw-r--r--lib/bundler/cli/install.rb214
-rw-r--r--lib/bundler/cli/issue.rb40
-rw-r--r--lib/bundler/cli/list.rb22
-rw-r--r--lib/bundler/cli/lock.rb63
-rw-r--r--lib/bundler/cli/open.rb26
-rw-r--r--lib/bundler/cli/outdated.rb260
-rw-r--r--lib/bundler/cli/package.rb49
-rw-r--r--lib/bundler/cli/platform.rb46
-rw-r--r--lib/bundler/cli/plugin.rb24
-rw-r--r--lib/bundler/cli/pristine.rb43
-rw-r--r--lib/bundler/cli/show.rb75
-rw-r--r--lib/bundler/cli/update.rb91
-rw-r--r--lib/bundler/cli/viz.rb31
-rw-r--r--lib/bundler/compact_index_client.rb109
-rw-r--r--lib/bundler/compact_index_client/cache.rb118
-rw-r--r--lib/bundler/compact_index_client/updater.rb107
-rw-r--r--lib/bundler/compatibility_guard.rb14
-rw-r--r--lib/bundler/constants.rb7
-rw-r--r--lib/bundler/current_ruby.rb86
-rw-r--r--lib/bundler/definition.rb984
-rw-r--r--lib/bundler/dep_proxy.rb48
-rw-r--r--lib/bundler/dependency.rb138
-rw-r--r--lib/bundler/deployment.rb69
-rw-r--r--lib/bundler/deprecate.rb43
-rw-r--r--lib/bundler/dsl.rb599
-rw-r--r--lib/bundler/endpoint_specification.rb141
-rw-r--r--lib/bundler/env.rb153
-rw-r--r--lib/bundler/environment_preserver.rb59
-rw-r--r--lib/bundler/errors.rb158
-rw-r--r--lib/bundler/feature_flag.rb67
-rw-r--r--lib/bundler/fetcher.rb312
-rw-r--r--lib/bundler/fetcher/base.rb52
-rw-r--r--lib/bundler/fetcher/compact_index.rb126
-rw-r--r--lib/bundler/fetcher/dependency.rb82
-rw-r--r--lib/bundler/fetcher/downloader.rb79
-rw-r--r--lib/bundler/fetcher/index.rb52
-rw-r--r--lib/bundler/friendly_errors.rb129
-rw-r--r--lib/bundler/gem_helper.rb202
-rw-r--r--lib/bundler/gem_helpers.rb101
-rw-r--r--lib/bundler/gem_remote_fetcher.rb43
-rw-r--r--lib/bundler/gem_tasks.rb7
-rw-r--r--lib/bundler/gem_version_promoter.rb176
-rw-r--r--lib/bundler/gemdeps.rb29
-rw-r--r--lib/bundler/graph.rb152
-rw-r--r--lib/bundler/index.rb213
-rw-r--r--lib/bundler/injector.rb94
-rw-r--r--lib/bundler/inline.rb74
-rw-r--r--lib/bundler/installer.rb287
-rw-r--r--lib/bundler/installer/gem_installer.rb78
-rw-r--r--lib/bundler/installer/parallel_installer.rb228
-rw-r--r--lib/bundler/installer/standalone.rb53
-rw-r--r--lib/bundler/lazy_specification.rb123
-rw-r--r--lib/bundler/lockfile_generator.rb95
-rw-r--r--lib/bundler/lockfile_parser.rb256
-rw-r--r--lib/bundler/match_platform.rb24
-rw-r--r--lib/bundler/mirror.rb223
-rw-r--r--lib/bundler/plugin.rb285
-rw-r--r--lib/bundler/plugin/api.rb81
-rw-r--r--lib/bundler/plugin/api/source.rb306
-rw-r--r--lib/bundler/plugin/dsl.rb53
-rw-r--r--lib/bundler/plugin/index.rb157
-rw-r--r--lib/bundler/plugin/installer.rb96
-rw-r--r--lib/bundler/plugin/installer/git.rb38
-rw-r--r--lib/bundler/plugin/installer/rubygems.rb27
-rw-r--r--lib/bundler/plugin/source_list.rb27
-rw-r--r--lib/bundler/process_lock.rb24
-rw-r--r--lib/bundler/psyched_yaml.rb37
-rw-r--r--lib/bundler/remote_specification.rb114
-rw-r--r--lib/bundler/resolver.rb372
-rw-r--r--lib/bundler/resolver/spec_group.rb111
-rw-r--r--lib/bundler/retry.rb66
-rw-r--r--lib/bundler/ruby_dsl.rb18
-rw-r--r--lib/bundler/ruby_version.rb152
-rw-r--r--lib/bundler/rubygems_ext.rb210
-rw-r--r--lib/bundler/rubygems_gem_installer.rb99
-rw-r--r--lib/bundler/rubygems_integration.rb892
-rw-r--r--lib/bundler/runtime.rb316
-rw-r--r--lib/bundler/settings.rb442
-rw-r--r--lib/bundler/settings/validator.rb79
-rw-r--r--lib/bundler/setup.rb28
-rw-r--r--lib/bundler/shared_helpers.rb366
-rw-r--r--lib/bundler/similarity_detector.rb63
-rw-r--r--lib/bundler/source.rb94
-rw-r--r--lib/bundler/source/gemspec.rb18
-rw-r--r--lib/bundler/source/git.rb328
-rw-r--r--lib/bundler/source/git/git_proxy.rb257
-rw-r--r--lib/bundler/source/metadata.rb63
-rw-r--r--lib/bundler/source/path.rb249
-rw-r--r--lib/bundler/source/path/installer.rb74
-rw-r--r--lib/bundler/source/rubygems.rb530
-rw-r--r--lib/bundler/source/rubygems/remote.rb66
-rw-r--r--lib/bundler/source_list.rb186
-rw-r--r--lib/bundler/spec_set.rb189
-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.rb108
-rw-r--r--lib/bundler/templates/.document1
-rwxr-xr-xlib/bundler/templates/Executable29
-rw-r--r--lib/bundler/templates/Executable.bundler105
-rw-r--r--lib/bundler/templates/Executable.standalone14
-rw-r--r--lib/bundler/templates/Gemfile7
-rw-r--r--lib/bundler/templates/gems.rb8
-rw-r--r--lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt74
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt6
-rw-r--r--lib/bundler/templates/newgem/LICENSE.txt.tt21
-rw-r--r--lib/bundler/templates/newgem/README.md.tt47
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt29
-rw-r--r--lib/bundler/templates/newgem/bin/console.tt14
-rw-r--r--lib/bundler/templates/newgem/bin/setup.tt8
-rw-r--r--lib/bundler/templates/newgem/exe/newgem.tt3
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt3
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/newgem.c.tt9
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/newgem.h.tt6
-rw-r--r--lib/bundler/templates/newgem/gitignore.tt20
-rw-r--r--lib/bundler/templates/newgem/lib/newgem.rb.tt12
-rw-r--r--lib/bundler/templates/newgem/lib/newgem/version.rb.tt7
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt49
-rw-r--r--lib/bundler/templates/newgem/rspec.tt3
-rw-r--r--lib/bundler/templates/newgem/spec/newgem_spec.rb.tt9
-rw-r--r--lib/bundler/templates/newgem/spec/spec_helper.rb.tt14
-rw-r--r--lib/bundler/templates/newgem/test/newgem_test.rb.tt11
-rw-r--r--lib/bundler/templates/newgem/test/test_helper.rb.tt4
-rw-r--r--lib/bundler/templates/newgem/travis.yml.tt5
-rw-r--r--lib/bundler/ui.rb9
-rw-r--r--lib/bundler/ui/rg_proxy.rb19
-rw-r--r--lib/bundler/ui/shell.rb144
-rw-r--r--lib/bundler/ui/silent.rb69
-rw-r--r--lib/bundler/uri_credentials_filter.rb37
-rw-r--r--lib/bundler/vendor/fileutils/lib/fileutils.rb1638
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo.rb12
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb26
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb57
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb81
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb223
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb36
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb66
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb62
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb63
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb61
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb126
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb46
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb36
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb126
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/errors.rb138
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb6
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb101
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb67
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb837
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb46
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/state.rb58
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb27
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb1233
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb129
-rw-r--r--lib/bundler/vendor/thor/lib/thor.rb509
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions.rb321
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/create_file.rb104
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/create_link.rb60
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/directory.rb118
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb143
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb364
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb109
-rw-r--r--lib/bundler/vendor/thor/lib/thor/base.rb679
-rw-r--r--lib/bundler/vendor/thor/lib/thor/command.rb135
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb97
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb12
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb129
-rw-r--r--lib/bundler/vendor/thor/lib/thor/error.rb32
-rw-r--r--lib/bundler/vendor/thor/lib/thor/group.rb281
-rw-r--r--lib/bundler/vendor/thor/lib/thor/invocation.rb177
-rw-r--r--lib/bundler/vendor/thor/lib/thor/line_editor.rb17
-rw-r--r--lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb37
-rw-r--r--lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb88
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser.rb4
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/argument.rb70
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/arguments.rb175
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/option.rb146
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/options.rb221
-rw-r--r--lib/bundler/vendor/thor/lib/thor/rake_compat.rb71
-rw-r--r--lib/bundler/vendor/thor/lib/thor/runner.rb324
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell.rb81
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/basic.rb437
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/color.rb149
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/html.rb126
-rw-r--r--lib/bundler/vendor/thor/lib/thor/util.rb268
-rw-r--r--lib/bundler/vendor/thor/lib/thor/version.rb3
-rw-r--r--lib/bundler/vendored_fileutils.rb9
-rw-r--r--lib/bundler/vendored_molinillo.rb4
-rw-r--r--lib/bundler/vendored_persistent.rb52
-rw-r--r--lib/bundler/vendored_thor.rb8
-rw-r--r--lib/bundler/version.rb28
-rw-r--r--lib/bundler/version_ranges.rb76
-rw-r--r--lib/bundler/vlad.rb17
-rw-r--r--lib/bundler/worker.rb106
-rw-r--r--lib/bundler/yaml_serializer.rb90
214 files changed, 0 insertions, 27740 deletions
diff --git a/lib/bundler/build_metadata.rb b/lib/bundler/build_metadata.rb
deleted file mode 100644
index 54436f982d..0000000000
--- a/lib/bundler/build_metadata.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # Represents metadata from when the Bundler gem was built.
- module BuildMetadata
- # begin ivars
- @release = false
- # end ivars
-
- # A hash representation of the build metadata.
- def self.to_h
- {
- "Built At" => built_at,
- "Git SHA" => git_commit_sha,
- "Released Version" => release?,
- }
- end
-
- # A string representing the date the bundler gem was built.
- def self.built_at
- @built_at ||= Time.now.utc.strftime("%Y-%m-%d").freeze
- end
-
- # The SHA for the git commit the bundler gem was built from.
- def self.git_commit_sha
- @git_commit_sha ||= Dir.chdir(File.expand_path("..", __FILE__)) do
- `git rev-parse --short HEAD`.strip.freeze
- end
- end
-
- # Whether this is an official release build of Bundler.
- def self.release?
- @release
- end
- end
-end
diff --git a/lib/bundler/capistrano.rb b/lib/bundler/capistrano.rb
deleted file mode 100644
index 1b7145b72b..0000000000
--- a/lib/bundler/capistrano.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/shared_helpers"
-Bundler::SharedHelpers.major_deprecation 2,
- "The Bundler task for Capistrano. Please use http://github.com/capistrano/bundler"
-
-# Capistrano task for Bundler.
-#
-# Add "require 'bundler/capistrano'" in your Capistrano deploy.rb, and
-# Bundler will be activated after each new deployment.
-require "bundler/deployment"
-require "capistrano/version"
-
-if defined?(Capistrano::Version) && Gem::Version.new(Capistrano::Version).release >= Gem::Version.new("3.0")
- raise "For Capistrano 3.x integration, please use http://github.com/capistrano/bundler"
-end
-
-Capistrano::Configuration.instance(:must_exist).load do
- before "deploy:finalize_update", "bundle:install"
- Bundler::Deployment.define_task(self, :task, :except => { :no_release => true })
- set :rake, lambda { "#{fetch(:bundle_cmd, "bundle")} exec rake" }
-end
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
deleted file mode 100644
index 05e1851c18..0000000000
--- a/lib/bundler/cli.rb
+++ /dev/null
@@ -1,746 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler"
-require "bundler/vendored_thor"
-
-module Bundler
- class CLI < Thor
- require "bundler/cli/common"
-
- package_name "Bundler"
-
- AUTO_INSTALL_CMDS = %w[show binstubs outdated exec open console licenses clean].freeze
- PARSEABLE_COMMANDS = %w[
- check config help exec platform show version
- ].freeze
-
- def self.start(*)
- super
- rescue Exception => e
- Bundler.ui = UI::Shell.new
- raise e
- ensure
- Bundler::SharedHelpers.print_major_deprecations!
- end
-
- def self.dispatch(*)
- super do |i|
- i.send(:print_command)
- i.send(:warn_on_outdated_bundler)
- end
- end
-
- def initialize(*args)
- super
-
- custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile]
- if custom_gemfile && !custom_gemfile.empty?
- Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile)
- Bundler.reset_paths!
- end
-
- Bundler.settings.set_command_option_if_given :retry, options[:retry]
-
- current_cmd = args.last[:current_command].name
- auto_install if AUTO_INSTALL_CMDS.include?(current_cmd)
- rescue UnknownArgumentError => e
- raise InvalidOption, e.message
- ensure
- self.options ||= {}
- unprinted_warnings = Bundler.ui.unprinted_warnings
- Bundler.ui = UI::Shell.new(options)
- Bundler.ui.level = "debug" if options["verbose"]
- unprinted_warnings.each {|w| Bundler.ui.warn(w) }
-
- if ENV["RUBYGEMS_GEMDEPS"] && !ENV["RUBYGEMS_GEMDEPS"].empty?
- Bundler.ui.warn(
- "The RUBYGEMS_GEMDEPS environment variable is set. This enables RubyGems' " \
- "experimental Gemfile mode, which may conflict with Bundler and cause unexpected errors. " \
- "To remove this warning, unset RUBYGEMS_GEMDEPS.", :wrap => true
- )
- 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
-
- desc "cli_help", "Prints a summary of bundler commands", :hide => true
- def cli_help
- version
- Bundler.ui.info "\n"
-
- primary_commands = ["install", "update",
- Bundler.feature_flag.cache_command_is_package? ? "cache" : "package",
- "exec", "config", "help"]
-
- list = self.class.printable_commands(true)
- by_name = list.group_by {|name, _message| name.match(/^bundle (\w+)/)[1] }
- utilities = by_name.keys.sort - primary_commands
- primary_commands.map! {|name| (by_name[name] || raise("no primary command #{name}")).first }
- utilities.map! {|name| by_name[name].first }
-
- shell.say "Bundler commands:\n\n"
-
- shell.say " Primary commands:\n"
- shell.print_table(primary_commands, :indent => 4, :truncate => true)
- shell.say
- shell.say " Utilities:\n"
- shell.print_table(utilities, :indent => 4, :truncate => true)
- shell.say
- self.class.send(:class_options_help, shell)
- end
- default_task(Bundler.feature_flag.default_cli_command)
-
- class_option "no-color", :type => :boolean, :desc => "Disable colorization in output"
- class_option "retry", :type => :numeric, :aliases => "-r", :banner => "NUM",
- :desc => "Specify the number of times you wish to attempt network commands"
- class_option "verbose", :type => :boolean, :desc => "Enable verbose output mode", :aliases => "-V"
-
- def help(cli = nil)
- case cli
- when "gemfile" then command = "gemfile"
- when nil then command = "bundle"
- else command = "bundle-#{cli}"
- end
-
- man_path = File.expand_path("../../../man", __FILE__)
- man_pages = Hash[Dir.glob(File.join(man_path, "*")).grep(/.*\.\d*\Z/).collect do |f|
- [File.basename(f, ".*"), f]
- end]
-
- if man_pages.include?(command)
- if Bundler.which("man") && man_path !~ %r{^file:/.+!/META-INF/jruby.home/.+}
- Kernel.exec "man #{man_pages[command]}"
- else
- puts File.read("#{man_path}/#{File.basename(man_pages[command])}.txt")
- end
- elsif command_path = Bundler.which("bundler-#{cli}")
- Kernel.exec(command_path, "--help")
- else
- super
- end
- end
-
- def self.handle_no_command_error(command, has_namespace = $thor_runner)
- if Bundler.feature_flag.plugins? && Bundler::Plugin.command?(command)
- return Bundler::Plugin.exec_command(command, ARGV[1..-1])
- end
-
- return super unless command_path = Bundler.which("bundler-#{command}")
-
- Kernel.exec(command_path, *ARGV[1..-1])
- end
-
- desc "init [OPTIONS]", "Generates a Gemfile into the current working directory"
- long_desc <<-D
- Init generates a default Gemfile in the current working directory. When adding a
- 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"
- def init
- require "bundler/cli/init"
- Init.new(options.dup).run
- end
-
- desc "check [OPTIONS]", "Checks if the dependencies listed in Gemfile are satisfied by currently installed gems"
- long_desc <<-D
- Check searches the local machine for each of the gems requested in the Gemfile. If
- all gems are found, Bundler prints a success message and exits with a status of 0.
- If not, the first missing gem is listed and Bundler exits status 1.
- D
- method_option "dry-run", :type => :boolean, :default => false, :banner =>
- "Lock the Gemfile"
- method_option "gemfile", :type => :string, :banner =>
- "Use the specified gemfile instead of Gemfile"
- 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" unless Bundler.feature_flag.forget_cli_options?}"
- map "c" => "check"
- def check
- require "bundler/cli/check"
- Check.new(options).run
- end
-
- desc "install [OPTIONS]", "Install the current environment to the system"
- long_desc <<-D
- Install will install all of the gems in the current bundle, making them available
- for use. In a freshly checked out repository, this command will give you the same
- gem versions as the last person who updated the Gemfile and ran `bundle update`.
-
- Passing [DIR] to install (e.g. vendor) will cause the unpacked gems to be installed
- into the [DIR] directory rather than into system gems.
-
- 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 =>
- "Generate bin stubs for bundled gems to ./bin"
- deprecated_option "clean", :type => :boolean, :banner =>
- "Run bundle clean automatically after install"
- deprecated_option "deployment", :type => :boolean, :banner =>
- "Install using defaults tuned for deployment environments"
- deprecated_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"
- method_option "gemfile", :type => :string, :banner =>
- "Use the specified gemfile instead of Gemfile"
- method_option "jobs", :aliases => "-j", :type => :numeric, :banner =>
- "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 =>
- "Don't update the existing gem cache."
- method_option "redownload", :type => :boolean, :aliases =>
- [Bundler.feature_flag.forget_cli_options? ? nil : "--force"].compact, :banner =>
- "Force downloading every gem."
- deprecated_option "no-prune", :type => :boolean, :banner =>
- "Don't remove stale gems from the cache."
- deprecated_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 =>
- "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 =>
- "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 =>
- "Exclude gems that are part of the specified named group."
- deprecated_option "with", :type => :array, :banner =>
- "Include gems that are part of the specified named group."
- map "i" => "install"
- def install
- require "bundler/cli/install"
- Bundler.settings.temporary(:no_install => false) do
- Install.new(options.dup).run
- end
- end
-
- desc "update [OPTIONS]", "Update the current environment"
- long_desc <<-D
- Update will install the newest versions of the gems listed in the Gemfile. Use
- update when you have changed the Gemfile, or if you want to get the newest
- possible versions of the gems in the bundle.
- D
- method_option "full-index", :type => :boolean, :banner =>
- "Fall back to using the single-file index of all gems"
- method_option "group", :aliases => "-g", :type => :array, :banner =>
- "Update a specific group"
- method_option "jobs", :aliases => "-j", :type => :numeric, :banner =>
- "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"
- method_option "quiet", :type => :boolean, :banner =>
- "Only output warnings and errors."
- method_option "source", :type => :array, :banner =>
- "Update a specific source (and all gems associated with it)"
- method_option "force", :type => :boolean, :banner =>
- "Force downloading every gem."
- method_option "ruby", :type => :boolean, :banner =>
- "Update ruby specified in Gemfile.lock"
- method_option "bundler", :type => :string, :lazy_default => "> 0.a", :banner =>
- "Update the locked version of bundler"
- method_option "patch", :type => :boolean, :banner =>
- "Prefer updating only to next patch version"
- method_option "minor", :type => :boolean, :banner =>
- "Prefer updating only to next minor version"
- method_option "major", :type => :boolean, :banner =>
- "Prefer updating to next major version (default)"
- method_option "strict", :type => :boolean, :banner =>
- "Do not allow any gem to be updated past latest --patch | --minor | --major"
- method_option "conservative", :type => :boolean, :banner =>
- "Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
- method_option "all", :type => :boolean, :banner =>
- "Update everything."
- def update(*gems)
- require "bundler/cli/update"
- Update.new(options, gems).run
- 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)
- Bundler::SharedHelpers.major_deprecation(2, "use `bundle list` instead of `bundle show`") if ARGV[0] == "show"
- 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"
- def list
- require "bundler/cli/list"
- List.new(options).run
- end
-
- map %w[ls] => "list"
- else
- map %w[list] => "show"
- end
-
- desc "info GEM [OPTIONS]", "Show information for the given gem"
- method_option "path", :type => :boolean, :banner => "Print full path to gem"
- def info(gem_name)
- require "bundler/cli/info"
- Info.new(options, gem_name).run
- end
-
- desc "binstubs GEM [OPTIONS]", "Install the binstubs of the listed gem"
- long_desc <<-D
- Generate binstubs for executables in [GEM]. Binstubs are put into bin,
- or the --binstubs directory if one has been set. Calling binstubs with [GEM [GEM]]
- will create binstubs for all given gems.
- D
- method_option "force", :type => :boolean, :default => false, :banner =>
- "Overwrite existing binstubs if they exist"
- method_option "path", :type => :string, :lazy_default => "bin", :banner =>
- "Binstub destination directory (default bin)"
- method_option "shebang", :type => :string, :banner =>
- "Specify a different shebang executable name than the default (usually 'ruby')"
- method_option "standalone", :type => :boolean, :banner =>
- "Make binstubs that can work without the Bundler runtime"
- def binstubs(*gems)
- require "bundler/cli/binstubs"
- Binstubs.new(options, gems).run
- end
-
- desc "add GEM VERSION", "Add gem to Gemfile and run bundle install"
- long_desc <<-D
- Adds the specified gem to Gemfile (if valid) and run 'bundle install' in one step.
- D
- method_option "version", :aliases => "-v", :type => :string
- method_option "group", :aliases => "-g", :type => :string
- method_option "source", :aliases => "-s", :type => :string
-
- def add(gem_name)
- require "bundler/cli/add"
- Add.new(options.dup, gem_name).run
- end
-
- desc "outdated GEM [OPTIONS]", "List installed gems with newer versions available"
- long_desc <<-D
- Outdated lists the names and versions of gems that have a newer version available
- in the given source. Calling outdated with [GEM [GEM]] will only check for newer
- versions of the given gems. Prerelease gems are ignored by default. If your gems
- are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1.
-
- For more information on patch level options (--major, --minor, --patch,
- --update-strict) see documentation on the same options on the update command.
- D
- method_option "group", :type => :string, :banner => "List gems from a specific group"
- method_option "groups", :type => :boolean, :banner => "List gems organized by groups"
- method_option "local", :type => :boolean, :banner =>
- "Do not attempt to fetch gems remotely and use the gem cache instead"
- method_option "pre", :type => :boolean, :banner => "Check for newer pre-release gems"
- method_option "source", :type => :array, :banner => "Check against a specific source"
- method_option "strict", :type => :boolean, :banner =>
- "Only list newer versions allowed by your Gemfile requirements"
- method_option "update-strict", :type => :boolean, :banner =>
- "Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major"
- method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version"
- method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)"
- method_option "patch", :type => :boolean, :banner => "Prefer updating only to next patch version"
- method_option "filter-major", :type => :boolean, :banner => "Only list major newer versions"
- method_option "filter-minor", :type => :boolean, :banner => "Only list minor newer versions"
- method_option "filter-patch", :type => :boolean, :banner => "Only list patch newer versions"
- method_option "parseable", :aliases => "--porcelain", :type => :boolean, :banner =>
- "Use minimal formatting for more parseable output"
- def outdated(*gems)
- require "bundler/cli/outdated"
- Outdated.new(options, gems).run
- end
-
- if Bundler.feature_flag.cache_command_is_package?
- map %w[cache] => :package
- else
- desc "cache [OPTIONS]", "Cache all the gems to vendor/cache", :hide => true
- unless Bundler.feature_flag.cache_command_is_package?
- method_option "all", :type => :boolean,
- :banner => "Include all sources (including path and git)."
- end
- method_option "all-platforms", :type => :boolean, :banner => "Include gems for all platforms present in the lockfile, not only the current one"
- method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
- def cache
- require "bundler/cli/cache"
- Cache.new(options).run
- end
- end
-
- desc "#{Bundler.feature_flag.cache_command_is_package? ? :cache : :package} [OPTIONS]", "Locks and then caches all of the gems into vendor/cache"
- unless Bundler.feature_flag.cache_command_is_package?
- method_option "all", :type => :boolean,
- :banner => "Include all sources (including path and git)."
- end
- method_option "all-platforms", :type => :boolean, :banner => "Include gems for all platforms present in the lockfile, not only the current one"
- method_option "cache-path", :type => :string, :banner =>
- "Specify a different cache path than the default (vendor/cache)."
- method_option "gemfile", :type => :string, :banner => "Use the specified gemfile instead of Gemfile"
- method_option "no-install", :type => :boolean, :banner => "Don't install the gems, only the package."
- method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
- 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."
- method_option "frozen", :type => :boolean, :banner =>
- "Do not allow the Gemfile.lock to be updated after this package operation's install"
- long_desc <<-D
- The package command will copy the .gem files for every gem in the bundle into the
- directory ./vendor/cache. If you then check that directory into your source
- control repository, others who check out your source will be able to install the
- bundle without having to download any additional gems.
- D
- def package
- require "bundler/cli/package"
- Package.new(options).run
- end
- map %w[pack] => :package
-
- desc "exec [OPTIONS]", "Run the command in context of the bundle"
- method_option :keep_file_descriptors, :type => :boolean, :default => false
- long_desc <<-D
- Exec runs a command, providing it access to the gems in the bundle. While using
- bundle exec you can require and call the bundled gems as if they were installed
- into the system wide RubyGems repository.
- D
- map "e" => "exec"
- def exec(*args)
- require "bundler/cli/exec"
- Exec.new(options, args).run
- end
-
- desc "config NAME [VALUE]", "Retrieve or set a configuration value"
- long_desc <<-D
- Retrieves or sets a configuration value. If only one parameter is provided, retrieve the value. If two parameters are provided, replace the
- existing value with the newly provided one.
-
- By default, setting a configuration value sets it for all projects
- on the machine.
-
- If a global setting is superceded by local configuration, this command
- 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
-
- desc "open GEM", "Opens the source directory of the given bundled gem"
- def open(name)
- require "bundler/cli/open"
- Open.new(options, name).run
- end
-
- if Bundler.feature_flag.console_command?
- desc "console [GROUP]", "Opens an IRB session with the bundle pre-loaded"
- def console(group = nil)
- require "bundler/cli/console"
- Console.new(options, group).run
- end
- end
-
- desc "version", "Prints the bundler's version information"
- def version
- cli_help = current_command.name == "cli_help"
- if cli_help || ARGV.include?("version")
- build_info = " (#{BuildMetadata.built_at} commit #{BuildMetadata.git_commit_sha})"
- end
-
- if !cli_help && Bundler.feature_flag.print_only_version_number?
- Bundler.ui.info "#{Bundler::VERSION}#{build_info}"
- else
- Bundler.ui.info "Bundler version #{Bundler::VERSION}#{build_info}"
- end
- end
- map %w[-v --version] => :version
-
- desc "licenses", "Prints the license of all gems in the bundle"
- def licenses
- Bundler.load.specs.sort_by {|s| s.license.to_s }.reverse_each do |s|
- gem_name = s.name
- license = s.license || s.licenses
-
- if license.empty?
- Bundler.ui.warn "#{gem_name}: Unknown"
- else
- Bundler.ui.info "#{gem_name}: #{license}"
- end
- end
- end
-
- 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.
- Viz requires the ruby-graphviz gem (and its dependencies).
- The associated gems must also be installed via 'bundle install'.
- D
- method_option :file, :type => :string, :default => "gem_graph", :aliases => "-f", :desc => "The name to use for the generated file. see format option"
- method_option :format, :type => :string, :default => "png", :aliases => "-F", :desc => "This is output format option. Supported format is png, jpg, svg, dot ..."
- method_option :requirements, :type => :boolean, :default => false, :aliases => "-R", :desc => "Set to show the version of each required dependency."
- 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
- require "bundler/cli/viz"
- Viz.new(options.dup).run
- end
-
- old_gem = instance_method(:gem)
-
- 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 :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 :test, :type => :string, :lazy_default => "rspec", :aliases => "-t", :banner => "rspec",
- :desc => "Generate a test directory for your library, either rspec or minitest. Set a default with `bundle config gem.test rspec`."
- def gem(name)
- end
-
- commands["gem"].tap do |gem_command|
- def gem_command.run(instance, args = [])
- arity = 1 # name
-
- require "bundler/cli/gem"
- cmd_args = args + [instance]
- cmd_args.unshift(instance.options)
-
- cmd = begin
- Gem.new(*cmd_args)
- rescue ArgumentError => e
- instance.class.handle_argument_error(self, e, args, arity)
- end
-
- cmd.run
- end
- end
-
- undef_method(:gem)
- define_method(:gem, old_gem)
- private :gem
-
- def self.source_root
- File.expand_path(File.join(File.dirname(__FILE__), "templates"))
- end
-
- desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory", :hide => true
- method_option "dry-run", :type => :boolean, :default => false, :banner =>
- "Only print out changes, do not clean gems"
- method_option "force", :type => :boolean, :default => false, :banner =>
- "Forces clean even if --path is not set"
- def clean
- require "bundler/cli/clean"
- Clean.new(options.dup).run
- end
-
- desc "platform [OPTIONS]", "Displays platform compatibility information"
- method_option "ruby", :type => :boolean, :default => false, :banner =>
- "only display ruby related platform information"
- def platform
- require "bundler/cli/platform"
- Platform.new(options).run
- end
-
- desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile", :hide => true
- method_option "source", :type => :string, :banner =>
- "Install gem from the given source"
- method_option "group", :type => :string, :banner =>
- "Install gem into a bundler group"
- def inject(name, version)
- 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
-
- desc "lock", "Creates a lockfile without installing"
- method_option "update", :type => :array, :lazy_default => true, :banner =>
- "ignore the existing lockfile, update all gems by default, or update list of given gems"
- method_option "local", :type => :boolean, :default => false, :banner =>
- "do not attempt to fetch remote gemspecs and use the local gem cache only"
- method_option "print", :type => :boolean, :default => false, :banner =>
- "print the lockfile to STDOUT instead of writing to the file system"
- 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 =>
- "Fall back to using the single-file index of all gems"
- method_option "add-platform", :type => :array, :default => [], :banner =>
- "Add a new platform to the lockfile"
- method_option "remove-platform", :type => :array, :default => [], :banner =>
- "Remove a platform from the lockfile"
- method_option "patch", :type => :boolean, :banner =>
- "If updating, prefer updating only to next patch version"
- method_option "minor", :type => :boolean, :banner =>
- "If updating, prefer updating only to next minor version"
- method_option "major", :type => :boolean, :banner =>
- "If updating, prefer updating to next major version (default)"
- method_option "strict", :type => :boolean, :banner =>
- "If updating, do not allow any gem to be updated past latest --patch | --minor | --major"
- method_option "conservative", :type => :boolean, :banner =>
- "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated"
- def lock
- require "bundler/cli/lock"
- Lock.new(options).run
- end
-
- desc "env", "Print information about the environment Bundler is running under"
- def env
- Env.write($stdout)
- end
-
- desc "doctor [OPTIONS]", "Checks the bundle for common problems"
- long_desc <<-D
- Doctor scans the OS dependencies of each of the gems requested in the Gemfile. If
- missing dependencies are detected, Bundler prints them and exits status 1.
- Otherwise, Bundler prints a success message and exits with a status of 0.
- D
- method_option "gemfile", :type => :string, :banner =>
- "Use the specified gemfile instead of Gemfile"
- method_option "quiet", :type => :boolean, :banner =>
- "Only output warnings and errors."
- def doctor
- require "bundler/cli/doctor"
- Doctor.new(options).run
- end
-
- desc "issue", "Learn how to report an issue in Bundler"
- def issue
- require "bundler/cli/issue"
- Issue.new.run
- end
-
- desc "pristine [GEMS...]", "Restores installed gems to pristine condition"
- long_desc <<-D
- Restores installed gems to pristine condition from files located in the
- gem cache. Gems installed from a git repository will be issued `git
- checkout --force`.
- D
- def pristine(*gems)
- require "bundler/cli/pristine"
- Pristine.new(gems).run
- end
-
- if Bundler.feature_flag.plugins?
- require "bundler/cli/plugin"
- desc "plugin", "Manage the bundler plugins"
- subcommand "plugin", Plugin
- end
-
- # Reformat the arguments passed to bundle that include a --help flag
- # into the corresponding `bundle help #{command}` call
- def self.reformatted_help_args(args)
- bundler_commands = all_commands.keys
- help_flags = %w[--help -h]
- exec_commands = %w[e ex exe exec]
- help_used = args.index {|a| help_flags.include? a }
- exec_used = args.index {|a| exec_commands.include? a }
- command = args.find {|a| bundler_commands.include? a }
- if exec_used && help_used
- if exec_used + help_used == 1
- %w[help exec]
- else
- args
- end
- elsif help_used
- args = args.dup
- args.delete_at(help_used)
- ["help", command || args].flatten.compact
- else
- args
- end
- end
-
- private
-
- # Automatically invoke `bundle install` and resume if
- # Bundler.settings[:auto_install] exists. This is set through config cmd
- # `bundle config 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
- # `Installer` that'll keep a reference to the old one instead.
- def auto_install
- return unless Bundler.settings[:auto_install]
-
- begin
- Bundler.definition.specs
- rescue GemNotFound
- Bundler.ui.info "Automatically installing missing gems."
- Bundler.reset!
- invoke :install, []
- Bundler.reset!
- end
- end
-
- def current_command
- _, _, config = @_initializer
- config[:current_command]
- end
-
- def print_command
- return unless Bundler.ui.debug?
- cmd = current_command
- command_name = cmd.name
- return if PARSEABLE_COMMANDS.include?(command_name)
- command = ["bundle", command_name] + args
- options_to_print = options.dup
- options_to_print.delete_if do |k, v|
- next unless o = cmd.options[k]
- o.default == v
- end
- command << Thor::Options.to_switches(options_to_print.sort_by(&:first)).strip
- command.reject!(&:empty?)
- Bundler.ui.info "Running `#{command * " "}` with bundler #{Bundler::VERSION}"
- end
-
- def warn_on_outdated_bundler
- return if Bundler.settings[:disable_version_check]
-
- command_name = current_command.name
- return if PARSEABLE_COMMANDS.include?(command_name)
-
- latest = Fetcher::CompactIndex.
- new(nil, Source::Rubygems::Remote.new(URI("https://rubygems.org")), nil).
- send(:compact_index_client).
- instance_variable_get(:@cache).
- dependencies("bundler").
- map {|d| Gem::Version.new(d.first) }.
- max
- return unless latest
-
- current = Gem::Version.new(VERSION)
- return if current >= latest
- latest_installed = Bundler.rubygems.find_name("bundler").map(&:version).max
-
- installation = "To install the latest version, run `gem install bundler#{" --pre" if latest.prerelease?}`"
- if latest_installed && latest_installed > current
- suggestion = "To update to the most recent installed version (#{latest_installed}), run `bundle update --bundler`"
- suggestion = "#{installation}\n#{suggestion}" if latest_installed < latest
- else
- suggestion = installation
- end
-
- Bundler.ui.warn "The latest bundler is #{latest}, but you are currently running #{current}.\n#{suggestion}"
- rescue
- nil
- end
- end
-end
diff --git a/lib/bundler/cli/add.rb b/lib/bundler/cli/add.rb
deleted file mode 100644
index 1fcbd22f28..0000000000
--- a/lib/bundler/cli/add.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Add
- def initialize(options, gem_name)
- @gem_name = gem_name
- @options = options
- @options[:group] = @options[:group].split(",").map(&:strip) if !@options[:group].nil? && !@options[:group].empty?
- end
-
- def run
- version = @options[:version].nil? ? nil : @options[:version].split(",").map(&:strip)
-
- unless version.nil?
- version.each do |v|
- raise InvalidOption, "Invalid gem requirement pattern '#{v}'" unless Gem::Requirement::PATTERN =~ v.to_s
- end
- end
- dependency = Bundler::Dependency.new(@gem_name, version, @options)
-
- Injector.inject([dependency], :conservative_versioning => @options[:version].nil?) # Perform conservative versioning only when version is not specified
- Installer.install(Bundler.root, Bundler.definition)
- end
- end
-end
diff --git a/lib/bundler/cli/binstubs.rb b/lib/bundler/cli/binstubs.rb
deleted file mode 100644
index 449204d821..0000000000
--- a/lib/bundler/cli/binstubs.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Binstubs
- attr_reader :options, :gems
- def initialize(options, gems)
- @options = options
- @gems = gems
- end
-
- def run
- Bundler.definition.validate_runtime!
- path_option = options["path"]
- path_option = nil if path_option && path_option.empty?
- Bundler.settings.set_command_option :bin, path_option if options["path"]
- Bundler.settings.set_command_option_if_given :shebang, options["shebang"]
- installer = Installer.new(Bundler.root, Bundler.definition)
-
- if gems.empty?
- Bundler.ui.error "`bundle binstubs` needs at least one gem to run."
- exit 1
- end
-
- gems.each do |gem_name|
- spec = Bundler.definition.specs.find {|s| s.name == gem_name }
- unless spec
- raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(
- gem_name, Bundler.definition.specs
- )
- end
-
- if options[:standalone]
- next Bundler.ui.warn("Sorry, Bundler can only be run via RubyGems.") if gem_name == "bundler"
- Bundler.settings.temporary(:path => (Bundler.settings[:path] || Bundler.root)) do
- installer.generate_standalone_bundler_executable_stubs(spec)
- end
- else
- installer.generate_bundler_executable_stubs(spec, :force => options[:force], :binstubs_cmd => true)
- end
- end
- end
- end
-end
diff --git a/lib/bundler/cli/cache.rb b/lib/bundler/cli/cache.rb
deleted file mode 100644
index 9d2ba87d34..0000000000
--- a/lib/bundler/cli/cache.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Cache
- attr_reader :options
- def initialize(options)
- @options = options
- end
-
- def run
- Bundler.definition.validate_runtime!
- Bundler.definition.resolve_with_cache!
- setup_cache_all
- Bundler.settings.set_command_option_if_given :cache_all_platforms, options["all-platforms"]
- Bundler.load.cache
- Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"]
- Bundler.load.lock
- rescue GemNotFound => e
- Bundler.ui.error(e.message)
- Bundler.ui.warn "Run `bundle install` to install missing gems."
- exit 1
- end
-
- private
-
- def setup_cache_all
- Bundler.settings.set_command_option_if_given :cache_all, options[:all]
-
- 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."
- end
- end
- end
-end
diff --git a/lib/bundler/cli/check.rb b/lib/bundler/cli/check.rb
deleted file mode 100644
index e572787dc4..0000000000
--- a/lib/bundler/cli/check.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Check
- attr_reader :options
-
- def initialize(options)
- @options = options
- end
-
- def run
- Bundler.settings.set_command_option_if_given :path, options[:path]
-
- begin
- definition = Bundler.definition
- definition.validate_runtime!
- not_installed = definition.missing_specs
- rescue GemNotFound, VersionConflict
- Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies."
- Bundler.ui.warn "Install missing gems with `bundle install`."
- exit 1
- end
-
- if not_installed.any?
- Bundler.ui.error "The following gems are missing"
- not_installed.each {|s| Bundler.ui.error " * #{s.name} (#{s.version})" }
- Bundler.ui.warn "Install missing gems with `bundle install`"
- exit 1
- elsif !Bundler.default_lockfile.file? && Bundler.frozen?
- Bundler.ui.error "This bundle has been frozen, but there is no #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} present"
- exit 1
- else
- Bundler.load.lock(:preserve_unknown_sections => true) unless options[:"dry-run"]
- Bundler.ui.info "The Gemfile's dependencies are satisfied"
- end
- end
- end
-end
diff --git a/lib/bundler/cli/clean.rb b/lib/bundler/cli/clean.rb
deleted file mode 100644
index 4a407fbae7..0000000000
--- a/lib/bundler/cli/clean.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Clean
- attr_reader :options
-
- def initialize(options)
- @options = options
- end
-
- def run
- require_path_or_force unless options[:"dry-run"]
- Bundler.load.clean(options[:"dry-run"])
- end
-
- protected
-
- def require_path_or_force
- return unless Bundler.use_system_gems? && !options[:force]
- raise InvalidOption, "Cleaning all the gems on your system is dangerous! " \
- "If you're sure you want to remove every system gem not in this " \
- "bundle, run `bundle clean --force`."
- end
- end
-end
diff --git a/lib/bundler/cli/common.rb b/lib/bundler/cli/common.rb
deleted file mode 100644
index 9d40ee9dfd..0000000000
--- a/lib/bundler/cli/common.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module CLI::Common
- def self.output_post_install_messages(messages)
- return if Bundler.settings["ignore_messages"]
- messages.to_a.each do |name, msg|
- print_post_install_message(name, msg) unless Bundler.settings["ignore_messages.#{name}"]
- end
- end
-
- def self.print_post_install_message(name, msg)
- Bundler.ui.confirm "Post-install message from #{name}:"
- Bundler.ui.info msg
- end
-
- def self.output_without_groups_message
- return if Bundler.settings[:without].empty?
- Bundler.ui.confirm without_groups_message
- end
-
- def self.without_groups_message
- 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"
- "Gems in the #{group_str} #{group_list} were not installed."
- end
-
- def self.select_spec(name, regex_match = nil)
- specs = []
- regexp = Regexp.new(name) if regex_match
-
- Bundler.definition.specs.each do |spec|
- return spec if spec.name == name
- specs << spec if regexp && spec.name =~ regexp
- end
-
- case specs.count
- when 0
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
- when 1
- specs.first
- else
- ask_for_spec_from(specs)
- end
- rescue RegexpError
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
- 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
- Bundler.ui.info "0 : - exit -", true
-
- num = Bundler.ui.ask("> ").to_i
- num > 0 ? specs[num - 1] : nil
- end
-
- def self.gem_not_found_message(missing_gem_name, alternatives)
- require "bundler/similarity_detector"
- message = "Could not find gem '#{missing_gem_name}'."
- alternate_names = alternatives.map {|a| a.respond_to?(:name) ? a.name : a }
- suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name)
- message += "\nDid you mean #{suggestions}?" if suggestions
- message
- end
-
- def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems)
- locked_names = locked_gems.specs.map(&:name)
- names.-(locked_names).each do |g|
- raise GemNotFound, gem_not_found_message(g, locked_names)
- end
- end
-
- def self.configure_gem_version_promoter(definition, options)
- patch_level = patch_level_options(options)
- 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"]
- end
- end
-
- def self.patch_level_options(options)
- [:major, :minor, :patch].select {|v| options.keys.include?(v.to_s) }
- end
-
- def self.clean_after_install?
- clean = Bundler.settings[:clean]
- return clean unless clean.nil?
- clean ||= Bundler.feature_flag.auto_clean_without_path? && Bundler.settings[:path].nil?
- clean &&= !Bundler.use_system_gems?
- clean
- end
- end
-end
diff --git a/lib/bundler/cli/config.rb b/lib/bundler/cli/config.rb
deleted file mode 100644
index 12f71ea8fe..0000000000
--- a/lib/bundler/cli/config.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-# 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]
- end
-
- def run
- unless name
- confirm_all
- return
- end
-
- unless valid_scope?(scope)
- Bundler.ui.error "Invalid scope --#{scope} given. Please use --local or --global."
- exit 1
- end
-
- if scope == "delete"
- Bundler.settings.set_local(name, nil)
- Bundler.settings.set_global(name, nil)
- return
- end
-
- if args.empty?
- if options[:parseable]
- if value = Bundler.settings[name]
- Bundler.ui.info("#{name}=#{value}")
- end
- return
- end
-
- confirm(name)
- return
- end
-
- Bundler.ui.info(message) if message
- Bundler.settings.send("set_#{scope}", name, new_value)
- end
-
- private
-
- 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|
- 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 new_value
- pathname = Pathname.new(args.join(" "))
- if name.start_with?("local.") && pathname.directory?
- pathname.expand_path.to_s
- else
- args.join(" ")
- 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}"
- 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
- end
- end
- end
-
- def valid_scope?(scope)
- %w[delete local global].include?(scope)
- end
- end
-end
diff --git a/lib/bundler/cli/console.rb b/lib/bundler/cli/console.rb
deleted file mode 100644
index 853eca8358..0000000000
--- a/lib/bundler/cli/console.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Console
- attr_reader :options, :group
- def initialize(options, group)
- @options = options
- @group = group
- end
-
- def run
- 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
- ARGV.clear
-
- console = get_console(Bundler.settings[:console] || "irb")
- console.start
- end
-
- def get_console(name)
- require name
- get_constant(name)
- rescue LoadError
- Bundler.ui.error "Couldn't load console #{name}, falling back to irb"
- require "irb"
- get_constant("irb")
- end
-
- def get_constant(name)
- const_name = {
- "pry" => :Pry,
- "ripl" => :Ripl,
- "irb" => :IRB,
- }[name]
- Object.const_get(const_name)
- rescue NameError
- Bundler.ui.error "Could not find constant #{const_name}"
- exit 1
- end
- end
-end
diff --git a/lib/bundler/cli/doctor.rb b/lib/bundler/cli/doctor.rb
deleted file mode 100644
index 7f28a5eb13..0000000000
--- a/lib/bundler/cli/doctor.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: true
-
-require "rbconfig"
-
-module Bundler
- class CLI::Doctor
- DARWIN_REGEX = /\s+(.+) \(compatibility /
- LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/
-
- attr_reader :options
-
- def initialize(options)
- @options = options
- end
-
- def otool_available?
- Bundler.which("otool")
- end
-
- def ldd_available?
- Bundler.which("ldd")
- end
-
- def dylibs_darwin(path)
- output = `/usr/bin/otool -L "#{path}"`.chomp
- dylibs = output.split("\n")[1..-1].map {|l| l.match(DARWIN_REGEX).captures[0] }.uniq
- # ignore @rpath and friends
- dylibs.reject {|dylib| dylib.start_with? "@" }
- end
-
- def dylibs_ldd(path)
- output = `/usr/bin/ldd "#{path}"`.chomp
- output.split("\n").map do |l|
- match = l.match(LDD_REGEX)
- next if match.nil?
- match.captures[0]
- end.compact
- end
-
- def dylibs(path)
- case RbConfig::CONFIG["host_os"]
- when /darwin/
- return [] unless otool_available?
- dylibs_darwin(path)
- when /(linux|solaris|bsd)/
- return [] unless ldd_available?
- dylibs_ldd(path)
- else # Windows, etc.
- Bundler.ui.warn("Dynamic library check not supported on this platform.")
- []
- end
- end
-
- def bundles_for_gem(spec)
- Dir.glob("#{spec.full_gem_path}/**/*.bundle")
- end
-
- def check!
- require "bundler/cli/check"
- Bundler::CLI::Check.new({}).run
- end
-
- def run
- Bundler.ui.level = "error" if options[:quiet]
- Bundler.settings.validate!
- check!
-
- definition = Bundler.definition
- broken_links = {}
-
- definition.specs.each do |spec|
- bundles_for_gem(spec).each do |bundle|
- bad_paths = dylibs(bundle).select {|f| !File.exist?(f) }
- if bad_paths.any?
- broken_links[spec] ||= []
- broken_links[spec].concat(bad_paths)
- end
- end
- end
-
- if broken_links.any?
- message = "The following gems are missing OS dependencies:"
- broken_links.map do |spec, paths|
- paths.uniq.map do |path|
- "\n * #{spec.name}: #{path}"
- end
- end.flatten.sort.each {|m| message += m }
- raise ProductionError, message
- else
- Bundler.ui.info "No issues found with the installed bundle"
- end
- end
- end
-end
diff --git a/lib/bundler/cli/exec.rb b/lib/bundler/cli/exec.rb
deleted file mode 100644
index 2fdc614fbb..0000000000
--- a/lib/bundler/cli/exec.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/current_ruby"
-
-module Bundler
- class CLI::Exec
- attr_reader :options, :args, :cmd
-
- RESERVED_SIGNALS = %w[SEGV BUS ILL FPE VTALRM KILL STOP].freeze
-
- def initialize(options, args)
- @options = options
- @cmd = args.shift
- @args = args
-
- if Bundler.current_ruby.ruby_2? && !Bundler.current_ruby.jruby?
- @args << { :close_others => !options.keep_file_descriptors? }
- elsif options.keep_file_descriptors?
- Bundler.ui.warn "Ruby version #{RUBY_VERSION} defaults to keeping non-standard file descriptors on Kernel#exec."
- end
- end
-
- def run
- validate_cmd!
- SharedHelpers.set_bundle_environment
- if bin_path = Bundler.which(cmd)
- if !Bundler.settings[:disable_exec_load] && ruby_shebang?(bin_path)
- return kernel_load(bin_path, *args)
- end
- # First, try to exec directly to something in PATH
- if Bundler.current_ruby.jruby_18?
- kernel_exec(bin_path, *args)
- else
- kernel_exec([bin_path, cmd], *args)
- end
- else
- # exec using the given command
- kernel_exec(cmd, *args)
- end
- end
-
- private
-
- def validate_cmd!
- return unless cmd.nil?
- Bundler.ui.error "bundler: exec needs a command to run"
- exit 128
- end
-
- def kernel_exec(*args)
- ui = Bundler.ui
- Bundler.ui = nil
- Kernel.exec(*args)
- rescue Errno::EACCES, Errno::ENOEXEC
- Bundler.ui = ui
- Bundler.ui.error "bundler: not executable: #{cmd}"
- exit 126
- rescue Errno::ENOENT
- Bundler.ui = ui
- Bundler.ui.error "bundler: command not found: #{cmd}"
- Bundler.ui.warn "Install missing gem executables with `bundle install`"
- exit 127
- end
-
- def kernel_load(file, *args)
- args.pop if args.last.is_a?(Hash)
- ARGV.replace(args)
- $0 = file
- Process.setproctitle(process_title(file, args)) if Process.respond_to?(:setproctitle)
- ui = Bundler.ui
- Bundler.ui = nil
- require "bundler/setup"
- signals = Signal.list.keys - RESERVED_SIGNALS
- signals.each {|s| trap(s, "DEFAULT") }
- Kernel.load(file)
- rescue SystemExit, SignalException
- raise
- rescue Exception => e # rubocop:disable Lint/RescueException
- Bundler.ui = ui
- Bundler.ui.error "bundler: failed to load command: #{cmd} (#{file})"
- backtrace = e.backtrace.take_while {|bt| !bt.start_with?(__FILE__) }
- abort "#{e.class}: #{e.message}\n #{backtrace.join("\n ")}"
- end
-
- def process_title(file, args)
- "#{file} #{args.join(" ")}".strip
- end
-
- def ruby_shebang?(file)
- possibilities = [
- "#!/usr/bin/env ruby\n",
- "#!/usr/bin/env jruby\n",
- "#!#{Gem.ruby}\n",
- ]
-
- if File.zero?(file)
- Bundler.ui.warn "#{file} is empty"
- return false
- end
-
- first_line = File.open(file, "rb") {|f| f.read(possibilities.map(&:size).max) }
- possibilities.any? {|shebang| first_line.start_with?(shebang) }
- end
- end
-end
diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb
deleted file mode 100644
index 885578e819..0000000000
--- a/lib/bundler/cli/gem.rb
+++ /dev/null
@@ -1,249 +0,0 @@
-# frozen_string_literal: true
-
-require "pathname"
-
-module Bundler
- class CLI
- Bundler.require_thor_actions
- include Thor::Actions
- end
-
- class CLI::Gem
- TEST_FRAMEWORK_VERSIONS = {
- "rspec" => "3.0",
- "minitest" => "5.0"
- }.freeze
-
- attr_reader :options, :gem_name, :thor, :name, :target
-
- def initialize(options, gem_name, thor)
- @options = options
- @gem_name = resolve_name(gem_name)
-
- @thor = thor
- thor.behavior = :invoke
- thor.destination_root = nil
-
- @name = @gem_name
- @target = SharedHelpers.pwd.join(gem_name)
-
- validate_ext_name if options[:ext]
- end
-
- def run
- Bundler.ui.confirm "Creating gem '#{name}'..."
-
- underscored_name = name.tr("-", "_")
- namespaced_path = name.tr("-", "/")
- constant_name = name.gsub(/-[_-]*(?![_-]|$)/) { "::" }.gsub(/([_-]+|(::)|^)(.|$)/) { $2.to_s + $3.upcase }
- constant_array = constant_name.split("::")
-
- git_installed = Bundler.git_present?
-
- git_author_name = git_installed ? `git config user.name`.chomp : ""
- github_username = git_installed ? `git config github.user`.chomp : ""
- git_user_email = git_installed ? `git config user.email`.chomp : ""
-
- config = {
- :name => name,
- :underscored_name => underscored_name,
- :namespaced_path => namespaced_path,
- :makefile_path => "#{underscored_name}/#{underscored_name}",
- :constant_name => constant_name,
- :constant_array => constant_array,
- :author => git_author_name.empty? ? "TODO: Write your name" : git_author_name,
- :email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
- :test => options[:test],
- :ext => options[:ext],
- :exe => options[:exe],
- :bundler_version => bundler_dependency_version,
- :github_username => github_username.empty? ? "[USERNAME]" : github_username
- }
- ensure_safe_gem_name(name, constant_array)
-
- templates = {
- "Gemfile.tt" => "Gemfile",
- "lib/newgem.rb.tt" => "lib/#{namespaced_path}.rb",
- "lib/newgem/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
- "newgem.gemspec.tt" => "#{name}.gemspec",
- "Rakefile.tt" => "Rakefile",
- "README.md.tt" => "README.md",
- "bin/console.tt" => "bin/console",
- "bin/setup.tt" => "bin/setup"
- }
-
- executables = %w[
- bin/console
- bin/setup
- ]
-
- templates.merge!("gitignore.tt" => ".gitignore") if Bundler.git_present?
-
- if test_framework = ask_and_set_test_framework
- config[:test] = test_framework
- config[:test_framework_version] = TEST_FRAMEWORK_VERSIONS[test_framework]
-
- templates.merge!("travis.yml.tt" => ".travis.yml")
-
- case test_framework
- when "rspec"
- templates.merge!(
- "rspec.tt" => ".rspec",
- "spec/spec_helper.rb.tt" => "spec/spec_helper.rb",
- "spec/newgem_spec.rb.tt" => "spec/#{namespaced_path}_spec.rb"
- )
- when "minitest"
- templates.merge!(
- "test/test_helper.rb.tt" => "test/test_helper.rb",
- "test/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
- )
- end
- end
-
- config[:test_task] = config[:test] == "minitest" ? "test" : "spec"
-
- if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?",
- "This means that any other developer or company will be legally allowed to use your code " \
- "for free as long as they admit you created it. You can read more about the MIT license " \
- "at http://choosealicense.com/licenses/mit.")
- config[:mit] = true
- Bundler.ui.info "MIT License enabled in config"
- templates.merge!("LICENSE.txt.tt" => "LICENSE.txt")
- end
-
- if ask_and_set(:coc, "Do you want to include a code of conduct in gems you generate?",
- "Codes of conduct can increase contributions to your project by contributors who " \
- "prefer collaborative, safe spaces. You can read more about the code of conduct at " \
- "contributor-covenant.org. Having a code of conduct means agreeing to the responsibility " \
- "of enforcing it, so be sure that you are prepared to do that. Be sure that your email " \
- "address is specified as a contact in the generated code of conduct so that people know " \
- "who to contact in case of a violation. For suggestions about " \
- "how to enforce codes of conduct, see http://bit.ly/coc-enforcement.")
- config[:coc] = true
- Bundler.ui.info "Code of conduct enabled in config"
- templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md")
- end
-
- templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
-
- if options[:ext]
- templates.merge!(
- "ext/newgem/extconf.rb.tt" => "ext/#{name}/extconf.rb",
- "ext/newgem/newgem.h.tt" => "ext/#{name}/#{underscored_name}.h",
- "ext/newgem/newgem.c.tt" => "ext/#{name}/#{underscored_name}.c"
- )
- end
-
- templates.each do |src, dst|
- destination = target.join(dst)
- SharedHelpers.filesystem_access(destination) do
- thor.template("newgem/#{src}", destination, config)
- end
- end
-
- executables.each do |file|
- SharedHelpers.filesystem_access(target.join(file)) do |path|
- executable = (path.stat.mode | 0o111)
- path.chmod(executable)
- end
- end
-
- if Bundler.git_present?
- Bundler.ui.info "Initializing git repo in #{target}"
- Dir.chdir(target) do
- `git init`
- `git add .`
- end
- end
-
- # Open gemspec in editor
- open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit]
- rescue Errno::EEXIST => e
- raise GenericSystemCallError.new(e, "There was a conflict while creating the new gem.")
- end
-
- private
-
- def resolve_name(name)
- SharedHelpers.pwd.join(name).basename.to_s
- end
-
- def ask_and_set(key, header, message)
- choice = options[key]
- choice = Bundler.settings["gem.#{key}"] if choice.nil?
-
- if choice.nil?
- Bundler.ui.confirm header
- choice = Bundler.ui.yes? "#{message} y/(n):"
- Bundler.settings.set_global("gem.#{key}", choice)
- end
-
- choice
- end
-
- def validate_ext_name
- return unless gem_name.index("-")
-
- Bundler.ui.error "You have specified a gem name which does not conform to the \n" \
- "naming guidelines for C extensions. For more information, \n" \
- "see the 'Extension Naming' section at the following URL:\n" \
- "http://guides.rubygems.org/gems-with-extensions/\n"
- exit 1
- end
-
- def ask_and_set_test_framework
- test_framework = options[:test] || Bundler.settings["gem.test"]
-
- if test_framework.nil?
- Bundler.ui.confirm "Do you want to generate tests with your gem?"
- result = Bundler.ui.ask "Type 'rspec' or 'minitest' to generate those test files now and " \
- "in the future. rspec/minitest/(none):"
- if result =~ /rspec|minitest/
- test_framework = result
- else
- test_framework = false
- end
- end
-
- if Bundler.settings["gem.test"].nil?
- Bundler.settings.set_global("gem.test", test_framework)
- end
-
- test_framework
- end
-
- def bundler_dependency_version
- v = Gem::Version.new(Bundler::VERSION)
- req = v.segments[0..1]
- req << "a" if v.prerelease?
- req.join(".")
- end
-
- def ensure_safe_gem_name(name, constant_array)
- if name =~ /^\d/
- Bundler.ui.error "Invalid gem name #{name} Please give a name which does not start with numbers."
- exit 1
- end
-
- constant_name = constant_array.join("::")
-
- existing_constant = constant_array.inject(Object) do |c, s|
- defined = begin
- c.const_defined?(s)
- rescue NameError
- Bundler.ui.error "Invalid gem name #{name} -- `#{constant_name}` is an invalid constant name"
- exit 1
- end
- (defined && c.const_get(s)) || break
- end
-
- return unless existing_constant
- Bundler.ui.error "Invalid gem name #{name} constant #{constant_name} is already in use. Please choose another gem name."
- exit 1
- end
-
- def open_editor(editor, file)
- thor.run(%(#{editor} "#{file}"))
- end
- end
-end
diff --git a/lib/bundler/cli/info.rb b/lib/bundler/cli/info.rb
deleted file mode 100644
index 958b525067..0000000000
--- a/lib/bundler/cli/info.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Info
- attr_reader :gem_name, :options
- def initialize(options, gem_name)
- @options = options
- @gem_name = gem_name
- end
-
- def run
- 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)
- end
-
- private
-
- def spec_for_gem(gem_name)
- spec = Bundler.definition.specs.find {|s| s.name == gem_name }
- spec || default_gem_spec(gem_name)
- end
-
- def default_gem_spec(gem_name)
- return unless Gem::Specification.respond_to?(:find_all_by_name)
- gem_spec = Gem::Specification.find_all_by_name(gem_name).last
- return gem_spec if gem_spec && gem_spec.respond_to?(:default_gem?) && gem_spec.default_gem?
- end
-
- def spec_not_found(gem_name)
- raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(gem_name, Bundler.definition.dependencies)
- end
-
- def print_gem_path(spec)
- Bundler.ui.info spec.full_gem_path
- end
-
- def print_gem_info(spec)
- gem_info = String.new
- gem_info << " * #{spec.name} (#{spec.version}#{spec.git_version})\n"
- gem_info << "\tSummary: #{spec.summary}\n" if spec.summary
- gem_info << "\tHomepage: #{spec.homepage}\n" if spec.homepage
- gem_info << "\tPath: #{spec.full_gem_path}\n"
- gem_info << "\tDefault Gem: yes" if spec.respond_to?(:default_gem?) && spec.default_gem?
- Bundler.ui.info gem_info
- end
- end
-end
diff --git a/lib/bundler/cli/init.rb b/lib/bundler/cli/init.rb
deleted file mode 100644
index fa53e7c74b..0000000000
--- a/lib/bundler/cli/init.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Init
- attr_reader :options
- def initialize(options)
- @options = options
- end
-
- def run
- if File.exist?(gemfile)
- Bundler.ui.error "#{gemfile} already exists at #{File.expand_path(gemfile)}"
- exit 1
- end
-
- if options[:gemspec]
- gemspec = File.expand_path(options[:gemspec])
- unless File.exist?(gemspec)
- Bundler.ui.error "Gem specification #{gemspec} doesn't exist"
- exit 1
- end
-
- spec = Bundler.load_gemspec_uncached(gemspec)
-
- File.open(gemfile, "wb") do |file|
- file << "# Generated from #{gemspec}\n"
- file << spec.to_gemfile
- end
- else
- FileUtils.cp(File.expand_path("../../templates/#{gemfile}", __FILE__), gemfile)
- end
-
- puts "Writing new #{gemfile} to #{SharedHelpers.pwd}/#{gemfile}"
- end
-
- private
-
- def gemfile
- @gemfile ||= Bundler.feature_flag.init_gems_rb? ? "gems.rb" : "Gemfile"
- end
- end
-end
diff --git a/lib/bundler/cli/inject.rb b/lib/bundler/cli/inject.rb
deleted file mode 100644
index b00675d348..0000000000
--- a/lib/bundler/cli/inject.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Inject
- attr_reader :options, :name, :version, :group, :source, :gems
- def initialize(options, name, version)
- @options = options
- @name = name
- @version = version || last_version_number
- @group = options[:group].split(",") unless options[:group].nil?
- @source = options[:source]
- @gems = []
- end
-
- def run
- # The required arguments allow Thor to give useful feedback when the arguments
- # are incorrect. This adds those first two arguments onto the list as a whole.
- gems.unshift(source).unshift(group).unshift(version).unshift(name)
-
- # Build an array of Dependency objects out of the arguments
- deps = []
- # when `inject` support addition of more than one gem, then this loop will
- # help. Currently this loop is running once.
- gems.each_slice(4) do |gem_name, gem_version, gem_group, gem_source|
- ops = Gem::Requirement::OPS.map {|key, _val| key }
- has_op = ops.any? {|op| gem_version.start_with? op }
- gem_version = "~> #{gem_version}" unless has_op
- deps << Bundler::Dependency.new(gem_name, gem_version, "group" => gem_group, "source" => gem_source)
- end
-
- added = Injector.inject(deps, options)
-
- if added.any?
- Bundler.ui.confirm "Added to Gemfile:"
- Bundler.ui.confirm(added.map do |d|
- name = "'#{d.name}'"
- requirement = ", '#{d.requirement}'"
- group = ", :group => #{d.groups.inspect}" if d.groups != Array(:default)
- source = ", :source => '#{d.source}'" unless d.source.nil?
- %(gem #{name}#{requirement}#{group}#{source})
- end.join("\n"))
- else
- Bundler.ui.confirm "All gems were already present in the Gemfile"
- end
- end
-
- private
-
- def last_version_number
- definition = Bundler.definition(true)
- definition.resolve_remotely!
- specs = definition.index[name].sort_by(&:version)
- unless options[:pre]
- specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
- end
- spec = specs.last
- spec.version.to_s
- end
- end
-end
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
deleted file mode 100644
index f0b821ed84..0000000000
--- a/lib/bundler/cli/install.rb
+++ /dev/null
@@ -1,214 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Install
- attr_reader :options
- def initialize(options)
- @options = options
- end
-
- def run
- Bundler.ui.level = "error" if options[:quiet]
-
- warn_if_root
-
- normalize_groups
-
- Bundler::SharedHelpers.set_env "RB_USER_INSTALL", "1" if Bundler::FREEBSD
-
- # Disable color in deployment mode
- Bundler.ui.shell = Thor::Shell::Basic.new if options[:deployment]
-
- check_for_options_conflicts
-
- check_trust_policy
-
- if options[:deployment] || options[:frozen] || Bundler.frozen?
- unless Bundler.default_lockfile.exist?
- flag = "--deployment flag" if options[:deployment]
- flag ||= "--frozen flag" if options[:frozen]
- flag ||= "deployment setting"
- raise ProductionError, "The #{flag} requires a #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}. Please make " \
- "sure you have checked your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} into version control " \
- "before deploying."
- end
-
- options[:local] = true if Bundler.app_cache.exist?
-
- if Bundler.feature_flag.deployment_means_frozen?
- Bundler.settings.set_command_option :deployment, true
- else
- Bundler.settings.set_command_option :frozen, true
- end
- end
-
- # When install is called with --no-deployment, disable deployment mode
- if options[:deployment] == false
- Bundler.settings.set_command_option :frozen, nil
- options[:system] = true
- end
-
- normalize_settings
-
- Bundler::Fetcher.disable_endpoint = options["full-index"]
-
- if options["binstubs"]
- Bundler::SharedHelpers.major_deprecation 2,
- "The --binstubs option will be removed in favor of `bundle binstubs`"
- end
-
- Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins?
-
- definition = Bundler.definition
- definition.validate_runtime!
-
- installer = Installer.install(Bundler.root, definition, options)
- Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen?
-
- Bundler.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}."
- Bundler::CLI::Common.output_without_groups_message
-
- if Bundler.use_system_gems?
- Bundler.ui.confirm "Use `bundle info [gemname]` to see where a bundled gem is installed."
- else
- absolute_path = File.expand_path(Bundler.configured_bundle_path.base_path)
- relative_path = absolute_path.sub(File.expand_path(".") + File::SEPARATOR, "." + File::SEPARATOR)
- Bundler.ui.confirm "Bundled gems are installed into `#{relative_path}`"
- end
-
- Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
-
- warn_ambiguous_gems
-
- if CLI::Common.clean_after_install?
- require "bundler/cli/clean"
- Bundler::CLI::Clean.new(options).run
- end
- rescue GemNotFound, VersionConflict => e
- if options[:local] && Bundler.app_cache.exist?
- Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
- end
-
- unless Bundler.definition.has_rubygems_remotes?
- Bundler.ui.warn <<-WARN, :wrap => true
- Your Gemfile has no gem server sources. If you need gems that are \
- not already on your machine, add a line like this to your Gemfile:
- source 'https://rubygems.org'
- WARN
- end
- raise e
- rescue Gem::InvalidSpecificationException => e
- Bundler.ui.warn "You have one or more invalid gemspecs that need to be fixed."
- raise e
- end
-
- private
-
- def warn_if_root
- return if Bundler.settings[:silence_root_warning] || Bundler::WINDOWS || !Process.uid.zero?
- Bundler.ui.warn "Don't run Bundler as root. Bundler can ask for sudo " \
- "if it is needed, and installing your bundle as root will break this " \
- "application for all non-root users on this machine.", :wrap => true
- end
-
- def dependencies_count_for(definition)
- count = definition.dependencies.count
- "#{count} Gemfile #{count == 1 ? "dependency" : "dependencies"}"
- end
-
- def gems_installed_for(definition)
- count = definition.specs.count
- "#{count} #{count == 1 ? "gem" : "gems"} now installed"
- end
-
- def check_for_group_conflicts_in_cli_options
- conflicting_groups = Array(options[:without]) & Array(options[:with])
- return if conflicting_groups.empty?
- raise InvalidOption, "You can't list a group in both with and without." \
- " The offending groups are: #{conflicting_groups.join(", ")}."
- end
-
- def check_for_options_conflicts
- if (options[:path] || options[:deployment]) && options[:system]
- error_message = String.new
- error_message << "You have specified both --path as well as --system. Please choose only one option.\n" if options[:path]
- error_message << "You have specified both --deployment as well as --system. Please choose only one option.\n" if options[:deployment]
- raise InvalidOption.new(error_message)
- end
- end
-
- def check_trust_policy
- trust_policy = options["trust-policy"]
- unless Bundler.rubygems.security_policies.keys.unshift(nil).include?(trust_policy)
- raise InvalidOption, "RubyGems doesn't know about trust policy '#{trust_policy}'. " \
- "The known policies are: #{Bundler.rubygems.security_policies.keys.join(", ")}."
- end
- Bundler.settings.set_command_option_if_given :"trust-policy", trust_policy
- end
-
- def normalize_groups
- options[:with] &&= options[:with].join(":").tr(" ", ":").split(":")
- options[:without] &&= options[:without].join(":").tr(" ", ":").split(":")
-
- check_for_group_conflicts_in_cli_options
-
- Bundler.settings.set_command_option :with, nil if options[:with] == []
- Bundler.settings.set_command_option :without, nil if options[:without] == []
-
- with = options.fetch(:with, [])
- with |= Bundler.settings[:with].map(&:to_s)
- with -= options[:without] if options[:without]
-
- without = options.fetch(:without, [])
- without |= Bundler.settings[:without].map(&:to_s)
- without -= options[:with] if options[:with]
-
- options[:with] = with
- options[:without] = without
- end
-
- def normalize_settings
- Bundler.settings.set_command_option :path, nil if options[:system]
- Bundler.settings.set_command_option :path, "vendor/bundle" if options[:deployment]
- Bundler.settings.set_command_option_if_given :path, options["path"]
- Bundler.settings.set_command_option :path, "bundle" if options["standalone"] && Bundler.settings[:path].nil?
-
- bin_option = options["binstubs"]
- bin_option = nil if bin_option && bin_option.empty?
- Bundler.settings.set_command_option :bin, bin_option if options["binstubs"]
-
- Bundler.settings.set_command_option_if_given :shebang, options["shebang"]
-
- Bundler.settings.set_command_option_if_given :jobs, options["jobs"]
-
- Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"]
-
- Bundler.settings.set_command_option_if_given :no_install, options["no-install"]
-
- Bundler.settings.set_command_option_if_given :clean, options["clean"]
-
- unless Bundler.settings[:without] == options[:without] && Bundler.settings[:with] == options[:with]
- # need to nil them out first to get around validation for backwards compatibility
- Bundler.settings.set_command_option :without, nil
- Bundler.settings.set_command_option :with, nil
- Bundler.settings.set_command_option :without, options[:without] - options[:with]
- Bundler.settings.set_command_option :with, options[:with]
- end
-
- options[:force] = options[:redownload]
- end
-
- def warn_ambiguous_gems
- 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."
- end
- end
- end
-end
diff --git a/lib/bundler/cli/issue.rb b/lib/bundler/cli/issue.rb
deleted file mode 100644
index 91f827ea99..0000000000
--- a/lib/bundler/cli/issue.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-require "rbconfig"
-
-module Bundler
- class CLI::Issue
- def run
- Bundler.ui.info <<-EOS.gsub(/^ {8}/, "")
- Did you find an issue with Bundler? Before filing a new issue,
- be sure to check out these resources:
-
- 1. Check out our troubleshooting guide for quick fixes to common issues:
- 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/
-
- 3. Information about each Bundler command can be found in the Bundler
- man pages: http://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
- that we can diagnose and help fix the problem you're having. Please
- view the Filing Issues guide for more information:
- https://github.com/bundler/bundler/blob/master/doc/contributing/ISSUES.md
-
- EOS
-
- Bundler.ui.info Bundler::Env.report
-
- Bundler.ui.info "\n## Bundle Doctor"
- doctor
- end
-
- def doctor
- require "bundler/cli/doctor"
- Bundler::CLI::Doctor.new({}).run
- end
- end
-end
diff --git a/lib/bundler/cli/list.rb b/lib/bundler/cli/list.rb
deleted file mode 100644
index b5e7c1e650..0000000000
--- a/lib/bundler/cli/list.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::List
- def initialize(options)
- @options = options
- end
-
- def run
- specs = Bundler.load.specs.reject {|s| s.name == "bundler" }.sort_by(&:name)
- return specs.each {|s| Bundler.ui.info s.name } if @options["name-only"]
-
- return Bundler.ui.info "No gems in the Gemfile" if specs.empty?
- Bundler.ui.info "Gems included by the bundle:"
- specs.each do |s|
- Bundler.ui.info " * #{s.name} (#{s.version}#{s.git_version})"
- end
-
- Bundler.ui.info "Use `bundle info` to print more detailed information about a gem"
- end
- end
-end
diff --git a/lib/bundler/cli/lock.rb b/lib/bundler/cli/lock.rb
deleted file mode 100644
index 7dd078b1ef..0000000000
--- a/lib/bundler/cli/lock.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Lock
- attr_reader :options
-
- def initialize(options)
- @options = options
- end
-
- def run
- unless Bundler.default_gemfile
- Bundler.ui.error "Unable to find a Gemfile to lock"
- exit 1
- end
-
- print = options[:print]
- ui = Bundler.ui
- Bundler.ui = UI::Silent.new if print
-
- Bundler::Fetcher.disable_endpoint = options["full-index"]
-
- update = options[:update]
- if update.is_a?(Array) # unlocking specific gems
- Bundler::CLI::Common.ensure_all_gems_in_lockfile!(update)
- update = { :gems => update, :lock_shared_dependencies => options[:conservative] }
- end
- definition = Bundler.definition(update)
-
- Bundler::CLI::Common.configure_gem_version_promoter(Bundler.definition, options) if options[:update]
-
- options["remove-platform"].each do |platform|
- definition.remove_platform(platform)
- end
-
- options["add-platform"].each do |platform_string|
- platform = Gem::Platform.new(platform_string)
- if platform.to_s == "unknown"
- Bundler.ui.warn "The platform `#{platform_string}` is unknown to RubyGems " \
- "and adding it will likely lead to resolution errors"
- end
- definition.add_platform(platform)
- end
-
- if definition.platforms.empty?
- raise InvalidOption, "Removing all platforms from the bundle is not allowed"
- end
-
- definition.resolve_remotely! unless options[:local]
-
- if print
- puts definition.to_lock
- else
- file = options[:lockfile]
- file = file ? File.expand_path(file) : Bundler.default_lockfile
- puts "Writing lockfile to #{file}"
- definition.lock(file)
- end
-
- Bundler.ui = ui
- end
- end
-end
diff --git a/lib/bundler/cli/open.rb b/lib/bundler/cli/open.rb
deleted file mode 100644
index 552fe6f128..0000000000
--- a/lib/bundler/cli/open.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-require "shellwords"
-
-module Bundler
- class CLI::Open
- attr_reader :options, :name
- def initialize(options, name)
- @options = options
- @name = name
- end
-
- def run
- editor = [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? }
- return Bundler.ui.info("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR") unless editor
- return unless spec = Bundler::CLI::Common.select_spec(name, :regex_match)
- path = spec.full_gem_path
- Dir.chdir(path) do
- command = Shellwords.split(editor) + [path]
- Bundler.with_original_env do
- system(*command)
- end || Bundler.ui.info("Could not run '#{command.join(" ")}'")
- end
- end
- end
-end
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
deleted file mode 100644
index 5125cc710b..0000000000
--- a/lib/bundler/cli/outdated.rb
+++ /dev/null
@@ -1,260 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Outdated
- attr_reader :options, :gems
-
- def initialize(options, gems)
- @options = options
- @gems = gems
- end
-
- def run
- check_for_deployment_mode
-
- sources = Array(options[:source])
-
- gems.each do |gem_name|
- Bundler::CLI::Common.select_spec(gem_name)
- end
-
- Bundler.definition.validate_runtime!
- current_specs = Bundler.ui.silence { Bundler.definition.resolve }
- current_dependencies = {}
- Bundler.ui.silence do
- Bundler.load.dependencies.each do |dep|
- current_dependencies[dep.name] = dep
- end
- end
-
- definition = if gems.empty? && sources.empty?
- # We're doing a full update
- Bundler.definition(true)
- else
- Bundler.definition(:gems => gems, :sources => sources)
- end
-
- Bundler::CLI::Common.configure_gem_version_promoter(
- Bundler.definition,
- options
- )
-
- # the patch level options imply strict is also true. It wouldn't make
- # sense otherwise.
- strict = options[:strict] ||
- Bundler::CLI::Common.patch_level_options(options).any?
-
- filter_options_patch = options.keys &
- %w[filter-major filter-minor filter-patch]
-
- definition_resolution = proc do
- options[:local] ? definition.resolve_with_cache! : definition.resolve_remotely!
- end
-
- if options[:parseable]
- Bundler.ui.silence(&definition_resolution)
- else
- definition_resolution.call
- end
-
- Bundler.ui.info ""
- outdated_gems_by_groups = {}
- outdated_gems_list = []
-
- # Loop through the current specs
- gemfile_specs, dependency_specs = current_specs.partition do |spec|
- current_dependencies.key? spec.name
- end
-
- (gemfile_specs + dependency_specs).sort_by(&:name).each do |current_spec|
- next if !gems.empty? && !gems.include?(current_spec.name)
-
- dependency = current_dependencies[current_spec.name]
- active_spec = retrieve_active_spec(strict, definition, current_spec)
-
- next if active_spec.nil?
- if filter_options_patch.any?
- update_present = update_present_via_semver_portions(current_spec, active_spec, options)
- next unless update_present
- end
-
- gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
- next unless gem_outdated || (current_spec.git_version != active_spec.git_version)
- groups = nil
- if dependency && !options[:parseable]
- groups = dependency.groups.join(", ")
- end
-
- outdated_gems_list << { :active_spec => active_spec,
- :current_spec => current_spec,
- :dependency => dependency,
- :groups => groups }
-
- outdated_gems_by_groups[groups] ||= []
- outdated_gems_by_groups[groups] << { :active_spec => active_spec,
- :current_spec => current_spec,
- :dependency => dependency,
- :groups => groups }
- end
-
- if outdated_gems_list.empty?
- display_nothing_outdated_message(filter_options_patch)
- else
- unless options[:parseable]
- if options[:pre]
- Bundler.ui.info "Outdated gems included in the bundle (including " \
- "pre-releases):"
- else
- Bundler.ui.info "Outdated gems included in the bundle:"
- end
- end
-
- options_include_groups = [:group, :groups].select do |v|
- options.keys.include?(v.to_s)
- end
-
- if options_include_groups.any?
- ordered_groups = outdated_gems_by_groups.keys.compact.sort
- [nil, ordered_groups].flatten.each do |groups|
- gems = outdated_gems_by_groups[groups]
- contains_group = if groups
- groups.split(",").include?(options[:group])
- else
- options[:group] == "group"
- end
-
- next if (!options[:groups] && !contains_group) || gems.nil?
-
- unless options[:parseable]
- if groups
- Bundler.ui.info "===== Group #{groups} ====="
- else
- Bundler.ui.info "===== Without group ====="
- end
- end
-
- gems.each do |gem|
- print_gem(
- gem[:current_spec],
- gem[:active_spec],
- gem[:dependency],
- groups,
- options_include_groups.any?
- )
- end
- end
- else
- outdated_gems_list.each do |gem|
- print_gem(
- gem[:current_spec],
- gem[:active_spec],
- gem[:dependency],
- gem[:groups],
- options_include_groups.any?
- )
- end
- end
-
- exit 1
- end
- end
-
- private
-
- def retrieve_active_spec(strict, definition, current_spec)
- if strict
- active_spec = definition.find_resolved_spec(current_spec)
- else
- active_specs = definition.find_indexed_specs(current_spec)
- if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
- active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
- end
- active_spec = active_specs.last
- end
-
- active_spec
- end
-
- def display_nothing_outdated_message(filter_options_patch)
- unless options[:parseable]
- if filter_options_patch.any?
- display = filter_options_patch.map do |o|
- o.sub("filter-", "")
- end.join(" or ")
-
- Bundler.ui.info "No #{display} updates to display.\n"
- else
- Bundler.ui.info "Bundle up to date!\n"
- end
- end
- end
-
- def print_gem(current_spec, active_spec, dependency, groups, options_include_groups)
- spec_version = "#{active_spec.version}#{active_spec.git_version}"
- spec_version += " (from #{active_spec.loaded_from})" if Bundler.ui.debug? && active_spec.loaded_from
- current_version = "#{current_spec.version}#{current_spec.git_version}"
-
- if dependency && dependency.specific?
- dependency_version = %(, requested #{dependency.requirement})
- end
-
- spec_outdated_info = "#{active_spec.name} (newest #{spec_version}, " \
- "installed #{current_version}#{dependency_version})"
-
- output_message = if options[:parseable]
- spec_outdated_info.to_s
- elsif options_include_groups || !groups
- " * #{spec_outdated_info}"
- else
- " * #{spec_outdated_info} in groups \"#{groups}\""
- end
-
- Bundler.ui.info output_message.rstrip
- end
-
- def check_for_deployment_mode
- return unless Bundler.frozen?
- suggested_command = if Bundler.settings.locations("frozen")[:global]
- "bundle config --delete frozen"
- elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
- "bundle config --delete deployment"
- else
- "bundle install --no-deployment"
- end
- raise ProductionError, "You are trying to check outdated gems in " \
- "deployment mode. Run `bundle outdated` elsewhere.\n" \
- "\nIf this is a development machine, remove the " \
- "#{Bundler.default_gemfile} freeze" \
- "\nby running `#{suggested_command}`."
- end
-
- def update_present_via_semver_portions(current_spec, active_spec, options)
- current_major = current_spec.version.segments.first
- active_major = active_spec.version.segments.first
-
- update_present = false
- update_present = active_major > current_major if options["filter-major"]
-
- if !update_present && (options["filter-minor"] || options["filter-patch"]) && current_major == active_major
- current_minor = get_version_semver_portion_value(current_spec, 1)
- active_minor = get_version_semver_portion_value(active_spec, 1)
-
- update_present = active_minor > current_minor if options["filter-minor"]
-
- if !update_present && options["filter-patch"] && current_minor == active_minor
- current_patch = get_version_semver_portion_value(current_spec, 2)
- active_patch = get_version_semver_portion_value(active_spec, 2)
-
- update_present = active_patch > current_patch
- end
- end
-
- update_present
- end
-
- def get_version_semver_portion_value(spec, version_portion_index)
- version_section = spec.version.segments[version_portion_index, 1]
- version_section.nil? ? 0 : (version_section.first || 0)
- end
- end
-end
diff --git a/lib/bundler/cli/package.rb b/lib/bundler/cli/package.rb
deleted file mode 100644
index 2dcd0e1e29..0000000000
--- a/lib/bundler/cli/package.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Package
- attr_reader :options
-
- def initialize(options)
- @options = options
- end
-
- def run
- Bundler.ui.level = "error" if options[:quiet]
- Bundler.settings.set_command_option_if_given :path, options[:path]
- Bundler.settings.set_command_option_if_given :cache_all_platforms, options["all-platforms"]
- Bundler.settings.set_command_option_if_given :cache_path, options["cache-path"]
-
- setup_cache_all
- install
-
- # TODO: move cache contents here now that all bundles are locked
- custom_path = Bundler.settings[:path] if options[:path]
- Bundler.load.cache(custom_path)
- end
-
- private
-
- def install
- require "bundler/cli/install"
- options = self.options.dup
- if Bundler.settings[:cache_all_platforms]
- options["local"] = false
- options["update"] = true
- end
- Bundler::CLI::Install.new(options).run
- end
-
- def setup_cache_all
- all = options.fetch(:all, Bundler.feature_flag.cache_command_is_package? || nil)
-
- Bundler.settings.set_command_option_if_given :cache_all, all
-
- 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."
- end
- end
- end
-end
diff --git a/lib/bundler/cli/platform.rb b/lib/bundler/cli/platform.rb
deleted file mode 100644
index e97cad49a4..0000000000
--- a/lib/bundler/cli/platform.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Platform
- attr_reader :options
- def initialize(options)
- @options = options
- end
-
- def run
- platforms, ruby_version = Bundler.ui.silence do
- locked_ruby_version = Bundler.locked_gems && Bundler.locked_gems.ruby_version
- gemfile_ruby_version = Bundler.definition.ruby_version && Bundler.definition.ruby_version.single_version_string
- [Bundler.definition.platforms.map {|p| "* #{p}" },
- locked_ruby_version || gemfile_ruby_version]
- end
- output = []
-
- if options[:ruby]
- if ruby_version
- output << ruby_version
- else
- output << "No ruby version specified"
- end
- else
- output << "Your platform is: #{RUBY_PLATFORM}"
- output << "Your app has gems that work on these platforms:\n#{platforms.join("\n")}"
-
- if ruby_version
- output << "Your Gemfile specifies a Ruby version requirement:\n* #{ruby_version}"
-
- begin
- Bundler.definition.validate_runtime!
- output << "Your current platform satisfies the Ruby version requirement."
- rescue RubyVersionMismatch => e
- output << e.message
- end
- else
- output << "Your Gemfile does not specify a Ruby version requirement."
- end
- end
-
- Bundler.ui.info output.join("\n\n")
- end
- end
-end
diff --git a/lib/bundler/cli/plugin.rb b/lib/bundler/cli/plugin.rb
deleted file mode 100644
index 5488a9f28d..0000000000
--- a/lib/bundler/cli/plugin.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/vendored_thor"
-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
- D
- method_option "source", :type => :string, :default => nil, :banner =>
- "URL of the RubyGems source to fetch the plugin from"
- method_option "version", :type => :string, :default => nil, :banner =>
- "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 "branch", :type => :string, :default => nil, :banner =>
- "The git branch to checkout"
- method_option "ref", :type => :string, :default => nil, :banner =>
- "The git revision to check out"
- def install(*plugins)
- Bundler::Plugin.install(plugins, options)
- end
- end
-end
diff --git a/lib/bundler/cli/pristine.rb b/lib/bundler/cli/pristine.rb
deleted file mode 100644
index 9b9cdaa9b3..0000000000
--- a/lib/bundler/cli/pristine.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Pristine
- def initialize(gems)
- @gems = gems
- end
-
- def run
- CLI::Common.ensure_all_gems_in_lockfile!(@gems)
- definition = Bundler.definition
- definition.validate_runtime!
- installer = Bundler::Installer.new(Bundler.root, definition)
-
- Bundler.load.specs.each do |spec|
- next if spec.name == "bundler" # Source::Rubygems doesn't install bundler
- next if !@gems.empty? && !@gems.include?(spec.name)
-
- gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})"
- gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY
-
- case source = spec.source
- when Source::Rubygems
- cached_gem = spec.cache_file
- unless File.exist?(cached_gem)
- Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.")
- next
- end
-
- FileUtils.rm_rf spec.full_gem_path
- when Source::Git
- source.remote!
- FileUtils.rm_rf spec.full_gem_path
- else
- Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
- next
- end
-
- Bundler::GemInstaller.new(spec, installer, false, 0, true).install_from_spec
- end
- end
- end
-end
diff --git a/lib/bundler/cli/show.rb b/lib/bundler/cli/show.rb
deleted file mode 100644
index 61756801b2..0000000000
--- a/lib/bundler/cli/show.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Show
- attr_reader :options, :gem_name, :latest_specs
- def initialize(options, gem_name)
- @options = options
- @gem_name = gem_name
- @verbose = options[:verbose] || options[:outdated]
- @latest_specs = fetch_latest_specs if @verbose
- end
-
- def run
- Bundler.ui.silence do
- Bundler.definition.validate_runtime!
- Bundler.load.lock
- end
-
- if gem_name
- if gem_name == "bundler"
- path = File.expand_path("../../../..", __FILE__)
- else
- spec = Bundler::CLI::Common.select_spec(gem_name, :regex_match)
- 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:"
- end
- end
- return Bundler.ui.info(path)
- end
-
- if options[:paths]
- Bundler.load.specs.sort_by(&:name).map do |s|
- Bundler.ui.info s.full_gem_path
- end
- else
- Bundler.ui.info "Gems included by the bundle:"
- Bundler.load.specs.sort_by(&:name).each do |s|
- desc = " * #{s.name} (#{s.version}#{s.git_version})"
- if @verbose
- latest = latest_specs.find {|l| l.name == s.name }
- Bundler.ui.info <<-END.gsub(/^ +/, "")
- #{desc}
- \tSummary: #{s.summary || "No description available."}
- \tHomepage: #{s.homepage || "No website available."}
- \tStatus: #{outdated?(s, latest) ? "Outdated - #{s.version} < #{latest.version}" : "Up to date"}
- END
- else
- Bundler.ui.info desc
- end
- end
- end
- end
-
- private
-
- def fetch_latest_specs
- definition = Bundler.definition(true)
- if options[:outdated]
- Bundler.ui.info "Fetching remote specs for outdated check...\n\n"
- Bundler.ui.silence { definition.resolve_remotely! }
- else
- definition.resolve_with_cache!
- end
- Bundler.reset!
- definition.specs
- end
-
- def outdated?(current, latest)
- return false unless latest
- Gem::Version.new(current.version) < Gem::Version.new(latest.version)
- end
- end
-end
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
deleted file mode 100644
index 3890ea307a..0000000000
--- a/lib/bundler/cli/update.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Update
- attr_reader :options, :gems
- def initialize(options, gems)
- @options = options
- @gems = gems
- end
-
- def run
- Bundler.ui.level = "error" if options[:quiet]
-
- Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins?
-
- sources = Array(options[:source])
- groups = Array(options[:group]).map(&:to_sym)
-
- full_update = gems.empty? && sources.empty? && groups.empty? && !options[:ruby] && !options[:bundler]
-
- if full_update && !options[:all]
- if Bundler.feature_flag.update_requires_all_flag?
- raise InvalidOption, "To update everything, pass the `--all` flag."
- end
- 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
-
- if full_update
- # We're doing a full update
- Bundler.definition(true)
- else
- unless Bundler.default_lockfile.exist?
- raise GemfileLockNotFound, "This Bundle hasn't been installed yet. " \
- "Run `bundle install` to update and install the bundled gems."
- end
- Bundler::CLI::Common.ensure_all_gems_in_lockfile!(gems)
-
- if groups.any?
- specs = Bundler.definition.specs_for groups
- gems.concat(specs.map(&:name))
- end
-
- Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby],
- :lock_shared_dependencies => options[:conservative],
- :bundler => options[:bundler])
- end
-
- Bundler::CLI::Common.configure_gem_version_promoter(Bundler.definition, options)
-
- Bundler::Fetcher.disable_endpoint = options["full-index"]
-
- opts = options.dup
- opts["update"] = true
- opts["local"] = options[:local]
-
- Bundler.settings.set_command_option_if_given :jobs, opts["jobs"]
-
- Bundler.definition.validate_runtime!
- installer = Installer.install Bundler.root, Bundler.definition, opts
- Bundler.load.cache if Bundler.app_cache.exist?
-
- if CLI::Common.clean_after_install?
- require "bundler/cli/clean"
- Bundler::CLI::Clean.new(options).run
- end
-
- if locked_gems = Bundler.definition.locked_gems
- gems.each do |name|
- locked_version = locked_gems.specs.find {|s| s.name == name }
- locked_version &&= locked_version.version
- next unless locked_version
- new_version = Bundler.definition.specs[name].first
- new_version &&= new_version.version
- if !new_version
- Bundler.ui.warn "Bundler attempted to update #{name} but it was removed from the bundle"
- elsif new_version < locked_version
- Bundler.ui.warn "Bundler attempted to update #{name} but its version regressed from #{locked_version} to #{new_version}"
- elsif new_version == locked_version
- Bundler.ui.warn "Bundler attempted to update #{name} but its version stayed the same"
- end
- end
- end
-
- Bundler.ui.confirm "Bundle updated!"
- Bundler::CLI::Common.output_without_groups_message
- Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
- end
- end
-end
diff --git a/lib/bundler/cli/viz.rb b/lib/bundler/cli/viz.rb
deleted file mode 100644
index 644f9b25cf..0000000000
--- a/lib/bundler/cli/viz.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Viz
- attr_reader :options, :gem_name
- def initialize(options)
- @options = options
- end
-
- def run
- # make sure we get the right `graphviz`. There is also a `graphviz`
- # gem we're not built to support
- gem "ruby-graphviz"
- require "graphviz"
-
- options[:without] = options[:without].join(":").tr(" ", ":").split(":")
- output_file = File.expand_path(options[:file])
-
- graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format], options[:without])
- graph.viz
- rescue LoadError => e
- Bundler.ui.error e.inspect
- Bundler.ui.warn "Make sure you have the graphviz ruby gem. You can install it with:"
- Bundler.ui.warn "`gem install ruby-graphviz`"
- rescue StandardError => e
- raise unless e.message =~ /GraphViz not installed or dot not in PATH/
- Bundler.ui.error e.message
- Bundler.ui.warn "Please install GraphViz. On a Mac with Homebrew, you can run `brew install graphviz`."
- end
- end
-end
diff --git a/lib/bundler/compact_index_client.rb b/lib/bundler/compact_index_client.rb
deleted file mode 100644
index 6c241ca07a..0000000000
--- a/lib/bundler/compact_index_client.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-# frozen_string_literal: true
-
-require "pathname"
-require "set"
-
-module Bundler
- class CompactIndexClient
- DEBUG_MUTEX = Mutex.new
- def self.debug
- return unless ENV["DEBUG_COMPACT_INDEX"]
- DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
- end
-
- class Error < StandardError; end
-
- require "bundler/compact_index_client/cache"
- require "bundler/compact_index_client/updater"
-
- 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)
- @cache = Cache.new(@directory)
- @endpoints = Set.new
- @info_checksums_by_name = {}
- @parsed_checksums = false
- @mutex = Mutex.new
- @in_parallel = lambda do |inputs, &blk|
- inputs.map(&blk)
- end
- end
-
- def names
- Bundler::CompactIndexClient.debug { "/names" }
- update(@cache.names_path, "names")
- @cache.names
- end
-
- def versions
- Bundler::CompactIndexClient.debug { "/versions" }
- update(@cache.versions_path, "versions")
- versions, @info_checksums_by_name = @cache.versions
- versions
- end
-
- def dependencies(names)
- Bundler::CompactIndexClient.debug { "dependencies(#{names})" }
- in_parallel.call(names) do |name|
- update_info(name)
- @cache.dependencies(name).map {|d| d.unshift(name) }
- end.flatten(1)
- end
-
- def spec(name, version, platform = nil)
- Bundler::CompactIndexClient.debug { "spec(name = #{name}, version = #{version}, platform = #{platform})" }
- update_info(name)
- @cache.specific_dependency(name, version, platform)
- end
-
- def update_and_parse_checksums!
- Bundler::CompactIndexClient.debug { "update_and_parse_checksums!" }
- return @info_checksums_by_name if @parsed_checksums
- update(@cache.versions_path, "versions")
- @info_checksums_by_name = @cache.checksums
- @parsed_checksums = true
- end
-
- private
-
- def update(local_path, remote_path)
- Bundler::CompactIndexClient.debug { "update(#{local_path}, #{remote_path})" }
- unless synchronize { @endpoints.add?(remote_path) }
- Bundler::CompactIndexClient.debug { "already fetched #{remote_path}" }
- return
- end
- @updater.update(local_path, url(remote_path))
- end
-
- def update_info(name)
- Bundler::CompactIndexClient.debug { "update_info(#{name})" }
- path = @cache.info_path(name)
- checksum = @updater.checksum_for_file(path)
- unless existing = @info_checksums_by_name[name]
- Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since it is missing from versions" }
- return
- end
- if checksum == existing
- Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since the versions checksum matches the local checksum" }
- return
- end
- Bundler::CompactIndexClient.debug { "updating info for #{name} since the versions checksum #{existing} != the local checksum #{checksum}" }
- update(path, "info/#{name}")
- end
-
- def url(path)
- path
- end
-
- def synchronize
- @mutex.synchronize { yield }
- end
- end
-end
diff --git a/lib/bundler/compact_index_client/cache.rb b/lib/bundler/compact_index_client/cache.rb
deleted file mode 100644
index f6105d3bb3..0000000000
--- a/lib/bundler/compact_index_client/cache.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CompactIndexClient
- class Cache
- attr_reader :directory
-
- def initialize(directory)
- @directory = Pathname.new(directory).expand_path
- info_roots.each do |dir|
- SharedHelpers.filesystem_access(dir) do
- FileUtils.mkdir_p(dir)
- end
- end
- end
-
- def names
- lines(names_path)
- end
-
- def names_path
- directory.join("names")
- end
-
- def versions
- versions_by_name = Hash.new {|hash, key| hash[key] = [] }
- info_checksums_by_name = {}
-
- lines(versions_path).each do |line|
- name, versions_string, info_checksum = line.split(" ", 3)
- info_checksums_by_name[name] = info_checksum || ""
- versions_string.split(",").each do |version|
- if version.start_with?("-")
- version = version[1..-1].split("-", 2).unshift(name)
- versions_by_name[name].delete(version)
- else
- version = version.split("-", 2).unshift(name)
- versions_by_name[name] << version
- end
- end
- end
-
- [versions_by_name, info_checksums_by_name]
- end
-
- def versions_path
- directory.join("versions")
- end
-
- def checksums
- checksums = {}
-
- lines(versions_path).each do |line|
- name, _, checksum = line.split(" ", 3)
- checksums[name] = checksum
- end
-
- checksums
- end
-
- def dependencies(name)
- lines(info_path(name)).map do |line|
- parse_gem(line)
- end
- end
-
- def info_path(name)
- name = name.to_s
- if name =~ /[^a-z0-9_-]/
- name += "-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}"
- info_roots.last.join(name)
- else
- info_roots.first.join(name)
- end
- end
-
- def specific_dependency(name, version, platform)
- pattern = [version, platform].compact.join("-")
- return nil if pattern.empty?
-
- gem_lines = info_path(name).read
- gem_line = gem_lines[/^#{Regexp.escape(pattern)}\b.*/, 0]
- gem_line ? parse_gem(gem_line) : nil
- end
-
- private
-
- def lines(path)
- return [] unless path.file?
- lines = SharedHelpers.filesystem_access(path, :read, &:read).split("\n")
- header = lines.index("---")
- header ? lines[header + 1..-1] : lines
- end
-
- def parse_gem(string)
- version_and_platform, rest = string.split(" ", 2)
- version, platform = version_and_platform.split("-", 2)
- dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
- dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
- requirements = requirements ? requirements.map {|r| parse_dependency(r) } : []
- [version, platform, dependencies, requirements]
- end
-
- def parse_dependency(string)
- dependency = string.split(":")
- dependency[-1] = dependency[-1].split("&") if dependency.size > 1
- dependency
- end
-
- def info_roots
- [
- directory.join("info"),
- directory.join("info-special-characters"),
- ]
- end
- end
- end
-end
diff --git a/lib/bundler/compact_index_client/updater.rb b/lib/bundler/compact_index_client/updater.rb
deleted file mode 100644
index 3a4e4441ca..0000000000
--- a/lib/bundler/compact_index_client/updater.rb
+++ /dev/null
@@ -1,107 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/vendored_fileutils"
-require "stringio"
-require "zlib"
-
-module Bundler
- class CompactIndexClient
- class Updater
- class MisMatchedChecksumError < Error
- def initialize(path, server_checksum, local_checksum)
- @path = path
- @server_checksum = server_checksum
- @local_checksum = local_checksum
- end
-
- def message
- "The checksum of /#{@path} does not match the checksum provided by the server! Something is wrong " \
- "(local checksum is #{@local_checksum.inspect}, was expecting #{@server_checksum.inspect})."
- end
- end
-
- def initialize(fetcher)
- @fetcher = fetcher
- require "tmpdir"
- end
-
- def update(local_path, remote_path, retrying = nil)
- headers = {}
-
- Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir|
- local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename)
-
- # first try to fetch any new bytes on the existing file
- if retrying.nil? && local_path.file?
- FileUtils.cp local_path, local_temp_path
- headers["If-None-Match"] = etag_for(local_temp_path)
- headers["Range"] =
- if local_temp_path.size.nonzero?
- # Subtract a byte to ensure the range won't be empty.
- # Avoids 416 (Range Not Satisfiable) responses.
- "bytes=#{local_temp_path.size - 1}-"
- else
- "bytes=#{local_temp_path.size}-"
- end
- else
- # Fastly ignores Range when Accept-Encoding: gzip is set
- headers["Accept-Encoding"] = "gzip"
- end
-
- response = @fetcher.call(remote_path, headers)
- return nil if response.is_a?(Net::HTTPNotModified)
-
- content = response.body
- if response["Content-Encoding"] == "gzip"
- content = Zlib::GzipReader.new(StringIO.new(content)).read
- end
-
- SharedHelpers.filesystem_access(local_temp_path) do
- if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
- local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
- else
- local_temp_path.open("w") {|f| f << content }
- end
- end
-
- response_etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
- if etag_for(local_temp_path) == response_etag
- SharedHelpers.filesystem_access(local_path) do
- FileUtils.mv(local_temp_path, local_path)
- end
- return nil
- end
-
- if retrying
- raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_temp_path))
- end
-
- update(local_path, remote_path, :retrying)
- end
- end
-
- def etag_for(path)
- sum = checksum_for_file(path)
- sum ? %("#{sum}") : nil
- 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
- end
-
- def checksum_for_file(path)
- return nil unless path.file?
- # This must use IO.read instead of Digest.file().hexdigest
- # because we need to preserve \n line endings on windows when calculating
- # the checksum
- SharedHelpers.filesystem_access(path, :read) do
- SharedHelpers.digest(:MD5).hexdigest(IO.read(path))
- end
- end
- end
- end
-end
diff --git a/lib/bundler/compatibility_guard.rb b/lib/bundler/compatibility_guard.rb
deleted file mode 100644
index 750a1db04f..0000000000
--- a/lib/bundler/compatibility_guard.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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/constants.rb b/lib/bundler/constants.rb
deleted file mode 100644
index 2e4ebb37ee..0000000000
--- a/lib/bundler/constants.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/
- FREEBSD = RbConfig::CONFIG["host_os"] =~ /bsd/
- NULL = WINDOWS ? "NUL" : "/dev/null"
-end
diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb
deleted file mode 100644
index 31532d108d..0000000000
--- a/lib/bundler/current_ruby.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # Returns current version of Ruby
- #
- # @return [CurrentRuby] Current version of Ruby
- def self.current_ruby
- @current_ruby ||= CurrentRuby.new
- end
-
- class CurrentRuby
- KNOWN_MINOR_VERSIONS = %w[
- 1.8
- 1.9
- 2.0
- 2.1
- 2.2
- 2.3
- 2.4
- 2.5
- ].freeze
-
- KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze
-
- KNOWN_PLATFORMS = %w[
- jruby
- maglev
- mingw
- mri
- mswin
- mswin64
- rbx
- ruby
- x64_mingw
- ].freeze
-
- def ruby?
- !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev")
- end
-
- def mri?
- !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby")
- end
-
- def rbx?
- ruby? && defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
- end
-
- def jruby?
- defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
- end
-
- def maglev?
- defined?(RUBY_ENGINE) && RUBY_ENGINE == "maglev"
- end
-
- def mswin?
- Bundler::WINDOWS
- end
-
- def mswin64?
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
- end
-
- def mingw?
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
- end
-
- def x64_mingw?
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
- end
-
- (KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
- trimmed_version = version.tr(".", "")
- define_method(:"on_#{trimmed_version}?") do
- RUBY_VERSION.start_with?("#{version}.")
- end
-
- KNOWN_PLATFORMS.each do |platform|
- define_method(:"#{platform}_#{trimmed_version}?") do
- send(:"#{platform}?") && send(:"on_#{trimmed_version}?")
- end
- end
- end
- end
-end
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
deleted file mode 100644
index ad16389dae..0000000000
--- a/lib/bundler/definition.rb
+++ /dev/null
@@ -1,984 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/lockfile_parser"
-require "set"
-
-module Bundler
- class Definition
- include GemHelpers
-
- attr_reader(
- :dependencies,
- :gem_version_promoter,
- :locked_deps,
- :locked_gems,
- :platforms,
- :requires,
- :ruby_version,
- :lockfile,
- :gemfiles
- )
-
- # Given a gemfile and lockfile creates a Bundler definition
- #
- # @param gemfile [Pathname] Path to Gemfile
- # @param lockfile [Pathname,nil] Path to Gemfile.lock
- # @param unlock [Hash, Boolean, nil] Gems that have been requested
- # to be updated or true if all gems should be updated
- # @return [Bundler::Definition]
- def self.build(gemfile, lockfile, unlock)
- unlock ||= {}
- gemfile = Pathname.new(gemfile).expand_path
-
- raise GemfileNotFound, "#{gemfile} not found" unless gemfile.file?
-
- Dsl.evaluate(gemfile, lockfile, unlock)
- end
-
- #
- # How does the new system work?
- #
- # * Load information from Gemfile and Lockfile
- # * Invalidate stale locked specs
- # * All specs from stale source are stale
- # * All specs that are reachable only through a stale
- # dependency are stale.
- # * If all fresh dependencies are satisfied by the locked
- # specs, then we can try to resolve locally.
- #
- # @param lockfile [Pathname] Path to Gemfile.lock
- # @param dependencies [Array(Bundler::Dependency)] array of dependencies from Gemfile
- # @param sources [Bundler::SourceList]
- # @param unlock [Hash, Boolean, nil] Gems that have been requested
- # to be updated or true if all gems should be updated
- # @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
- # @param optional_groups [Array(String)] A list of optional groups
- def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = [])
- if [true, false].include?(unlock)
- @unlocking_bundler = false
- @unlocking = unlock
- else
- unlock = unlock.dup
- @unlocking_bundler = unlock.delete(:bundler)
- unlock.delete_if {|_k, v| Array(v).empty? }
- @unlocking = !unlock.empty?
- end
-
- @dependencies = dependencies
- @sources = sources
- @unlock = unlock
- @optional_groups = optional_groups
- @remote = false
- @specs = nil
- @ruby_version = ruby_version
- @gemfiles = gemfiles
-
- @lockfile = lockfile
- @lockfile_contents = String.new
- @locked_bundler_version = nil
- @locked_ruby_version = nil
-
- if lockfile && File.exist?(lockfile)
- @lockfile_contents = Bundler.read_file(lockfile)
- @locked_gems = LockfileParser.new(@lockfile_contents)
- @locked_platforms = @locked_gems.platforms
- @platforms = @locked_platforms.dup
- @locked_bundler_version = @locked_gems.bundler_version
- @locked_ruby_version = @locked_gems.ruby_version
-
- if unlock != true
- @locked_deps = @locked_gems.dependencies
- @locked_specs = SpecSet.new(@locked_gems.specs)
- @locked_sources = @locked_gems.sources
- else
- @unlock = {}
- @locked_deps = {}
- @locked_specs = SpecSet.new([])
- @locked_sources = []
- end
- else
- @unlock = {}
- @platforms = []
- @locked_gems = nil
- @locked_deps = {}
- @locked_specs = SpecSet.new([])
- @locked_sources = []
- @locked_platforms = []
- end
-
- @unlock[:gems] ||= []
- @unlock[:sources] ||= []
- @unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
- @ruby_version.diff(locked_ruby_version_object)
- end
- @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
-
- add_current_platform unless Bundler.frozen?
-
- converge_path_sources_to_gemspec_sources
- @path_changes = converge_paths
- @source_changes = converge_sources
-
- unless @unlock[:lock_shared_dependencies]
- eager_unlock = expand_dependencies(@unlock[:gems])
- @unlock[:gems] = @locked_specs.for(eager_unlock).map(&:name)
- end
-
- @gem_version_promoter = create_gem_version_promoter
-
- @dependency_changes = converge_dependencies
- @local_changes = converge_locals
-
- @requires = compute_requires
- end
-
- def create_gem_version_promoter
- locked_specs =
- if unlocking? && @locked_specs.empty? && !@lockfile_contents.empty?
- # Definition uses an empty set of locked_specs to indicate all gems
- # are unlocked, but GemVersionPromoter needs the locked_specs
- # for conservative comparison.
- Bundler::SpecSet.new(@locked_gems.specs)
- else
- @locked_specs
- end
- GemVersionPromoter.new(locked_specs, @unlock[:gems])
- end
-
- def resolve_with_cache!
- raise "Specs already loaded" if @specs
- sources.cached!
- specs
- end
-
- def resolve_remotely!
- raise "Specs already loaded" if @specs
- @remote = true
- sources.remote!
- specs
- end
-
- # For given dependency list returns a SpecSet with Gemspec of all the required
- # dependencies.
- # 1. The method first resolves the dependencies specified in Gemfile
- # 2. After that it tries and fetches gemspec of resolved dependencies
- #
- # @return [Bundler::SpecSet]
- def specs
- @specs ||= begin
- begin
- specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)
- rescue GemNotFound => e # Handle yanked gem
- gem_name, gem_version = extract_gem_info(e)
- locked_gem = @locked_specs[gem_name].last
- raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
- raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
- "be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
- "that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
- "to a different version of #{locked_gem} that hasn't been removed in order to install."
- end
- unless specs["bundler"].any?
- bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
- specs["bundler"] = bundler
- end
-
- specs
- end
- end
-
- def new_specs
- specs - @locked_specs
- end
-
- def removed_specs
- @locked_specs - specs
- end
-
- def new_platform?
- @new_platform
- end
-
- def missing_specs
- missing = []
- resolve.materialize(requested_dependencies, missing)
- missing
- end
-
- def missing_specs?
- missing = missing_specs
- return false if missing.empty?
- Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
- true
- rescue BundlerError => e
- @index = nil
- @resolve = nil
- @specs = nil
- @gem_version_promoter = create_gem_version_promoter
-
- Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
- true
- end
-
- def requested_specs
- @requested_specs ||= begin
- groups = requested_groups
- groups.map!(&:to_sym)
- specs_for(groups)
- end
- end
-
- def current_dependencies
- dependencies.select(&:should_include?)
- end
-
- def specs_for(groups)
- deps = dependencies.select {|d| (d.groups & groups).any? }
- deps.delete_if {|d| !d.should_include? }
- specs.for(expand_dependencies(deps))
- end
-
- # Resolve all the dependencies specified in Gemfile. It ensures that
- # dependencies that have been already resolved via locked file and are fresh
- # are reused when resolving dependencies
- #
- # @return [SpecSet] resolved dependencies
- def resolve
- @resolve ||= begin
- last_resolve = converge_locked_specs
- if Bundler.frozen?
- Bundler.ui.debug "Frozen, using resolution from the lockfile"
- last_resolve
- elsif !unlocking? && nothing_changed?
- Bundler.ui.debug("Found no changes, using resolution from the lockfile")
- last_resolve
- else
- # Run a resolve against the locally available gems
- Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
- last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
- end
- end
- end
-
- def index
- @index ||= Index.build do |idx|
- dependency_names = @dependencies.map(&:name)
-
- sources.all_sources.each do |source|
- source.dependency_names = dependency_names - pinned_spec_names(source)
- idx.add_source source.specs
- dependency_names.concat(source.unmet_deps).uniq!
- end
-
- double_check_for_index(idx, dependency_names)
- end
- end
-
- # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
- # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
- # but will not have found any versions of Bar from source B, which is a problem if the requested version
- # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
- # each spec we found, we add all possible versions from all sources to the index.
- def double_check_for_index(idx, dependency_names)
- pinned_names = pinned_spec_names
- loop do
- idxcount = idx.size
-
- names = :names # do this so we only have to traverse to get dependency_names from the index once
- unmet_dependency_names = lambda do
- return names unless names == :names
- new_names = sources.all_sources.map(&:dependency_names_to_double_check)
- return names = nil if new_names.compact!
- names = new_names.flatten(1).concat(dependency_names)
- names.uniq!
- names -= pinned_names
- names
- end
-
- sources.all_sources.each do |source|
- source.double_check_for(unmet_dependency_names)
- end
-
- break if idxcount == idx.size
- end
- end
- private :double_check_for_index
-
- def has_rubygems_remotes?
- sources.rubygems_sources.any? {|s| s.remotes.any? }
- end
-
- def has_local_dependencies?
- !sources.path_sources.empty? || !sources.git_sources.empty?
- end
-
- def spec_git_paths
- sources.git_sources.map {|s| s.path.to_s }
- end
-
- def groups
- dependencies.map(&:groups).flatten.uniq
- end
-
- def lock(file, preserve_unknown_sections = false)
- contents = to_lock
-
- # Convert to \r\n if the existing lock has them
- # i.e., Windows with `git config core.autocrlf=true`
- contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
-
- if @locked_bundler_version
- locked_major = @locked_bundler_version.segments.first
- current_major = Gem::Version.create(Bundler::VERSION).segments.first
-
- if updating_major = locked_major < current_major
- Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
- "after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
- end
- end
-
- preserve_unknown_sections ||= !updating_major && (Bundler.frozen? || !(unlocking? || @unlocking_bundler))
- return if lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
-
- if Bundler.frozen?
- Bundler.ui.error "Cannot write a changed lockfile while frozen."
- return
- end
-
- SharedHelpers.filesystem_access(file) do |p|
- File.open(p, "wb") {|f| f.puts(contents) }
- end
- end
-
- def locked_bundler_version
- if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
- new_version = Bundler::VERSION
- end
-
- new_version || @locked_bundler_version || Bundler::VERSION
- end
-
- def locked_ruby_version
- return unless ruby_version
- if @unlock[:ruby] || !@locked_ruby_version
- Bundler::RubyVersion.system
- else
- @locked_ruby_version
- end
- end
-
- def locked_ruby_version_object
- return unless @locked_ruby_version
- @locked_ruby_version_object ||= begin
- unless version = RubyVersion.from_string(@locked_ruby_version)
- raise LockfileError, "The Ruby version #{@locked_ruby_version} from " \
- "#{@lockfile} could not be parsed. " \
- "Try running bundle update --ruby to resolve this."
- end
- version
- end
- end
-
- def to_lock
- require "bundler/lockfile_generator"
- LockfileGenerator.generate(self)
- end
-
- def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
- msg = String.new
- msg << "You are trying to install in deployment mode after changing\n" \
- "your Gemfile. Run `bundle install` elsewhere and add the\n" \
- "updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control."
-
- unless explicit_flag
- suggested_command = if Bundler.settings.locations("frozen")[:global]
- "bundle config --delete frozen"
- elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
- "bundle config --delete deployment"
- else
- "bundle install --no-deployment"
- end
- msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
- "freeze \nby running `#{suggested_command}`."
- end
-
- added = []
- deleted = []
- changed = []
-
- new_platforms = @platforms - @locked_platforms
- deleted_platforms = @locked_platforms - @platforms
- added.concat new_platforms.map {|p| "* platform: #{p}" }
- deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
-
- gemfile_sources = sources.lock_sources
-
- new_sources = gemfile_sources - @locked_sources
- deleted_sources = @locked_sources - gemfile_sources
-
- new_deps = @dependencies - @locked_deps.values
- deleted_deps = @locked_deps.values - @dependencies
-
- # Check if it is possible that the source is only changed thing
- if (new_deps.empty? && deleted_deps.empty?) && (!new_sources.empty? && !deleted_sources.empty?)
- new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
- deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
- end
-
- if @locked_sources != gemfile_sources
- if new_sources.any?
- added.concat new_sources.map {|source| "* source: #{source}" }
- end
-
- if deleted_sources.any?
- deleted.concat deleted_sources.map {|source| "* source: #{source}" }
- end
- end
-
- added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
- if deleted_deps.any?
- deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
- end
-
- both_sources = Hash.new {|h, k| h[k] = [] }
- @dependencies.each {|d| both_sources[d.name][0] = d }
- @locked_deps.each {|name, d| both_sources[name][1] = d.source }
-
- both_sources.each do |name, (dep, lock_source)|
- next unless (dep.nil? && !lock_source.nil?) || (!dep.nil? && !lock_source.nil? && !lock_source.can_lock?(dep))
- gemfile_source_name = (dep && dep.source) || "no specified source"
- lockfile_source_name = lock_source || "no specified source"
- changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
- end
-
- reason = change_reason
- msg << "\n\n#{reason.split(", ").map(&:capitalize).join("\n")}" unless reason.strip.empty?
- msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
- msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
- msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
- msg << "\n"
-
- raise ProductionError, msg if added.any? || deleted.any? || changed.any? || !nothing_changed?
- end
-
- def validate_runtime!
- validate_ruby!
- validate_platforms!
- end
-
- def validate_ruby!
- return unless ruby_version
-
- if diff = ruby_version.diff(Bundler::RubyVersion.system)
- problem, expected, actual = diff
-
- msg = case problem
- when :engine
- "Your Ruby engine is #{actual}, but your Gemfile specified #{expected}"
- when :version
- "Your Ruby version is #{actual}, but your Gemfile specified #{expected}"
- when :engine_version
- "Your #{Bundler::RubyVersion.system.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}"
- when :patchlevel
- if !expected.is_a?(String)
- "The Ruby patchlevel in your Gemfile must be a string"
- else
- "Your Ruby patchlevel is #{actual}, but your Gemfile specified #{expected}"
- end
- end
-
- raise RubyVersionMismatch, msg
- end
- end
-
- def validate_platforms!
- return if @platforms.any? do |bundle_platform|
- Bundler.rubygems.platforms.any? do |local_platform|
- MatchPlatform.platforms_match?(bundle_platform, local_platform)
- end
- end
-
- raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
- "but your local platforms are #{Bundler.rubygems.platforms.map(&:to_s)}, and " \
- "there's no compatible match between those two lists."
- end
-
- def add_platform(platform)
- @new_platform ||= !@platforms.include?(platform)
- @platforms |= [platform]
- end
-
- def remove_platform(platform)
- return if @platforms.delete(Gem::Platform.new(platform))
- raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
- end
-
- def add_current_platform
- current_platform = Bundler.local_platform
- add_platform(current_platform) if Bundler.feature_flag.specific_platform?
- add_platform(generic(current_platform))
- end
-
- def find_resolved_spec(current_spec)
- specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
- end
-
- def find_indexed_specs(current_spec)
- index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
- end
-
- attr_reader :sources
- private :sources
-
- def nothing_changed?
- !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
- end
-
- def unlocking?
- @unlocking
- end
-
- private
-
- def change_reason
- if unlocking?
- unlock_reason = @unlock.reject {|_k, v| Array(v).empty? }.map do |k, v|
- if v == true
- k.to_s
- else
- v = Array(v)
- "#{k}: (#{v.join(", ")})"
- end
- end.join(", ")
- return "bundler is unlocking #{unlock_reason}"
- end
- [
- [@source_changes, "the list of sources changed"],
- [@dependency_changes, "the dependencies in your gemfile changed"],
- [@new_platform, "you added a new platform to your gemfile"],
- [@path_changes, "the gemspecs for path gems changed"],
- [@local_changes, "the gemspecs for git local gems changed"],
- ].select(&:first).map(&:last).join(", ")
- end
-
- def pretty_dep(dep, source = false)
- SharedHelpers.pretty_dependency(dep, source)
- end
-
- # Check if the specs of the given source changed
- # according to the locked source.
- def specs_changed?(source)
- locked = @locked_sources.find {|s| s == source }
-
- !locked || dependencies_for_source_changed?(source, locked) || specs_for_source_changed?(source)
- end
-
- def dependencies_for_source_changed?(source, locked_source = source)
- deps_for_source = @dependencies.select {|s| s.source == source }
- locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
-
- Set.new(deps_for_source) != Set.new(locked_deps_for_source)
- end
-
- def specs_for_source_changed?(source)
- locked_index = Index.new
- locked_index.use(@locked_specs.select {|s| source.can_lock?(s) })
-
- # order here matters, since Index#== is checking source.specs.include?(locked_index)
- locked_index != source.specs
- rescue PathError, GitError => e
- Bundler.ui.debug "Assuming that #{source} has not changed since fetching its specs errored (#{e})"
- false
- end
-
- # Get all locals and override their matching sources.
- # Return true if any of the locals changed (for example,
- # they point to a new revision) or depend on new specs.
- def converge_locals
- locals = []
-
- Bundler.settings.local_overrides.map do |k, v|
- spec = @dependencies.find {|s| s.name == k }
- source = spec && spec.source
- if source && source.respond_to?(:local_override!)
- source.unlock! if @unlock[:gems].include?(spec.name)
- locals << [source, source.local_override!(v)]
- end
- end
-
- sources_with_changes = locals.select do |source, changed|
- changed || specs_changed?(source)
- end.map(&:first)
- !sources_with_changes.each {|source| @unlock[:sources] << source.name }.empty?
- end
-
- def converge_paths
- sources.path_sources.any? do |source|
- specs_changed?(source)
- end
- end
-
- def converge_path_source_to_gemspec_source(source)
- return source unless source.instance_of?(Source::Path)
- gemspec_source = sources.path_sources.find {|s| s.is_a?(Source::Gemspec) && s.as_path_source == source }
- gemspec_source || source
- end
-
- def converge_path_sources_to_gemspec_sources
- @locked_sources.map! do |source|
- converge_path_source_to_gemspec_source(source)
- end
- @locked_specs.each do |spec|
- spec.source &&= converge_path_source_to_gemspec_source(spec.source)
- end
- @locked_deps.each do |_, dep|
- dep.source &&= converge_path_source_to_gemspec_source(dep.source)
- end
- end
-
- def converge_rubygems_sources
- return false if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
-
- changes = false
-
- # Get the RubyGems sources from the Gemfile.lock
- locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
- # Get the RubyGems remotes from the Gemfile
- actual_remotes = sources.rubygems_remotes
-
- # If there is a RubyGems source in both
- if !locked_gem_sources.empty? && !actual_remotes.empty?
- locked_gem_sources.each do |locked_gem|
- # Merge the remotes from the Gemfile into the Gemfile.lock
- changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
- end
- end
-
- changes
- end
-
- def converge_sources
- changes = false
-
- changes |= converge_rubygems_sources
-
- # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
- # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
- # source in the Gemfile.lock, use the one from the Gemfile.
- changes |= sources.replace_sources!(@locked_sources)
-
- sources.all_sources.each do |source|
- # If the source is unlockable and the current command allows an unlock of
- # the source (for example, you are doing a `bundle update <foo>` of a git-pinned
- # gem), unlock it. For git sources, this means to unlock the revision, which
- # will cause the `ref` used to be the most recent for the branch (or master) if
- # an explicit `ref` is not used.
- if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
- source.unlock!
- changes = true
- end
- end
-
- changes
- end
-
- def converge_dependencies
- frozen = Bundler.frozen?
- (@dependencies + @locked_deps.values).each do |dep|
- locked_source = @locked_deps[dep.name]
- # This is to make sure that if bundler is installing in deployment mode and
- # after locked_source and sources don't match, we still use locked_source.
- if frozen && !locked_source.nil? &&
- locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
- dep.source = locked_source.source
- elsif dep.source
- dep.source = sources.get(dep.source)
- end
- if dep.source.is_a?(Source::Gemspec)
- dep.platforms.concat(@platforms.map {|p| Dependency::REVERSE_PLATFORM_MAP[p] }.flatten(1)).uniq!
- end
- end
-
- changes = false
- # We want to know if all match, but don't want to check all entries
- # This means we need to return false if any dependency doesn't match
- # the lock or doesn't exist in the lock.
- @dependencies.each do |dependency|
- unless locked_dep = @locked_deps[dependency.name]
- changes = true
- next
- end
-
- # Gem::Dependency#== matches Gem::Dependency#type. As the lockfile
- # doesn't carry a notion of the dependency type, if you use
- # add_development_dependency in a gemspec that's loaded with the gemspec
- # directive, the lockfile dependencies and resolved dependencies end up
- # with a mismatch on #type. Work around that by setting the type on the
- # dep from the lockfile.
- locked_dep.instance_variable_set(:@type, dependency.type)
-
- # We already know the name matches from the hash lookup
- # so we only need to check the requirement now
- changes ||= dependency.requirement != locked_dep.requirement
- end
-
- changes
- end
-
- # Remove elements from the locked specs that are expired. This will most
- # commonly happen if the Gemfile has changed since the lockfile was last
- # generated
- def converge_locked_specs
- deps = []
-
- # Build a list of dependencies that are the same in the Gemfile
- # and Gemfile.lock. If the Gemfile modified a dependency, but
- # the gem in the Gemfile.lock still satisfies it, this is fine
- # too.
- @dependencies.each do |dep|
- locked_dep = @locked_deps[dep.name]
-
- # If the locked_dep doesn't match the dependency we're looking for then we ignore the locked_dep
- locked_dep = nil unless locked_dep == dep
-
- if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
- deps << dep
- elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source)
- @locked_specs.each do |s|
- @unlock[:gems] << s.name if s.source == dep.source
- end
-
- dep.source.unlock! if dep.source.respond_to?(:unlock!)
- dep.source.specs.each {|s| @unlock[:gems] << s.name }
- end
- end
-
- unlock_source_unlocks_spec = Bundler.feature_flag.unlock_source_unlocks_spec?
-
- converged = []
- @locked_specs.each do |s|
- # Replace the locked dependency's source with the equivalent source from the Gemfile
- dep = @dependencies.find {|d| s.satisfies?(d) }
- s.source = (dep && dep.source) || sources.get(s.source)
-
- # Don't add a spec to the list if its source is expired. For example,
- # if you change a Git gem to RubyGems.
- next if s.source.nil?
- next if @unlock[:sources].include?(s.source.name)
-
- # XXX This is a backwards-compatibility fix to preserve the ability to
- # unlock a single gem by passing its name via `--source`. See issue #3759
- # TODO: delete in Bundler 2
- next if unlock_source_unlocks_spec && @unlock[:sources].include?(s.name)
-
- # If the spec is from a path source and it doesn't exist anymore
- # then we unlock it.
-
- # Path sources have special logic
- if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
- other_sources_specs = begin
- s.source.specs
- rescue PathError, GitError
- # if we won't need the source (according to the lockfile),
- # don't error if the path/git source isn't available
- next if @locked_specs.
- for(requested_dependencies, [], false, true, false).
- none? {|locked_spec| locked_spec.source == s.source }
-
- raise
- end
-
- other = other_sources_specs[s].first
-
- # If the spec is no longer in the path source, unlock it. This
- # commonly happens if the version changed in the gemspec
- next unless other
-
- deps2 = other.dependencies.select {|d| d.type != :development }
- runtime_dependencies = s.dependencies.select {|d| d.type != :development }
- # If the dependencies of the path source have changed, unlock it
- next unless runtime_dependencies.sort == deps2.sort
- end
-
- converged << s
- end
-
- resolve = SpecSet.new(converged)
- resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems], false, false, false)
- diff = nil
-
- # Now, we unlock any sources that do not have anymore gems pinned to it
- sources.all_sources.each do |source|
- next unless source.respond_to?(:unlock!)
-
- unless resolve.any? {|s| s.source == source }
- diff ||= @locked_specs.to_a - resolve.to_a
- source.unlock! if diff.any? {|s| s.source == source }
- end
- end
-
- resolve
- end
-
- def in_locked_deps?(dep, locked_dep)
- # Because the lockfile can't link a dep to a specific remote, we need to
- # treat sources as equivalent anytime the locked dep has all the remotes
- # that the Gemfile dep does.
- locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
- end
-
- def satisfies_locked_spec?(dep)
- @locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
- end
-
- # This list of dependencies is only used in #resolve, so it's OK to add
- # the metadata dependencies here
- def expanded_dependencies
- @expanded_dependencies ||= begin
- expand_dependencies(dependencies + metadata_dependencies, @remote)
- end
- end
-
- def metadata_dependencies
- @metadata_dependencies ||= begin
- ruby_versions = concat_ruby_version_requirements(@ruby_version)
- if ruby_versions.empty? || !@ruby_version.exact?
- concat_ruby_version_requirements(RubyVersion.system)
- concat_ruby_version_requirements(locked_ruby_version_object) unless @unlock[:ruby]
- end
- [
- Dependency.new("ruby\0", ruby_versions),
- Dependency.new("rubygems\0", Gem::VERSION),
- ]
- end
- end
-
- def concat_ruby_version_requirements(ruby_version, ruby_versions = [])
- return ruby_versions unless ruby_version
- if ruby_version.patchlevel
- ruby_versions << ruby_version.to_gem_version_with_patchlevel
- else
- ruby_versions.concat(ruby_version.versions.map do |version|
- requirement = Gem::Requirement.new(version)
- if requirement.exact?
- "~> #{version}.0"
- else
- requirement
- end
- end)
- end
- end
-
- def expand_dependencies(dependencies, remote = false)
- sorted_platforms = Resolver.sort_platforms(@platforms)
- deps = []
- dependencies.each do |dep|
- dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
- next if !remote && !dep.current_platform?
- platforms = dep.gem_platforms(sorted_platforms)
- if platforms.empty?
- mapped_platforms = dep.platforms.map {|p| Dependency::PLATFORM_MAP[p] }
- Bundler.ui.warn \
- "The dependency #{dep} will be unused by any of the platforms Bundler is installing for. " \
- "Bundler is installing for #{@platforms.join ", "} but the dependency " \
- "is only for #{mapped_platforms.join ", "}. " \
- "To add those platforms to the bundle, " \
- "run `bundle lock --add-platform #{mapped_platforms.join " "}`."
- end
- platforms.each do |p|
- deps << DepProxy.new(dep, p) if remote || p == generic_local_platform
- end
- end
- deps
- end
-
- def requested_dependencies
- groups = requested_groups
- groups.map!(&:to_sym)
- dependencies.reject {|d| !d.should_include? || (d.groups & groups).empty? }
- end
-
- def source_requirements
- # Load all specs from remote sources
- index
-
- # Record the specs available in each gem's source, so that those
- # specs will be available later when the resolver knows where to
- # 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?
- dependencies.each do |dep|
- next unless source = dep.source || default
- source_requirements[dep.name] = source
- end
- metadata_dependencies.each do |dep|
- source_requirements[dep.name] = sources.metadata_source
- end
- source_requirements["bundler"] = sources.metadata_source # needs to come last to override
- source_requirements
- end
-
- def pinned_spec_names(skip = nil)
- pinned_names = []
- default = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? && sources.default_source
- @dependencies.each do |dep|
- next unless dep_source = dep.source || default
- next if dep_source == skip
- pinned_names << dep.name
- end
- pinned_names
- end
-
- def requested_groups
- groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
- end
-
- def lockfiles_equal?(current, proposed, preserve_unknown_sections)
- if preserve_unknown_sections
- sections_to_ignore = LockfileParser.sections_to_ignore(@locked_bundler_version)
- sections_to_ignore += LockfileParser.unknown_sections_in_lockfile(current)
- sections_to_ignore += LockfileParser::ENVIRONMENT_VERSION_SECTIONS
- pattern = /#{Regexp.union(sections_to_ignore)}\n(\s{2,}.*\n)+/
- whitespace_cleanup = /\n{2,}/
- current = current.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip
- proposed = proposed.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip
- end
- current == proposed
- end
-
- def extract_gem_info(error)
- # This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
- # to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
- error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
- end
-
- def compute_requires
- dependencies.reduce({}) do |requires, dep|
- next requires unless dep.should_include?
- requires[dep.name] = Array(dep.autorequire || dep.name).map do |file|
- # Allow `require: true` as an alias for `require: <name>`
- file == true ? dep.name : file
- end
- requires
- end
- end
-
- def additional_base_requirements_for_resolve
- return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions?
- dependencies_by_name = dependencies.group_by(&:name)
- @locked_gems.specs.reduce({}) do |requirements, locked_spec|
- name = locked_spec.name
- next requirements if @locked_deps[name] != dependencies_by_name[name]
- dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
- requirements[name] = DepProxy.new(dep, locked_spec.platform)
- requirements
- end.values
- end
-
- def equivalent_rubygems_remotes?(source)
- return false unless source.is_a?(Source::Rubygems)
-
- Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
- end
- end
-end
diff --git a/lib/bundler/dep_proxy.rb b/lib/bundler/dep_proxy.rb
deleted file mode 100644
index 7a9423b14a..0000000000
--- a/lib/bundler/dep_proxy.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class DepProxy
- attr_reader :__platform, :dep
-
- def initialize(dep, platform)
- @dep = dep
- @__platform = platform
- end
-
- def hash
- @hash ||= dep.hash
- end
-
- def ==(other)
- return if other.nil?
- dep == other.dep && __platform == other.__platform
- end
-
- alias_method :eql?, :==
-
- def type
- @dep.type
- end
-
- def name
- @dep.name
- end
-
- def requirement
- @dep.requirement
- end
-
- def to_s
- s = name.dup
- s << " (#{requirement})" unless requirement == Gem::Requirement.default
- s << " #{__platform}" unless __platform == Gem::Platform::RUBY
- s
- end
-
- private
-
- def method_missing(*args, &blk)
- @dep.send(*args, &blk)
- end
- end
-end
diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb
deleted file mode 100644
index 24257bc113..0000000000
--- a/lib/bundler/dependency.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# frozen_string_literal: true
-
-require "rubygems/dependency"
-require "bundler/shared_helpers"
-require "bundler/rubygems_ext"
-
-module Bundler
- class Dependency < Gem::Dependency
- attr_reader :autorequire
- attr_reader :groups
- attr_reader :platforms
-
- PLATFORM_MAP = {
- :ruby => Gem::Platform::RUBY,
- :ruby_18 => Gem::Platform::RUBY,
- :ruby_19 => Gem::Platform::RUBY,
- :ruby_20 => Gem::Platform::RUBY,
- :ruby_21 => Gem::Platform::RUBY,
- :ruby_22 => Gem::Platform::RUBY,
- :ruby_23 => Gem::Platform::RUBY,
- :ruby_24 => Gem::Platform::RUBY,
- :ruby_25 => Gem::Platform::RUBY,
- :mri => Gem::Platform::RUBY,
- :mri_18 => Gem::Platform::RUBY,
- :mri_19 => Gem::Platform::RUBY,
- :mri_20 => Gem::Platform::RUBY,
- :mri_21 => Gem::Platform::RUBY,
- :mri_22 => Gem::Platform::RUBY,
- :mri_23 => Gem::Platform::RUBY,
- :mri_24 => Gem::Platform::RUBY,
- :mri_25 => Gem::Platform::RUBY,
- :rbx => Gem::Platform::RUBY,
- :jruby => Gem::Platform::JAVA,
- :jruby_18 => Gem::Platform::JAVA,
- :jruby_19 => Gem::Platform::JAVA,
- :mswin => Gem::Platform::MSWIN,
- :mswin_18 => Gem::Platform::MSWIN,
- :mswin_19 => Gem::Platform::MSWIN,
- :mswin_20 => Gem::Platform::MSWIN,
- :mswin_21 => Gem::Platform::MSWIN,
- :mswin_22 => Gem::Platform::MSWIN,
- :mswin_23 => Gem::Platform::MSWIN,
- :mswin_24 => Gem::Platform::MSWIN,
- :mswin_25 => Gem::Platform::MSWIN,
- :mswin64 => Gem::Platform::MSWIN64,
- :mswin64_19 => Gem::Platform::MSWIN64,
- :mswin64_20 => Gem::Platform::MSWIN64,
- :mswin64_21 => Gem::Platform::MSWIN64,
- :mswin64_22 => Gem::Platform::MSWIN64,
- :mswin64_23 => Gem::Platform::MSWIN64,
- :mswin64_24 => Gem::Platform::MSWIN64,
- :mswin64_25 => Gem::Platform::MSWIN64,
- :mingw => Gem::Platform::MINGW,
- :mingw_18 => Gem::Platform::MINGW,
- :mingw_19 => Gem::Platform::MINGW,
- :mingw_20 => Gem::Platform::MINGW,
- :mingw_21 => Gem::Platform::MINGW,
- :mingw_22 => Gem::Platform::MINGW,
- :mingw_23 => Gem::Platform::MINGW,
- :mingw_24 => Gem::Platform::MINGW,
- :mingw_25 => Gem::Platform::MINGW,
- :x64_mingw => Gem::Platform::X64_MINGW,
- :x64_mingw_20 => Gem::Platform::X64_MINGW,
- :x64_mingw_21 => Gem::Platform::X64_MINGW,
- :x64_mingw_22 => Gem::Platform::X64_MINGW,
- :x64_mingw_23 => Gem::Platform::X64_MINGW,
- :x64_mingw_24 => Gem::Platform::X64_MINGW,
- :x64_mingw_25 => Gem::Platform::X64_MINGW,
- }.freeze
-
- REVERSE_PLATFORM_MAP = {}.tap do |reverse_platform_map|
- PLATFORM_MAP.each do |key, value|
- reverse_platform_map[value] ||= []
- reverse_platform_map[value] << key
- end
-
- reverse_platform_map.each {|_, platforms| platforms.freeze }
- end.freeze
-
- def initialize(name, version, options = {}, &blk)
- type = options["type"] || :runtime
- super(name, version, type)
-
- @autorequire = nil
- @groups = Array(options["group"] || :default).map(&:to_sym)
- @source = options["source"]
- @platforms = Array(options["platforms"])
- @env = options["env"]
- @should_include = options.fetch("should_include", true)
-
- @autorequire = Array(options["require"] || []) if options.key?("require")
- end
-
- # Returns the platforms this dependency is valid for, in the same order as
- # passed in the `valid_platforms` parameter
- def gem_platforms(valid_platforms)
- return valid_platforms if @platforms.empty?
-
- @gem_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.uniq
-
- valid_platforms & @gem_platforms
- end
-
- def should_include?
- @should_include && current_env? && current_platform?
- end
-
- def current_env?
- return true unless @env
- if @env.is_a?(Hash)
- @env.all? do |key, val|
- ENV[key.to_s] && (val.is_a?(String) ? ENV[key.to_s] == val : ENV[key.to_s] =~ val)
- end
- else
- ENV[@env.to_s]
- end
- end
-
- def current_platform?
- return true if @platforms.empty?
- @platforms.any? do |p|
- Bundler.current_ruby.send("#{p}?")
- end
- end
-
- def to_lock
- out = super
- out << "!" if source
- out << "\n"
- end
-
- def specific?
- super
- rescue NoMethodError
- requirement != ">= 0"
- end
- end
-end
diff --git a/lib/bundler/deployment.rb b/lib/bundler/deployment.rb
deleted file mode 100644
index 291e158ca0..0000000000
--- a/lib/bundler/deployment.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/shared_helpers"
-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."
-
-module Bundler
- class Deployment
- def self.define_task(context, task_method = :task, opts = {})
- if defined?(Capistrano) && context.is_a?(Capistrano::Configuration)
- context_name = "capistrano"
- role_default = "{:except => {:no_release => true}}"
- error_type = ::Capistrano::CommandError
- else
- context_name = "vlad"
- role_default = "[:app]"
- error_type = ::Rake::CommandFailedError
- end
-
- roles = context.fetch(:bundle_roles, false)
- opts[:roles] = roles if roles
-
- context.send :namespace, :bundle do
- send :desc, <<-DESC
- Install the current Bundler environment. By default, gems will be \
- installed to the shared/bundle path. Gems in the development and \
- test group will not be installed. The install command is executed \
- with the --deployment and --quiet flags. If the bundle cmd cannot \
- be found then you can override the bundle_cmd variable to specify \
- which one it should use. The base path to the app is fetched from \
- the :latest_release variable. Set it for custom deploy layouts.
-
- You can override any of these defaults by setting the variables shown below.
-
- N.B. bundle_roles must be defined before you require 'bundler/#{context_name}' \
- in your deploy.rb file.
-
- set :bundle_gemfile, "Gemfile"
- set :bundle_dir, File.join(fetch(:shared_path), 'bundle')
- set :bundle_flags, "--deployment --quiet"
- set :bundle_without, [:development, :test]
- set :bundle_with, [:mysql]
- set :bundle_cmd, "bundle" # e.g. "/opt/ruby/bin/bundle"
- set :bundle_roles, #{role_default} # e.g. [:app, :batch]
- DESC
- send task_method, :install, opts do
- bundle_cmd = context.fetch(:bundle_cmd, "bundle")
- bundle_flags = context.fetch(:bundle_flags, "--deployment --quiet")
- bundle_dir = context.fetch(:bundle_dir, File.join(context.fetch(:shared_path), "bundle"))
- bundle_gemfile = context.fetch(:bundle_gemfile, "Gemfile")
- bundle_without = [*context.fetch(:bundle_without, [:development, :test])].compact
- bundle_with = [*context.fetch(:bundle_with, [])].compact
- app_path = context.fetch(:latest_release)
- if app_path.to_s.empty?
- raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
- end
- args = ["--gemfile #{File.join(app_path, bundle_gemfile)}"]
- args << "--path #{bundle_dir}" unless bundle_dir.to_s.empty?
- args << bundle_flags.to_s
- args << "--without #{bundle_without.join(" ")}" unless bundle_without.empty?
- args << "--with #{bundle_with.join(" ")}" unless bundle_with.empty?
-
- run "cd #{app_path} && #{bundle_cmd} install #{args.join(" ")}"
- end
- end
- end
- end
-end
diff --git a/lib/bundler/deprecate.rb b/lib/bundler/deprecate.rb
deleted file mode 100644
index 387f632a39..0000000000
--- a/lib/bundler/deprecate.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-begin
- require "rubygems/deprecate"
-rescue LoadError
- # it's fine if it doesn't exist on the current RubyGems...
- nil
-end
-
-module Bundler
- if defined? Bundler::Deprecate
- # nothing to do!
- elsif defined? ::Deprecate
- Deprecate = ::Deprecate
- elsif defined? Gem::Deprecate
- Deprecate = Gem::Deprecate
- else
- class Deprecate
- end
- end
-
- unless Deprecate.respond_to?(:skip_during)
- def Deprecate.skip_during
- original = skip
- self.skip = true
- yield
- ensure
- self.skip = original
- end
- end
-
- unless Deprecate.respond_to?(:skip)
- def Deprecate.skip
- @skip ||= false
- end
- end
-
- unless Deprecate.respond_to?(:skip=)
- def Deprecate.skip=(skip)
- @skip = skip
- end
- end
-end
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
deleted file mode 100644
index 8681163277..0000000000
--- a/lib/bundler/dsl.rb
+++ /dev/null
@@ -1,599 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/dependency"
-require "bundler/ruby_dsl"
-
-module Bundler
- class Dsl
- include RubyDsl
-
- def self.evaluate(gemfile, lockfile, unlock)
- builder = new
- builder.eval_gemfile(gemfile)
- builder.to_definition(lockfile, unlock)
- end
-
- VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze
-
- VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
- platform platforms type source install_if].freeze
-
- attr_reader :gemspecs
- attr_accessor :dependencies
-
- def initialize
- @source = nil
- @sources = SourceList.new
- @git_sources = {}
- @dependencies = []
- @groups = []
- @install_conditionals = []
- @optional_groups = []
- @platforms = []
- @env = nil
- @ruby_version = nil
- @gemspecs = []
- @gemfile = nil
- @gemfiles = []
- add_git_sources
- end
-
- def eval_gemfile(gemfile, contents = nil)
- expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile && @gemfile.parent)
- original_gemfile = @gemfile
- @gemfile = expanded_gemfile_path
- @gemfiles << expanded_gemfile_path
- contents ||= Bundler.read_file(@gemfile.to_s)
- instance_eval(contents.dup.untaint, gemfile.to_s, 1)
- rescue Exception => e
- message = "There was an error " \
- "#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
- "`#{File.basename gemfile.to_s}`: #{e.message}"
-
- raise DSLError.new(message, gemfile, e.backtrace, contents)
- ensure
- @gemfile = original_gemfile
- end
-
- def gemspec(opts = nil)
- opts ||= {}
- path = opts[:path] || "."
- glob = opts[:glob]
- name = opts[:name]
- development_group = opts[:development_group] || :development
- expanded_path = gemfile_root.join(path)
-
- gemspecs = Dir[File.join(expanded_path, "{,*}.gemspec")].map {|g| Bundler.load_gemspec(g) }.compact
- gemspecs.reject! {|s| s.name != name } if name
- Index.sort_specs(gemspecs)
- specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] }
-
- case specs_by_name_and_version.size
- when 1
- specs = specs_by_name_and_version.values.first
- spec = specs.find {|s| s.match_platform(Bundler.local_platform) } || specs.first
-
- @gemspecs << spec
-
- gem_platforms = Bundler::Dependency::REVERSE_PLATFORM_MAP[Bundler::GemHelpers.generic_local_platform]
- gem spec.name, :name => spec.name, :path => path, :glob => glob, :platforms => gem_platforms
-
- group(development_group) do
- spec.development_dependencies.each do |dep|
- gem dep.name, *(dep.requirement.as_list + [:type => :development])
- end
- end
- when 0
- raise InvalidOption, "There are no gemspecs at #{expanded_path}"
- else
- raise InvalidOption, "There are multiple gemspecs at #{expanded_path}. " \
- "Please use the :name option to specify which one should be used"
- end
- end
-
- def gem(name, *args)
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
- version = args || [">= 0"]
-
- normalize_options(name, version, options)
-
- dep = Dependency.new(name, version, options)
-
- # if there's already a dependency with this name we try to prefer one
- if current = @dependencies.find {|d| d.name == dep.name }
- deleted_dep = @dependencies.delete(current) if current.type == :development
-
- if current.requirement != dep.requirement
- unless deleted_dep
- return if dep.type == :development
- raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
- "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})"
- end
-
- else
- Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
- "You should probably keep only one of them.\n" \
- "While it's not a problem now, it could cause errors if you change the version of one of them later."
- end
-
- if current.source != dep.source
- unless deleted_dep
- return if dep.type == :development
- raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
- "You specified that #{dep.name} (#{dep.requirement}) should come from " \
- "#{current.source || "an unspecified source"} and #{dep.source}\n"
- end
- end
- end
-
- @dependencies << dep
- end
-
- def source(source, *args, &blk)
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
- options = normalize_hash(options)
- source = normalize_source(source)
-
- if options.key?("type")
- options["type"] = options["type"].to_s
- unless Plugin.source?(options["type"])
- raise InvalidOption, "No plugin sources available for #{options["type"]}"
- end
-
- unless block_given?
- raise InvalidOption, "You need to pass a block to #source with :type option"
- end
-
- source_opts = options.merge("uri" => source)
- with_source(@sources.add_plugin_source(options["type"], source_opts), &blk)
- elsif block_given?
- with_source(@sources.add_rubygems_source("remotes" => source), &blk)
- else
- check_primary_source_safety(@sources)
- @sources.global_rubygems_source = source
- end
- end
-
- def git_source(name, &block)
- unless block_given?
- raise InvalidOption, "You need to pass a block to #git_source"
- end
-
- if valid_keys.include?(name.to_s)
- raise InvalidOption, "You cannot use #{name} as a git source. It " \
- "is a reserved key. Reserved keys are: #{valid_keys.join(", ")}"
- end
-
- @git_sources[name.to_s] = block
- end
-
- def path(path, options = {}, &blk)
- unless block_given?
- msg = "You can no longer specify a path source by itself. Instead, \n" \
- "either use the :path option on a gem, or specify the gems that \n" \
- "bundler should find in the path source by passing a block to \n" \
- "the path method, like: \n\n" \
- " path 'dir/containing/rails' do\n" \
- " gem 'rails'\n" \
- " end\n\n"
-
- raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource?
- SharedHelpers.major_deprecation(2, msg.strip)
- end
-
- source_options = normalize_hash(options).merge(
- "path" => Pathname.new(path),
- "root_path" => gemfile_root,
- "gemspec" => gemspecs.find {|g| g.name == options["name"] }
- )
- source = @sources.add_path_source(source_options)
- with_source(source, &blk)
- end
-
- def git(uri, options = {}, &blk)
- unless block_given?
- msg = "You can no longer specify a git source by itself. Instead, \n" \
- "either use the :git option on a gem, or specify the gems that \n" \
- "bundler should find in the git source by passing a block to \n" \
- "the git method, like: \n\n" \
- " git 'git://github.com/rails/rails.git' do\n" \
- " gem 'rails'\n" \
- " end"
- raise DeprecatedError, msg
- end
-
- with_source(@sources.add_git_source(normalize_hash(options).merge("uri" => uri)), &blk)
- end
-
- def github(repo, options = {})
- raise ArgumentError, "GitHub sources require a block" unless block_given?
- raise DeprecatedError, "The #github method has been removed" if Bundler.feature_flag.skip_default_git_sources?
- github_uri = @git_sources["github"].call(repo)
- git_options = normalize_hash(options).merge("uri" => github_uri)
- git_source = @sources.add_git_source(git_options)
- with_source(git_source) { yield }
- end
-
- def to_definition(lockfile, unlock)
- Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
- end
-
- def group(*args, &blk)
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
- normalize_group_options(options, args)
-
- @groups.concat args
-
- if options["optional"]
- optional_groups = args - @optional_groups
- @optional_groups.concat optional_groups
- end
-
- yield
- ensure
- args.each { @groups.pop }
- end
-
- def install_if(*args)
- @install_conditionals.concat args
- yield
- ensure
- args.each { @install_conditionals.pop }
- end
-
- def platforms(*platforms)
- @platforms.concat platforms
- yield
- ensure
- platforms.each { @platforms.pop }
- end
- alias_method :platform, :platforms
-
- def env(name)
- old = @env
- @env = name
- yield
- ensure
- @env = old
- end
-
- def plugin(*args)
- # Pass on
- end
-
- def method_missing(name, *args)
- raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
- end
-
- private
-
- def add_git_sources
- return if Bundler.feature_flag.skip_default_git_sources?
-
- git_source(:github) do |repo_name|
- 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 2, "The `github.https` setting will be removed"
- "https://github.com/#{repo_name}.git"
- else
- "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("/")
-repo_name ||= user_name
-"https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
- RUBY
-
- user_name, repo_name = repo_name.split("/")
- repo_name ||= user_name
- "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
- end
- end
-
- def with_source(source)
- old_source = @source
- if block_given?
- @source = source
- yield
- end
- source
- ensure
- @source = old_source
- end
-
- def normalize_hash(opts)
- opts.keys.each do |k|
- opts[k.to_s] = opts.delete(k) unless k.is_a?(String)
- end
- opts
- end
-
- def valid_keys
- @valid_keys ||= VALID_KEYS
- end
-
- def normalize_options(name, version, opts)
- if name.is_a?(Symbol)
- raise GemfileError, %(You need to specify gem names as Strings. Use 'gem "#{name}"' instead)
- end
- 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
-
- normalize_hash(opts)
-
- git_names = @git_sources.keys.map(&:to_s)
- validate_keys("gem '#{name}'", opts, valid_keys + git_names)
-
- groups = @groups.dup
- opts["group"] = opts.delete("groups") || opts["group"]
- groups.concat Array(opts.delete("group"))
- groups = [:default] if groups.empty?
-
- install_if = @install_conditionals.dup
- install_if.concat Array(opts.delete("install_if"))
- install_if = install_if.reduce(true) do |memo, val|
- memo && (val.respond_to?(:call) ? val.call : val)
- end
-
- platforms = @platforms.dup
- opts["platforms"] = opts["platform"] || opts["platforms"]
- platforms.concat Array(opts.delete("platforms"))
- platforms.map!(&:to_sym)
- platforms.each do |p|
- next if VALID_PLATFORMS.include?(p)
- raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
- end
-
- # Save sources passed in a key
- if opts.key?("source")
- source = normalize_source(opts["source"])
- opts["source"] = @sources.add_rubygems_source("remotes" => source)
- end
-
- git_name = (git_names & opts.keys).last
- if @git_sources[git_name]
- opts["git"] = @git_sources[git_name].call(opts[git_name])
- end
-
- %w[git path].each do |type|
- next unless param = opts[type]
- if version.first && version.first =~ /^\s*=?\s*(\d[^\s]*)\s*$/
- options = opts.merge("name" => name, "version" => $1)
- else
- options = opts.dup
- end
- source = send(type, param, options) {}
- opts["source"] = source
- end
-
- opts["source"] ||= @source
- opts["env"] ||= @env
- opts["platforms"] = platforms.dup
- opts["group"] = groups
- opts["should_include"] = install_if
- end
-
- def normalize_group_options(opts, groups)
- normalize_hash(opts)
-
- groups = groups.map {|group| ":#{group}" }.join(", ")
- validate_keys("group #{groups}", opts, %w[optional])
-
- opts["optional"] ||= false
- end
-
- def validate_keys(command, opts, valid_keys)
- invalid_keys = opts.keys - valid_keys
-
- git_source = opts.keys & @git_sources.keys.map(&:to_s)
- if opts["branch"] && !(opts["git"] || opts["github"] || git_source.any?)
- raise GemfileError, %(The `branch` option for `#{command}` is not allowed. Only gems with a git source can specify a branch)
- end
-
- return true unless invalid_keys.any?
-
- 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
-
- message << " Valid options are: #{valid_keys.join(", ")}."
- message << " You may be able to resolve this by upgrading Bundler to the newest version."
- raise InvalidOption, message
- end
-
- def normalize_source(source)
- case source
- when :gemcutter, :rubygems, :rubyforge
- 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"
- when String
- source
- else
- raise GemfileError, "Unknown source '#{source}'"
- end
- end
-
- def check_primary_source_safety(source_list)
- return if source_list.rubygems_primary_remotes.empty? && source_list.global_rubygems_source.nil?
-
- if Bundler.feature_flag.disable_multisource?
- 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_2_mode?
- msg += ". To downgrade this error to a warning, run " \
- "`bundle config --delete disable_multisource`"
- end
- raise GemfileEvalError, msg
- else
- 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 " \
- "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} }"
- else
- "do |repo_name|\n#{replacement.to_s.gsub(/^/, " ")}\n end"
- end
-
- Bundler::SharedHelpers.major_deprecation 2, <<-EOS
-The :#{name} git source is deprecated, and will be removed in Bundler 2.0.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
-
- git_source(:#{name}) #{replacement}
-
- EOS
- end
-
- class DSLError < GemfileError
- # @return [String] the description that should be presented to the user.
- #
- attr_reader :description
-
- # @return [String] the path of the dsl file that raised the exception.
- #
- attr_reader :dsl_path
-
- # @return [Exception] the backtrace of the exception raised by the
- # evaluation of the dsl file.
- #
- attr_reader :backtrace
-
- # @param [Exception] backtrace @see backtrace
- # @param [String] dsl_path @see dsl_path
- #
- def initialize(description, dsl_path, backtrace, contents = nil)
- @status_code = $!.respond_to?(:status_code) && $!.status_code
-
- @description = description
- @dsl_path = dsl_path
- @backtrace = backtrace
- @contents = contents
- end
-
- def status_code
- @status_code || super
- end
-
- # @return [String] the contents of the DSL that cause the exception to
- # be raised.
- #
- def contents
- @contents ||= begin
- dsl_path && File.exist?(dsl_path) && File.read(dsl_path)
- end
- end
-
- # The message of the exception reports the content of podspec for the
- # line that generated the original exception.
- #
- # @example Output
- #
- # Invalid podspec at `RestKit.podspec` - undefined method
- # `exclude_header_search_paths=' for #<Pod::Specification for
- # `RestKit/Network (0.9.3)`>
- #
- # from spec-repos/master/RestKit/0.9.3/RestKit.podspec:36
- # -------------------------------------------
- # # because it would break: #import <CoreData/CoreData.h>
- # > ns.exclude_header_search_paths = 'Code/RestKit.h'
- # end
- # -------------------------------------------
- #
- # @return [String] the message of the exception.
- #
- def to_s
- @to_s ||= begin
- trace_line, description = parse_line_number_from_description
-
- m = String.new("\n[!] ")
- m << description
- m << ". Bundler cannot continue.\n"
-
- return m unless backtrace && dsl_path && contents
-
- trace_line = backtrace.find {|l| l.include?(dsl_path.to_s) } || trace_line
- return m unless trace_line
- line_numer = trace_line.split(":")[1].to_i - 1
- return m unless line_numer
-
- lines = contents.lines.to_a
- indent = " # "
- indicator = indent.tr("#", ">")
- first_line = line_numer.zero?
- last_line = (line_numer == (lines.count - 1))
-
- m << "\n"
- m << "#{indent}from #{trace_line.gsub(/:in.*$/, "")}\n"
- m << "#{indent}-------------------------------------------\n"
- m << "#{indent}#{lines[line_numer - 1]}" unless first_line
- m << "#{indicator}#{lines[line_numer]}"
- m << "#{indent}#{lines[line_numer + 1]}" unless last_line
- m << "\n" unless m.end_with?("\n")
- m << "#{indent}-------------------------------------------\n"
- end
- end
-
- private
-
- def parse_line_number_from_description
- 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", " - ")
- end
- [trace_line, description]
- end
- end
-
- def gemfile_root
- @gemfile ||= Bundler.default_gemfile
- @gemfile.dirname
- end
- end
-end
diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb
deleted file mode 100644
index 8668c4ea7f..0000000000
--- a/lib/bundler/endpoint_specification.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # used for Creating Specifications from the Gemcutter Endpoint
- class EndpointSpecification < Gem::Specification
- ILLFORMED_MESSAGE = 'Ill-formed requirement ["#<YAML::Syck::DefaultKey'.freeze
- include MatchPlatform
-
- attr_reader :name, :version, :platform, :required_rubygems_version, :required_ruby_version, :checksum
- attr_accessor :source, :remote, :dependencies
-
- def initialize(name, version, platform, dependencies, metadata = nil)
- super()
- @name = name
- @version = Gem::Version.create version
- @platform = platform
- @dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
-
- @loaded_from = nil
- @remote_specification = nil
-
- parse_metadata(metadata)
- end
-
- def fetch_platform
- @platform
- end
-
- # needed for standalone, load required_paths from local gemspec
- # after the gem is installed
- def require_paths
- if @remote_specification
- @remote_specification.require_paths
- elsif _local_specification
- _local_specification.require_paths
- else
- super
- end
- end
-
- # needed for inline
- def load_paths
- # remote specs aren't installed, and can't have load_paths
- if _local_specification
- _local_specification.load_paths
- else
- super
- end
- end
-
- # needed for binstubs
- def executables
- if @remote_specification
- @remote_specification.executables
- elsif _local_specification
- _local_specification.executables
- else
- super
- end
- end
-
- # needed for bundle clean
- def bindir
- if @remote_specification
- @remote_specification.bindir
- elsif _local_specification
- _local_specification.bindir
- else
- super
- end
- end
-
- # needed for post_install_messages during install
- def post_install_message
- if @remote_specification
- @remote_specification.post_install_message
- elsif _local_specification
- _local_specification.post_install_message
- else
- super
- end
- end
-
- # needed for "with native extensions" during install
- def extensions
- if @remote_specification
- @remote_specification.extensions
- elsif _local_specification
- _local_specification.extensions
- else
- super
- end
- end
-
- def _local_specification
- return unless @loaded_from && File.exist?(local_specification_path)
- eval(File.read(local_specification_path)).tap do |spec|
- spec.loaded_from = @loaded_from
- end
- end
-
- def __swap__(spec)
- SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
- @remote_specification = spec
- end
-
- private
-
- def local_specification_path
- "#{base_dir}/specifications/#{full_name}.gemspec"
- end
-
- def parse_metadata(data)
- return unless data
- data.each do |k, v|
- next unless v
- case k.to_s
- when "checksum"
- @checksum = v.last
- when "rubygems"
- @required_rubygems_version = Gem::Requirement.new(v)
- when "ruby"
- @required_ruby_version = Gem::Requirement.new(v)
- end
- end
- rescue => e
- raise GemspecError, "There was an error parsing the metadata for the gem #{name} (#{version}): #{e.class}\n#{e}\nThe metadata was #{data.inspect}"
- end
-
- def build_dependency(name, requirements)
- Gem::Dependency.new(name, requirements)
- rescue ArgumentError => e
- raise unless e.message.include?(ILLFORMED_MESSAGE)
- puts # we shouldn't print the error message on the "fetching info" status line
- raise GemspecError,
- "Unfortunately, the gem #{name} (#{version}) has an invalid " \
- "gemspec.\nPlease ask the gem author to yank the bad version to fix " \
- "this issue. For more information, see http://bit.ly/syck-defaultkey."
- end
- end
-end
diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb
deleted file mode 100644
index 58fe20dbe7..0000000000
--- a/lib/bundler/env.rb
+++ /dev/null
@@ -1,153 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/rubygems_integration"
-require "bundler/source/git/git_proxy"
-
-module Bundler
- class Env
- def self.write(io)
- io.write report
- end
-
- def self.report(options = {})
- print_gemfile = options.delete(:print_gemfile) { true }
- print_gemspecs = options.delete(:print_gemspecs) { true }
-
- out = String.new
- append_formatted_table("Environment", environment, out)
- append_formatted_table("Bundler Build Metadata", BuildMetadata.to_h, out)
-
- unless Bundler.settings.all.empty?
- out << "\n## Bundler settings\n\n```\n"
- Bundler.settings.all.each do |setting|
- out << setting << "\n"
- Bundler.settings.pretty_values_for(setting).each do |line|
- out << " " << line << "\n"
- end
- end
- out << "```\n"
- end
-
- return out unless SharedHelpers.in_bundle?
-
- if print_gemfile
- gemfiles = [Bundler.default_gemfile]
- begin
- gemfiles = Bundler.definition.gemfiles
- rescue GemfileNotFound
- nil
- end
-
- out << "\n## Gemfile\n"
- gemfiles.each do |gemfile|
- out << "\n### #{Pathname.new(gemfile).relative_path_from(SharedHelpers.pwd)}\n\n"
- out << "```ruby\n" << read_file(gemfile).chomp << "\n```\n"
- end
-
- out << "\n### #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}\n\n"
- out << "```\n" << read_file(Bundler.default_lockfile).chomp << "\n```\n"
- end
-
- if print_gemspecs
- dsl = Dsl.new.tap {|d| d.eval_gemfile(Bundler.default_gemfile) }
- out << "\n## Gemspecs\n" unless dsl.gemspecs.empty?
- dsl.gemspecs.each do |gs|
- out << "\n### #{File.basename(gs.loaded_from)}"
- out << "\n\n```ruby\n" << read_file(gs.loaded_from).chomp << "\n```\n"
- end
- end
-
- out
- end
-
- def self.read_file(filename)
- File.read(filename.to_s).strip
- rescue Errno::ENOENT
- "<No #{filename} found>"
- rescue => e
- "#{e.class}: #{e.message}"
- end
-
- 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
- end
-
- def self.git_version
- Bundler::Source::Git::GitProxy.new(nil, nil, nil).full_version
- rescue Bundler::Source::Git::GitNotInstalledError
- "not installed"
- end
-
- def self.version_of(script)
- return "not installed" unless Bundler.which(script)
- `#{script} --version`
- end
-
- def self.chruby_version
- return "not installed" unless Bundler.which("chruby-exec")
- `chruby-exec -- chruby --version`.
- sub(/.*^chruby: (#{Gem::Version::VERSION_PATTERN}).*/m, '\1')
- end
-
- def self.environment
- out = []
-
- out << ["Bundler", Bundler::VERSION]
- out << [" Platforms", Gem.platforms.join(", ")]
- out << ["Ruby", ruby_version]
- out << [" Full Path", Gem.ruby]
- out << [" Config Dir", Pathname.new(Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE).dirname]
- out << ["RubyGems", Gem::VERSION]
- out << [" Gem Home", ENV.fetch("GEM_HOME") { Gem.dir }]
- out << [" Gem Path", ENV.fetch("GEM_PATH") { Gem.path.join(File::PATH_SEPARATOR) }]
- out << [" User Path", Gem.user_dir]
- out << [" Bin Dir", Gem.bindir]
- out << ["OpenSSL"] if defined?(OpenSSL)
- out << [" Compiled", OpenSSL::OPENSSL_VERSION] if defined?(OpenSSL::OPENSSL_VERSION)
- out << [" Loaded", OpenSSL::OPENSSL_LIBRARY_VERSION] if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION)
- out << [" Cert File", OpenSSL::X509::DEFAULT_CERT_FILE] if defined?(OpenSSL::X509::DEFAULT_CERT_FILE)
- out << [" Cert Dir", OpenSSL::X509::DEFAULT_CERT_DIR] if defined?(OpenSSL::X509::DEFAULT_CERT_DIR)
- out << ["Tools"]
- out << [" Git", git_version]
- out << [" RVM", ENV.fetch("rvm_version") { version_of("rvm") }]
- out << [" rbenv", version_of("rbenv")]
- out << [" chruby", chruby_version]
-
- %w[rubygems-bundler open_gem].each do |name|
- specs = Bundler.rubygems.find_name(name)
- out << [" #{name}", "(#{specs.map(&:version).join(",")})"] unless specs.empty?
- end
- if (exe = caller.last.split(":").first) && exe =~ %r{(exe|bin)/bundler?\z}
- shebang = File.read(exe).lines.first
- shebang.sub!(/^#!\s*/, "")
- unless shebang.start_with?(Gem.ruby, "/usr/bin/env ruby")
- out << ["Gem.ruby", Gem.ruby]
- out << ["bundle #!", shebang]
- end
- end
-
- out
- end
-
- def self.append_formatted_table(title, pairs, out)
- return if pairs.empty?
- out << "\n" unless out.empty?
- out << "## #{title}\n\n```\n"
- ljust = pairs.map {|k, _v| k.to_s.length }.max
- pairs.each do |k, v|
- out << "#{k.to_s.ljust(ljust)} #{v}\n"
- end
- out << "```\n"
- end
-
- private_class_method :read_file, :ruby_version, :git_version, :append_formatted_table, :version_of, :chruby_version
- end
-end
diff --git a/lib/bundler/environment_preserver.rb b/lib/bundler/environment_preserver.rb
deleted file mode 100644
index af7c1ef0a4..0000000000
--- a/lib/bundler/environment_preserver.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class EnvironmentPreserver
- INTENTIONALLY_NIL = "BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL".freeze
- BUNDLER_KEYS = %w[
- BUNDLE_BIN_PATH
- BUNDLE_GEMFILE
- BUNDLER_ORIG_MANPATH
- BUNDLER_VERSION
- GEM_HOME
- GEM_PATH
- MANPATH
- PATH
- RB_USER_INSTALL
- RUBYLIB
- RUBYOPT
- ].map(&:freeze).freeze
- BUNDLER_PREFIX = "BUNDLER_ORIG_".freeze
-
- # @param env [ENV]
- # @param keys [Array<String>]
- def initialize(env, keys)
- @original = env.to_hash
- @keys = keys
- @prefix = BUNDLER_PREFIX
- end
-
- # @return [Hash]
- def backup
- env = @original.clone
- @keys.each do |key|
- value = env[key]
- if !value.nil? && !value.empty?
- env[@prefix + key] ||= value
- elsif value.nil?
- env[@prefix + key] ||= INTENTIONALLY_NIL
- end
- end
- env
- end
-
- # @return [Hash]
- def restore
- env = @original.clone
- @keys.each do |key|
- value_original = env[@prefix + key]
- next if value_original.nil? || value_original.empty?
- if value_original == INTENTIONALLY_NIL
- env.delete(key)
- else
- env[key] = value_original
- end
- env.delete(@prefix + key)
- end
- env
- end
- end
-end
diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb
deleted file mode 100644
index e471bce0b6..0000000000
--- a/lib/bundler/errors.rb
+++ /dev/null
@@ -1,158 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class BundlerError < StandardError
- def self.status_code(code)
- define_method(:status_code) { code }
- if match = BundlerError.all_errors.find {|_k, v| v == code }
- error, _ = match
- raise ArgumentError,
- "Trying to register #{self} for status code #{code} but #{error} is already registered"
- end
- BundlerError.all_errors[self] = code
- end
-
- def self.all_errors
- @all_errors ||= {}
- end
- end
-
- class GemfileError < BundlerError; status_code(4); end
- class InstallError < BundlerError; status_code(5); end
-
- # Internal error, should be rescued
- class VersionConflict < BundlerError
- attr_reader :conflicts
-
- def initialize(conflicts, msg = nil)
- super(msg)
- @conflicts = conflicts
- end
-
- status_code(6)
- end
-
- class GemNotFound < BundlerError; status_code(7); end
- class InstallHookError < BundlerError; status_code(8); end
- class GemfileNotFound < BundlerError; status_code(10); end
- class GitError < BundlerError; status_code(11); end
- class DeprecatedError < BundlerError; status_code(12); end
- class PathError < BundlerError; status_code(13); end
- class GemspecError < BundlerError; status_code(14); end
- class InvalidOption < BundlerError; status_code(15); end
- class ProductionError < BundlerError; status_code(16); end
- class HTTPError < BundlerError
- status_code(17)
- def filter_uri(uri)
- URICredentialsFilter.credential_filtered_uri(uri)
- end
- end
- class RubyVersionMismatch < BundlerError; status_code(18); end
- class SecurityError < BundlerError; status_code(19); end
- class LockfileError < BundlerError; status_code(20); end
- class CyclicDependencyError < BundlerError; status_code(21); end
- class GemfileLockNotFound < BundlerError; status_code(22); end
- class PluginError < BundlerError; status_code(29); end
- class SudoNotPermittedError < BundlerError; status_code(30); end
- class ThreadCreationError < BundlerError; status_code(33); end
- class APIResponseMismatchError < BundlerError; status_code(34); end
- class GemfileEvalError < GemfileError; end
- class MarshalError < StandardError; end
-
- class PermissionError < BundlerError
- def initialize(path, permission_type = :write)
- @path = path
- @permission_type = permission_type
- end
-
- def action
- case @permission_type
- when :read then "read from"
- when :write then "write to"
- when :executable, :exec then "execute"
- else @permission_type.to_s
- end
- end
-
- def message
- "There was an error while trying to #{action} `#{@path}`. " \
- "It is likely that you need to grant #{@permission_type} permissions " \
- "for that path."
- end
-
- status_code(23)
- end
-
- class GemRequireError < BundlerError
- attr_reader :orig_exception
-
- def initialize(orig_exception, msg)
- full_message = msg + "\nGem Load Error is: #{orig_exception.message}\n"\
- "Backtrace for gem load error is:\n"\
- "#{orig_exception.backtrace.join("\n")}\n"\
- "Bundler Error Backtrace:\n"
- super(full_message)
- @orig_exception = orig_exception
- end
-
- status_code(24)
- end
-
- class YamlSyntaxError < BundlerError
- attr_reader :orig_exception
-
- def initialize(orig_exception, msg)
- super(msg)
- @orig_exception = orig_exception
- end
-
- status_code(25)
- end
-
- class TemporaryResourceError < PermissionError
- def message
- "There was an error while trying to #{action} `#{@path}`. " \
- "Some resource was temporarily unavailable. It's suggested that you try" \
- "the operation again."
- end
-
- status_code(26)
- end
-
- class VirtualProtocolError < BundlerError
- def message
- "There was an error relating to virtualization and file access." \
- "It is likely that you need to grant access to or mount some file system correctly."
- end
-
- status_code(27)
- end
-
- class OperationNotSupportedError < PermissionError
- def message
- "Attempting to #{action} `#{@path}` is unsupported by your OS."
- end
-
- status_code(28)
- end
-
- class NoSpaceOnDeviceError < PermissionError
- def message
- "There was an error while trying to #{action} `#{@path}`. " \
- "There was insufficient space remaining on the device."
- end
-
- status_code(31)
- end
-
- class GenericSystemCallError < BundlerError
- attr_reader :underlying_error
-
- def initialize(underlying_error, message)
- @underlying_error = underlying_error
- super("#{message}\nThe underlying system error is #{@underlying_error.class}: #{@underlying_error}")
- end
-
- status_code(32)
- end
-end
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
deleted file mode 100644
index 6a1809cd40..0000000000
--- a/lib/bundler/feature_flag.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class FeatureFlag
- def self.settings_flag(flag, &default)
- unless Bundler::Settings::BOOL_KEYS.include?(flag.to_s)
- raise "Cannot use `#{flag}` as a settings feature flag since it isn't a bool key"
- end
-
- settings_method("#{flag}?", flag, &default)
- end
- private_class_method :settings_flag
-
- def self.settings_option(key, &default)
- settings_method(key, key, &default)
- end
- private_class_method :settings_option
-
- 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
- end
- end
- private_class_method :settings_method
-
- (1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } }
-
- settings_flag(:allow_bundler_dependency_conflicts) { bundler_2_mode? }
- settings_flag(:allow_offline_install) { bundler_2_mode? }
- settings_flag(:auto_clean_without_path) { bundler_2_mode? }
- settings_flag(:cache_all) { bundler_2_mode? }
- settings_flag(:cache_command_is_package) { bundler_2_mode? }
- settings_flag(:console_command) { !bundler_2_mode? }
- settings_flag(:default_install_uses_path) { bundler_2_mode? }
- settings_flag(:deployment_means_frozen) { bundler_2_mode? }
- settings_flag(:disable_multisource) { bundler_2_mode? }
- settings_flag(:error_on_stderr) { bundler_2_mode? }
- settings_flag(:forget_cli_options) { bundler_2_mode? }
- settings_flag(:global_gem_cache) { bundler_2_mode? }
- settings_flag(:init_gems_rb) { bundler_2_mode? }
- settings_flag(:list_command) { bundler_2_mode? }
- settings_flag(:lockfile_uses_separate_rubygems_sources) { bundler_2_mode? }
- settings_flag(:only_update_to_newer_versions) { bundler_2_mode? }
- settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
- settings_flag(:prefer_gems_rb) { bundler_2_mode? }
- settings_flag(:print_only_version_number) { bundler_2_mode? }
- settings_flag(:setup_makes_kernel_gem_public) { !bundler_2_mode? }
- settings_flag(:skip_default_git_sources) { bundler_2_mode? }
- settings_flag(:specific_platform) { bundler_2_mode? }
- settings_flag(:suppress_install_using_messages) { bundler_2_mode? }
- settings_flag(:unlock_source_unlocks_spec) { !bundler_2_mode? }
- settings_flag(:update_requires_all_flag) { bundler_2_mode? }
-
- settings_option(:default_cli_command) { bundler_2_mode? ? :cli_help : :install }
-
- def initialize(bundler_version)
- @bundler_version = Gem::Version.create(bundler_version)
- end
-
- def major_version
- @bundler_version.segments.first
- end
- private :major_version
- end
-end
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb
deleted file mode 100644
index 03ff528826..0000000000
--- a/lib/bundler/fetcher.rb
+++ /dev/null
@@ -1,312 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/vendored_persistent"
-require "cgi"
-require "securerandom"
-require "zlib"
-
-module Bundler
- # Handles all the fetching with the rubygems server
- class Fetcher
- autoload :CompactIndex, "bundler/fetcher/compact_index"
- autoload :Downloader, "bundler/fetcher/downloader"
- autoload :Dependency, "bundler/fetcher/dependency"
- autoload :Index, "bundler/fetcher/index"
-
- # This error is raised when it looks like the network is down
- class NetworkDownError < 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
- class CertificateFailureError < HTTPError
- def initialize(remote_uri)
- remote_uri = filter_uri(remote_uri)
- super "Could not verify the SSL certificate for #{remote_uri}.\nThere" \
- " is a chance you are experiencing a man-in-the-middle attack, but" \
- " most likely your system doesn't have the CA certificates needed" \
- " for verification. For information about OpenSSL certificates, see" \
- " http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile" \
- " sources and change 'https' to 'http'."
- end
- end
- # This is the error raised when a source is HTTPS and OpenSSL didn't load
- class SSLError < HTTPError
- def initialize(msg = nil)
- super msg || "Could not load OpenSSL.\n" \
- "You must recompile Ruby with OpenSSL support or change the sources in your " \
- "Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL " \
- "using RVM are available at rvm.io/packages/openssl."
- end
- end
- # This error is raised if HTTP authentication is required, but not provided.
- class AuthenticationRequiredError < HTTPError
- def initialize(remote_uri)
- 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"
- end
- end
- # This error is raised if HTTP authentication is provided, but incorrect.
- class BadAuthenticationError < HTTPError
- def initialize(remote_uri)
- remote_uri = filter_uri(remote_uri)
- super "Bad username or password for #{remote_uri}.\n" \
- "Please double-check your credentials and correct them."
- end
- end
-
- # Exceptions classes that should bypass retry attempts. If your password didn't work the
- # first time, it's not going to the third time.
- NET_ERRORS = [:HTTPBadGateway, :HTTPBadRequest, :HTTPFailedDependency,
- :HTTPForbidden, :HTTPInsufficientStorage, :HTTPMethodNotAllowed,
- :HTTPMovedPermanently, :HTTPNoContent, :HTTPNotFound,
- :HTTPNotImplemented, :HTTPPreconditionFailed, :HTTPRequestEntityTooLarge,
- :HTTPRequestURITooLong, :HTTPUnauthorized, :HTTPUnprocessableEntity,
- :HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze
- FAIL_ERRORS = begin
- fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError]
- fail_errors << Gem::Requirement::BadRequirementError if defined?(Gem::Requirement::BadRequirementError)
- fail_errors.concat(NET_ERRORS.map {|e| SharedHelpers.const_get_safely(e, Net) }.compact)
- end.freeze
-
- class << self
- attr_accessor :disable_endpoint, :api_timeout, :redirect_limit, :max_retries
- end
-
- self.redirect_limit = Bundler.settings[:redirect] # How many redirects to allow in one request
- self.api_timeout = Bundler.settings[:timeout] # How long to wait for each API call
- self.max_retries = Bundler.settings[:retry] # How many retries for the API call
-
- def initialize(remote)
- @remote = remote
-
- Socket.do_not_reverse_lookup = true
- connection # create persistent connection
- end
-
- def uri
- @remote.anonymized_uri
- end
-
- # fetch a gem specification
- def fetch_spec(spec)
- spec -= [nil, "ruby", ""]
- spec_file_name = "#{spec.join "-"}.gemspec"
-
- uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
- if uri.scheme == "file"
- Bundler.load_marshal Gem.inflate(Gem.read_binary(uri.path))
- elsif cached_spec_path = gemspec_cached_path(spec_file_name)
- Bundler.load_gemspec(cached_spec_path)
- else
- Bundler.load_marshal Gem.inflate(downloader.fetch(uri).body)
- end
- rescue MarshalError
- raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
- "Your network or your gem server is probably having issues right now."
- end
-
- # return the specs in the bundler format as an index with retries
- def specs_with_retry(gem_names, source)
- Bundler::Retry.new("fetcher", FAIL_ERRORS).attempts do
- specs(gem_names, source)
- end
- end
-
- # return the specs in the bundler format as an index
- def specs(gem_names, source)
- old = Bundler.rubygems.sources
- index = Bundler::Index.new
-
- if Bundler::Fetcher.disable_endpoint
- @use_api = false
- specs = fetchers.last.specs(gem_names)
- else
- specs = []
- fetchers.shift until fetchers.first.available? || fetchers.empty?
- fetchers.dup.each do |f|
- break unless f.api_fetcher? && !gem_names || !specs = f.specs(gem_names)
- fetchers.delete(f)
- end
- @use_api = false if fetchers.none?(&:api_fetcher?)
- end
-
- specs.each do |name, version, platform, dependencies, metadata|
- next if name == "bundler"
- spec = if dependencies
- EndpointSpecification.new(name, version, platform, dependencies, metadata)
- else
- RemoteSpecification.new(name, version, platform, self)
- end
- spec.source = source
- spec.remote = @remote
- index << spec
- end
-
- index
- rescue CertificateFailureError
- Bundler.ui.info "" if gem_names && use_api # newline after dots
- raise
- ensure
- Bundler.rubygems.sources = old
- end
-
- def use_api
- return @use_api if defined?(@use_api)
-
- fetchers.shift until fetchers.first.available?
-
- @use_api = if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
- false
- else
- fetchers.first.api_fetcher?
- end
- end
-
- def user_agent
- @user_agent ||= begin
- ruby = Bundler::RubyVersion.system
-
- agent = String.new("bundler/#{Bundler::VERSION}")
- agent << " rubygems/#{Gem::VERSION}"
- agent << " ruby/#{ruby.versions_string(ruby.versions)}"
- agent << " (#{ruby.host})"
- agent << " command/#{ARGV.first}"
-
- if ruby.engine != "ruby"
- # engine_version raises on unknown engines
- engine_version = begin
- ruby.engine_versions
- rescue
- "???"
- end
- agent << " #{ruby.engine}/#{ruby.versions_string(engine_version)}"
- end
-
- agent << " options/#{Bundler.settings.all.join(",")}"
-
- agent << " ci/#{cis.join(",")}" if cis.any?
-
- # add a random ID so we can consolidate runs server-side
- agent << " " << SecureRandom.hex(8)
-
- # add any user agent strings set in the config
- extra_ua = Bundler.settings[:user_agent]
- agent << " " << extra_ua if extra_ua
-
- agent
- end
- end
-
- def fetchers
- @fetchers ||= FETCHERS.map {|f| f.new(downloader, @remote, uri) }
- end
-
- def http_proxy
- return unless uri = connection.proxy_uri
- uri.to_s
- end
-
- def inspect
- "#<#{self.class}:0x#{object_id} uri=#{uri}>"
- end
-
- private
-
- FETCHERS = [CompactIndex, Dependency, Index].freeze
-
- def cis
- env_cis = {
- "TRAVIS" => "travis",
- "CIRCLECI" => "circle",
- "SEMAPHORE" => "semaphore",
- "JENKINS_URL" => "jenkins",
- "BUILDBOX" => "buildbox",
- "GO_SERVER_URL" => "go",
- "SNAP_CI" => "snap",
- "CI_NAME" => ENV["CI_NAME"],
- "CI" => "ci"
- }
- env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci }
- end
-
- def connection
- @connection ||= begin
- needs_ssl = remote_uri.scheme == "https" ||
- Bundler.settings[:ssl_verify_mode] ||
- Bundler.settings[:ssl_client_cert]
- raise SSLError if needs_ssl && !defined?(OpenSSL::SSL)
-
- con = PersistentHTTP.new "bundler", :ENV
- if gem_proxy = Bundler.rubygems.configuration[:http_proxy]
- con.proxy = URI.parse(gem_proxy) if gem_proxy != :no_proxy
- end
-
- if remote_uri.scheme == "https"
- con.verify_mode = (Bundler.settings[:ssl_verify_mode] ||
- OpenSSL::SSL::VERIFY_PEER)
- con.cert_store = bundler_cert_store
- end
-
- ssl_client_cert = Bundler.settings[:ssl_client_cert] ||
- (Bundler.rubygems.configuration.ssl_client_cert if
- Bundler.rubygems.configuration.respond_to?(:ssl_client_cert))
- if ssl_client_cert
- pem = File.read(ssl_client_cert)
- con.cert = OpenSSL::X509::Certificate.new(pem)
- con.key = OpenSSL::PKey::RSA.new(pem)
- end
-
- con.read_timeout = Fetcher.api_timeout
- con.open_timeout = Fetcher.api_timeout
- con.override_headers["User-Agent"] = user_agent
- con.override_headers["X-Gemfile-Source"] = @remote.original_uri.to_s if @remote.original_uri
- con
- end
- end
-
- # cached gem specification path, if one exists
- def gemspec_cached_path(spec_file_name)
- paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
- paths = paths.select {|path| File.file? path }
- paths.first
- end
-
- HTTP_ERRORS = [
- Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
- Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
- Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
- PersistentHTTP::Error, Zlib::BufError, Errno::EHOSTUNREACH
- ].freeze
-
- def bundler_cert_store
- store = OpenSSL::X509::Store.new
- ssl_ca_cert = Bundler.settings[:ssl_ca_cert] ||
- (Bundler.rubygems.configuration.ssl_ca_cert if
- Bundler.rubygems.configuration.respond_to?(:ssl_ca_cert))
- if ssl_ca_cert
- if File.directory? ssl_ca_cert
- store.add_path ssl_ca_cert
- else
- store.add_file ssl_ca_cert
- end
- else
- store.set_default_paths
- certs = File.expand_path("../ssl_certs/*/*.pem", __FILE__)
- Dir.glob(certs).each {|c| store.add_file c }
- end
- store
- end
-
- private
-
- def remote_uri
- @remote.uri
- end
-
- def downloader
- @downloader ||= Downloader.new(connection, self.class.redirect_limit)
- end
- end
-end
diff --git a/lib/bundler/fetcher/base.rb b/lib/bundler/fetcher/base.rb
deleted file mode 100644
index 27987f670a..0000000000
--- a/lib/bundler/fetcher/base.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Fetcher
- class Base
- attr_reader :downloader
- attr_reader :display_uri
- attr_reader :remote
-
- def initialize(downloader, remote, display_uri)
- raise "Abstract class" if self.class == Base
- @downloader = downloader
- @remote = remote
- @display_uri = display_uri
- end
-
- def remote_uri
- @remote.uri
- end
-
- def fetch_uri
- @fetch_uri ||= begin
- if remote_uri.host == "rubygems.org"
- uri = remote_uri.dup
- uri.host = "index.rubygems.org"
- uri
- else
- remote_uri
- end
- end
- end
-
- def available?
- true
- end
-
- def api_fetcher?
- false
- end
-
- private
-
- def log_specs(debug_msg)
- if Bundler.ui.debug?
- Bundler.ui.debug debug_msg
- else
- Bundler.ui.info ".", false
- end
- end
- end
- end
-end
diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb
deleted file mode 100644
index cfc74d642c..0000000000
--- a/lib/bundler/fetcher/compact_index.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/fetcher/base"
-require "bundler/worker"
-
-module Bundler
- autoload :CompactIndexClient, "bundler/compact_index_client"
-
- class Fetcher
- class CompactIndex < Base
- def self.compact_index_request(method_name)
- method = instance_method(method_name)
- undef_method(method_name)
- define_method(method_name) do |*args, &blk|
- begin
- method.bind(self).call(*args, &blk)
- rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
- raise HTTPError, e.message
- rescue AuthenticationRequiredError
- # Fail since we got a 401 from the server.
- raise
- rescue HTTPError => e
- Bundler.ui.trace(e)
- nil
- end
- end
- end
-
- def specs(gem_names)
- specs_for_names(gem_names)
- end
- compact_index_request :specs
-
- def specs_for_names(gem_names)
- gem_info = []
- complete_gems = []
- remaining_gems = gem_names.dup
-
- until remaining_gems.empty?
- log_specs "Looking up gems #{remaining_gems.inspect}"
-
- deps = compact_index_client.dependencies(remaining_gems)
- 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!
- remaining_gems = next_gems - complete_gems
- end
- @bundle_worker.stop if @bundle_worker
- @bundle_worker = nil # reset it. Not sure if necessary
-
- gem_info
- end
-
- def fetch_spec(spec)
- spec -= [nil, "ruby", ""]
- contents = compact_index_client.spec(*spec)
- return nil if contents.nil?
- contents.unshift(spec.first)
- contents[3].map! {|d| Gem::Dependency.new(*d) }
- EndpointSpecification.new(*contents)
- end
- compact_index_request :fetch_spec
-
- def available?
- return nil unless SharedHelpers.md5_available?
- user_home = Bundler.user_home
- return nil unless user_home.directory? && user_home.writable?
- # Read info file checksums out of /versions, so we can know if gems are up to date
- fetch_uri.scheme != "file" && compact_index_client.update_and_parse_checksums!
- rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
- Bundler.ui.debug(e.message)
- nil
- end
- compact_index_request :available?
-
- def api_fetcher?
- true
- end
-
- private
-
- def compact_index_client
- @compact_index_client ||= begin
- 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
- end
-
- def bundle_worker(func = nil)
- @bundle_worker ||= begin
- worker_name = "Compact Index (#{display_uri.host})"
- Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)
- end
- @bundle_worker.tap do |worker|
- worker.instance_variable_set(:@func, func) if func
- end
- end
-
- def cache_path
- Bundler.user_cache.join("compact_index", remote.cache_slug)
- end
-
- def client_fetcher
- ClientFetcher.new(self, Bundler.ui)
- end
-
- ClientFetcher = Struct.new(:fetcher, :ui) do
- def call(path, headers)
- fetcher.downloader.fetch(fetcher.fetch_uri + path, headers)
- rescue NetworkDownError => e
- raise unless Bundler.feature_flag.allow_offline_install? && headers["If-None-Match"]
- ui.warn "Using the cached data for the new index because of a network error: #{e}"
- Net::HTTPNotModified.new(nil, nil, nil)
- end
- end
- end
- end
-end
diff --git a/lib/bundler/fetcher/dependency.rb b/lib/bundler/fetcher/dependency.rb
deleted file mode 100644
index 1430d1ebeb..0000000000
--- a/lib/bundler/fetcher/dependency.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/fetcher/base"
-require "cgi"
-
-module Bundler
- class Fetcher
- class Dependency < Base
- def available?
- @available ||= fetch_uri.scheme != "file" && downloader.fetch(dependency_api_uri)
- rescue NetworkDownError => e
- raise HTTPError, e.message
- rescue AuthenticationRequiredError
- # Fail since we got a 401 from the server.
- raise
- rescue HTTPError
- false
- end
-
- def api_fetcher?
- true
- end
-
- def specs(gem_names, full_dependency_list = [], last_spec_list = [])
- query_list = gem_names.uniq - full_dependency_list
-
- log_specs "Query List: #{query_list.inspect}"
-
- return last_spec_list if query_list.empty?
-
- spec_list, deps_list = Bundler::Retry.new("dependency api", FAIL_ERRORS).attempts do
- dependency_specs(query_list)
- end
-
- returned_gems = spec_list.map(&:first).uniq
- specs(deps_list, full_dependency_list + returned_gems, spec_list + last_spec_list)
- rescue MarshalError
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- Bundler.ui.debug "could not fetch from the dependency API, trying the full index"
- nil
- rescue HTTPError, GemspecError
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- Bundler.ui.debug "could not fetch from the dependency API\nit's suggested to retry using the full index via `bundle install --full-index`"
- nil
- end
-
- def dependency_specs(gem_names)
- Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(",")}"
-
- gem_list = unmarshalled_dep_gems(gem_names)
- get_formatted_specs_and_deps(gem_list)
- end
-
- def unmarshalled_dep_gems(gem_names)
- gem_list = []
- gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names|
- marshalled_deps = downloader.fetch(dependency_api_uri(names)).body
- gem_list.concat(Bundler.load_marshal(marshalled_deps))
- end
- gem_list
- end
-
- def get_formatted_specs_and_deps(gem_list)
- deps_list = []
- spec_list = []
-
- gem_list.each do |s|
- deps_list.concat(s[:dependencies].map(&:first))
- deps = s[:dependencies].map {|n, d| [n, d.split(", ")] }
- spec_list.push([s[:name], s[:number], s[:platform], deps])
- end
- [spec_list, deps_list]
- end
-
- def dependency_api_uri(gem_names = [])
- uri = fetch_uri + "api/v1/dependencies"
- uri.query = "gems=#{CGI.escape(gem_names.sort.join(","))}" if gem_names.any?
- uri
- end
- end
- end
-end
diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb
deleted file mode 100644
index cbc5e220bd..0000000000
--- a/lib/bundler/fetcher/downloader.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Fetcher
- class Downloader
- attr_reader :connection
- attr_reader :redirect_limit
-
- def initialize(connection, redirect_limit)
- @connection = connection
- @redirect_limit = redirect_limit
- end
-
- def fetch(uri, options = {}, counter = 0)
- raise HTTPError, "Too many redirects" if counter >= redirect_limit
-
- response = request(uri, options)
- Bundler.ui.debug("HTTP #{response.code} #{response.message} #{uri}")
-
- case response
- when Net::HTTPSuccess, Net::HTTPNotModified
- response
- when Net::HTTPRedirection
- new_uri = URI.parse(response["location"])
- if new_uri.host == uri.host
- new_uri.user = uri.user
- new_uri.password = uri.password
- end
- fetch(new_uri, options, counter + 1)
- when Net::HTTPRequestEntityTooLarge
- raise FallbackError, response.body
- when Net::HTTPUnauthorized
- raise AuthenticationRequiredError, uri.host
- when Net::HTTPNotFound
- raise FallbackError, "Net::HTTPNotFound"
- else
- raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
- end
- end
-
- def request(uri, options)
- validate_uri_scheme!(uri)
-
- Bundler.ui.debug "HTTP GET #{uri}"
- req = Net::HTTP::Get.new uri.request_uri, options
- if uri.user
- user = CGI.unescape(uri.user)
- password = uri.password ? CGI.unescape(uri.password) : nil
- req.basic_auth(user, password)
- end
- connection.request(uri, req)
- rescue NoMethodError => e
- raise unless ["undefined method", "use_ssl="].all? {|snippet| e.message.include? snippet }
- raise LoadError.new("cannot load such file -- openssl")
- rescue OpenSSL::SSL::SSLError
- raise CertificateFailureError.new(uri)
- rescue *HTTP_ERRORS => e
- Bundler.ui.trace e
- case e.message
- when /host down:/, /getaddrinfo: nodename nor servname provided/
- raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \
- "connection and try again."
- else
- raise HTTPError, "Network error while fetching #{URICredentialsFilter.credential_filtered_uri(uri)}" \
- " (#{e})"
- end
- end
-
- private
-
- def validate_uri_scheme!(uri)
- return if uri.scheme =~ /\Ahttps?\z/
- raise InvalidOption,
- "The request uri `#{uri}` has an invalid scheme (`#{uri.scheme}`). " \
- "Did you mean `http` or `https`?"
- end
- end
- end
-end
diff --git a/lib/bundler/fetcher/index.rb b/lib/bundler/fetcher/index.rb
deleted file mode 100644
index 9529944391..0000000000
--- a/lib/bundler/fetcher/index.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/fetcher/base"
-require "rubygems/remote_fetcher"
-
-module Bundler
- class Fetcher
- class Index < Base
- def specs(_gem_names)
- Bundler.rubygems.fetch_all_remote_specs(remote)
- rescue Gem::RemoteFetcher::FetchError, OpenSSL::SSL::SSLError, Net::HTTPFatalError => e
- case e.message
- when /certificate verify failed/
- raise CertificateFailureError.new(display_uri)
- when /401/
- raise AuthenticationRequiredError, remote_uri
- when /403/
- raise BadAuthenticationError, remote_uri if remote_uri.userinfo
- raise AuthenticationRequiredError, remote_uri
- else
- Bundler.ui.trace e
- raise HTTPError, "Could not fetch specs from #{display_uri}"
- end
- end
-
- def fetch_spec(spec)
- spec -= [nil, "ruby", ""]
- spec_file_name = "#{spec.join "-"}.gemspec"
-
- uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
- if uri.scheme == "file"
- Bundler.load_marshal Gem.inflate(Gem.read_binary(uri.path))
- elsif cached_spec_path = gemspec_cached_path(spec_file_name)
- Bundler.load_gemspec(cached_spec_path)
- else
- Bundler.load_marshal Gem.inflate(downloader.fetch(uri).body)
- end
- rescue MarshalError
- raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
- "Your network or your gem server is probably having issues right now."
- end
-
- private
-
- # cached gem specification path, if one exists
- def gemspec_cached_path(spec_file_name)
- paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
- paths.find {|path| File.file? path }
- end
- end
- end
-end
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
deleted file mode 100644
index f624185773..0000000000
--- a/lib/bundler/friendly_errors.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-# encoding: utf-8
-# frozen_string_literal: true
-
-require "cgi"
-require "bundler/vendored_thor"
-
-module Bundler
- module FriendlyErrors
- module_function
-
- def log_error(error)
- case error
- when YamlSyntaxError
- Bundler.ui.error error.message
- Bundler.ui.trace error.orig_exception
- when Dsl::DSLError, GemspecError
- Bundler.ui.error error.message
- when GemRequireError
- Bundler.ui.error error.message
- Bundler.ui.trace error.orig_exception, nil, true
- when BundlerError
- Bundler.ui.error error.message, :wrap => true
- Bundler.ui.trace error
- when Thor::Error
- Bundler.ui.error error.message
- when LoadError
- raise error unless error.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/
- Bundler.ui.error "\nCould not load OpenSSL."
- Bundler.ui.warn <<-WARN, :wrap => true
- You must recompile Ruby with OpenSSL support or change the sources in your \
- Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL \
- using RVM are available at http://rvm.io/packages/openssl.
- WARN
- Bundler.ui.trace error
- when Interrupt
- Bundler.ui.error "\nQuitting..."
- Bundler.ui.trace error
- when Gem::InvalidSpecificationException
- Bundler.ui.error error.message, :wrap => true
- when SystemExit
- when *[defined?(Java::JavaLang::OutOfMemoryError) && Java::JavaLang::OutOfMemoryError].compact
- Bundler.ui.error "\nYour JVM has run out of memory, and Bundler cannot continue. " \
- "You can decrease the amount of memory Bundler needs by removing gems from your Gemfile, " \
- "especially large gems. (Gems can be as large as hundreds of megabytes, and Bundler has to read those files!). " \
- "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
- end
-
- def exit_status(error)
- case error
- when BundlerError then error.status_code
- when Thor::Error then 15
- when SystemExit then error.status
- else 1
- end
- end
-
- def request_issue_report_for(e)
- Bundler.ui.info <<-EOS.gsub(/^ {8}/, "")
- --- ERROR REPORT TEMPLATE -------------------------------------------------------
- # Error Report
-
- ## Questions
-
- Please fill out answers to these questions, it'll help us figure out
- why things are going wrong.
-
- - **What did you do?**
-
- I ran the command `#{$PROGRAM_NAME} #{ARGV.join(" ")}`
-
- - **What did you expect to happen?**
-
- I expected Bundler to...
-
- - **What happened instead?**
-
- Instead, what happened was...
-
- - **Have you tried any solutions posted on similar issues in our issue tracker, stack overflow, or google?**
-
- I tried...
-
- - **Have you read our issues document, https://github.com/bundler/bundler/blob/master/doc/contributing/ISSUES.md?**
-
- ...
-
- ## Backtrace
-
- ```
- #{e.class}: #{e.message}
- #{e.backtrace && e.backtrace.join("\n ").chomp}
- ```
-
- #{Bundler::Env.report}
- --- TEMPLATE END ----------------------------------------------------------------
-
- EOS
-
- Bundler.ui.error "Unfortunately, an unexpected error occurred, and Bundler cannot continue."
-
- Bundler.ui.warn <<-EOS.gsub(/^ {8}/, "")
-
- First, try this link to see if there are any existing issue reports for this error:
- #{issues_url(e)}
-
- If there aren't any reports for this error yet, please create copy and paste the report template above into a new issue. Don't forget to anonymize any private data! The new issue form is located at:
- https://github.com/bundler/bundler/issues/new
- EOS
- end
-
- def issues_url(exception)
- message = exception.message.lines.first.tr(":", " ").chomp
- message = message.split("-").first if exception.is_a?(Errno)
- "https://github.com/bundler/bundler/search?q=" \
- "#{CGI.escape(message)}&type=Issues"
- end
- end
-
- def self.with_friendly_errors
- yield
- rescue SignalException
- raise
- rescue Exception => e
- FriendlyErrors.log_error(e)
- exit FriendlyErrors.exit_status(e)
- end
-end
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb
deleted file mode 100644
index 1d7fc508d5..0000000000
--- a/lib/bundler/gem_helper.rb
+++ /dev/null
@@ -1,202 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/vendored_thor" unless defined?(Thor)
-require "bundler"
-
-module Bundler
- class GemHelper
- include Rake::DSL if defined? Rake::DSL
-
- class << self
- # set when install'd.
- attr_accessor :instance
-
- def install_tasks(opts = {})
- new(opts[:dir], opts[:name]).install
- end
-
- def gemspec(&block)
- gemspec = instance.gemspec
- block.call(gemspec) if block
- gemspec
- end
- end
-
- attr_reader :spec_path, :base, :gemspec
-
- def initialize(base = nil, name = nil)
- Bundler.ui = UI::Shell.new
- @base = (base ||= SharedHelpers.pwd)
- gemspecs = name ? [File.join(base, "#{name}.gemspec")] : Dir[File.join(base, "{,*}.gemspec")]
- raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1
- @spec_path = gemspecs.first
- @gemspec = Bundler.load_gemspec(@spec_path)
- end
-
- def install
- built_gem_path = nil
-
- desc "Build #{name}-#{version}.gem into the pkg directory."
- task "build" do
- built_gem_path = build_gem
- end
-
- desc "Build and install #{name}-#{version}.gem into system gems."
- task "install" => "build" do
- install_gem(built_gem_path)
- end
-
- desc "Build and install #{name}-#{version}.gem into system gems without network access."
- task "install:local" => "build" do
- install_gem(built_gem_path, :local)
- end
-
- desc "Create tag #{version_tag} and build and push #{name}-#{version}.gem to #{gem_push_host}\n" \
- "To prevent publishing in RubyGems use `gem_push=no rake release`"
- task "release", [:remote] => ["build", "release:guard_clean",
- "release:source_control_push", "release:rubygem_push"] do
- end
-
- task "release:guard_clean" do
- guard_clean
- end
-
- task "release:source_control_push", [:remote] do |_, args|
- tag_version { git_push(args[:remote]) } unless already_tagged?
- end
-
- task "release:rubygem_push" do
- rubygem_push(built_gem_path) if gem_push?
- end
-
- GemHelper.instance = self
- end
-
- def build_gem
- file_name = nil
- sh("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")
- Bundler.ui.confirm "#{name} #{version} built to pkg/#{file_name}."
- end
- File.join(base, "pkg", file_name)
- end
-
- def install_gem(built_gem_path = nil, local = false)
- built_gem_path ||= build_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/]
- 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
- 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
- sh(gem_command)
- Bundler.ui.confirm "Pushed #{name} #{version} to #{gem_push_host}"
- end
-
- def built_gem_path
- Dir[File.join(base, "#{name}-*.gem")].sort_by {|f| File.mtime(f) }.last
- end
-
- def git_push(remote = "")
- perform_git_push remote
- perform_git_push "#{remote} --tags"
- Bundler.ui.confirm "Pushed git commits and tags."
- end
-
- def allowed_push_host
- @gemspec.metadata["allowed_push_host"] if @gemspec.respond_to?(:metadata)
- end
-
- def gem_push_host
- env_rubygems_host = ENV["RUBYGEMS_HOST"]
- env_rubygems_host = nil if
- env_rubygems_host && env_rubygems_host.empty?
-
- allowed_push_host || env_rubygems_host || "rubygems.org"
- end
-
- 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
- end
-
- def already_tagged?
- return false unless sh("git tag").split(/\n/).include?(version_tag)
- Bundler.ui.confirm "Tag #{version_tag} has already been created."
- true
- end
-
- def guard_clean
- clean? && committed? || raise("There are files that need to be committed first.")
- end
-
- def clean?
- sh_with_code("git diff --exit-code")[1] == 0
- end
-
- def committed?
- sh_with_code("git diff-index --quiet --cached HEAD")[1] == 0
- end
-
- def tag_version
- sh "git tag -m \"Version #{version}\" #{version_tag}"
- Bundler.ui.confirm "Tagged #{version_tag}."
- yield if block_given?
- rescue
- Bundler.ui.error "Untagging #{version_tag} due to error."
- sh_with_code "git tag -d #{version_tag}"
- raise
- end
-
- def version
- gemspec.version
- end
-
- def version_tag
- "v#{version}"
- end
-
- def name
- gemspec.name
- end
-
- def sh(cmd, &block)
- out, code = sh_with_code(cmd, &block)
- unless code.zero?
- 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
- Bundler.ui.debug(cmd)
- SharedHelpers.chdir(base) do
- outbuf = `#{cmd}`
- status = $?.exitstatus
- block.call(outbuf) if status.zero? && block
- [outbuf, status]
- end
- end
-
- def gem_key
- Bundler.settings["gem.push_key"].to_s.downcase if Bundler.settings["gem.push_key"]
- end
-
- def gem_push?
- !%w[n no nil false off 0].include?(ENV["gem_push"].to_s.downcase)
- end
- end
-end
diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb
deleted file mode 100644
index 019ae10c66..0000000000
--- a/lib/bundler/gem_helpers.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module GemHelpers
- GENERIC_CACHE = {} # rubocop:disable MutableConstant
- GENERICS = [
- [Gem::Platform.new("java"), Gem::Platform.new("java")],
- [Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")],
- [Gem::Platform.new("mswin64"), Gem::Platform.new("mswin64")],
- [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")]
- ].freeze
-
- def generic(p)
- return p if p == Gem::Platform::RUBY
-
- GENERIC_CACHE[p] ||= begin
- _, found = GENERICS.find do |match, _generic|
- p.os == match.os && (!match.cpu || p.cpu == match.cpu)
- end
- found || Gem::Platform::RUBY
- end
- end
- module_function :generic
-
- def generic_local_platform
- generic(Bundler.local_platform)
- end
- module_function :generic_local_platform
-
- def platform_specificity_match(spec_platform, user_platform)
- spec_platform = Gem::Platform.new(spec_platform)
- return PlatformMatch::EXACT_MATCH if spec_platform == user_platform
- return PlatformMatch::WORST_MATCH if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
-
- PlatformMatch.new(
- PlatformMatch.os_match(spec_platform, user_platform),
- PlatformMatch.cpu_match(spec_platform, user_platform),
- PlatformMatch.platform_version_match(spec_platform, user_platform)
- )
- end
- module_function :platform_specificity_match
-
- def select_best_platform_match(specs, platform)
- specs.select {|spec| spec.match_platform(platform) }.
- min_by {|spec| platform_specificity_match(spec.platform, platform) }
- end
- module_function :select_best_platform_match
-
- PlatformMatch = Struct.new(:os_match, :cpu_match, :platform_version_match)
- class PlatformMatch
- def <=>(other)
- return nil unless other.is_a?(PlatformMatch)
-
- m = os_match <=> other.os_match
- return m unless m.zero?
-
- m = cpu_match <=> other.cpu_match
- return m unless m.zero?
-
- m = platform_version_match <=> other.platform_version_match
- m
- end
-
- EXACT_MATCH = new(-1, -1, -1).freeze
- WORST_MATCH = new(1_000_000, 1_000_000, 1_000_000).freeze
-
- def self.os_match(spec_platform, user_platform)
- if spec_platform.os == user_platform.os
- 0
- else
- 1
- end
- end
-
- def self.cpu_match(spec_platform, user_platform)
- if spec_platform.cpu == user_platform.cpu
- 0
- elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm")
- 0
- elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal"
- 1
- else
- 2
- end
- end
-
- def self.platform_version_match(spec_platform, user_platform)
- if spec_platform.version == user_platform.version
- 0
- elsif spec_platform.version.nil?
- 1
- else
- 2
- end
- end
- end
- end
-end
diff --git a/lib/bundler/gem_remote_fetcher.rb b/lib/bundler/gem_remote_fetcher.rb
deleted file mode 100644
index 9577535d63..0000000000
--- a/lib/bundler/gem_remote_fetcher.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-require "rubygems/remote_fetcher"
-
-module Bundler
- # Adds support for setting custom HTTP headers when fetching gems from the
- # server.
- #
- # TODO: Get rid of this when and if gemstash only supports RubyGems versions
- # that contain https://github.com/rubygems/rubygems/commit/3db265cc20b2f813.
- class GemRemoteFetcher < Gem::RemoteFetcher
- attr_accessor :headers
-
- # Extracted from RubyGems 2.4.
- def fetch_http(uri, last_modified = nil, head = false, depth = 0)
- fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
- # beginning of change
- response = request uri, fetch_type, last_modified do |req|
- headers.each {|k, v| req.add_field(k, v) } if headers
- end
- # end of change
-
- case response
- when Net::HTTPOK, Net::HTTPNotModified then
- response.uri = uri if response.respond_to? :uri
- head ? response : response.body
- when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
- Net::HTTPTemporaryRedirect then
- raise FetchError.new("too many redirects", uri) if depth > 10
-
- location = URI.parse response["Location"]
-
- if https?(uri) && !https?(location)
- raise FetchError.new("redirecting to non-https resource: #{location}", uri)
- end
-
- fetch_http(location, last_modified, head, depth + 1)
- else
- raise FetchError.new("bad response #{response.message} #{response.code}", uri)
- end
- end
- end
-end
diff --git a/lib/bundler/gem_tasks.rb b/lib/bundler/gem_tasks.rb
deleted file mode 100644
index f736517bd7..0000000000
--- a/lib/bundler/gem_tasks.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-require "rake/clean"
-CLOBBER.include "pkg"
-
-require "bundler/gem_helper"
-Bundler::GemHelper.install_tasks
diff --git a/lib/bundler/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb
deleted file mode 100644
index 52b5386045..0000000000
--- a/lib/bundler/gem_version_promoter.rb
+++ /dev/null
@@ -1,176 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # This class contains all of the logic for determining the next version of a
- # Gem to update to based on the requested level (patch, minor, major).
- # Primarily designed to work with Resolver which will provide it the list of
- # available dependency versions as found in its index, before returning it to
- # to the resolution engine to select the best version.
- class GemVersionPromoter
- attr_reader :level, :locked_specs, :unlock_gems
-
- # By default, strict is false, meaning every available version of a gem
- # is returned from sort_versions. The order gives preference to the
- # requested level (:patch, :minor, :major) but in complicated requirement
- # cases some gems will by necessity by promoted past the requested level,
- # or even reverted to older versions.
- #
- # If strict is set to true, the results from sort_versions will be
- # truncated, eliminating any version outside the current level scope.
- # This can lead to unexpected outcomes or even VersionConflict exceptions
- # that report a version of a gem not existing for versions that indeed do
- # existing in the referenced source.
- attr_accessor :strict
-
- # Given a list of locked_specs and a list of gems to unlock creates a
- # GemVersionPromoter instance.
- #
- # @param locked_specs [SpecSet] All current locked specs. Unlike Definition
- # where this list is empty if all gems are being updated, this should
- # always be populated for all gems so this class can properly function.
- # @param unlock_gems [String] List of gem names being unlocked. If empty,
- # all gems will be considered unlocked.
- # @return [GemVersionPromoter]
- def initialize(locked_specs = SpecSet.new([]), unlock_gems = [])
- @level = :major
- @strict = false
- @locked_specs = locked_specs
- @unlock_gems = unlock_gems
- @sort_versions = {}
- end
-
- # @param value [Symbol] One of three Symbols: :major, :minor or :patch.
- def level=(value)
- v = case value
- when String, Symbol
- value.to_sym
- end
-
- raise ArgumentError, "Unexpected level #{v}. Must be :major, :minor or :patch" unless [:major, :minor, :patch].include?(v)
- @level = v
- end
-
- # Given a Dependency and an Array of SpecGroups of available versions for a
- # gem, this method will return the Array of SpecGroups sorted (and possibly
- # truncated if strict is true) in an order to give preference to the current
- # level (:major, :minor or :patch) when resolution is deciding what versions
- # best resolve all dependencies in the bundle.
- # @param dep [Dependency] The Dependency of the gem.
- # @param spec_groups [SpecGroup] An array of SpecGroups for the same gem
- # named in the @dep param.
- # @return [SpecGroup] A new instance of the SpecGroup Array sorted and
- # possibly filtered.
- def sort_versions(dep, spec_groups)
- before_result = "before sort_versions: #{debug_format_result(dep, spec_groups).inspect}" if ENV["DEBUG_RESOLVER"]
-
- @sort_versions[dep] ||= begin
- gem_name = dep.name
-
- # An Array per version returned, different entries for different platforms.
- # We only need the version here so it's ok to hard code this to the first instance.
- locked_spec = locked_specs[gem_name].first
-
- if strict
- filter_dep_specs(spec_groups, locked_spec)
- else
- sort_dep_specs(spec_groups, locked_spec)
- end.tap do |specs|
- if ENV["DEBUG_RESOLVER"]
- STDERR.puts before_result
- STDERR.puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
- end
- end
- end
- end
-
- # @return [bool] Convenience method for testing value of level variable.
- def major?
- level == :major
- end
-
- # @return [bool] Convenience method for testing value of level variable.
- def minor?
- level == :minor
- end
-
- private
-
- def filter_dep_specs(spec_groups, locked_spec)
- res = spec_groups.select do |spec_group|
- if locked_spec && !major?
- gsv = spec_group.version
- lsv = locked_spec.version
-
- must_match = minor? ? [0] : [0, 1]
-
- matches = must_match.map {|idx| gsv.segments[idx] == lsv.segments[idx] }
- (matches.uniq == [true]) ? (gsv >= lsv) : false
- else
- true
- end
- end
-
- sort_dep_specs(res, locked_spec)
- end
-
- def sort_dep_specs(spec_groups, locked_spec)
- return spec_groups unless locked_spec
- @gem_name = locked_spec.name
- @locked_version = locked_spec.version
-
- result = spec_groups.sort do |a, b|
- @a_ver = a.version
- @b_ver = b.version
- if major?
- @a_ver <=> @b_ver
- elsif either_version_older_than_locked
- @a_ver <=> @b_ver
- elsif segments_do_not_match(:major)
- @b_ver <=> @a_ver
- elsif !minor? && segments_do_not_match(:minor)
- @b_ver <=> @a_ver
- else
- @a_ver <=> @b_ver
- end
- end
- post_sort(result)
- end
-
- def either_version_older_than_locked
- @a_ver < @locked_version || @b_ver < @locked_version
- end
-
- def segments_do_not_match(level)
- index = [:major, :minor].index(level)
- @a_ver.segments[index] != @b_ver.segments[index]
- end
-
- def unlocking_gem?
- unlock_gems.empty? || unlock_gems.include?(@gem_name)
- end
-
- # Specific version moves can't always reliably be done during sorting
- # as not all elements are compared against each other.
- def post_sort(result)
- # default :major behavior in Bundler does not do this
- return result if major?
- if unlocking_gem?
- result
- else
- move_version_to_end(result, @locked_version)
- end
- end
-
- def move_version_to_end(result, version)
- move, keep = result.partition {|s| s.version.to_s == version.to_s }
- keep.concat(move)
- end
-
- def debug_format_result(dep, spec_groups)
- a = [dep.to_s,
- spec_groups.map {|sg| [sg.version, sg.dependencies_for_activated_platforms.map {|dp| [dp.name, dp.requirement.to_s] }] }]
- last_map = a.last.map {|sg_data| [sg_data.first.version, sg_data.last.map {|aa| aa.join(" ") }] }
- [a.first, last_map, level, strict ? :strict : :not_strict]
- end
- end
-end
diff --git a/lib/bundler/gemdeps.rb b/lib/bundler/gemdeps.rb
deleted file mode 100644
index cd4b25d0e6..0000000000
--- a/lib/bundler/gemdeps.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Gemdeps
- def initialize(runtime)
- @runtime = runtime
- end
-
- def requested_specs
- @runtime.requested_specs
- end
-
- def specs
- @runtime.specs
- end
-
- def dependencies
- @runtime.dependencies
- end
-
- def current_dependencies
- @runtime.current_dependencies
- end
-
- def requires
- @runtime.requires
- end
- end
-end
diff --git a/lib/bundler/graph.rb b/lib/bundler/graph.rb
deleted file mode 100644
index de6bba0214..0000000000
--- a/lib/bundler/graph.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-# frozen_string_literal: true
-
-require "set"
-module Bundler
- class Graph
- GRAPH_NAME = :Gemfile
-
- def initialize(env, output_file, show_version = false, show_requirements = false, output_format = "png", without = [])
- @env = env
- @output_file = output_file
- @show_version = show_version
- @show_requirements = show_requirements
- @output_format = output_format
- @without_groups = without.map(&:to_sym)
-
- @groups = []
- @relations = Hash.new {|h, k| h[k] = Set.new }
- @node_options = {}
- @edge_options = {}
-
- _populate_relations
- end
-
- attr_reader :groups, :relations, :node_options, :edge_options, :output_file, :output_format
-
- def viz
- GraphVizClient.new(self).run
- end
-
- private
-
- def _populate_relations
- parent_dependencies = _groups.values.to_set.flatten
- loop do
- break if parent_dependencies.empty?
-
- tmp = Set.new
- parent_dependencies.each do |dependency|
- child_dependencies = spec_for_dependency(dependency).runtime_dependencies.to_set
- @relations[dependency.name] += child_dependencies.map(&:name).to_set
- tmp += child_dependencies
-
- @node_options[dependency.name] = _make_label(dependency, :node)
- child_dependencies.each do |c_dependency|
- @edge_options["#{dependency.name}_#{c_dependency.name}"] = _make_label(c_dependency, :edge)
- end
- end
- parent_dependencies = tmp
- end
- end
-
- def _groups
- relations = Hash.new {|h, k| h[k] = Set.new }
- @env.current_dependencies.each do |dependency|
- dependency.groups.each do |group|
- next if @without_groups.include?(group)
-
- relations[group.to_s].add(dependency)
- @relations[group.to_s].add(dependency.name)
-
- @node_options[group.to_s] ||= _make_label(group, :node)
- @edge_options["#{group}_#{dependency.name}"] = _make_label(dependency, :edge)
- end
- end
- @groups = relations.keys
- relations
- end
-
- def _make_label(symbol_or_string_or_dependency, element_type)
- case element_type.to_sym
- when :node
- if symbol_or_string_or_dependency.is_a?(Gem::Dependency)
- label = symbol_or_string_or_dependency.name.dup
- label << "\n#{spec_for_dependency(symbol_or_string_or_dependency).version}" if @show_version
- else
- label = symbol_or_string_or_dependency.to_s
- end
- when :edge
- label = nil
- if symbol_or_string_or_dependency.respond_to?(:requirements_list) && @show_requirements
- tmp = symbol_or_string_or_dependency.requirements_list.join(", ")
- label = tmp if tmp != ">= 0"
- end
- else
- raise ArgumentError, "2nd argument is invalid"
- end
- label.nil? ? {} : { :label => label }
- end
-
- def spec_for_dependency(dependency)
- @env.requested_specs.find {|s| s.name == dependency.name }
- end
-
- class GraphVizClient
- def initialize(graph_instance)
- @graph_name = graph_instance.class::GRAPH_NAME
- @groups = graph_instance.groups
- @relations = graph_instance.relations
- @node_options = graph_instance.node_options
- @edge_options = graph_instance.edge_options
- @output_file = graph_instance.output_file
- @output_format = graph_instance.output_format
- end
-
- def g
- @g ||= ::GraphViz.digraph(@graph_name, :concentrate => true, :normalize => true, :nodesep => 0.55) do |g|
- g.edge[:weight] = 2
- g.edge[:fontname] = g.node[:fontname] = "Arial, Helvetica, SansSerif"
- g.edge[:fontsize] = 12
- end
- end
-
- def run
- @groups.each do |group|
- g.add_nodes(
- group, {
- :style => "filled",
- :fillcolor => "#B9B9D5",
- :shape => "box3d",
- :fontsize => 16
- }.merge(@node_options[group])
- )
- end
-
- @relations.each do |parent, children|
- children.each do |child|
- if @groups.include?(parent)
- g.add_nodes(child, { :style => "filled", :fillcolor => "#B9B9D5" }.merge(@node_options[child]))
- g.add_edges(parent, child, { :constraint => false }.merge(@edge_options["#{parent}_#{child}"]))
- else
- g.add_nodes(child, @node_options[child])
- g.add_edges(parent, child, @edge_options["#{parent}_#{child}"])
- end
- end
- end
-
- if @output_format.to_s == "debug"
- $stdout.puts g.output :none => String
- Bundler.ui.info "debugging bundle viz..."
- else
- begin
- 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"
- raise e
- end
- end
- end
- end
- end
-end
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
deleted file mode 100644
index 9166a92738..0000000000
--- a/lib/bundler/index.rb
+++ /dev/null
@@ -1,213 +0,0 @@
-# frozen_string_literal: true
-
-require "set"
-
-module Bundler
- class Index
- include Enumerable
-
- def self.build
- i = new
- yield i
- i
- end
-
- attr_reader :specs, :all_specs, :sources
- protected :specs, :all_specs
-
- RUBY = "ruby".freeze
- NULL = "\0".freeze
-
- def initialize
- @sources = []
- @cache = {}
- @specs = Hash.new {|h, k| h[k] = {} }
- @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH }
- end
-
- def initialize_copy(o)
- @sources = o.sources.dup
- @cache = {}
- @specs = Hash.new {|h, k| h[k] = {} }
- @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH }
-
- o.specs.each do |name, hash|
- @specs[name] = hash.dup
- end
- o.all_specs.each do |name, array|
- @all_specs[name] = array.dup
- end
- end
-
- def inspect
- "#<#{self.class}:0x#{object_id} sources=#{sources.map(&:inspect)} specs.size=#{specs.size}>"
- end
-
- def empty?
- each { return false }
- true
- end
-
- def search_all(name)
- all_matches = local_search(name) + @all_specs[name]
- @sources.each do |source|
- all_matches.concat(source.search_all(name))
- end
- all_matches
- end
-
- # Search this index's specs, and any source indexes that this index knows
- # about, returning all of the results.
- def search(query, base = nil)
- sort_specs(unsorted_search(query, base))
- end
-
- def unsorted_search(query, base)
- results = local_search(query, base)
-
- seen = results.map(&:full_name).to_set unless @sources.empty?
-
- @sources.each do |source|
- source.unsorted_search(query, base).each do |spec|
- results << spec if seen.add?(spec.full_name)
- end
- end
-
- results
- end
- protected :unsorted_search
-
- def self.sort_specs(specs)
- specs.sort_by do |s|
- platform_string = s.platform.to_s
- [s.version, platform_string == RUBY ? NULL : platform_string]
- end
- end
-
- def sort_specs(specs)
- self.class.sort_specs(specs)
- end
-
- def local_search(query, base = nil)
- case query
- when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query)
- when String then specs_by_name(query)
- when Gem::Dependency then search_by_dependency(query, base)
- when DepProxy then search_by_dependency(query.dep, base)
- else
- raise "You can't search for a #{query.inspect}."
- end
- end
-
- alias_method :[], :search
-
- def <<(spec)
- @specs[spec.name][spec.full_name] = spec
- spec
- end
-
- def each(&blk)
- return enum_for(:each) unless blk
- specs.values.each do |spec_sets|
- spec_sets.values.each(&blk)
- end
- sources.each {|s| s.each(&blk) }
- self
- end
-
- def spec_names
- names = specs.keys + sources.map(&:spec_names)
- names.uniq!
- names
- end
-
- # returns a list of the dependencies
- def unmet_dependency_names
- dependency_names.select do |name|
- name != "bundler" && search(name).empty?
- end
- end
-
- def dependency_names
- names = []
- each do |spec|
- spec.dependencies.each do |dep|
- next if dep.type == :development
- names << dep.name
- end
- end
- names.uniq
- end
-
- def use(other, override_dupes = false)
- return unless other
- other.each do |s|
- if (dupes = search_by_spec(s)) && !dupes.empty?
- # safe to << since it's a new array when it has contents
- @all_specs[s.name] = dupes << s
- next unless override_dupes
- end
- self << s
- end
- self
- end
-
- def size
- @sources.inject(@specs.size) do |size, source|
- size += source.size
- end
- end
-
- # Whether all the specs in self are in other
- # TODO: rename to #include?
- def ==(other)
- all? do |spec|
- other_spec = other[spec].first
- other_spec && dependencies_eql?(spec, other_spec) && spec.source == other_spec.source
- end
- end
-
- def dependencies_eql?(spec, other_spec)
- deps = spec.dependencies.select {|d| d.type != :development }
- other_deps = other_spec.dependencies.select {|d| d.type != :development }
- Set.new(deps) == Set.new(other_deps)
- end
-
- def add_source(index)
- raise ArgumentError, "Source must be an index, not #{index.class}" unless index.is_a?(Index)
- @sources << index
- @sources.uniq! # need to use uniq! here instead of checking for the item before adding
- end
-
- private
-
- def specs_by_name(name)
- @specs[name].values
- end
-
- def search_by_dependency(dependency, base = nil)
- @cache[base || false] ||= {}
- @cache[base || false][dependency] ||= begin
- specs = specs_by_name(dependency.name)
- specs += base if base
- found = specs.select do |spec|
- next true if spec.source.is_a?(Source::Gemspec)
- if base # allow all platforms when searching from a lockfile
- dependency.matches_spec?(spec)
- else
- dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
- end
- end
-
- found
- end
- end
-
- EMPTY_SEARCH = [].freeze
-
- def search_by_spec(spec)
- spec = @specs[spec.name][spec.full_name]
- spec ? [spec] : EMPTY_SEARCH
- end
- end
-end
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
deleted file mode 100644
index 7fe6a91ddd..0000000000
--- a/lib/bundler/injector.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Injector
- def self.inject(new_deps, options = {})
- injector = new(new_deps, options)
- injector.inject(Bundler.default_gemfile, Bundler.default_lockfile)
- end
-
- def initialize(new_deps, options = {})
- @new_deps = new_deps
- @options = options
- end
-
- def inject(gemfile_path, lockfile_path)
- if Bundler.frozen?
- # ensure the lock and Gemfile are synced
- Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true)
- end
-
- # temporarily unfreeze
- Bundler.settings.temporary(:deployment => false, :frozen => false) do
- # evaluate the Gemfile we have now
- builder = Dsl.new
- builder.eval_gemfile(gemfile_path)
-
- # don't inject any gems that are already in the Gemfile
- @new_deps -= builder.dependencies
-
- # add new deps to the end of the in-memory Gemfile
- # Set conservative versioning to false because we want to let the resolver resolve the version first
- builder.eval_gemfile("injected gems", build_gem_lines(false)) if @new_deps.any?
-
- # resolve to see if the new deps broke anything
- @definition = builder.to_definition(lockfile_path, {})
- @definition.resolve_remotely!
-
- # since nothing broke, we can add those gems to the gemfile
- append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @new_deps.any?
-
- # since we resolved successfully, write out the lockfile
- @definition.lock(Bundler.default_lockfile)
-
- # invalidate the cached Bundler.definition
- Bundler.reset_paths!
-
- # return an array of the deps that we added
- @new_deps
- end
- end
-
- private
-
- def conservative_version(spec)
- version = spec.version
- return ">= 0" if version.nil?
- segments = version.segments
- seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2
-
- prerelease_suffix = version.to_s.gsub(version.release.to_s, "") if version.prerelease?
- "~> #{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
- end
-
- def build_gem_lines(conservative_versioning)
- @new_deps.map do |d|
- name = d.name.dump
-
- requirement = if conservative_versioning
- ", \"#{conservative_version(@definition.specs[d.name][0])}\""
- else
- ", #{d.requirement.as_list.map(&:dump).join(", ")}"
- end
-
- if d.groups != Array(:default)
- group = d.groups.size == 1 ? ", :group => #{d.groups.inspect}" : ", :groups => #{d.groups.inspect}"
- end
-
- source = ", :source => \"#{d.source}\"" unless d.source.nil?
-
- %(gem #{name}#{requirement}#{group}#{source})
- end.join("\n")
- end
-
- def append_to(gemfile_path, new_gem_lines)
- gemfile_path.open("a") do |f|
- f.puts
- if @options["timestamp"] || @options["timestamp"].nil?
- f.puts "# Added at #{Time.now} by #{`whoami`.chomp}:"
- end
- f.puts new_gem_lines
- end
- end
- end
-end
diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb
deleted file mode 100644
index 9d25f3261a..0000000000
--- a/lib/bundler/inline.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/compatibility_guard"
-
-# Allows for declaring a Gemfile inline in a ruby script, optionally installing
-# any gems that aren't already installed on the user's system.
-#
-# @note Every gem that is specified in this 'Gemfile' will be `require`d, as if
-# the user had manually called `Bundler.require`. To avoid a requested gem
-# being automatically required, add the `:require => false` option to the
-# `gem` dependency declaration.
-#
-# @param install [Boolean] whether gems that aren't already installed on the
-# user's system should be installed.
-# Defaults to `false`.
-#
-# @param gemfile [Proc] a block that is evaluated as a `Gemfile`.
-#
-# @example Using an inline Gemfile
-#
-# #!/usr/bin/env ruby
-#
-# require 'bundler/inline'
-#
-# gemfile do
-# source 'https://rubygems.org'
-# gem 'json', require: false
-# gem 'nap', require: 'rest'
-# gem 'cocoapods', '~> 0.34.1'
-# end
-#
-# puts Pod::VERSION # => "0.34.4"
-#
-def gemfile(install = false, options = {}, &gemfile)
- require "bundler"
-
- opts = options.dup
- ui = opts.delete(:ui) { Bundler::UI::Shell.new }
- raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
-
- old_root = Bundler.method(:root)
- def Bundler.root
- Bundler::SharedHelpers.pwd.expand_path
- end
- Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
-
- Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
- builder = Bundler::Dsl.new
- builder.instance_eval(&gemfile)
-
- definition = builder.to_definition(nil, true)
- def definition.lock(*); end
- definition.validate_runtime!
-
- missing_specs = proc do
- definition.missing_specs?
- end
-
- Bundler.ui = ui if install
- if install || missing_specs.call
- Bundler.settings.temporary(:inline => true) do
- installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
- installer.post_install_messages.each do |name, message|
- Bundler.ui.info "Post-install message from #{name}:\n#{message}"
- end
- end
- end
-
- runtime = Bundler::Runtime.new(nil, definition)
- runtime.setup.require
-ensure
- bundler_module = class << Bundler; self; end
- bundler_module.send(:define_method, :root, old_root) if old_root
-end
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
deleted file mode 100644
index d1066c9c19..0000000000
--- a/lib/bundler/installer.rb
+++ /dev/null
@@ -1,287 +0,0 @@
-# frozen_string_literal: true
-
-require "erb"
-require "rubygems/dependency_installer"
-require "bundler/worker"
-require "bundler/installer/parallel_installer"
-require "bundler/installer/standalone"
-require "bundler/installer/gem_installer"
-
-module Bundler
- class Installer
- class << self
- attr_accessor :ambiguous_gems
-
- Installer.ambiguous_gems = []
- end
-
- attr_reader :post_install_messages
-
- # Begins the installation process for Bundler.
- # For more information see the #run method on this class.
- def self.install(root, definition, options = {})
- installer = new(root, definition)
- Plugin.hook("before-install-all", definition.dependencies)
- installer.run(options)
- installer
- end
-
- def initialize(root, definition)
- @root = root
- @definition = definition
- @post_install_messages = {}
- end
-
- # Runs the install procedures for a specific Gemfile.
- #
- # Firstly, this method will check to see if `Bundler.bundle_path` exists
- # and if not then Bundler will create the directory. This is usually the same
- # location as RubyGems which typically is the `~/.gem` directory
- # unless other specified.
- #
- # Secondly, it checks if Bundler has been configured to be "frozen".
- # Frozen ensures that the Gemfile and the Gemfile.lock file are matching.
- # This stops a situation where a developer may update the Gemfile but may not run
- # `bundle install`, which leads to the Gemfile.lock file not being correctly updated.
- # If this file is not correctly updated then any other developer running
- # `bundle install` will potentially not install the correct gems.
- #
- # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile.
- # If there are no dependencies specified then Bundler returns a warning message stating
- # so and this method returns.
- #
- # Fourthly, Bundler checks if the Gemfile.lock exists, and if so
- # then proceeds to set up a definition based on the Gemfile and the Gemfile.lock.
- # During this step Bundler will also download information about any new gems
- # that are not in the Gemfile.lock and resolve any dependencies if needed.
- #
- # Fifthly, Bundler resolves the dependencies either through a cache of gems or by remote.
- # This then leads into the gems being installed, along with stubs for their executables,
- # but only if the --binstubs option has been passed or Bundler.options[:bin] has been set
- # earlier.
- #
- # Sixthly, a new Gemfile.lock is created from the installed gems to ensure that the next time
- # that a user runs `bundle install` they will receive any updates from this process.
- #
- # Finally, if the user has specified the standalone flag, Bundler will generate the needed
- # require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more
- # information.
- def run(options)
- create_bundle_path
-
- ProcessLock.lock do
- if Bundler.frozen?
- @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
- end
-
- if @definition.dependencies.empty?
- Bundler.ui.warn "The Gemfile specifies no dependencies"
- lock
- return
- end
-
- if resolve_if_needed(options)
- ensure_specs_are_compatible!
- warn_on_incompatible_bundler_deps
- load_plugins
- options.delete(:jobs)
- else
- options[:jobs] = 1 # to avoid the overhead of Bundler::Worker
- end
- install(options)
-
- lock unless Bundler.frozen?
- Standalone.new(options[:standalone], @definition).generate if options[:standalone]
- end
- end
-
- def generate_bundler_executable_stubs(spec, options = {})
- if options[:binstubs_cmd] && spec.executables.empty?
- options = {}
- spec.runtime_dependencies.each do |dep|
- bins = @definition.specs[dep].first.executables
- options[dep.name] = bins unless bins.empty?
- end
- if options.any?
- Bundler.ui.warn "#{spec.name} has no executables, but you may want " \
- "one from a gem it depends on."
- options.each {|name, bins| Bundler.ui.warn " #{name} has: #{bins.join(", ")}" }
- else
- Bundler.ui.warn "There are no executables for the gem #{spec.name}."
- end
- return
- end
-
- # double-assignment to avoid warnings about variables that will be used by ERB
- bin_path = Bundler.bin_path
- bin_path = bin_path
- relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
- relative_gemfile_path = relative_gemfile_path
- ruby_command = Thor::Util.ruby_command
- ruby_command = ruby_command
- template_path = File.expand_path("../templates/Executable", __FILE__)
- if spec.name == "bundler"
- template_path += ".bundler"
- spec.executables = %(bundle)
- end
- template = File.read(template_path)
-
- exists = []
- spec.executables.each do |executable|
- binstub_path = "#{bin_path}/#{executable}"
- if File.exist?(binstub_path) && !options[:force]
- exists << executable
- next
- end
-
- File.open(binstub_path, "w", 0o777 & ~File.umask) do |f|
- f.puts ERB.new(template, nil, "-").result(binding)
- end
- end
-
- if options[:binstubs_cmd] && exists.any?
- case exists.size
- when 1
- Bundler.ui.warn "Skipped #{exists[0]} since it already exists."
- when 2
- Bundler.ui.warn "Skipped #{exists.join(" and ")} since they already exist."
- else
- items = exists[0...-1].empty? ? nil : exists[0...-1].join(", ")
- skipped = [items, exists[-1]].compact.join(" and ")
- Bundler.ui.warn "Skipped #{skipped} since they already exist."
- end
- Bundler.ui.warn "If you want to overwrite skipped stubs, use --force."
- end
- end
-
- def generate_standalone_bundler_executable_stubs(spec)
- # double-assignment to avoid warnings about variables that will be used by ERB
- bin_path = Bundler.bin_path
- unless path = Bundler.settings[:path]
- raise "Can't standalone without an explicit path set"
- end
- standalone_path = Bundler.root.join(path).relative_path_from(bin_path)
- standalone_path = standalone_path
- template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__))
- ruby_command = Thor::Util.ruby_command
- ruby_command = ruby_command
-
- spec.executables.each do |executable|
- next if executable == "bundle"
- executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
- executable_path = executable_path
- File.open "#{bin_path}/#{executable}", "w", 0o755 do |f|
- f.puts ERB.new(template, nil, "-").result(binding)
- end
- end
- end
-
- private
-
- # the order that the resolver provides is significant, since
- # dependencies might affect the installation of a gem.
- # that said, it's a rare situation (other than rake), and parallel
- # installation is SO MUCH FASTER. so we let people opt in.
- def install(options)
- force = options["force"]
- jobs = options.delete(:jobs) do
- if can_install_in_parallel?
- [Bundler.settings[:jobs].to_i - 1, 1].max
- else
- 1
- end
- end
- install_in_parallel jobs, options[:standalone], force
- end
-
- def load_plugins
- Bundler.rubygems.load_plugins
-
- requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
- path_plugin_files = requested_path_gems.map do |spec|
- begin
- Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
- rescue TypeError
- error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
- raise Gem::InvalidSpecificationException, error_message
- end
- end.flatten
- Bundler.rubygems.load_plugin_files(path_plugin_files)
- end
-
- def ensure_specs_are_compatible!
- system_ruby = Bundler::RubyVersion.system
- rubygems_version = Gem::Version.create(Gem::VERSION)
- @definition.specs.each do |spec|
- if required_ruby_version = spec.required_ruby_version
- unless required_ruby_version.satisfied_by?(system_ruby.gem_version)
- raise InstallError, "#{spec.full_name} requires ruby version #{required_ruby_version}, " \
- "which is incompatible with the current version, #{system_ruby}"
- end
- end
- next unless required_rubygems_version = spec.required_rubygems_version
- unless required_rubygems_version.satisfied_by?(rubygems_version)
- raise InstallError, "#{spec.full_name} requires rubygems version #{required_rubygems_version}, " \
- "which is incompatible with the current version, #{rubygems_version}"
- end
- end
- end
-
- def warn_on_incompatible_bundler_deps
- bundler_version = Gem::Version.create(Bundler::VERSION)
- @definition.specs.each do |spec|
- spec.dependencies.each do |dep|
- next if dep.type == :development
- next unless dep.name == "bundler".freeze
- next if dep.requirement.satisfied_by?(bundler_version)
-
- Bundler.ui.warn "#{spec.name} (#{spec.version}) has dependency" \
- " #{SharedHelpers.pretty_dependency(dep)}" \
- ", which is unsatisfied by the current bundler version #{VERSION}" \
- ", so the dependency is being ignored"
- end
- end
- 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
- end
-
- def install_in_parallel(size, standalone, force = false)
- spec_installations = ParallelInstaller.call(self, @definition.specs, size, standalone, force)
- spec_installations.each do |installation|
- post_install_messages[installation.name] = installation.post_install_message if installation.has_post_install_message?
- end
- end
-
- def create_bundle_path
- SharedHelpers.filesystem_access(Bundler.bundle_path.to_s) do |p|
- Bundler.mkdir_p(p)
- end unless Bundler.bundle_path.exist?
- rescue Errno::EEXIST
- raise PathError, "Could not install to path `#{Bundler.bundle_path}` " \
- "because a file already exists at that path. Either remove or rename the file so the directory can be created."
- end
-
- # returns whether or not a re-resolve was needed
- def resolve_if_needed(options)
- if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
- return false if @definition.nothing_changed? && !@definition.missing_specs?
- end
-
- options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
- true
- end
-
- def lock(opts = {})
- @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
- end
- end
-end
diff --git a/lib/bundler/installer/gem_installer.rb b/lib/bundler/installer/gem_installer.rb
deleted file mode 100644
index 086b763d20..0000000000
--- a/lib/bundler/installer/gem_installer.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class GemInstaller
- attr_reader :spec, :standalone, :worker, :force, :installer
-
- def initialize(spec, installer, standalone = false, worker = 0, force = false)
- @spec = spec
- @installer = installer
- @standalone = standalone
- @worker = worker
- @force = force
- end
-
- def install_from_spec
- post_install_message = spec_settings ? install_with_settings : install
- Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
- generate_executable_stubs
- return true, post_install_message
- rescue Bundler::InstallHookError, Bundler::SecurityError, APIResponseMismatchError
- raise
- rescue Errno::ENOSPC
- return false, out_of_space_message
- rescue => e
- return false, specific_failure_message(e)
- end
-
- private
-
- def specific_failure_message(e)
- message = "#{e.class}: #{e.message}\n"
- message += " " + e.backtrace.join("\n ") + "\n\n" if Bundler.ui.debug?
- message = message.lines.first + Bundler.ui.add_color(message.lines.drop(1).join, :clear)
- message + Bundler.ui.add_color(failure_message, :red)
- end
-
- def failure_message
- return install_error_message if spec.source.options["git"]
- "#{install_error_message}\n#{gem_install_message}"
- end
-
- def install_error_message
- "An error occurred while installing #{spec.name} (#{spec.version}), and Bundler cannot continue."
- end
-
- def gem_install_message
- "Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
- end
-
- def spec_settings
- # Fetch the build settings, if there are any
- Bundler.settings["build.#{spec.name}"]
- end
-
- def install
- spec.source.install(spec, :force => force, :ensure_builtin_gems_cached => standalone, :build_args => Array(spec_settings))
- end
-
- def install_with_settings
- # Build arguments are global, so this is mutexed
- Bundler.rubygems.install_with_build_args([spec_settings]) { install }
- end
-
- def out_of_space_message
- "#{install_error_message}\nYour disk is out of space. Free some space to be able to install your bundle."
- end
-
- def generate_executable_stubs
- return if Bundler.feature_flag.forget_cli_options?
- return if Bundler.settings[:inline]
- if Bundler.settings[:bin] && standalone
- installer.generate_standalone_bundler_executable_stubs(spec)
- elsif Bundler.settings[:bin]
- installer.generate_bundler_executable_stubs(spec, :force => true)
- end
- end
- end
-end
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
deleted file mode 100644
index 95d9575c44..0000000000
--- a/lib/bundler/installer/parallel_installer.rb
+++ /dev/null
@@ -1,228 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/worker"
-require "bundler/installer/gem_installer"
-
-module Bundler
- class ParallelInstaller
- class SpecInstallation
- attr_accessor :spec, :name, :post_install_message, :state, :error
- def initialize(spec)
- @spec = spec
- @name = spec.name
- @state = :none
- @post_install_message = ""
- @error = nil
- end
-
- def installed?
- state == :installed
- end
-
- def enqueued?
- state == :enqueued
- end
-
- def failed?
- state == :failed
- end
-
- def installation_attempted?
- installed? || failed?
- end
-
- # Only true when spec in neither installed nor already enqueued
- def ready_to_enqueue?
- !enqueued? && !installation_attempted?
- end
-
- def has_post_install_message?
- !post_install_message.empty?
- end
-
- def ignorable_dependency?(dep)
- dep.type == :development || dep.name == @name
- end
-
- # Checks installed dependencies against spec's dependencies to make
- # sure needed dependencies have been installed.
- def dependencies_installed?(all_specs)
- installed_specs = all_specs.select(&:installed?).map(&:name)
- dependencies.all? {|d| installed_specs.include? d.name }
- end
-
- # Represents only the non-development dependencies, the ones that are
- # itself and are in the total list.
- def dependencies
- @dependencies ||= begin
- all_dependencies.reject {|dep| ignorable_dependency? dep }
- end
- end
-
- def missing_lockfile_dependencies(all_spec_names)
- deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
- deps.reject {|dep| all_spec_names.include? dep.name }
- end
-
- # Represents all dependencies
- def all_dependencies
- @spec.dependencies
- end
-
- def to_s
- "#<#{self.class} #{@spec.full_name} (#{state})>"
- end
- end
-
- def self.call(*args)
- new(*args).call
- end
-
- attr_reader :size
-
- def initialize(installer, all_specs, size, standalone, force)
- @installer = installer
- @size = size
- @standalone = standalone
- @force = force
- @specs = all_specs.map {|s| SpecInstallation.new(s) }
- @spec_set = all_specs
- 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
- install_with_worker
- else
- install_serially
- end
-
- handle_error if @specs.any?(&:failed?)
- @specs
- ensure
- worker_pool && worker_pool.stop
- end
-
- def check_for_corrupt_lockfile
- missing_dependencies = @specs.map do |s|
- [
- s,
- s.missing_lockfile_dependencies(@specs.map(&:name)),
- ]
- end.reject { |a| a.last.empty? }
- return if missing_dependencies.empty?
-
- warning = []
- warning << "Your lockfile was created by an old Bundler that left some things out."
- if @size != 1
- warning << "Because of the missing DEPENDENCIES, we can only install gems one at a time, instead of installing #{@size} at a time."
- @size = 1
- end
- warning << "You can fix this by adding the missing gems to your Gemfile, running bundle install, and then removing the gems from your Gemfile."
- warning << "The missing gems are:"
-
- missing_dependencies.each do |spec, missing|
- warning << "* #{missing.map(&:name).join(", ")} depended upon by #{spec.name}"
- end
-
- Bundler.ui.warn(warning.join("\n"))
- end
-
- private
-
- def install_with_worker
- enqueue_specs
- process_specs until finished_installing?
- end
-
- def install_serially
- until finished_installing?
- raise "failed to find a spec to enqueue while installing serially" unless spec_install = @specs.find(&:ready_to_enqueue?)
- spec_install.state = :enqueued
- do_install(spec_install, 0)
- end
- end
-
- def worker_pool
- @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
- do_install(spec_install, worker_num)
- }
- end
-
- def do_install(spec_install, worker_num)
- gem_installer = Bundler::GemInstaller.new(
- spec_install.spec, @installer, @standalone, worker_num, @force
- )
- success, message = begin
- gem_installer.install_from_spec
- rescue => e
- raise e, "#{e}\n\n#{require_tree_for_spec(spec_install.spec)}"
- end
- if success
- spec_install.state = :installed
- spec_install.post_install_message = message unless message.nil?
- else
- spec_install.state = :failed
- spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
- end
- spec_install
- end
-
- # Dequeue a spec and save its post-install message and then enqueue the
- # remaining specs.
- # Some specs might've had to wait til this spec was installed to be
- # processed so the call to `enqueue_specs` is important after every
- # dequeue.
- def process_specs
- worker_pool.deq
- enqueue_specs
- end
-
- def finished_installing?
- @specs.all? do |spec|
- return true if spec.failed?
- spec.installed?
- end
- end
-
- def handle_error
- errors = @specs.select(&:failed?).map(&:error)
- if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
- raise exception
- end
- raise Bundler::InstallError, errors.map(&:to_s).join("\n\n")
- end
-
- def require_tree_for_spec(spec)
- tree = @spec_set.what_required(spec)
- t = String.new("In #{File.basename(SharedHelpers.default_gemfile)}:\n")
- tree.each_with_index do |s, depth|
- t << " " * depth.succ << s.name
- unless tree.last == s
- t << %( was resolved to #{s.version}, which depends on)
- end
- t << %(\n)
- end
- t
- end
-
- # Keys in the remains hash represent uninstalled gems specs.
- # We enqueue all gem specs that do not have any dependencies.
- # Later we call this lambda again to install specs that depended on
- # previously installed specifications. We continue until all specs
- # are installed.
- def enqueue_specs
- @specs.select(&:ready_to_enqueue?).each do |spec|
- if spec.dependencies_installed? @specs
- spec.state = :enqueued
- worker_pool.enq spec
- end
- end
- end
- end
-end
diff --git a/lib/bundler/installer/standalone.rb b/lib/bundler/installer/standalone.rb
deleted file mode 100644
index ce0c9df1eb..0000000000
--- a/lib/bundler/installer/standalone.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Standalone
- def initialize(groups, definition)
- @specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
- end
-
- def generate
- SharedHelpers.filesystem_access(bundler_path) do |p|
- FileUtils.mkdir_p(p)
- end
- File.open File.join(bundler_path, "setup.rb"), "w" do |file|
- file.puts "require 'rbconfig'"
- file.puts "# ruby 1.8.7 doesn't define RUBY_ENGINE"
- file.puts "ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'"
- file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
- file.puts "path = File.expand_path('..', __FILE__)"
- paths.each do |path|
- file.puts %($:.unshift "\#{path}/#{path}")
- end
- end
- end
-
- private
-
- def paths
- @specs.map do |spec|
- next if spec.name == "bundler"
- Array(spec.require_paths).map do |path|
- gem_path(path, spec).sub(version_dir, '#{ruby_engine}/#{ruby_version}')
- # This is a static string intentionally. It's interpolated at a later time.
- end
- end.flatten
- end
-
- def version_dir
- "#{Bundler::RubyVersion.system.engine}/#{RbConfig::CONFIG["ruby_version"]}"
- end
-
- def bundler_path
- Bundler.root.join(Bundler.settings[:path], "bundler")
- end
-
- def gem_path(path, spec)
- full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
- Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
- rescue TypeError
- error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
- raise Gem::InvalidSpecificationException.new(error_message)
- end
- end
-end
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
deleted file mode 100644
index 993952c23b..0000000000
--- a/lib/bundler/lazy_specification.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-# frozen_string_literal: true
-
-require "uri"
-require "bundler/match_platform"
-
-module Bundler
- class LazySpecification
- Identifier = Struct.new(:name, :version, :source, :platform, :dependencies)
- class Identifier
- include Comparable
- def <=>(other)
- return unless other.is_a?(Identifier)
- [name, version, platform_string] <=> [other.name, other.version, other.platform_string]
- end
-
- protected
-
- def platform_string
- platform_string = platform.to_s
- platform_string == Index::RUBY ? Index::NULL : platform_string
- end
- end
-
- include MatchPlatform
-
- attr_reader :name, :version, :dependencies, :platform
- attr_accessor :source, :remote
-
- def initialize(name, version, platform, source = nil)
- @name = name
- @version = version
- @dependencies = []
- @platform = platform || Gem::Platform::RUBY
- @source = source
- @specification = nil
- end
-
- def full_name
- if platform == Gem::Platform::RUBY || platform.nil?
- "#{@name}-#{@version}"
- else
- "#{@name}-#{@version}-#{platform}"
- end
- end
-
- def ==(other)
- identifier == other.identifier
- end
-
- def satisfies?(dependency)
- @name == dependency.name && dependency.requirement.satisfied_by?(Gem::Version.new(@version))
- end
-
- def to_lock
- out = String.new
-
- if platform == Gem::Platform::RUBY || platform.nil?
- out << " #{name} (#{version})\n"
- else
- out << " #{name} (#{version}-#{platform})\n"
- end
-
- dependencies.sort_by(&:to_s).uniq.each do |dep|
- next if dep.type == :development
- out << " #{dep.to_lock}\n"
- end
-
- out
- end
-
- def __materialize__
- search_object = Bundler.feature_flag.specific_platform? || Bundler.settings[:force_ruby_platform] ? self : Dependency.new(name, version)
- @specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name
- source.gemspec.tap {|s| s.source = source }
- else
- search = source.specs.search(search_object).last
- 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."
- search = source.specs.search(self).last
- end
- search.dependencies = dependencies if search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)
- search
- end
- end
-
- def respond_to?(*args)
- super || @specification ? @specification.respond_to?(*args) : nil
- end
-
- def to_s
- @__to_s ||= if platform == Gem::Platform::RUBY || platform.nil?
- "#{name} (#{version})"
- else
- "#{name} (#{version}-#{platform})"
- end
- end
-
- def identifier
- @__identifier ||= Identifier.new(name, version, source, platform, dependencies)
- end
-
- def git_version
- return unless source.is_a?(Bundler::Source::Git)
- " #{source.revision[0..6]}"
- end
-
- private
-
- def to_ary
- nil
- end
-
- def method_missing(method, *args, &blk)
- raise "LazySpecification has not been materialized yet (calling :#{method} #{args.inspect})" unless @specification
-
- return super unless respond_to?(method)
-
- @specification.send(method, *args, &blk)
- end
- end
-end
diff --git a/lib/bundler/lockfile_generator.rb b/lib/bundler/lockfile_generator.rb
deleted file mode 100644
index 585077d18d..0000000000
--- a/lib/bundler/lockfile_generator.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class LockfileGenerator
- attr_reader :definition
- attr_reader :out
-
- # @private
- def initialize(definition)
- @definition = definition
- @out = String.new
- end
-
- def self.generate(definition)
- new(definition).generate!
- end
-
- def generate!
- add_sources
- add_platforms
- add_dependencies
- add_locked_ruby_version
- add_bundled_with
-
- out
- end
-
- private
-
- def add_sources
- definition.send(:sources).lock_sources.each_with_index do |source, idx|
- out << "\n" unless idx.zero?
-
- # Add the source header
- out << source.to_lock
-
- # Find all specs for this source
- specs = definition.resolve.select {|s| source.can_lock?(s) }
- add_specs(specs)
- end
- end
-
- def add_specs(specs)
- # This needs to be sorted by full name so that
- # gems with the same name, but different platform
- # are ordered consistently
- specs.sort_by(&:full_name).each do |spec|
- next if spec.name == "bundler".freeze
- out << spec.to_lock
- end
- end
-
- def add_platforms
- add_section("PLATFORMS", definition.platforms)
- end
-
- def add_dependencies
- out << "\nDEPENDENCIES\n"
-
- handled = []
- definition.dependencies.sort_by(&:to_s).each do |dep|
- next if handled.include?(dep.name)
- out << dep.to_lock
- handled << dep.name
- end
- end
-
- def add_locked_ruby_version
- return unless locked_ruby_version = definition.locked_ruby_version
- add_section("RUBY VERSION", locked_ruby_version.to_s)
- end
-
- def add_bundled_with
- add_section("BUNDLED WITH", definition.locked_bundler_version.to_s)
- end
-
- def add_section(name, value)
- out << "\n#{name}\n"
- case value
- when Array
- value.map(&:to_s).sort.each do |val|
- out << " #{val}\n"
- end
- when Hash
- value.to_a.sort_by {|k, _| k.to_s }.each do |key, val|
- out << " #{key}: #{val}\n"
- end
- when String
- out << " #{value}\n"
- else
- raise ArgumentError, "#{value.inspect} can't be serialized in a lockfile"
- end
- end
- end
-end
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
deleted file mode 100644
index ff706fca1d..0000000000
--- a/lib/bundler/lockfile_parser.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-# frozen_string_literal: true
-
-# Some versions of the Bundler 1.1 RC series introduced corrupted
-# lockfiles. There were two major problems:
-#
-# * multiple copies of the same GIT section appeared in the lockfile
-# * when this happened, those sections got multiple copies of gems
-# in those sections.
-#
-# As a result, Bundler 1.1 contains code that fixes the earlier
-# corruption. We will remove this fix-up code in Bundler 1.2.
-
-module Bundler
- class LockfileParser
- attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
-
- BUNDLED = "BUNDLED WITH".freeze
- DEPENDENCIES = "DEPENDENCIES".freeze
- PLATFORMS = "PLATFORMS".freeze
- RUBY = "RUBY VERSION".freeze
- GIT = "GIT".freeze
- GEM = "GEM".freeze
- PATH = "PATH".freeze
- PLUGIN = "PLUGIN SOURCE".freeze
- SPECS = " specs:".freeze
- OPTIONS = /^ ([a-z]+): (.*)$/i
- 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,
- }.freeze
-
- KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze
-
- ENVIRONMENT_VERSION_SECTIONS = [BUNDLED, RUBY].freeze
-
- def self.sections_in_lockfile(lockfile_contents)
- lockfile_contents.scan(/^\w[\w ]*$/).uniq
- end
-
- def self.unknown_sections_in_lockfile(lockfile_contents)
- sections_in_lockfile(lockfile_contents) - KNOWN_SECTIONS
- end
-
- def self.sections_to_ignore(base_version = nil)
- base_version &&= base_version.release
- base_version ||= Gem::Version.create("1.0".dup)
- attributes = []
- SECTIONS_BY_VERSION_INTRODUCED.each do |version, introduced|
- next if version <= base_version
- attributes += introduced
- end
- attributes
- end
-
- def initialize(lockfile)
- @platforms = []
- @sources = []
- @dependencies = {}
- @state = nil
- @specs = {}
-
- @rubygems_aggregate = Source::Rubygems.new
-
- if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
- raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \
- "Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock."
- end
-
- lockfile.split(/(?:\r?\n)+/).each do |line|
- if SOURCE.include?(line)
- @state = :source
- parse_source(line)
- elsif line == DEPENDENCIES
- @state = :dependency
- elsif line == PLATFORMS
- @state = :platform
- elsif line == RUBY
- @state = :ruby
- elsif line == BUNDLED
- @state = :bundled_with
- elsif line =~ /^[^\s]/
- @state = nil
- elsif @state
- send("parse_#{@state}", line)
- end
- end
- @sources << @rubygems_aggregate unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
- @specs = @specs.values.sort_by(&:identifier)
- warn_for_outdated_bundler_version
- rescue ArgumentError => e
- Bundler.ui.debug(e)
- raise LockfileError, "Your lockfile is unreadable. Run `rm #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \
- "and then `bundle install` to generate a new lockfile."
- end
-
- def warn_for_outdated_bundler_version
- return unless bundler_version
- prerelease_text = bundler_version.prerelease? ? " --pre" : ""
- current_version = Gem::Version.create(Bundler::VERSION)
- case current_version.segments.first <=> bundler_version.segments.first
- when -1
- raise LockfileError, "You must use Bundler #{bundler_version.segments.first} or greater with this lockfile."
- 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"
- end
- end
- end
-
- private
-
- TYPES = {
- GIT => Bundler::Source::Git,
- GEM => Bundler::Source::Rubygems,
- PATH => Bundler::Source::Path,
- PLUGIN => Bundler::Plugin,
- }.freeze
-
- def parse_source(line)
- case line
- when SPECS
- case @type
- when PATH
- @current_source = TYPES[@type].from_lock(@opts)
- @sources << @current_source
- when GIT
- @current_source = TYPES[@type].from_lock(@opts)
- # Strip out duplicate GIT sections
- if @sources.include?(@current_source)
- @current_source = @sources.find {|s| s == @current_source }
- else
- @sources << @current_source
- end
- when GEM
- if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
- @opts["remotes"] = @opts.delete("remote")
- @current_source = TYPES[@type].from_lock(@opts)
- @sources << @current_source
- else
- Array(@opts["remote"]).each do |url|
- @rubygems_aggregate.add_remote(url)
- end
- @current_source = @rubygems_aggregate
- end
- when PLUGIN
- @current_source = Plugin.source_from_lock(@opts)
- @sources << @current_source
- end
- when OPTIONS
- value = $2
- value = true if value == "true"
- value = false if value == "false"
-
- key = $1
-
- if @opts[key]
- @opts[key] = Array(@opts[key])
- @opts[key] << value
- else
- @opts[key] = value
- end
- when *SOURCE
- @current_source = nil
- @opts = {}
- @type = line
- else
- parse_spec(line)
- end
- end
-
- space = / /
- NAME_VERSION = /
- ^(#{space}{2}|#{space}{4}|#{space}{6})(?!#{space}) # Exactly 2, 4, or 6 spaces at the start of the line
- (.*?) # Name
- (?:#{space}\(([^-]*) # Space, followed by version
- (?:-(.*))?\))? # Optional platform
- (!)? # Optional pinned marker
- $ # Line end
- /xo
-
- def parse_dependency(line)
- return unless line =~ NAME_VERSION
- spaces = $1
- return unless spaces.size == 2
- name = $2
- version = $3
- pinned = $5
-
- version = version.split(",").map(&:strip) if version
-
- dep = Bundler::Dependency.new(name, version)
-
- if pinned && dep.name != "bundler"
- spec = @specs.find {|_, v| v.name == dep.name }
- dep.source = spec.last.source if spec
-
- # Path sources need to know what the default name / version
- # to use in the case that there are no gemspecs present. A fake
- # gemspec is created based on the version set on the dependency
- # TODO: Use the version from the spec instead of from the dependency
- if version && version.size == 1 && version.first =~ /^\s*= (.+)\s*$/ && dep.source.is_a?(Bundler::Source::Path)
- dep.source.name = name
- dep.source.version = $1
- end
- end
-
- @dependencies[dep.name] = dep
- end
-
- def parse_spec(line)
- return unless line =~ NAME_VERSION
- spaces = $1
- name = $2
- version = $3
- platform = $4
-
- if spaces.size == 4
- version = Gem::Version.new(version)
- platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
- @current_spec = LazySpecification.new(name, version, platform)
- @current_spec.source = @current_source
-
- # Avoid introducing multiple copies of the same spec (caused by
- # duplicate GIT sections)
- @specs[@current_spec.identifier] ||= @current_spec
- elsif spaces.size == 6
- version = version.split(",").map(&:strip) if version
- dep = Gem::Dependency.new(name, version)
- @current_spec.dependencies << dep
- end
- end
-
- def parse_platform(line)
- @platforms << Gem::Platform.new($1) if line =~ /^ (.*)$/
- end
-
- def parse_bundled_with(line)
- line = line.strip
- return unless Gem::Version.correct?(line)
- @bundler_version = Gem::Version.create(line)
- end
-
- def parse_ruby(line)
- @ruby_version = line.strip
- end
- end
-end
diff --git a/lib/bundler/match_platform.rb b/lib/bundler/match_platform.rb
deleted file mode 100644
index 56cbbfb95d..0000000000
--- a/lib/bundler/match_platform.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/gem_helpers"
-
-module Bundler
- module MatchPlatform
- include GemHelpers
-
- def match_platform(p)
- MatchPlatform.platforms_match?(platform, p)
- end
-
- def self.platforms_match?(gemspec_platform, local_platform)
- return true if gemspec_platform.nil?
- return true if Gem::Platform::RUBY == gemspec_platform
- return true if local_platform == gemspec_platform
- gemspec_platform = Gem::Platform.new(gemspec_platform)
- return true if GemHelpers.generic(gemspec_platform) === local_platform
- return true if gemspec_platform === local_platform
-
- false
- end
- end
-end
diff --git a/lib/bundler/mirror.rb b/lib/bundler/mirror.rb
deleted file mode 100644
index a6fa070eb8..0000000000
--- a/lib/bundler/mirror.rb
+++ /dev/null
@@ -1,223 +0,0 @@
-# frozen_string_literal: true
-
-require "socket"
-
-module Bundler
- class Settings
- # Class used to build the mirror set and then find a mirror for a given URI
- #
- # @param prober [Prober object, nil] by default a TCPSocketProbe, this object
- # will be used to probe the mirror address to validate that the mirror replies.
- class Mirrors
- def initialize(prober = nil)
- @all = Mirror.new
- @prober = prober || TCPSocketProbe.new
- @mirrors = {}
- end
-
- # Returns a mirror for the given uri.
- #
- # Depending on the uri having a valid mirror or not, it may be a
- # mirror that points to the provided uri
- def for(uri)
- if @all.validate!(@prober).valid?
- @all
- else
- fetch_valid_mirror_for(Settings.normalize_uri(uri))
- end
- end
-
- def each
- @mirrors.each do |k, v|
- yield k, v.uri.to_s
- end
- end
-
- def parse(key, value)
- config = MirrorConfig.new(key, value)
- mirror = if config.all?
- @all
- else
- @mirrors[config.uri] ||= Mirror.new
- end
- config.update_mirror(mirror)
- end
-
- private
-
- def fetch_valid_mirror_for(uri)
- downcased = uri.to_s.downcase
- mirror = @mirrors[downcased] || @mirrors[URI(downcased).host] || Mirror.new(uri)
- mirror.validate!(@prober)
- mirror = Mirror.new(uri) unless mirror.valid?
- mirror
- end
- end
-
- # A mirror
- #
- # Contains both the uri that should be used as a mirror and the
- # fallback timeout which will be used for probing if the mirror
- # replies on time or not.
- class Mirror
- DEFAULT_FALLBACK_TIMEOUT = 0.1
-
- attr_reader :uri, :fallback_timeout
-
- def initialize(uri = nil, fallback_timeout = 0)
- self.uri = uri
- self.fallback_timeout = fallback_timeout
- @valid = nil
- end
-
- def uri=(uri)
- @uri = if uri.nil?
- nil
- else
- URI(uri.to_s)
- end
- @valid = nil
- end
-
- def fallback_timeout=(timeout)
- case timeout
- when true, "true"
- @fallback_timeout = DEFAULT_FALLBACK_TIMEOUT
- when false, "false"
- @fallback_timeout = 0
- else
- @fallback_timeout = timeout.to_i
- end
- @valid = nil
- end
-
- def ==(other)
- !other.nil? && uri == other.uri && fallback_timeout == other.fallback_timeout
- end
-
- def valid?
- return false if @uri.nil?
- return @valid unless @valid.nil?
- false
- end
-
- def validate!(probe = nil)
- @valid = false if uri.nil?
- if @valid.nil?
- @valid = fallback_timeout == 0 || (probe || TCPSocketProbe.new).replies?(self)
- end
- self
- end
- end
-
- # Class used to parse one configuration line
- #
- # Gets the configuration line and the value.
- # This object provides a `update_mirror` method
- # used to setup the given mirror value.
- class MirrorConfig
- attr_accessor :uri, :value
-
- def initialize(config_line, value)
- uri, fallback =
- config_line.match(%r{\Amirror\.(all|.+?)(\.fallback_timeout)?\/?\z}).captures
- @fallback = !fallback.nil?
- @all = false
- if uri == "all"
- @all = true
- else
- @uri = URI(uri).absolute? ? Settings.normalize_uri(uri) : uri
- end
- @value = value
- end
-
- def all?
- @all
- end
-
- def update_mirror(mirror)
- if @fallback
- mirror.fallback_timeout = @value
- else
- mirror.uri = Settings.normalize_uri(@value)
- end
- end
- end
-
- # Class used for probing TCP availability for a given mirror.
- class TCPSocketProbe
- def replies?(mirror)
- MirrorSockets.new(mirror).any? do |socket, address, timeout|
- begin
- socket.connect_nonblock(address)
- rescue Errno::EINPROGRESS
- wait_for_writtable_socket(socket, address, timeout)
- rescue # Connection failed somehow, again
- false
- end
- end
- end
-
- private
-
- def wait_for_writtable_socket(socket, address, timeout)
- if IO.select(nil, [socket], nil, timeout)
- probe_writtable_socket(socket, address)
- else # TCP Handshake timed out, or there is something dropping packets
- false
- end
- end
-
- def probe_writtable_socket(socket, address)
- socket.connect_nonblock(address)
- rescue Errno::EISCONN
- true
- rescue # Connection failed
- false
- end
- end
- end
-
- # Class used to build the list of sockets that correspond to
- # a given mirror.
- #
- # One mirror may correspond to many different addresses, both
- # because of it having many dns entries or because
- # the network interface is both ipv4 and ipv5
- class MirrorSockets
- def initialize(mirror)
- @timeout = mirror.fallback_timeout
- @addresses = Socket.getaddrinfo(mirror.uri.host, mirror.uri.port).map do |address|
- SocketAddress.new(address[0], address[3], address[1])
- end
- end
-
- def any?
- @addresses.any? do |address|
- socket = Socket.new(Socket.const_get(address.type), Socket::SOCK_STREAM, 0)
- socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
- value = yield socket, address.to_socket_address, @timeout
- socket.close unless socket.closed?
- value
- end
- end
- end
-
- # Socket address builder.
- #
- # Given a socket type, a host and a port,
- # provides a method to build sockaddr string
- class SocketAddress
- attr_reader :type, :host, :port
-
- def initialize(type, host, port)
- @type = type
- @host = host
- @port = port
- end
-
- def to_socket_address
- Socket.pack_sockaddr_in(@port, @host)
- end
- end
-end
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
deleted file mode 100644
index 99c9a867b0..0000000000
--- a/lib/bundler/plugin.rb
+++ /dev/null
@@ -1,285 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/plugin/api"
-
-module Bundler
- module Plugin
- autoload :DSL, "bundler/plugin/dsl"
- autoload :Index, "bundler/plugin/index"
- autoload :Installer, "bundler/plugin/installer"
- autoload :SourceList, "bundler/plugin/source_list"
-
- class MalformattedPlugin < PluginError; end
- class UndefinedCommandError < PluginError; end
- class UnknownSourceError < PluginError; end
-
- PLUGIN_FILE_NAME = "plugins.rb".freeze
-
- module_function
-
- def reset!
- instance_variables.each {|i| remove_instance_variable(i) }
-
- @sources = {}
- @commands = {}
- @hooks_by_event = Hash.new {|h, k| h[k] = [] }
- @loaded_plugin_names = []
- end
-
- reset!
-
- # Installs a new plugin by the given name
- #
- # @param [Array<String>] names the name of plugin to be installed
- # @param [Hash] options various parameters as described in description.
- # Refer to cli/plugin for available options
- def install(names, options)
- specs = Installer.new.install(names, options)
-
- save_plugins names, specs
- rescue PluginError => e
- if specs
- specs_to_delete = Hash[specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }]
- specs_to_delete.values.each {|spec| Bundler.rm_rf(spec.full_gem_path) }
- end
-
- Bundler.ui.error "Failed to install plugin #{name}: #{e.message}\n #{e.backtrace.join("\n ")}"
- 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)
-
- return if definition.dependencies.empty?
-
- 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
- rescue => e
- unless e.is_a?(GemfileError)
- Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}"
- end
- raise
- end
-
- # The index object used to store the details about the plugin
- def index
- @index ||= Index.new
- end
-
- # The directory root for all plugin related data
- #
- # Points to root in app_config_path if ran in an app else points to the one
- # in user_bundle_path
- def root
- @root ||= if SharedHelpers.in_bundle?
- local_root
- else
- global_root
- end
- end
-
- def local_root
- Bundler.app_config_path.join("plugin")
- end
-
- # The global directory root for all plugin related data
- def global_root
- Bundler.user_bundle_path.join("plugin")
- end
-
- # The cache directory for plugin stuffs
- def cache
- @cache ||= root.join("cache")
- end
-
- # To be called via the API to register to handle a command
- def add_command(command, cls)
- @commands[command] = cls
- end
-
- # Checks if any plugin handles the command
- def command?(command)
- !index.command_plugin(command).nil?
- end
-
- # To be called from Cli class to pass the command and argument to
- # approriate plugin class
- def exec_command(command, args)
- raise UndefinedCommandError, "Command `#{command}` not found" unless command? command
-
- load_plugin index.command_plugin(command) unless @commands.key? command
-
- @commands[command].new.exec(command, args)
- end
-
- # To be called via the API to register to handle a source plugin
- def add_source(source, cls)
- @sources[source] = cls
- end
-
- # Checks if any plugin declares the source
- def source?(name)
- !index.source_plugin(name.to_s).nil?
- end
-
- # @return [Class] that handles the source. The calss includes API::Source
- def source(name)
- raise UnknownSourceError, "Source #{name} not found" unless source? name
-
- load_plugin(index.source_plugin(name)) unless @sources.key? name
-
- @sources[name]
- end
-
- # @param [Hash] The options that are present in the lock file
- # @return [API::Source] the instance of the class that handles the source
- # type passed in locked_opts
- def source_from_lock(locked_opts)
- src = source(locked_opts["type"])
-
- src.new(locked_opts.merge("uri" => locked_opts["remote"]))
- end
-
- # To be called via the API to register a hooks and corresponding block that
- # will be called to handle the hook
- def add_hook(event, &block)
- @hooks_by_event[event.to_s] << block
- end
-
- # Runs all the hooks that are registered for the passed event
- #
- # It passes the passed arguments and block to the block registered with
- # the api.
- #
- # @param [String] event
- def hook(event, *args, &arg_blk)
- return unless Bundler.feature_flag.plugins?
-
- plugins = index.hook_plugins(event)
- return unless plugins.any?
-
- (plugins - @loaded_plugin_names).each {|name| load_plugin(name) }
-
- @hooks_by_event[event].each {|blk| blk.call(*args, &arg_blk) }
- end
-
- # currently only intended for specs
- #
- # @return [String, nil] installed path
- def installed?(plugin)
- Index.new.installed?(plugin)
- end
-
- # Post installation processing and registering with index
- #
- # @param [Array<String>] plugins list to be installed
- # @param [Hash] specs of plugins mapped to installation path (currently they
- # contain all the installed specs, including plugins)
- # @param [Array<String>] names of inferred source plugins that can be ignored
- def save_plugins(plugins, specs, optional_plugins = [])
- plugins.each do |name|
- spec = specs[name]
- validate_plugin! Pathname.new(spec.full_gem_path)
- installed = register_plugin(name, spec, optional_plugins.include?(name))
- Bundler.ui.info "Installed plugin #{name}" if installed
- end
- end
-
- # Checks if the gem is good to be a plugin
- #
- # At present it only checks whether it contains plugins.rb file
- #
- # @param [Pathname] plugin_path the path plugin is installed at
- # @raise [MalformattedPlugin] if plugins.rb file is not found
- def validate_plugin!(plugin_path)
- plugin_file = plugin_path.join(PLUGIN_FILE_NAME)
- raise MalformattedPlugin, "#{PLUGIN_FILE_NAME} was not found in the plugin." unless plugin_file.file?
- end
-
- # Runs the plugins.rb file in an isolated namespace, records the plugin
- # actions it registers for and then passes the data to index to be stored.
- #
- # @param [String] name the name of the plugin
- # @param [Specification] spec of installed plugin
- # @param [Boolean] optional_plugin, removed if there is conflict with any
- # other plugin (used for default source plugins)
- #
- # @raise [MalformattedPlugin] if plugins.rb raises any error
- def register_plugin(name, spec, optional_plugin = false)
- commands = @commands
- sources = @sources
- hooks = @hooks_by_event
-
- @commands = {}
- @sources = {}
- @hooks_by_event = Hash.new {|h, k| h[k] = [] }
-
- load_paths = spec.load_paths
- add_to_load_path(load_paths)
- path = Pathname.new spec.full_gem_path
-
- begin
- load path.join(PLUGIN_FILE_NAME), true
- rescue StandardError => e
- raise MalformattedPlugin, "#{e.class}: #{e.message}"
- end
-
- if optional_plugin && @sources.keys.any? {|s| source? s }
- Bundler.rm_rf(path)
- false
- else
- index.register_plugin(name, path.to_s, load_paths, @commands.keys,
- @sources.keys, @hooks_by_event.keys)
- true
- end
- ensure
- @commands = commands
- @sources = sources
- @hooks_by_event = hooks
- end
-
- # Executes the plugins.rb file
- #
- # @param [String] name of the plugin
- def load_plugin(name)
- # Need to ensure before this that plugin root where the rest of gems
- # are installed to be on load path to support plugin deps. Currently not
- # done to avoid conflicts
- path = index.plugin_path(name)
-
- add_to_load_path(index.load_paths(name))
-
- load path.join(PLUGIN_FILE_NAME)
-
- @loaded_plugin_names << name
- rescue => e
- Bundler.ui.error "Failed loading plugin #{name}: #{e.message}"
- raise
- end
-
- def add_to_load_path(load_paths)
- if insert_index = Bundler.rubygems.load_path_insert_index
- $LOAD_PATH.insert(insert_index, *load_paths)
- else
- $LOAD_PATH.unshift(*load_paths)
- end
- end
-
- class << self
- private :load_plugin, :register_plugin, :save_plugins, :validate_plugin!,
- :add_to_load_path
- end
- end
-end
diff --git a/lib/bundler/plugin/api.rb b/lib/bundler/plugin/api.rb
deleted file mode 100644
index a2d5cbb4ac..0000000000
--- a/lib/bundler/plugin/api.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # This is the interfacing class represents the API that we intend to provide
- # the plugins to use.
- #
- # For plugins to be independent of the Bundler internals they shall limit their
- # interactions to methods of this class only. This will save them from breaking
- # when some internal change.
- #
- # Currently we are delegating the methods defined in Bundler class to
- # itself. So, this class acts as a buffer.
- #
- # If there is some change in the Bundler class that is incompatible to its
- # previous behavior or if otherwise desired, we can reimplement(or implement)
- # the method to preserve compatibility.
- #
- # To use this, either the class can inherit this class or use it directly.
- # For example of both types of use, refer the file `spec/plugins/command.rb`
- #
- # To use it without inheriting, you will have to create an object of this
- # to use the functions (except for declaration functions like command, source,
- # and hooks).
- module Plugin
- class API
- autoload :Source, "bundler/plugin/api/source"
-
- # The plugins should declare that they handle a command through this helper.
- #
- # @param [String] command being handled by them
- # @param [Class] (optional) class that handles the command. If not
- # provided, the `self` class will be used.
- def self.command(command, cls = self)
- Plugin.add_command command, cls
- end
-
- # The plugins should declare that they provide a installation source
- # through this helper.
- #
- # @param [String] the source type they provide
- # @param [Class] (optional) class that handles the source. If not
- # provided, the `self` class will be used.
- def self.source(source, cls = self)
- cls.send :include, Bundler::Plugin::API::Source
- Plugin.add_source source, cls
- end
-
- def self.hook(event, &block)
- Plugin.add_hook(event, &block)
- end
-
- # The cache dir to be used by the plugins for storage
- #
- # @return [Pathname] path of the cache dir
- def cache_dir
- Plugin.cache.join("plugins")
- end
-
- # A tmp dir to be used by plugins
- # Accepts names that get concatenated as suffix
- #
- # @return [Pathname] object for the new directory created
- def tmp(*names)
- Bundler.tmp(["plugin", *names].join("-"))
- end
-
- def method_missing(name, *args, &blk)
- return Bundler.send(name, *args, &blk) if Bundler.respond_to?(name)
-
- return SharedHelpers.send(name, *args, &blk) if SharedHelpers.respond_to?(name)
-
- super
- end
-
- def respond_to_missing?(name, include_private = false)
- SharedHelpers.respond_to?(name, include_private) ||
- Bundler.respond_to?(name, include_private) || super
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
deleted file mode 100644
index 586477efb5..0000000000
--- a/lib/bundler/plugin/api/source.rb
+++ /dev/null
@@ -1,306 +0,0 @@
-# frozen_string_literal: true
-
-require "uri"
-
-module Bundler
- module Plugin
- class API
- # This class provides the base to build source plugins
- # All the method here are required to build a source plugin (except
- # `uri_hash`, `gem_install_dir`; they are helpers).
- #
- # Defaults for methods, where ever possible are provided which is
- # expected to work. But, all source plugins have to override
- # `fetch_gemspec_files` and `install`. Defaults are also not provided for
- # `remote!`, `cache!` and `unlock!`.
- #
- # The defaults shall work for most situations but nevertheless they can
- # be (preferably should be) overridden as per the plugins' needs safely
- # (as long as they behave as expected).
- # On overriding `initialize` you should call super first.
- #
- # If required plugin should override `hash`, `==` and `eql?` methods to be
- # able to match objects representing same sources, but may be created in
- # different situation (like form gemfile and lockfile). The default ones
- # checks only for class and uri, but elaborate source plugins may need
- # more comparisons (e.g. git checking on branch or tag).
- #
- # @!attribute [r] uri
- # @return [String] the remote specified with `source` block in Gemfile
- #
- # @!attribute [r] options
- # @return [String] options passed during initialization (either from
- # lockfile or Gemfile)
- #
- # @!attribute [r] name
- # @return [String] name that can be used to uniquely identify a source
- #
- # @!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
- # is present to be compatible with `Definition` and is used by
- # rubygems source.
- module Source
- attr_reader :uri, :options, :name
- attr_accessor :dependency_names
-
- def initialize(opts)
- @options = opts
- @dependency_names = []
- @uri = opts["uri"]
- @type = opts["type"]
- @name = opts["name"] || "#{@type} at #{@uri}"
- end
-
- # This is used by the default `spec` method to constructs the
- # Specification objects for the gems and versions that can be installed
- # by this source plugin.
- #
- # Note: If the spec method is overridden, this function is not necessary
- #
- # @return [Array<String>] paths of the gemspec files for gems that can
- # be installed
- def fetch_gemspec_files
- []
- end
-
- # Options to be saved in the lockfile so that the source plugin is able
- # to check out same version of gem later.
- #
- # There options are passed when the source plugin is created from the
- # lock file.
- #
- # @return [Hash]
- def options_to_lock
- {}
- end
-
- # Install the gem specified by the spec at appropriate path.
- # `install_path` provides a sufficient default, if the source can only
- # satisfy one gem, but is not binding.
- #
- # @return [String] post installation message (if any)
- def install(spec, opts)
- raise MalformattedPlugin, "Source plugins need to override the install method."
- end
-
- # It builds extensions, generates bins and installs them for the spec
- # provided.
- #
- # It depends on `spec.loaded_from` to get full_gem_path. The source
- # plugins should set that.
- #
- # It should be called in `install` after the plugin is done placing the
- # gem at correct install location.
- #
- # It also runs Gem hooks `pre_install`, `post_build` and `post_install`
- #
- # Note: Do not override if you don't know what you are doing.
- def post_install(spec, disable_exts = false)
- opts = { :env_shebang => false, :disable_extensions => disable_exts }
- installer = Bundler::Source::Path::Installer.new(spec, opts)
- installer.post_install
- end
-
- # A default installation path to install a single gem. If the source
- # servers multiple gems, it's not of much use and the source should one
- # of its own.
- def install_path
- @install_path ||=
- begin
- base_name = File.basename(URI.parse(uri).normalize.path)
-
- gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}")
- end
- end
-
- # Parses the gemspec files to find the specs for the gems that can be
- # satisfied by the source.
- #
- # Few important points to keep in mind:
- # - If the gems are not installed then it shall return specs for all
- # the gems it can satisfy
- # - If gem is installed (that is to be detected by the plugin itself)
- # then it shall return at least the specs that are installed.
- # - The `loaded_from` for each of the specs shall be correct (it is
- # used to find the load path)
- #
- # @return [Bundler::Index] index containing the specs
- def specs
- files = fetch_gemspec_files
-
- Bundler::Index.build do |index|
- files.each do |file|
- next unless spec = Bundler.load_gemspec(file)
- Bundler.rubygems.set_installed_by_version(spec)
-
- spec.source = self
- Bundler.rubygems.validate(spec)
-
- index << spec
- end
- end
- end
-
- # Set internal representation to fetch the gems/specs from remote.
- #
- # When this is called, the source should try to fetch the specs and
- # install from remote path.
- def remote!
- end
-
- # Set internal representation to fetch the gems/specs from app cache.
- #
- # When this is called, the source should try to fetch the specs and
- # install from the path provided by `app_cache_path`.
- def cached!
- end
-
- # This is called to update the spec and installation.
- #
- # If the source plugin is loaded from lockfile or otherwise, it shall
- # refresh the cache/specs (e.g. git sources can make a fresh clone).
- def unlock!
- end
-
- # Name of directory where plugin the is expected to cache the gems when
- # #cache is called.
- #
- # Also this name is matched against the directories in cache for pruning
- #
- # This is used by `app_cache_path`
- def app_cache_dirname
- base_name = File.basename(URI.parse(uri).normalize.path)
- "#{base_name}-#{uri_hash}"
- end
-
- # This method is called while caching to save copy of the gems that the
- # source can resolve to path provided by `app_cache_app`so that they can
- # be reinstalled from the cache without querying the remote (i.e. an
- # alternative to remote)
- #
- # This is stored with the app and source plugins should try to provide
- # specs and install only from this cache when `cached!` is called.
- #
- # This cache is different from the internal caching that can be done
- # at sub paths of `cache_path` (from API). This can be though as caching
- # by bundler.
- def cache(spec, custom_path = nil)
- new_cache_path = app_cache_path(custom_path)
-
- FileUtils.rm_rf(new_cache_path)
- FileUtils.cp_r(install_path, new_cache_path)
- FileUtils.touch(app_cache_path.join(".bundlecache"))
- end
-
- # This shall check if two source object represent the same source.
- #
- # The comparison shall take place only on the attribute that can be
- # inferred from the options passed from Gemfile and not on attibutes
- # that are used to pin down the gem to specific version (e.g. Git
- # sources should compare on branch and tag but not on commit hash)
- #
- # The sources objects are constructed from Gemfile as well as from
- # lockfile. To converge the sources, it is necessary that they match.
- #
- # The same applies for `eql?` and `hash`
- def ==(other)
- other.is_a?(self.class) && uri == other.uri
- end
-
- # When overriding `eql?` please preserve the behaviour as mentioned in
- # docstring for `==` method.
- alias_method :eql?, :==
-
- # When overriding `hash` please preserve the behaviour as mentioned in
- # docstring for `==` method, i.e. two methods equal by above comparison
- # should have same hash.
- def hash
- [self.class, uri].hash
- end
-
- # A helper method, not necessary if not used internally.
- def installed?
- File.directory?(install_path)
- end
-
- # The full path where the plugin should cache the gem so that it can be
- # installed latter.
- #
- # Note: Do not override if you don't know what you are doing.
- def app_cache_path(custom_path = nil)
- @app_cache_path ||= Bundler.app_cache(custom_path).join(app_cache_dirname)
- end
-
- # Used by definition.
- #
- # Note: Do not override if you don't know what you are doing.
- def unmet_deps
- specs.unmet_dependency_names
- end
-
- # Note: Do not override if you don't know what you are doing.
- def can_lock?(spec)
- spec.source == self
- end
-
- # Generates the content to be entered into the lockfile.
- # Saves type and remote and also calls to `options_to_lock`.
- #
- # Plugin should use `options_to_lock` to save information in lockfile
- # and not override this.
- #
- # Note: Do not override if you don't know what you are doing.
- def to_lock
- out = String.new("#{LockfileParser::PLUGIN}\n")
- out << " remote: #{@uri}\n"
- out << " type: #{@type}\n"
- options_to_lock.each do |opt, value|
- out << " #{opt}: #{value}\n"
- end
- out << " specs:\n"
- end
-
- def to_s
- "plugin source for #{options[:type]} with uri #{uri}"
- end
-
- # Note: Do not override if you don't know what you are doing.
- def include?(other)
- other == self
- end
-
- def uri_hash
- SharedHelpers.digest(:SHA1).hexdigest(uri)
- end
-
- # Note: Do not override if you don't know what you are doing.
- def gem_install_dir
- Bundler.install_path
- end
-
- # It is used to obtain the full_gem_path.
- #
- # spec's loaded_from path is expanded against this to get full_gem_path
- #
- # Note: Do not override if you don't know what you are doing.
- def root
- Bundler.root
- end
-
- # @private
- # Returns true
- def bundler_plugin_api_source?
- true
- end
-
- # @private
- # This API on source might not be stable, and for now we expect plugins
- # to download all specs in `#specs`, so we implement the method for
- # compatibility purposes and leave it undocumented (and don't support)
- # overriding it)
- def double_check_for(*); end
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/dsl.rb b/lib/bundler/plugin/dsl.rb
deleted file mode 100644
index 4bfc8437e0..0000000000
--- a/lib/bundler/plugin/dsl.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module Plugin
- # Dsl to parse the Gemfile looking for plugins to install
- class DSL < Bundler::Dsl
- class PluginGemfileError < PluginError; end
- alias_method :_gem, :gem # To use for plugin installation as gem
-
- # So that we don't have to override all there methods to dummy ones
- # explicitly.
- # They will be handled by method_missing
- [:gemspec, :gem, :path, :install_if, :platforms, :env].each {|m| undef_method m }
-
- # This lists the plugins that was added automatically and not specified by
- # the user.
- #
- # When we encounter :type attribute with a source block, we add a plugin
- # by name bundler-source-<type> to list of plugins to be installed.
- #
- # These plugins are optional and are not installed when there is conflict
- # with any other plugin.
- attr_reader :inferred_plugins
-
- def initialize
- super
- @sources = Plugin::SourceList.new
- @inferred_plugins = [] # The source plugins inferred from :type
- end
-
- def plugin(name, *args)
- _gem(name, *args)
- end
-
- def method_missing(name, *args)
- raise PluginGemfileError, "Undefined local variable or method `#{name}' for Gemfile" unless Bundler::Dsl.method_defined? name
- end
-
- def source(source, *args, &blk)
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
- options = normalize_hash(options)
- return super unless options.key?("type")
-
- plugin_name = "bundler-source-#{options["type"]}"
-
- return if @dependencies.any? {|d| d.name == plugin_name }
-
- plugin(plugin_name)
- @inferred_plugins << plugin_name
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb
deleted file mode 100644
index 8dde072f16..0000000000
--- a/lib/bundler/plugin/index.rb
+++ /dev/null
@@ -1,157 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # Manages which plugins are installed and their sources. This also is supposed to map
- # which plugin does what (currently the features are not implemented so this class is
- # now a stub class).
- module Plugin
- class Index
- class CommandConflict < PluginError
- def initialize(plugin, commands)
- msg = "Command(s) `#{commands.join("`, `")}` declared by #{plugin} are already registered."
- super msg
- end
- end
-
- class SourceConflict < PluginError
- def initialize(plugin, sources)
- msg = "Source(s) `#{sources.join("`, `")}` declared by #{plugin} are already registered."
- super msg
- end
- end
-
- attr_reader :commands
-
- def initialize
- @plugin_paths = {}
- @commands = {}
- @sources = {}
- @hooks = {}
- @load_paths = {}
-
- load_index(global_index_file, true)
- load_index(local_index_file) if SharedHelpers.in_bundle?
- end
-
- # This function is to be called when a new plugin is installed. This
- # function shall add the functions of the plugin to existing maps and also
- # the name to source location.
- #
- # @param [String] name of the plugin to be registered
- # @param [String] path where the plugin is installed
- # @param [Array<String>] load_paths for the plugin
- # @param [Array<String>] commands that are handled by the plugin
- # @param [Array<String>] sources that are handled by the plugin
- def register_plugin(name, path, load_paths, commands, sources, hooks)
- old_commands = @commands.dup
-
- common = commands & @commands.keys
- raise CommandConflict.new(name, common) unless common.empty?
- commands.each {|c| @commands[c] = name }
-
- common = sources & @sources.keys
- raise SourceConflict.new(name, common) unless common.empty?
- sources.each {|k| @sources[k] = name }
-
- hooks.each {|e| (@hooks[e] ||= []) << name }
-
- @plugin_paths[name] = path
- @load_paths[name] = load_paths
- save_index
- rescue
- @commands = old_commands
- raise
- end
-
- # Path of default index file
- def index_file
- Plugin.root.join("index")
- end
-
- # Path where the global index file is stored
- def global_index_file
- Plugin.global_root.join("index")
- end
-
- # Path where the local index file is stored
- def local_index_file
- Plugin.local_root.join("index")
- end
-
- def plugin_path(name)
- Pathname.new @plugin_paths[name]
- end
-
- def load_paths(name)
- @load_paths[name]
- end
-
- # Fetch the name of plugin handling the command
- def command_plugin(command)
- @commands[command]
- end
-
- def installed?(name)
- @plugin_paths[name]
- end
-
- def source?(source)
- @sources.key? source
- end
-
- def source_plugin(name)
- @sources[name]
- end
-
- # Returns the list of plugin names handling the passed event
- def hook_plugins(event)
- @hooks[event] || []
- end
-
- private
-
- # Reads the index file from the directory and initializes the instance
- # variables.
- #
- # It skips the sources if the second param is true
- # @param [Pathname] index file path
- # @param [Boolean] is the index file global index
- def load_index(index_file, global = false)
- SharedHelpers.filesystem_access(index_file, :read) do |index_f|
- valid_file = index_f && index_f.exist? && !index_f.size.zero?
- break unless valid_file
-
- data = index_f.read
-
- require "bundler/yaml_serializer"
- index = YAMLSerializer.load(data)
-
- @commands.merge!(index["commands"])
- @hooks.merge!(index["hooks"])
- @load_paths.merge!(index["load_paths"])
- @plugin_paths.merge!(index["plugin_paths"])
- @sources.merge!(index["sources"]) unless global
- end
- end
-
- # Should be called when any of the instance variables change. Stores the
- # instance variables in YAML format. (The instance variables are supposed
- # to be only String key value pairs)
- def save_index
- index = {
- "commands" => @commands,
- "hooks" => @hooks,
- "load_paths" => @load_paths,
- "plugin_paths" => @plugin_paths,
- "sources" => @sources,
- }
-
- require "bundler/yaml_serializer"
- SharedHelpers.filesystem_access(index_file) do |index_f|
- FileUtils.mkdir_p(index_f.dirname)
- File.open(index_f, "w") {|f| f.puts YAMLSerializer.dump(index) }
- end
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb
deleted file mode 100644
index 5379c38979..0000000000
--- a/lib/bundler/plugin/installer.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # Handles the installation of plugin in appropriate directories.
- #
- # This class is supposed to be wrapper over the existing gem installation infra
- # but currently it itself handles everything as the Source's subclasses (e.g. Source::RubyGems)
- # are heavily dependent on the Gemfile.
- module Plugin
- class Installer
- autoload :Rubygems, "bundler/plugin/installer/rubygems"
- autoload :Git, "bundler/plugin/installer/git"
-
- def install(names, options)
- version = options[:version] || [">= 0"]
- Bundler.settings.temporary(:lockfile_uses_separate_rubygems_sources => false, :disable_multisource => false) do
- if options[:git]
- install_git(names, version, options)
- else
- sources = options[:source] || Bundler.rubygems.sources
- install_rubygems(names, version, sources)
- end
- end
- end
-
- # Installs the plugin from Definition object created by limited parsing of
- # Gemfile searching for plugins to be installed
- #
- # @param [Definition] definition object
- # @return [Hash] map of names to their specs they are installed with
- def install_definition(definition)
- def definition.lock(*); end
- definition.resolve_remotely!
- specs = definition.specs
-
- install_from_specs specs
- end
-
- private
-
- 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
-
- deps = names.map {|name| Dependency.new name, version }
-
- definition = Definition.new(nil, deps, source_list, true)
- install_definition(definition)
- end
-
- # Installs the plugin from rubygems source and returns the path where the
- # plugin was installed
- #
- # @param [String] name of the plugin gem to search in the source
- # @param [Array] version of the gem to install
- # @param [String, Array<String>] source(s) to resolve the gem
- #
- # @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 }
-
- source_list = SourceList.new
- source_list.add_rubygems_source("remotes" => sources)
-
- definition = Definition.new(nil, deps, source_list, true)
- install_definition(definition)
- end
-
- # Installs the plugins and deps from the provided specs and returns map of
- # gems to their paths
- #
- # @param specs to install
- #
- # @return [Hash] map of names to the specs
- def install_from_specs(specs)
- paths = {}
-
- specs.each do |spec|
- spec.source.install spec
-
- paths[spec.name] = spec
- end
-
- paths
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/installer/git.rb b/lib/bundler/plugin/installer/git.rb
deleted file mode 100644
index fbb6c5e40e..0000000000
--- a/lib/bundler/plugin/installer/git.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module Plugin
- class Installer
- class Git < Bundler::Source::Git
- def cache_path
- @cache_path ||= begin
- git_scope = "#{base_name}-#{uri_hash}"
-
- Plugin.cache.join("bundler", "git", git_scope)
- end
- end
-
- def install_path
- @install_path ||= begin
- git_scope = "#{base_name}-#{shortref_for_path(revision)}"
-
- Plugin.root.join("bundler", "gems", git_scope)
- end
- end
-
- def version_message(spec)
- "#{spec.name} #{spec.version}"
- end
-
- def root
- Plugin.root
- end
-
- def generate_bin(spec, disable_extensions = false)
- # Need to find a way without code duplication
- # For now, we can ignore this
- end
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/installer/rubygems.rb b/lib/bundler/plugin/installer/rubygems.rb
deleted file mode 100644
index 7ae74fa93b..0000000000
--- a/lib/bundler/plugin/installer/rubygems.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module Plugin
- class Installer
- class Rubygems < Bundler::Source::Rubygems
- def version_message(spec)
- "#{spec.name} #{spec.version}"
- end
-
- private
-
- def requires_sudo?
- false # Will change on implementation of project level plugins
- end
-
- def rubygems_dir
- Plugin.root
- end
-
- def cache_path
- Plugin.cache
- end
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/source_list.rb b/lib/bundler/plugin/source_list.rb
deleted file mode 100644
index f0e212205f..0000000000
--- a/lib/bundler/plugin/source_list.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # SourceList object to be used while parsing the Gemfile, setting the
- # approptiate options to be used with Source classes for plugin installation
- module Plugin
- class SourceList < Bundler::SourceList
- def add_git_source(options = {})
- add_source_to_list Plugin::Installer::Git.new(options), git_sources
- end
-
- def add_rubygems_source(options = {})
- add_source_to_list Plugin::Installer::Rubygems.new(options), @rubygems_sources
- end
-
- def all_sources
- path_sources + git_sources + rubygems_sources + [metadata_source]
- end
-
- private
-
- def rubygems_aggregate_class
- Plugin::Installer::Rubygems
- end
- end
- end
-end
diff --git a/lib/bundler/process_lock.rb b/lib/bundler/process_lock.rb
deleted file mode 100644
index 4bd6931577..0000000000
--- a/lib/bundler/process_lock.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class ProcessLock
- def self.lock(bundle_path = Bundler.bundle_path)
- lock_file_path = File.join(bundle_path, "bundler.lock")
- has_lock = false
-
- File.open(lock_file_path, "w") do |f|
- f.flock(File::LOCK_EX)
- has_lock = true
- yield
- f.flock(File::LOCK_UN)
- end
- rescue Errno::EACCES, Errno::ENOLCK
- # In the case the user does not have access to
- # create the lock file or is using NFS where
- # locks are not available we skip locking.
- yield
- ensure
- FileUtils.rm_f(lock_file_path) if has_lock
- end
- end
-end
diff --git a/lib/bundler/psyched_yaml.rb b/lib/bundler/psyched_yaml.rb
deleted file mode 100644
index e654416a5a..0000000000
--- a/lib/bundler/psyched_yaml.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-# Psych could be a gem, so try to ask for it
-begin
- gem "psych"
-rescue LoadError
-end if defined?(gem)
-
-# Psych could be in the stdlib
-# but it's too late if Syck is already loaded
-begin
- require "psych" unless defined?(Syck)
-rescue LoadError
- # Apparently Psych wasn't available. Oh well.
-end
-
-# At least load the YAML stdlib, whatever that may be
-require "yaml" unless defined?(YAML.dump)
-
-module Bundler
- # On encountering invalid YAML,
- # Psych raises Psych::SyntaxError
- if defined?(::Psych::SyntaxError)
- YamlLibrarySyntaxError = ::Psych::SyntaxError
- else # Syck raises ArgumentError
- YamlLibrarySyntaxError = ::ArgumentError
- end
-end
-
-require "bundler/deprecate"
-begin
- Bundler::Deprecate.skip_during do
- require "rubygems/safe_yaml"
- end
-rescue LoadError
- # it's OK if the file isn't there
-end
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
deleted file mode 100644
index 23e1234330..0000000000
--- a/lib/bundler/remote_specification.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-# frozen_string_literal: true
-
-require "uri"
-
-module Bundler
- # Represents a lazily loaded gem specification, where the full specification
- # is on the source server in rubygems' "quick" index. The proxy object is to
- # be seeded with what we're given from the source's abbreviated index - the
- # full specification will only be fetched when necessary.
- class RemoteSpecification
- include MatchPlatform
- include Comparable
-
- attr_reader :name, :version, :platform
- attr_writer :dependencies
- attr_accessor :source, :remote
-
- def initialize(name, version, platform, spec_fetcher)
- @name = name
- @version = Gem::Version.create version
- @platform = platform
- @spec_fetcher = spec_fetcher
- @dependencies = nil
- end
-
- # Needed before installs, since the arch matters then and quick
- # specs don't bother to include the arch in the platform string
- def fetch_platform
- @platform = _remote_specification.platform
- end
-
- def full_name
- if platform == Gem::Platform::RUBY || platform.nil?
- "#{@name}-#{@version}"
- else
- "#{@name}-#{@version}-#{platform}"
- end
- end
-
- # Compare this specification against another object. Using sort_obj
- # is compatible with Gem::Specification and other Bundler or RubyGems
- # objects. Otherwise, use the default Object comparison.
- def <=>(other)
- if other.respond_to?(:sort_obj)
- sort_obj <=> other.sort_obj
- else
- super
- end
- end
-
- # Because Rubyforge cannot be trusted to provide valid specifications
- # once the remote gem is downloaded, the backend specification will
- # be swapped out.
- def __swap__(spec)
- SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
- @_remote_specification = spec
- end
-
- # Create a delegate used for sorting. This strategy is copied from
- # RubyGems 2.23 and ensures that Bundler's specifications can be
- # compared and sorted with RubyGems' own specifications.
- #
- # @see #<=>
- # @see Gem::Specification#sort_obj
- #
- # @return [Array] an object you can use to compare and sort this
- # specification against other specifications
- def sort_obj
- [@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1]
- end
-
- def to_s
- "#<#{self.class} name=#{name} version=#{version} platform=#{platform}>"
- end
-
- def dependencies
- @dependencies ||= begin
- deps = method_missing(:dependencies)
-
- # allow us to handle when the specs dependencies are an array of array of string
- # see https://github.com/bundler/bundler/issues/5797
- deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) }
-
- deps
- end
- end
-
- def git_version
- return unless loaded_from && source.is_a?(Bundler::Source::Git)
- " #{source.revision[0..6]}"
- end
-
- private
-
- def to_ary
- nil
- end
-
- def _remote_specification
- @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
- @_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \
- " missing from the server! Try installing with `--full-index` as a workaround.")
- end
-
- def method_missing(method, *args, &blk)
- _remote_specification.send(method, *args, &blk)
- end
-
- def respond_to?(method, include_all = false)
- super || _remote_specification.respond_to?(method, include_all)
- end
- public :respond_to?
- end
-end
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
deleted file mode 100644
index 052d776183..0000000000
--- a/lib/bundler/resolver.rb
+++ /dev/null
@@ -1,372 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Resolver
- require "bundler/vendored_molinillo"
- require "bundler/resolver/spec_group"
-
- # Figures out the best possible configuration of gems that satisfies
- # the list of passed dependencies and any child dependencies without
- # causing any gem activation errors.
- #
- # ==== Parameters
- # *dependencies<Gem::Dependency>:: The list of dependencies to resolve
- #
- # ==== Returns
- # <GemBundle>,nil:: If the list of dependencies can be resolved, a
- # collection of gemspecs is returned. Otherwise, nil is returned.
- def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
- platforms = Set.new(platforms) if platforms
- base = SpecSet.new(base) unless base.is_a?(SpecSet)
- resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
- result = resolver.start(requirements)
- SpecSet.new(result)
- end
-
- def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
- @index = index
- @source_requirements = source_requirements
- @base = base
- @resolver = Molinillo::Resolver.new(self, self)
- @search_for = {}
- @base_dg = Molinillo::DependencyGraph.new
- @base.each do |ls|
- dep = Dependency.new(ls.name, ls.version)
- @base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
- end
- additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
- @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?
- end
-
- def start(requirements)
- @prerelease_specified = {}
- requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
-
- verify_gemfile_dependencies_are_found!(requirements)
- dg = @resolver.resolve(requirements, @base_dg)
- dg.map(&:payload).
- reject {|sg| sg.name.end_with?("\0") }.
- map(&:to_specs).flatten
- rescue Molinillo::VersionConflict => e
- message = version_conflict_message(e)
- raise VersionConflict.new(e.conflicts.keys.uniq, message)
- rescue Molinillo::CircularDependencyError => e
- names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
- raise CyclicDependencyError, "Your bundle requires gems that depend" \
- " on each other, creating an infinite loop. Please remove" \
- " #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \
- " and try again."
- end
-
- include Molinillo::UI
-
- # Conveys debug information to the user.
- #
- # @param [Integer] depth the current depth of the resolution process.
- # @return [void]
- def debug(depth = 0)
- return unless debug?
- debug_info = yield
- debug_info = debug_info.inspect unless debug_info.is_a?(String)
- STDERR.puts debug_info.split("\n").map {|s| " " * depth + s }
- end
-
- def debug?
- return @debug_mode if defined?(@debug_mode)
- @debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
- end
-
- def before_resolution
- Bundler.ui.info "Resolving dependencies...", debug?
- end
-
- def after_resolution
- Bundler.ui.info ""
- end
-
- def indicate_progress
- Bundler.ui.info ".", false unless debug?
- end
-
- include Molinillo::SpecificationProvider
-
- def dependencies_for(specification)
- specification.dependencies_for_activated_platforms
- end
-
- def search_for(dependency)
- platform = dependency.__platform
- dependency = dependency.dep unless dependency.is_a? Gem::Dependency
- search = @search_for[dependency] ||= begin
- index = index_for(dependency)
- results = index.search(dependency, @base[dependency.name])
-
- unless @prerelease_specified[dependency.name]
- # Move prereleases to the beginning of the list, so they're considered
- # last during resolution.
- pre, results = results.partition {|spec| spec.version.prerelease? }
- results = pre + results
- end
-
- if vertex = @base_dg.vertex_named(dependency.name)
- locked_requirement = vertex.payload.requirement
- end
- spec_groups = if results.any?
- nested = []
- results.each do |spec|
- version, specs = nested.last
- if version == spec.version
- specs << spec
- else
- nested << [spec.version, [spec]]
- end
- end
- nested.reduce([]) do |groups, (version, specs)|
- next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
- spec_group = SpecGroup.new(specs)
- spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
- groups << spec_group
- end
- else
- []
- end
- # GVP handles major itself, but it's still a bit risky to trust it with it
- # until we get it settled with new behavior. For 2.x it can take over all cases.
- if @gem_version_promoter.major?
- spec_groups
- else
- @gem_version_promoter.sort_versions(dependency, spec_groups)
- end
- end
- search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
- end
-
- def index_for(dependency)
- source = @source_requirements[dependency.name]
- if source
- source.specs
- elsif @lockfile_uses_separate_rubygems_sources
- Index.build do |idx|
- if dependency.all_sources
- dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
- else
- idx.add_source @source_requirements[:default].specs
- end
- end
- else
- @index
- end
- end
-
- def name_for(dependency)
- dependency.name
- end
-
- def name_for_explicit_dependency_source
- Bundler.default_gemfile.basename.to_s
- rescue
- "Gemfile"
- end
-
- def name_for_locking_dependency_source
- Bundler.default_lockfile.basename.to_s
- rescue
- "Gemfile.lock"
- end
-
- def requirement_satisfied_by?(requirement, activated, spec)
- return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
- if spec.version.prerelease? && !requirement.prerelease? && search_for(requirement).any? {|sg| !sg.version.prerelease? }
- vertex = activated.vertex_named(spec.name)
- return false if vertex.requirements.none?(&:prerelease?)
- end
- spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
- true
- end
-
- def relevant_sources_for_vertex(vertex)
- if vertex.root?
- [@source_requirements[vertex.name]]
- elsif @lockfile_uses_separate_rubygems_sources
- vertex.recursive_predecessors.map do |v|
- @source_requirements[v.name]
- end << @source_requirements[:default]
- end
- end
-
- def sort_dependencies(dependencies, activated, conflicts)
- dependencies.sort_by do |dependency|
- dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
- name = name_for(dependency)
- vertex = activated.vertex_named(name)
- [
- @base_dg.vertex_named(name) ? 0 : 1,
- vertex.payload ? 0 : 1,
- vertex.root? ? 0 : 1,
- amount_constrained(dependency),
- conflicts[name] ? 0 : 1,
- vertex.payload ? 0 : search_for(dependency).count,
- self.class.platform_sort_key(dependency.__platform),
- ]
- end
- end
-
- # Sort platforms from most general to most specific
- def self.sort_platforms(platforms)
- platforms.sort_by do |platform|
- platform_sort_key(platform)
- end
- end
-
- def self.platform_sort_key(platform)
- return ["", "", ""] if Gem::Platform::RUBY == platform
- platform.to_a.map {|part| part || "" }
- end
-
- private
-
- # returns an integer \in (-\infty, 0]
- # a number closer to 0 means the dependency is less constraining
- #
- # dependencies w/ 0 or 1 possibilities (ignoring version requirements)
- # are given very negative values, so they _always_ sort first,
- # before dependencies that are unconstrained
- def amount_constrained(dependency)
- @amount_constrained ||= {}
- @amount_constrained[dependency.name] ||= begin
- if (base = @base[dependency.name]) && !base.empty?
- dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
- else
- all = index_for(dependency).search(dependency.name).size
-
- if all <= 1
- all - 1_000_000
- else
- search = search_for(dependency)
- search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
- search - all
- end
- end
- end
- end
-
- def verify_gemfile_dependencies_are_found!(requirements)
- requirements.each do |requirement|
- name = requirement.name
- next if name == "bundler"
- next unless search_for(requirement).empty?
-
- cache_message = begin
- " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
- rescue GemfileNotFound
- nil
- end
-
- if (base = @base[name]) && !base.empty?
- version = base.first.version
- message = "You have requested:\n" \
- " #{name} #{requirement.requirement}\n\n" \
- "The bundle currently has #{name} locked at #{version}.\n" \
- "Try running `bundle update #{name}`\n\n" \
- "If you are updating multiple gems in your Gemfile at once,\n" \
- "try passing them all to `bundle update`"
- elsif source = @source_requirements[name]
- specs = source.specs[name]
- 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
- else
- message = "Could not find gem '#{requirement}' in any of the gem sources " \
- "listed in your Gemfile#{cache_message}."
- end
- raise GemNotFound, message
- end
- end
-
- def formatted_versions_with_platforms(versions_with_platforms)
- version_platform_strs = versions_with_platforms.map do |vwp|
- version = vwp.first
- platform = vwp.last
- version_platform_str = String.new(version.to_s)
- version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
- version_platform_str
- end
- version_platform_strs.join(", ")
- end
-
- def version_conflict_message(e)
- e.message_with_trees(
- :solver_name => "Bundler",
- :possibility_type => "gem",
- :reduce_trees => lambda do |trees|
- # bail out if tree size is too big for Array#combination to make any sense
- return trees if trees.size > 15
- maximal = 1.upto(trees.size).map do |size|
- trees.map(&:last).flatten(1).combination(size).to_a
- 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.sort_by {|t| t.reverse.map(&:name) }
- end,
- :printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
- :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)
- end
-
- if name == "bundler" && other_bundler_required
- o << "\n"
- o << "This Gemfile requires a different version of Bundler.\n"
- o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
- end
- if conflict.locked_requirement
- o << "\n"
- o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
- o << %(the gems in your Gemfile, which may resolve the conflict.\n)
- elsif !conflict.existing
- o << "\n"
-
- relevant_sources = if conflict.requirement.source
- [conflict.requirement.source]
- elsif conflict.requirement.all_sources
- conflict.requirement.all_sources
- elsif @lockfile_uses_separate_rubygems_sources
- # every conflict should have an explicit group of sources when we
- # enforce strict pinning
- raise "no source set for #{conflict}"
- else
- []
- end.compact.map(&:to_s).uniq.sort
-
- o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
- if conflict.requirement_trees.first.size > 1
- o << ", which is required by "
- o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
- end
- 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
- end
- end,
- :version_for_spec => lambda {|spec| spec.version }
- )
- end
- end
-end
diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb
deleted file mode 100644
index 9c10a4b733..0000000000
--- a/lib/bundler/resolver/spec_group.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Resolver
- class SpecGroup
- include GemHelpers
-
- attr_accessor :name, :version, :source
- attr_accessor :ignores_bundler_dependencies
-
- def initialize(all_specs)
- raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
- @name = exemplary_spec.name
- @version = exemplary_spec.version
- @source = exemplary_spec.source
-
- @required_by = []
- @activated_platforms = []
- @dependencies = nil
- @specs = Hash.new do |specs, platform|
- specs[platform] = select_best_platform_match(all_specs, platform)
- end
- @ignores_bundler_dependencies = true
- end
-
- def to_specs
- @activated_platforms.map do |p|
- next unless s = @specs[p]
- lazy_spec = LazySpecification.new(name, version, s.platform, source)
- lazy_spec.dependencies.replace s.dependencies
- lazy_spec
- end.compact
- end
-
- def activate_platform!(platform)
- return unless for?(platform)
- return if @activated_platforms.include?(platform)
- @activated_platforms << platform
- end
-
- def for?(platform)
- spec = @specs[platform]
- !spec.nil?
- end
-
- def to_s
- @to_s ||= "#{name} (#{version})"
- end
-
- def dependencies_for_activated_platforms
- dependencies = @activated_platforms.map {|p| __dependencies[p] }
- metadata_dependencies = @activated_platforms.map do |platform|
- metadata_dependencies(@specs[platform], platform)
- end
- dependencies.concat(metadata_dependencies).flatten
- end
-
- def platforms_for_dependency_named(dependency)
- __dependencies.select {|_, deps| deps.map(&:name).include? dependency }.keys
- end
-
- def ==(other)
- return unless other.is_a?(SpecGroup)
- name == other.name &&
- version == other.version &&
- source == other.source
- end
-
- def eql?(other)
- name.eql?(other.name) &&
- version.eql?(other.version) &&
- source.eql?(other.source)
- end
-
- def hash
- to_s.hash ^ source.hash
- end
-
- private
-
- def __dependencies
- @dependencies = Hash.new do |dependencies, platform|
- dependencies[platform] = []
- if spec = @specs[platform]
- spec.dependencies.each do |dep|
- next if dep.type == :development
- next if @ignores_bundler_dependencies && dep.name == "bundler".freeze
- dependencies[platform] << DepProxy.new(dep, platform)
- end
- end
- dependencies[platform]
- end
- end
-
- def metadata_dependencies(spec, platform)
- return [] unless spec
- # Only allow endpoint specifications since they won't hit the network to
- # fetch the full gemspec when calling required_ruby_version
- 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)
- 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)
- end
- dependencies
- end
- end
- end
-end
diff --git a/lib/bundler/retry.rb b/lib/bundler/retry.rb
deleted file mode 100644
index 244606dcc9..0000000000
--- a/lib/bundler/retry.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # General purpose class for retrying code that may fail
- class Retry
- attr_accessor :name, :total_runs, :current_run
-
- class << self
- def default_attempts
- default_retries + 1
- end
- alias_method :attempts, :default_attempts
-
- def default_retries
- Bundler.settings[:retry]
- end
- end
-
- def initialize(name, exceptions = nil, retries = self.class.default_retries)
- @name = name
- @retries = retries
- @exceptions = Array(exceptions) || []
- @total_runs = @retries + 1 # will run once, then upto attempts.times
- end
-
- def attempt(&block)
- @current_run = 0
- @failed = false
- @error = nil
- run(&block) while keep_trying?
- @result
- end
- alias_method :attempts, :attempt
-
- private
-
- def run(&block)
- @failed = false
- @current_run += 1
- @result = block.call
- rescue => e
- fail_attempt(e)
- end
-
- def fail_attempt(e)
- @failed = true
- if last_attempt? || @exceptions.any? {|k| e.is_a?(k) }
- Bundler.ui.info "" unless Bundler.ui.debug?
- raise e
- end
- return true unless name
- Bundler.ui.info "" unless Bundler.ui.debug? # Add new line incase dots preceded this
- Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug?
- end
-
- def keep_trying?
- return true if current_run.zero?
- return false if last_attempt?
- return true if @failed
- end
-
- def last_attempt?
- current_run >= total_runs
- end
- end
-end
diff --git a/lib/bundler/ruby_dsl.rb b/lib/bundler/ruby_dsl.rb
deleted file mode 100644
index f6ba220cd5..0000000000
--- a/lib/bundler/ruby_dsl.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module RubyDsl
- def ruby(*ruby_version)
- options = ruby_version.last.is_a?(Hash) ? ruby_version.pop : {}
- ruby_version.flatten!
- raise GemfileError, "Please define :engine_version" if options[:engine] && options[:engine_version].nil?
- raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil?
-
- if options[:engine] == "ruby" && options[:engine_version] &&
- ruby_version != Array(options[:engine_version])
- raise GemfileEvalError, "ruby_version must match the :engine_version for MRI"
- end
- @ruby_version = RubyVersion.new(ruby_version, options[:patchlevel], options[:engine], options[:engine_version])
- end
- end
-end
diff --git a/lib/bundler/ruby_version.rb b/lib/bundler/ruby_version.rb
deleted file mode 100644
index d4e1bdbfd5..0000000000
--- a/lib/bundler/ruby_version.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class RubyVersion
- attr_reader :versions,
- :patchlevel,
- :engine,
- :engine_versions,
- :gem_version,
- :engine_gem_version
-
- def initialize(versions, patchlevel, engine, engine_version)
- # The parameters to this method must satisfy the
- # following constraints, which are verified in
- # the DSL:
- #
- # * If an engine is specified, an engine version
- # must also be specified
- # * If an engine version is specified, an engine
- # must also be specified
- # * If the engine is "ruby", the engine version
- # must not be specified, or the engine version
- # specified must match the version.
-
- @versions = Array(versions).map do |v|
- op, v = Gem::Requirement.parse(v)
- op == "=" ? v.to_s : "#{op} #{v}"
- end
-
- @gem_version = Gem::Requirement.create(@versions.first).requirements.first.last
- @input_engine = engine && engine.to_s
- @engine = engine && engine.to_s || "ruby"
- @engine_versions = (engine_version && Array(engine_version)) || @versions
- @engine_gem_version = Gem::Requirement.create(@engine_versions.first).requirements.first.last
- @patchlevel = patchlevel
- end
-
- def to_s(versions = self.versions)
- output = String.new("ruby #{versions_string(versions)}")
- output << "p#{patchlevel}" if patchlevel
- output << " (#{engine} #{versions_string(engine_versions)})" unless engine == "ruby"
-
- output
- end
-
- # @private
- PATTERN = /
- ruby\s
- ([\d.]+) # ruby version
- (?:p(-?\d+))? # optional patchlevel
- (?:\s\((\S+)\s(.+)\))? # optional engine info
- /xo
-
- # Returns a RubyVersion from the given string.
- # @param [String] the version string to match.
- # @return [RubyVersion,Nil] The version if the string is a valid RubyVersion
- # description, and nil otherwise.
- def self.from_string(string)
- new($1, $2, $3, $4) if string =~ PATTERN
- end
-
- def single_version_string
- to_s(gem_version)
- end
-
- def ==(other)
- versions == other.versions &&
- engine == other.engine &&
- engine_versions == other.engine_versions &&
- patchlevel == other.patchlevel
- end
-
- def host
- @host ||= [
- RbConfig::CONFIG["host_cpu"],
- RbConfig::CONFIG["host_vendor"],
- RbConfig::CONFIG["host_os"]
- ].join("-")
- end
-
- # Returns a tuple of these things:
- # [diff, this, other]
- # The priority of attributes are
- # 1. engine
- # 2. ruby_version
- # 3. engine_version
- def diff(other)
- raise ArgumentError, "Can only diff with a RubyVersion, not a #{other.class}" unless other.is_a?(RubyVersion)
- if engine != other.engine && @input_engine
- [:engine, engine, other.engine]
- elsif versions.empty? || !matches?(versions, other.gem_version)
- [:version, versions_string(versions), versions_string(other.versions)]
- elsif @input_engine && !matches?(engine_versions, other.engine_gem_version)
- [:engine_version, versions_string(engine_versions), versions_string(other.engine_versions)]
- elsif patchlevel && (!patchlevel.is_a?(String) || !other.patchlevel.is_a?(String) || !matches?(patchlevel, other.patchlevel))
- [:patchlevel, patchlevel, other.patchlevel]
- end
- end
-
- def versions_string(versions)
- Array(versions).join(", ")
- end
-
- def self.system
- ruby_engine = if defined?(RUBY_ENGINE) && !RUBY_ENGINE.nil?
- RUBY_ENGINE.dup
- else
- # not defined in ruby 1.8.7
- "ruby"
- end
- # :sob: mocking RUBY_VERSION breaks stuff on 1.8.7
- ruby_version = ENV.fetch("BUNDLER_SPEC_RUBY_VERSION") { RUBY_VERSION }.dup
- ruby_engine_version = case ruby_engine
- when "ruby"
- ruby_version
- when "rbx"
- Rubinius::VERSION.dup
- when "jruby"
- JRUBY_VERSION.dup
- else
- raise BundlerError, "RUBY_ENGINE value #{RUBY_ENGINE} is not recognized"
- end
- patchlevel = RUBY_PATCHLEVEL.to_s
-
- @ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version)
- end
-
- def to_gem_version_with_patchlevel
- @gem_version_with_patch ||= begin
- Gem::Version.create("#{@gem_version}.#{@patchlevel}")
- rescue ArgumentError
- @gem_version
- end
- end
-
- def exact?
- return @exact if defined?(@exact)
- @exact = versions.all? {|v| Gem::Requirement.create(v).exact? }
- end
-
- private
-
- def matches?(requirements, version)
- # Handles RUBY_PATCHLEVEL of -1 for instances like ruby-head
- return requirements == version if requirements.to_s == "-1" || version.to_s == "-1"
-
- Array(requirements).all? do |requirement|
- Gem::Requirement.create(requirement).satisfied_by?(Gem::Version.create(version))
- end
- end
- end
-end
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
deleted file mode 100644
index e9f0eac355..0000000000
--- a/lib/bundler/rubygems_ext.rb
+++ /dev/null
@@ -1,210 +0,0 @@
-# frozen_string_literal: true
-
-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
- # Possible use in Gem::Specification#source below and require
- # shouldn't be deferred.
- require "rubygems/source"
-rescue LoadError
- # Not available before RubyGems 2.0.0, ignore
- nil
-end
-
-require "bundler/match_platform"
-
-module Gem
- @loaded_stacks = Hash.new {|h, k| h[k] = [] }
-
- class Specification
- attr_accessor :remote, :location, :relative_loaded_from
-
- if instance_methods(false).map(&:to_sym).include?(:source)
- remove_method :source
- attr_writer :source
- def source
- (defined?(@source) && @source) || Gem::Source::Installed.new
- end
- else
- attr_accessor :source
- end
-
- alias_method :rg_full_gem_path, :full_gem_path
- alias_method :rg_loaded_from, :loaded_from
-
- attr_writer :full_gem_path unless instance_methods.include?(:full_gem_path=)
-
- def full_gem_path
- # this cannot check source.is_a?(Bundler::Plugin::API::Source)
- # because that _could_ trip the autoload, and if there are unresolved
- # gems at that time, this method could be called inside another require,
- # thus raising with that constant being undefined. Better to check a method
- if source.respond_to?(:path) || (source.respond_to?(:bundler_plugin_api_source?) && source.bundler_plugin_api_source?)
- Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.untaint
- else
- rg_full_gem_path
- end
- end
-
- def loaded_from
- if relative_loaded_from
- source.path.join(relative_loaded_from).to_s
- else
- rg_loaded_from
- end
- end
-
- def load_paths
- return full_require_paths if respond_to?(:full_require_paths)
-
- require_paths.map do |require_path|
- if require_path.include?(full_gem_path)
- require_path
- else
- File.join(full_gem_path, require_path)
- end
- end
- end
-
- if method_defined?(:extension_dir)
- alias_method :rg_extension_dir, :extension_dir
- def extension_dir
- @bundler_extension_dir ||= if source.respond_to?(:extension_dir_name)
- File.expand_path(File.join(extensions_dir, source.extension_dir_name))
- else
- rg_extension_dir
- end
- 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)
- def gem_dir
- full_gem_path
- end
-
- def groups
- @groups ||= []
- end
-
- def git_version
- return unless loaded_from && source.is_a?(Bundler::Source::Git)
- " #{source.revision[0..6]}"
- end
-
- def to_gemfile(path = nil)
- gemfile = String.new("source 'https://rubygems.org'\n")
- gemfile << dependencies_to_gemfile(nondevelopment_dependencies)
- unless development_dependencies.empty?
- gemfile << "\n"
- gemfile << dependencies_to_gemfile(development_dependencies, :development)
- end
- gemfile
- end
-
- def nondevelopment_dependencies
- dependencies - development_dependencies
- end
-
- private
-
- def dependencies_to_gemfile(dependencies, group = nil)
- gemfile = String.new
- if dependencies.any?
- gemfile << "group :#{group} do\n" if group
- dependencies.each do |dependency|
- gemfile << " " if group
- gemfile << %(gem "#{dependency.name}")
- req = dependency.requirements_list.first
- gemfile << %(, "#{req}") if req
- gemfile << "\n"
- end
- gemfile << "end\n" if group
- end
- gemfile
- end
- end
-
- class Dependency
- attr_accessor :source, :groups, :all_sources
-
- alias_method :eql?, :==
-
- def encode_with(coder)
- to_yaml_properties.each do |ivar|
- coder[ivar.to_s.sub(/^@/, "")] = instance_variable_get(ivar)
- end
- end
-
- def to_yaml_properties
- instance_variables.reject {|p| ["@source", "@groups", "@all_sources"].include?(p.to_s) }
- end
-
- def to_lock
- out = String.new(" #{name}")
- unless requirement.none?
- reqs = requirement.requirements.map {|o, v| "#{o} #{v}" }.sort.reverse
- out << " (#{reqs.join(", ")})"
- end
- out
- end
-
- # Backport of performance enhancement added to RubyGems 1.4
- def matches_spec?(spec)
- # name can be a Regexp, so use ===
- return false unless name === spec.name
- return true if requirement.none?
-
- requirement.satisfied_by?(spec.version)
- end unless allocate.respond_to?(:matches_spec?)
- end
-
- class Requirement
- # Backport of performance enhancement added to RubyGems 1.4
- def none?
- # note that it might be tempting to replace with with RubyGems 2.0's
- # improved implementation. Don't. It requires `DefaultRequirement` to be
- # defined, and more importantantly, these overrides are not used when the
- # running RubyGems defines these methods
- to_s == ">= 0"
- end unless allocate.respond_to?(:none?)
-
- # Backport of performance enhancement added to RubyGems 2.2
- def exact?
- return false unless @requirements.size == 1
- @requirements[0][0] == "="
- end unless allocate.respond_to?(:exact?)
- end
-
- class Platform
- JAVA = Gem::Platform.new("java") unless defined?(JAVA)
- MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
- MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
- MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
- X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
-
- undef_method :hash if method_defined? :hash
- def hash
- @cpu.hash ^ @os.hash ^ @version.hash
- end
-
- undef_method :eql? if method_defined? :eql?
- alias_method :eql?, :==
- end
-end
-
-module Gem
- class Specification
- include ::Bundler::MatchPlatform
- end
-end
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb
deleted file mode 100644
index 2b7fa8e0f6..0000000000
--- a/lib/bundler/rubygems_gem_installer.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-# frozen_string_literal: true
-
-require "rubygems/installer"
-
-module Bundler
- class RubyGemsGemInstaller < Gem::Installer
- unless respond_to?(:at)
- def self.at(*args)
- new(*args)
- end
- end
-
- def check_executable_overwrite(filename)
- # Bundler needs to install gems regardless of binstub overwriting
- end
-
- def pre_install_checks
- super && validate_bundler_checksum(options[:bundler_expected_checksum])
- end
-
- def build_extensions
- extension_cache_path = options[:bundler_extension_cache_path]
- return super unless extension_cache_path && extension_dir = Bundler.rubygems.spec_extension_dir(spec)
-
- extension_dir = Pathname.new(extension_dir)
- build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?)
- if build_complete && !options[:force]
- SharedHelpers.filesystem_access(extension_dir.parent, &:mkpath)
- SharedHelpers.filesystem_access(extension_cache_path) do
- FileUtils.cp_r extension_cache_path, spec.extension_dir
- end
- else
- super
- if extension_dir.directory? # not made for gems without extensions
- SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
- SharedHelpers.filesystem_access(extension_cache_path) do
- FileUtils.cp_r extension_dir, extension_cache_path
- end
- end
- end
- end
-
- private
-
- def validate_bundler_checksum(checksum)
- return true if Bundler.settings[:disable_checksum_validation]
- return true unless checksum
- return true unless source = @package.instance_variable_get(:@gem)
- return true unless source.respond_to?(:with_read_io)
- digest = source.with_read_io do |io|
- digest = SharedHelpers.digest(:SHA256).new
- digest << io.read(16_384) until io.eof?
- io.rewind
- send(checksum_type(checksum), digest)
- end
- unless digest == checksum
- raise SecurityError, <<-MESSAGE
- Bundler cannot continue installing #{spec.name} (#{spec.version}).
- The checksum for the downloaded `#{spec.full_name}.gem` does not match \
- the checksum given by the server. This means the contents of the downloaded \
- gem is different from what was uploaded to the server, and could be a potential security issue.
-
- To resolve this issue:
- 1. delete the downloaded gem located at: `#{spec.gem_dir}/#{spec.full_name}.gem`
- 2. run `bundle install`
-
- 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
- 2. run `bundle install`
-
- (More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
- checksum for the downloaded gem was #{digest.inspect}.)
- MESSAGE
- end
- true
- end
-
- def checksum_type(checksum)
- case checksum.length
- when 64 then :hexdigest!
- when 44 then :base64digest!
- else raise InstallError, "The given checksum for #{spec.full_name} (#{checksum.inspect}) is not a valid SHA256 hexdigest nor base64digest"
- end
- end
-
- def hexdigest!(digest)
- digest.hexdigest!
- end
-
- def base64digest!(digest)
- if digest.respond_to?(:base64digest!)
- digest.base64digest!
- else
- [digest.digest!].pack("m0")
- end
- end
- end
-end
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
deleted file mode 100644
index 0f16b6231d..0000000000
--- a/lib/bundler/rubygems_integration.rb
+++ /dev/null
@@ -1,892 +0,0 @@
-# frozen_string_literal: true
-
-require "monitor"
-require "rubygems"
-require "rubygems/config_file"
-
-module Bundler
- class RubygemsIntegration
- if defined?(Gem::Ext::Builder::CHDIR_MONITOR)
- EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR
- else
- EXT_LOCK = Monitor.new
- end
-
- def self.version
- @version ||= Gem::Version.new(Gem::VERSION)
- end
-
- def self.provides?(req_str)
- Gem::Requirement.new(req_str).satisfied_by?(version)
- end
-
- def initialize
- @replaced_methods = {}
- end
-
- def version
- self.class.version
- end
-
- def provides?(req_str)
- self.class.provides?(req_str)
- end
-
- def build_args
- Gem::Command.build_args
- end
-
- def build_args=(args)
- Gem::Command.build_args = args
- end
-
- def load_path_insert_index
- Gem.load_path_insert_index
- end
-
- def loaded_specs(name)
- Gem.loaded_specs[name]
- end
-
- def mark_loaded(spec)
- if spec.respond_to?(:activated=)
- current = Gem.loaded_specs[spec.name]
- current.activated = false if current
- spec.activated = true
- end
- Gem.loaded_specs[spec.name] = spec
- end
-
- def validate(spec)
- Bundler.ui.silence { spec.validate(false) }
- rescue Gem::InvalidSpecificationException => e
- error_message = "The gemspec at #{spec.loaded_from} is not valid. Please fix this gemspec.\n" \
- "The validation error was '#{e.message}'\n"
- raise Gem::InvalidSpecificationException.new(error_message)
- rescue Errno::ENOENT
- nil
- end
-
- def set_installed_by_version(spec, installed_by_version = Gem::VERSION)
- return unless spec.respond_to?(:installed_by_version=)
- spec.installed_by_version = Gem::Version.create(installed_by_version)
- end
-
- def spec_missing_extensions?(spec, default = true)
- return spec.missing_extensions? if spec.respond_to?(:missing_extensions?)
-
- return false if spec_default_gem?(spec)
- return false if spec.extensions.empty?
-
- default
- end
-
- def spec_default_gem?(spec)
- spec.respond_to?(:default_gem?) && spec.default_gem?
- end
-
- def spec_matches_for_glob(spec, glob)
- return spec.matches_for_glob(glob) if spec.respond_to?(:matches_for_glob)
-
- spec.load_paths.map do |lp|
- Dir["#{lp}/#{glob}#{suffix_pattern}"]
- end.flatten(1)
- end
-
- def spec_extension_dir(spec)
- return unless spec.respond_to?(:extension_dir)
- spec.extension_dir
- end
-
- def stub_set_spec(stub, spec)
- stub.instance_variable_set(:@spec, spec)
- end
-
- def path(obj)
- obj.to_s
- end
-
- def platforms
- return [Gem::Platform::RUBY] if Bundler.settings[:force_ruby_platform]
- Gem.platforms
- end
-
- def configuration
- require "bundler/psyched_yaml"
- Gem.configuration
- rescue Gem::SystemExitException, LoadError => e
- Bundler.ui.error "#{e.class}: #{e.message}"
- Bundler.ui.trace e
- raise
- rescue YamlLibrarySyntaxError => e
- raise YamlSyntaxError.new(e, "Your RubyGems configuration, which is " \
- "usually located in ~/.gemrc, contains invalid YAML syntax.")
- end
-
- def ruby_engine
- Gem.ruby_engine
- end
-
- def read_binary(path)
- Gem.read_binary(path)
- end
-
- def inflate(obj)
- Gem.inflate(obj)
- end
-
- def sources=(val)
- # Gem.configuration creates a new Gem::ConfigFile, which by default will read ~/.gemrc
- # If that file exists, its settings (including sources) will overwrite the values we
- # are about to set here. In order to avoid that, we force memoizing the config file now.
- configuration
-
- Gem.sources = val
- end
-
- def sources
- Gem.sources
- end
-
- def gem_dir
- Gem.dir
- end
-
- def gem_bindir
- Gem.bindir
- end
-
- def user_home
- Gem.user_home
- end
-
- def gem_path
- Gem.path
- end
-
- def reset
- Gem::Specification.reset
- end
-
- def post_reset_hooks
- Gem.post_reset_hooks
- end
-
- def suffix_pattern
- Gem.suffix_pattern
- end
-
- def gem_cache
- gem_path.map {|p| File.expand_path("cache", p) }
- end
-
- def spec_cache_dirs
- @spec_cache_dirs ||= begin
- dirs = gem_path.map {|dir| File.join(dir, "specifications") }
- dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) # Not in RubyGems 2.0.3 or earlier
- dirs.uniq.select {|dir| File.directory? dir }
- end
- end
-
- def marshal_spec_dir
- Gem::MARSHAL_SPEC_DIR
- end
-
- def config_map
- Gem::ConfigMap
- end
-
- def repository_subdirectories
- %w[cache doc gems specifications]
- end
-
- def clear_paths
- Gem.clear_paths
- end
-
- def bin_path(gem, bin, ver)
- Gem.bin_path(gem, bin, ver)
- end
-
- def path_separator
- File::PATH_SEPARATOR
- end
-
- def preserve_paths
- # this is a no-op outside of RubyGems 1.8
- yield
- end
-
- def loaded_gem_paths
- # RubyGems 2.2+ can put binary extension into dedicated folders,
- # therefore use RubyGems facilities to obtain their load paths.
- if Gem::Specification.method_defined? :full_require_paths
- loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
- loaded_gem_paths.flatten
- else
- $LOAD_PATH.select do |p|
- Bundler.rubygems.gem_path.any? {|gp| p =~ /^#{Regexp.escape(gp)}/ }
- end
- end
- end
-
- def load_plugins
- Gem.load_plugins if Gem.respond_to?(:load_plugins)
- end
-
- def load_plugin_files(files)
- Gem.load_plugin_files(files) if Gem.respond_to?(:load_plugin_files)
- end
-
- def ui=(obj)
- Gem::DefaultUserInteraction.ui = obj
- end
-
- def ext_lock
- EXT_LOCK
- end
-
- def fetch_specs(all, pre, &blk)
- require "rubygems/spec_fetcher"
- specs = Gem::SpecFetcher.new.list(all, pre)
- specs.each { yield } if block_given?
- specs
- end
-
- def fetch_prerelease_specs
- fetch_specs(false, true)
- rescue Gem::RemoteFetcher::FetchError
- {} # if we can't download them, there aren't any
- end
-
- # TODO: This is for older versions of RubyGems... should we support the
- # X-Gemfile-Source header on these old versions?
- # Maybe the newer implementation will work on older RubyGems?
- # It seems difficult to keep this implementation and still send the header.
- def fetch_all_remote_specs(remote)
- old_sources = Bundler.rubygems.sources
- Bundler.rubygems.sources = [remote.uri.to_s]
- # Fetch all specs, minus prerelease specs
- spec_list = fetch_specs(true, false)
- # Then fetch the prerelease specs
- fetch_prerelease_specs.each {|k, v| spec_list[k].concat(v) }
-
- spec_list.values.first
- ensure
- Bundler.rubygems.sources = old_sources
- end
-
- def with_build_args(args)
- ext_lock.synchronize do
- old_args = build_args
- begin
- self.build_args = args
- yield
- ensure
- self.build_args = old_args
- end
- end
- end
-
- def install_with_build_args(args)
- with_build_args(args) { yield }
- end
-
- def gem_from_path(path, policy = nil)
- require "rubygems/format"
- Gem::Format.from_file_by_path(path, policy)
- end
-
- def spec_from_gem(path, policy = nil)
- require "rubygems/security"
- require "bundler/psyched_yaml"
- 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
- if e.is_a?(Gem::Security::Exception) ||
- e.message =~ /unknown trust policy|unsigned gem/i ||
- e.message =~ /couldn't verify (meta)?data signature/i
- raise SecurityError,
- "The gem #{File.basename(path, ".gem")} can't be installed because " \
- "the security policy didn't allow it, with the message: #{e.message}"
- else
- raise e
- end
- end
-
- def build(spec, skip_validation = false)
- require "rubygems/builder"
- Gem::Builder.new(spec).build
- end
-
- def build_gem(gem_dir, spec)
- build(spec)
- end
-
- def download_gem(spec, uri, path)
- uri = Bundler.settings.mirror_for(uri)
- fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
- Bundler::Retry.new("download gem from #{uri}").attempts do
- fetcher.download(spec, uri, path)
- end
- end
-
- def security_policy_keys
- %w[High Medium Low AlmostNo No].map {|level| "#{level}Security" }
- end
-
- def security_policies
- @security_policies ||= begin
- require "rubygems/security"
- Gem::Security::Policies
- rescue LoadError, NameError
- {}
- end
- end
-
- def reverse_rubygems_kernel_mixin
- # Disable rubygems' gem activation system
- kernel = (class << ::Kernel; self; end)
- [kernel, ::Kernel].each do |k|
- if k.private_method_defined?(:gem_original_require)
- redefine_method(k, :require, k.instance_method(:gem_original_require))
- end
- end
- end
-
- def binstubs_call_gem?
- true
- end
-
- def stubs_provide_full_functionality?
- false
- end
-
- def replace_gem(specs, specs_by_name)
- reverse_rubygems_kernel_mixin
-
- executables = nil
-
- kernel = (class << ::Kernel; self; end)
- [kernel, ::Kernel].each do |kernel_class|
- redefine_method(kernel_class, :gem) do |dep, *reqs|
- executables ||= specs.map(&:executables).flatten if ::Bundler.rubygems.binstubs_call_gem?
- if executables && executables.include?(File.basename(caller.first.split(":").first))
- break
- end
-
- reqs.pop if reqs.last.is_a?(Hash)
-
- unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
- dep = Gem::Dependency.new(dep, reqs)
- end
-
- if spec = specs_by_name[dep.name]
- return true if dep.matches_spec?(spec)
- end
-
- message = if spec.nil?
- "#{dep.name} is not part of the bundle." \
- " Add it to your #{Bundler.default_gemfile.basename}."
- else
- "can't activate #{dep}, already activated #{spec.full_name}. " \
- "Make sure all dependencies are added to Gemfile."
- end
-
- e = Gem::LoadError.new(message)
- e.name = dep.name
- if e.respond_to?(:requirement=)
- e.requirement = dep.requirement
- elsif e.respond_to?(:version_requirement=)
- e.version_requirement = dep.requirement
- end
- raise e
- end
-
- # backwards compatibility shim, see https://github.com/bundler/bundler/issues/5102
- kernel_class.send(:public, :gem) if Bundler.feature_flag.setup_makes_kernel_gem_public?
- end
- end
-
- def stub_source_index(specs)
- Gem::SourceIndex.send(:alias_method, :old_initialize, :initialize)
- redefine_method(Gem::SourceIndex, :initialize) do |*args|
- @gems = {}
- # You're looking at this thinking: Oh! This is how I make those
- # rubygems deprecations go away!
- #
- # You'd be correct BUT using of this method in production code
- # must be approved by the rubygems team itself!
- #
- # This is your warning. If you use this and don't have approval
- # we can't protect you.
- #
- Deprecate.skip_during do
- self.spec_dirs = *args
- add_specs(*specs)
- end
- end
- end
-
- # 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)
- gem_class = (class << Gem; self; end)
-
- redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
- exec_name = args.first
-
- 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
-
- unless spec
- message = "can't find executable #{exec_name} for gem #{gem_name}"
- if !exec_name || 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 2,
- "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
- spec
- end
-
- redefine_method(gem_class, :activate_bin_path) do |name, *args|
- exec_name = args.first
- return ENV["BUNDLE_BIN_PATH"] if exec_name == "bundle"
-
- # Copy of Rubygems activate_bin_path impl
- requirement = args.last
- spec = find_spec_for_exe name, exec_name, [requirement]
-
- gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
- gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
- File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
- end
-
- redefine_method(gem_class, :bin_path) do |name, *args|
- exec_name = args.first
- return ENV["BUNDLE_BIN_PATH"] if exec_name == "bundle"
-
- spec = find_spec_for_exe(name, *args)
- exec_name ||= spec.default_executable
-
- gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
- gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
- File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
- end
- end
-
- # Because Bundler has a static view of what specs are available,
- # we don't #refresh, so stub it out.
- def replace_refresh
- gem_class = (class << Gem; self; end)
- redefine_method(gem_class, :refresh) {}
- end
-
- # Replace or hook into RubyGems to provide a bundlerized view
- # of the world.
- def replace_entrypoints(specs)
- specs_by_name = specs.reduce({}) do |h, s|
- h[s.name] = s
- h
- end
-
- replace_gem(specs, specs_by_name)
- stub_rubygems(specs)
- replace_bin_path(specs, specs_by_name)
- replace_refresh
-
- Gem.clear_paths
- end
-
- # This backports the correct segment generation code from RubyGems 1.4+
- # by monkeypatching it into the method in RubyGems 1.3.6 and 1.3.7.
- def backport_segment_generation
- redefine_method(Gem::Version, :segments) do
- @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
- /^\d+$/ =~ s ? s.to_i : s
- end
- end
- end
-
- # This backport fixes the marshaling of @segments.
- def backport_yaml_initialize
- redefine_method(Gem::Version, :yaml_initialize) do |_, map|
- @version = map["version"]
- @segments = nil
- @hash = nil
- end
- end
-
- # This backports base_dir which replaces installation path
- # RubyGems 1.8+
- def backport_base_dir
- redefine_method(Gem::Specification, :base_dir) do
- return Gem.dir unless loaded_from
- File.dirname File.dirname loaded_from
- end
- end
-
- def backport_cache_file
- redefine_method(Gem::Specification, :cache_dir) do
- @cache_dir ||= File.join base_dir, "cache"
- end
-
- redefine_method(Gem::Specification, :cache_file) do
- @cache_file ||= File.join cache_dir, "#{full_name}.gem"
- end
- end
-
- def backport_spec_file
- redefine_method(Gem::Specification, :spec_dir) do
- @spec_dir ||= File.join base_dir, "specifications"
- end
-
- redefine_method(Gem::Specification, :spec_file) do
- @spec_file ||= File.join spec_dir, "#{full_name}.gemspec"
- end
- end
-
- def undo_replacements
- @replaced_methods.each do |(sym, klass), method|
- redefine_method(klass, sym, method)
- end
- post_reset_hooks.reject! do |proc|
- proc.binding.eval("__FILE__") == __FILE__
- end
- @replaced_methods.clear
- end
-
- def redefine_method(klass, method, unbound_method = nil, &block)
- visibility = method_visibility(klass, method)
- begin
- if (instance_method = klass.instance_method(method)) && method != :initialize
- # doing this to ensure we also get private methods
- klass.send(:remove_method, method)
- end
- rescue NameError
- # method isn't defined
- nil
- end
- @replaced_methods[[method, klass]] = instance_method
- if unbound_method
- klass.send(:define_method, method, unbound_method)
- klass.send(visibility, method)
- elsif block
- klass.send(:define_method, method, &block)
- klass.send(visibility, method)
- end
- end
-
- def method_visibility(klass, method)
- if klass.private_method_defined?(method)
- :private
- elsif klass.protected_method_defined?(method)
- :protected
- else
- :public
- end
- end
-
- # RubyGems 1.4 through 1.6
- class Legacy < RubygemsIntegration
- def initialize
- super
- backport_base_dir
- backport_cache_file
- backport_spec_file
- backport_yaml_initialize
- end
-
- def stub_rubygems(specs)
- # RubyGems versions lower than 1.7 use SourceIndex#from_gems_in
- source_index_class = (class << Gem::SourceIndex; self; end)
- redefine_method(source_index_class, :from_gems_in) do |*args|
- Gem::SourceIndex.new.tap do |source_index|
- source_index.spec_dirs = *args
- source_index.add_specs(*specs)
- end
- end
- end
-
- def all_specs
- Gem.source_index.gems.values
- end
-
- def find_name(name)
- Gem.source_index.find_name(name)
- end
-
- def validate(spec)
- # These versions of RubyGems always validate in "packaging" mode,
- # which is too strict for the kinds of checks we care about. As a
- # result, validation is disabled on versions of RubyGems below 1.7.
- end
-
- def post_reset_hooks
- []
- end
-
- def reset
- end
- end
-
- # RubyGems versions 1.3.6 and 1.3.7
- class Ancient < Legacy
- def initialize
- super
- backport_segment_generation
- end
- end
-
- # RubyGems 1.7
- class Transitional < Legacy
- def stub_rubygems(specs)
- stub_source_index(specs)
- end
-
- def validate(spec)
- # Missing summary is downgraded to a warning in later versions,
- # so we set it to an empty string to prevent an exception here.
- spec.summary ||= ""
- RubygemsIntegration.instance_method(:validate).bind(self).call(spec)
- end
- end
-
- # RubyGems 1.8.5-1.8.19
- class Modern < RubygemsIntegration
- def stub_rubygems(specs)
- Gem::Specification.all = specs
-
- Gem.post_reset do
- Gem::Specification.all = specs
- end
-
- stub_source_index(specs)
- end
-
- def all_specs
- Gem::Specification.to_a
- end
-
- def find_name(name)
- Gem::Specification.find_all_by_name name
- end
- end
-
- # RubyGems 1.8.0 to 1.8.4
- class AlmostModern < Modern
- # RubyGems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
- # you call Gem::Installer#install with an :install_dir set. We have to
- # change it back for our sudo mode to work.
- def preserve_paths
- old_dir = gem_dir
- old_path = gem_path
- yield
- Gem.use_paths(old_dir, old_path)
- end
- end
-
- # RubyGems 1.8.20+
- class MoreModern < Modern
- # RubyGems 1.8.20 and adds the skip_validation parameter, so that's
- # when we start passing it through.
- def build(spec, skip_validation = false)
- require "rubygems/builder"
- Gem::Builder.new(spec).build(skip_validation)
- end
- end
-
- # RubyGems 2.0
- class Future < RubygemsIntegration
- def stub_rubygems(specs)
- Gem::Specification.all = specs
-
- Gem.post_reset do
- Gem::Specification.all = specs
- end
-
- redefine_method((class << Gem; self; end), :finish_resolve) do |*|
- []
- end
- end
-
- def all_specs
- Gem::Specification.to_a
- end
-
- def find_name(name)
- Gem::Specification.find_all_by_name name
- end
-
- def fetch_specs(source, remote, name)
- path = source + "#{name}.#{Gem.marshal_version}.gz"
- fetcher = gem_remote_fetcher
- fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
- string = fetcher.fetch_path(path)
- Bundler.load_marshal(string)
- rescue Gem::RemoteFetcher::FetchError => e
- # it's okay for prerelease to fail
- raise e unless name == "prerelease_specs"
- end
-
- def fetch_all_remote_specs(remote)
- source = remote.uri.is_a?(URI) ? remote.uri : URI.parse(source.to_s)
-
- specs = fetch_specs(source, remote, "specs")
- pres = fetch_specs(source, remote, "prerelease_specs") || []
-
- specs.concat(pres)
- end
-
- def download_gem(spec, uri, path)
- uri = Bundler.settings.mirror_for(uri)
- fetcher = gem_remote_fetcher
- fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
- Bundler::Retry.new("download gem from #{uri}").attempts do
- fetcher.download(spec, uri, path)
- end
- end
-
- def gem_remote_fetcher
- require "resolv"
- proxy = configuration[:http_proxy]
- dns = Resolv::DNS.new
- Bundler::GemRemoteFetcher.new(proxy, dns)
- end
-
- def gem_from_path(path, policy = nil)
- require "rubygems/package"
- p = Gem::Package.new(path)
- p.security_policy = policy if policy
- p
- end
-
- def build(spec, skip_validation = false)
- require "rubygems/package"
- Gem::Package.build(spec, skip_validation)
- end
-
- def repository_subdirectories
- Gem::REPOSITORY_SUBDIRECTORIES
- end
-
- def install_with_build_args(args)
- yield
- end
-
- def path_separator
- Gem.path_separator
- end
- end
-
- # RubyGems 2.1.0
- class MoreFuture < Future
- def initialize
- super
- backport_ext_builder_monitor
- end
-
- def all_specs
- require "bundler/remote_specification"
- Gem::Specification.stubs.map do |stub|
- StubSpecification.from_stub(stub)
- end
- end
-
- def backport_ext_builder_monitor
- # So we can avoid requiring "rubygems/ext" in its entirety
- Gem.module_eval <<-RB, __FILE__, __LINE__ + 1
- module Ext
- end
- RB
-
- require "rubygems/ext/builder"
-
- Gem::Ext::Builder.class_eval do
- unless const_defined?(:CHDIR_MONITOR)
- const_set(:CHDIR_MONITOR, EXT_LOCK)
- end
-
- remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
- const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
- end
- end
-
- if Gem::Specification.respond_to?(:stubs_for)
- def find_name(name)
- Gem::Specification.stubs_for(name).map(&:to_spec)
- end
- else
- def find_name(name)
- Gem::Specification.stubs.find_all do |spec|
- spec.name == name
- end.map(&:to_spec)
- end
- end
-
- def use_gemdeps(gemfile)
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
- require "bundler/gemdeps"
- runtime = Bundler.setup
- Bundler.ui = nil
- activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
- [Gemdeps.new(runtime), activated_spec_names]
- end
-
- if provides?(">= 2.5.2")
- # RubyGems-generated binstubs call Kernel#gem
- def binstubs_call_gem?
- false
- end
-
- # only 2.5.2+ has all of the stub methods we want to use, and since this
- # is a performance optimization _only_,
- # we'll restrict ourselves to the most
- # recent RG versions instead of all versions that have stubs
- def stubs_provide_full_functionality?
- true
- end
- end
- end
- end
-
- def self.rubygems
- @rubygems ||= if RubygemsIntegration.provides?(">= 2.1.0")
- RubygemsIntegration::MoreFuture.new
- elsif RubygemsIntegration.provides?(">= 1.99.99")
- RubygemsIntegration::Future.new
- elsif RubygemsIntegration.provides?(">= 1.8.20")
- RubygemsIntegration::MoreModern.new
- elsif RubygemsIntegration.provides?(">= 1.8.5")
- RubygemsIntegration::Modern.new
- elsif RubygemsIntegration.provides?(">= 1.8.0")
- RubygemsIntegration::AlmostModern.new
- elsif RubygemsIntegration.provides?(">= 1.7.0")
- RubygemsIntegration::Transitional.new
- elsif RubygemsIntegration.provides?(">= 1.4.0")
- RubygemsIntegration::Legacy.new
- else # RubyGems 1.3.6 and 1.3.7
- RubygemsIntegration::Ancient.new
- end
- end
-end
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
deleted file mode 100644
index f27597b854..0000000000
--- a/lib/bundler/runtime.rb
+++ /dev/null
@@ -1,316 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Runtime
- include SharedHelpers
-
- def initialize(root, definition)
- @root = root
- @definition = definition
- end
-
- def setup(*groups)
- @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen?
-
- groups.map!(&:to_sym)
-
- # Has to happen first
- clean_load_path
-
- specs = groups.any? ? @definition.specs_for(groups) : requested_specs
-
- SharedHelpers.set_bundle_environment
- Bundler.rubygems.replace_entrypoints(specs)
-
- # Activate the specs
- load_paths = specs.map do |spec|
- unless spec.loaded_from
- raise GemNotFound, "#{spec.full_name} is missing. Run `bundle install` to get it."
- end
-
- check_for_activated_spec!(spec)
-
- Bundler.rubygems.mark_loaded(spec)
- spec.load_paths.reject {|path| $LOAD_PATH.include?(path) }
- end.reverse.flatten
-
- # See Gem::Specification#add_self_to_load_path (since RubyGems 1.8)
- if insert_index = Bundler.rubygems.load_path_insert_index
- # Gem directories must come after -I and ENV['RUBYLIB']
- $LOAD_PATH.insert(insert_index, *load_paths)
- else
- # We are probably testing in core, -I and RUBYLIB don't apply
- $LOAD_PATH.unshift(*load_paths)
- end
-
- setup_manpath
-
- lock(:preserve_unknown_sections => true)
-
- self
- end
-
- REQUIRE_ERRORS = [
- /^no such file to load -- (.+)$/i,
- /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
- /^Missing API definition file in (.+)$/i,
- /^cannot load such file -- (.+)$/i,
- /^dlopen\([^)]*\): Library not loaded: (.+)$/i,
- ].freeze
-
- def require(*groups)
- groups.map!(&:to_sym)
- groups = [:default] if groups.empty?
-
- @definition.dependencies.each do |dep|
- # Skip the dependency if it is not in any of the requested groups, or
- # not for the current platform, or doesn't match the gem constraints.
- next unless (dep.groups & groups).any? && dep.should_include?
-
- required_file = nil
-
- begin
- # Loop through all the specified autorequires for the
- # dependency. If there are none, use the dependency's name
- # as the autorequire.
- Array(dep.autorequire || dep.name).each do |file|
- # Allow `require: true` as an alias for `require: <name>`
- file = dep.name if file == true
- required_file = file
- begin
- Kernel.require file
- rescue => e
- raise e if e.is_a?(LoadError) # we handle this a little later
- raise Bundler::GemRequireError.new e,
- "There was an error while trying to load the gem '#{file}'."
- end
- end
- rescue LoadError => e
- REQUIRE_ERRORS.find {|r| r =~ e.message }
- raise if dep.autorequire || $1 != required_file
-
- if dep.autorequire.nil? && dep.name.include?("-")
- begin
- namespaced_file = dep.name.tr("-", "/")
- Kernel.require namespaced_file
- rescue LoadError => e
- REQUIRE_ERRORS.find {|r| r =~ e.message }
- raise if $1 != namespaced_file
- end
- end
- end
- end
- end
-
- def self.definition_method(meth)
- define_method(meth) do
- raise ArgumentError, "no definition when calling Runtime##{meth}" unless @definition
- @definition.send(meth)
- end
- end
- private_class_method :definition_method
-
- definition_method :requested_specs
- definition_method :specs
- definition_method :dependencies
- definition_method :current_dependencies
- definition_method :requires
-
- def lock(opts = {})
- return if @definition.nothing_changed? && !@definition.unlocking?
- @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
- end
-
- alias_method :gems, :specs
-
- def cache(custom_path = nil)
- cache_path = Bundler.app_cache(custom_path)
- SharedHelpers.filesystem_access(cache_path) do |p|
- FileUtils.mkdir_p(p)
- end unless File.exist?(cache_path)
-
- Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
-
- specs_to_cache = Bundler.settings[:cache_all_platforms] ? @definition.resolve.materialized_for_all_platforms : specs
- specs_to_cache.each do |spec|
- next if spec.name == "bundler"
- next if spec.source.is_a?(Source::Gemspec)
- spec.source.send(:fetch_gem, spec) if Bundler.settings[:cache_all_platforms] && spec.source.respond_to?(:fetch_gem, true)
- spec.source.cache(spec, custom_path) if spec.source.respond_to?(:cache)
- end
-
- Dir[cache_path.join("*/.git")].each do |git_dir|
- FileUtils.rm_rf(git_dir)
- FileUtils.touch(File.expand_path("../.bundlecache", git_dir))
- end
-
- prune_cache(cache_path) unless Bundler.settings[:no_prune]
- end
-
- def prune_cache(cache_path)
- SharedHelpers.filesystem_access(cache_path) do |p|
- FileUtils.mkdir_p(p)
- end unless File.exist?(cache_path)
- resolve = @definition.resolve
- prune_gem_cache(resolve, cache_path)
- prune_git_and_path_cache(resolve, cache_path)
- end
-
- def clean(dry_run = false)
- gem_bins = Dir["#{Gem.dir}/bin/*"]
- git_dirs = Dir["#{Gem.dir}/bundler/gems/*"]
- git_cache_dirs = Dir["#{Gem.dir}/cache/bundler/git/*"]
- gem_dirs = Dir["#{Gem.dir}/gems/*"]
- gem_files = Dir["#{Gem.dir}/cache/*.gem"]
- gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"]
- spec_gem_paths = []
- # need to keep git sources around
- spec_git_paths = @definition.spec_git_paths
- spec_git_cache_dirs = []
- spec_gem_executables = []
- spec_cache_paths = []
- spec_gemspec_paths = []
- specs.each do |spec|
- spec_gem_paths << spec.full_gem_path
- # need to check here in case gems are nested like for the rails git repo
- md = %r{(.+bundler/gems/.+-[a-f0-9]{7,12})}.match(spec.full_gem_path)
- spec_git_paths << md[1] if md
- spec_gem_executables << spec.executables.collect do |executable|
- e = "#{Bundler.rubygems.gem_bindir}/#{executable}"
- [e, "#{e}.bat"]
- end
- spec_cache_paths << spec.cache_file
- spec_gemspec_paths << spec.spec_file
- spec_git_cache_dirs << spec.source.cache_path.to_s if spec.source.is_a?(Bundler::Source::Git)
- end
- spec_gem_paths.uniq!
- spec_gem_executables.flatten!
-
- stale_gem_bins = gem_bins - spec_gem_executables
- stale_git_dirs = git_dirs - spec_git_paths - ["#{Gem.dir}/bundler/gems/extensions"]
- stale_git_cache_dirs = git_cache_dirs - spec_git_cache_dirs
- stale_gem_dirs = gem_dirs - spec_gem_paths
- stale_gem_files = gem_files - spec_cache_paths
- stale_gemspec_files = gemspec_files - spec_gemspec_paths
-
- removed_stale_gem_dirs = stale_gem_dirs.collect {|dir| remove_dir(dir, dry_run) }
- removed_stale_git_dirs = stale_git_dirs.collect {|dir| remove_dir(dir, dry_run) }
- output = removed_stale_gem_dirs + removed_stale_git_dirs
-
- unless dry_run
- stale_files = stale_gem_bins + stale_gem_files + stale_gemspec_files
- stale_files.each do |file|
- SharedHelpers.filesystem_access(File.dirname(file)) do |_p|
- FileUtils.rm(file) if File.exist?(file)
- end
- end
- stale_git_cache_dirs.each do |cache_dir|
- SharedHelpers.filesystem_access(cache_dir) do |dir|
- FileUtils.rm_rf(dir) if File.exist?(dir)
- end
- end
- end
-
- output
- end
-
- private
-
- def prune_gem_cache(resolve, cache_path)
- cached = Dir["#{cache_path}/*.gem"]
-
- cached = cached.delete_if do |path|
- spec = Bundler.rubygems.spec_from_gem path
-
- resolve.any? do |s|
- s.name == spec.name && s.version == spec.version && !s.source.is_a?(Bundler::Source::Git)
- end
- end
-
- if cached.any?
- Bundler.ui.info "Removing outdated .gem files from #{Bundler.settings.app_cache_path}"
-
- cached.each do |path|
- Bundler.ui.info " * #{File.basename(path)}"
- File.delete(path)
- end
- end
- end
-
- def prune_git_and_path_cache(resolve, cache_path)
- cached = Dir["#{cache_path}/*/.bundlecache"]
-
- cached = cached.delete_if do |path|
- name = File.basename(File.dirname(path))
-
- resolve.any? do |s|
- source = s.source
- source.respond_to?(:app_cache_dirname) && source.app_cache_dirname == name
- end
- end
-
- if cached.any?
- Bundler.ui.info "Removing outdated git and path gems from #{Bundler.settings.app_cache_path}"
-
- cached.each do |path|
- path = File.dirname(path)
- Bundler.ui.info " * #{File.basename(path)}"
- FileUtils.rm_rf(path)
- end
- end
- end
-
- def setup_manpath
- # Add man/ subdirectories from activated bundles to MANPATH for man(1)
- manuals = $LOAD_PATH.map do |path|
- man_subdir = path.sub(/lib$/, "man")
- man_subdir unless Dir[man_subdir + "/man?/"].empty?
- end.compact
-
- return if manuals.empty?
- Bundler::SharedHelpers.set_env "MANPATH", manuals.concat(
- ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR)
- ).uniq.join(File::PATH_SEPARATOR)
- end
-
- def remove_dir(dir, dry_run)
- full_name = Pathname.new(dir).basename.to_s
-
- parts = full_name.split("-")
- name = parts[0..-2].join("-")
- version = parts.last
- output = "#{name} (#{version})"
-
- if dry_run
- Bundler.ui.info "Would have removed #{output}"
- else
- Bundler.ui.info "Removing #{output}"
- FileUtils.rm_rf(dir)
- end
-
- output
- end
-
- def check_for_activated_spec!(spec)
- return unless activated_spec = Bundler.rubygems.loaded_specs(spec.name)
- return if activated_spec.version == spec.version
-
- suggestion = if Bundler.rubygems.spec_default_gem?(activated_spec)
- "Since #{spec.name} is a default gem, you can either remove your dependency on it" \
- " or try updating to a newer version of bundler that supports #{spec.name} as a default gem."
- else
- "Prepending `bundle exec` to your command may solve this."
- end
-
- e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
- "but your Gemfile requires #{spec.name} #{spec.version}. #{suggestion}"
- e.name = spec.name
- if e.respond_to?(:requirement=)
- e.requirement = Gem::Requirement.new(spec.version.to_s)
- else
- e.version_requirement = Gem::Requirement.new(spec.version.to_s)
- end
- raise e
- end
- end
-end
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
deleted file mode 100644
index f33e9453be..0000000000
--- a/lib/bundler/settings.rb
+++ /dev/null
@@ -1,442 +0,0 @@
-# frozen_string_literal: true
-
-require "uri"
-
-module Bundler
- class Settings
- autoload :Mirror, "bundler/mirror"
- autoload :Mirrors, "bundler/mirror"
- autoload :Validator, "bundler/settings/validator"
-
- BOOL_KEYS = %w[
- allow_bundler_dependency_conflicts
- allow_deployment_source_credential_changes
- allow_offline_install
- auto_clean_without_path
- auto_install
- cache_all
- cache_all_platforms
- cache_command_is_package
- console_command
- default_install_uses_path
- deployment
- deployment_means_frozen
- disable_checksum_validation
- disable_exec_load
- disable_local_branch_check
- disable_multisource
- disable_shared_gems
- disable_version_check
- error_on_stderr
- force_ruby_platform
- forget_cli_options
- frozen
- gem.coc
- gem.mit
- global_gem_cache
- ignore_messages
- init_gems_rb
- list_command
- lockfile_uses_separate_rubygems_sources
- major_deprecations
- no_install
- no_prune
- only_update_to_newer_versions
- path.system
- plugins
- prefer_gems_rb
- print_only_version_number
- setup_makes_kernel_gem_public
- silence_root_warning
- skip_default_git_sources
- specific_platform
- suppress_install_using_messages
- unlock_source_unlocks_spec
- update_requires_all_flag
- ].freeze
-
- NUMBER_KEYS = %w[
- redirect
- retry
- ssl_verify_mode
- timeout
- ].freeze
-
- ARRAY_KEYS = %w[
- with
- without
- ].freeze
-
- DEFAULT_CONFIG = {
- :disable_version_check => true,
- :redirect => 5,
- :retry => 3,
- :timeout => 10,
- }.freeze
-
- def initialize(root = nil)
- @root = root
- @local_config = load_config(local_config_file)
- @global_config = load_config(global_config_file)
- @temporary = {}
- end
-
- def [](name)
- key = key_for(name)
- value = @temporary.fetch(key) do
- @local_config.fetch(key) do
- ENV.fetch(key) do
- @global_config.fetch(key) do
- DEFAULT_CONFIG.fetch(name) do
- nil
- end end end end end
-
- converted_value(value, name)
- end
-
- def set_command_option(key, value)
- if Bundler.feature_flag.forget_cli_options?
- 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 2,\
- "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
-
- def set_command_option_if_given(key, value)
- return if value.nil?
- set_command_option(key, value)
- end
-
- def set_local(key, value)
- local_config_file || raise(GemfileNotFound, "Could not locate Gemfile")
-
- set_key(key, value, @local_config, local_config_file)
- end
-
- def temporary(update)
- existing = Hash[update.map {|k, _| [k, @temporary[key_for(k)]] }]
- update.each do |k, v|
- set_key(k, v, @temporary, nil)
- end
- return unless block_given?
- begin
- yield
- ensure
- existing.each {|k, v| set_key(k, v, @temporary, nil) }
- end
- end
-
- def set_global(key, value)
- set_key(key, value, @global_config, global_config_file)
- end
-
- def all
- env_keys = ENV.keys.grep(/\ABUNDLE_.+/)
-
- keys = @temporary.keys | @global_config.keys | @local_config.keys | env_keys
-
- keys.map do |key|
- key.sub(/^BUNDLE_/, "").gsub(/__/, ".").downcase
- end
- end
-
- def local_overrides
- repos = {}
- all.each do |k|
- repos[$'] = self[k] if k =~ /^local\./
- end
- repos
- end
-
- def mirror_for(uri)
- uri = URI(uri.to_s) unless uri.is_a?(URI)
- gem_mirrors.for(uri.to_s).uri
- end
-
- def credentials_for(uri)
- self[uri.to_s] || self[uri.host]
- end
-
- def gem_mirrors
- all.inject(Mirrors.new) do |mirrors, k|
- mirrors.parse(k, self[k]) if k.start_with?("mirror.")
- mirrors
- end
- end
-
- def locations(key)
- key = key_for(key)
- locations = {}
- locations[:temporary] = @temporary[key] if @temporary.key?(key)
- locations[:local] = @local_config[key] if @local_config.key?(key)
- locations[:env] = ENV[key] if ENV[key]
- locations[:global] = @global_config[key] if @global_config.key?(key)
- locations[:default] = DEFAULT_CONFIG[key] if DEFAULT_CONFIG.key?(key)
- locations
- end
-
- def pretty_values_for(exposed_key)
- key = key_for(exposed_key)
-
- locations = []
-
- if @temporary.key?(key)
- locations << "Set for the current command: #{converted_value(@temporary[key], exposed_key).inspect}"
- end
-
- if @local_config.key?(key)
- locations << "Set for your local app (#{local_config_file}): #{converted_value(@local_config[key], exposed_key).inspect}"
- end
-
- if value = ENV[key]
- locations << "Set via #{key}: #{converted_value(value, exposed_key).inspect}"
- end
-
- if @global_config.key?(key)
- locations << "Set for the current user (#{global_config_file}): #{converted_value(@global_config[key], exposed_key).inspect}"
- end
-
- return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
- locations
- end
-
- # for legacy reasons, the ruby scope isnt appended when the setting comes from ENV or the global config,
- # nor do we respect :disable_shared_gems
- def path
- key = key_for(:path)
- path = ENV[key] || @global_config[key]
- if path && !@temporary.key?(key) && !@local_config.key?(key)
- return Path.new(path, false, false, false)
- end
-
- system_path = self["path.system"] || (self[:disable_shared_gems] == false)
- Path.new(self[:path], true, system_path, Bundler.feature_flag.default_install_uses_path?)
- end
-
- Path = Struct.new(:explicit_path, :append_ruby_scope, :system_path, :default_install_uses_path) do
- def path
- path = base_path
- path = File.join(path, Bundler.ruby_scope) if append_ruby_scope && !use_system_gems?
- path
- end
-
- def use_system_gems?
- return true if system_path
- return false if explicit_path
- !default_install_uses_path
- end
-
- def base_path
- path = explicit_path
- path ||= ".bundle" unless use_system_gems?
- path ||= Bundler.rubygems.gem_dir
- path
- end
-
- def validate!
- return unless explicit_path && system_path
- path = Bundler.settings.pretty_values_for(:path)
- path.unshift(nil, "path:") unless path.empty?
- system_path = Bundler.settings.pretty_values_for("path.system")
- system_path.unshift(nil, "path.system:") unless system_path.empty?
- disable_shared_gems = Bundler.settings.pretty_values_for(:disable_shared_gems)
- disable_shared_gems.unshift(nil, "disable_shared_gems:") unless disable_shared_gems.empty?
- raise InvalidOption,
- "Using a custom path while using system gems is unsupported.\n#{path.join("\n")}\n#{system_path.join("\n")}\n#{disable_shared_gems.join("\n")}"
- end
- end
-
- def allow_sudo?
- key = key_for(:path)
- path_configured = @temporary.key?(key) || @local_config.key?(key)
- !path_configured
- end
-
- def ignore_config?
- ENV["BUNDLE_IGNORE_CONFIG"]
- end
-
- def app_cache_path
- @app_cache_path ||= self[:cache_path] || "vendor/cache"
- end
-
- def validate!
- all.each do |raw_key|
- [@local_config, ENV, @global_config].each do |settings|
- value = converted_value(settings[key_for(raw_key)], raw_key)
- Validator.validate!(raw_key, value, settings.to_hash.dup)
- end
- end
- end
-
- def key_for(key)
- key = Settings.normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
- key = key.to_s.gsub(".", "__").upcase
- "BUNDLE_#{key}"
- end
-
- private
-
- def parent_setting_for(name)
- split_specific_setting_for(name)[0]
- end
-
- def specific_gem_for(name)
- split_specific_setting_for(name)[1]
- end
-
- def split_specific_setting_for(name)
- name.split(".")
- end
-
- def is_bool(name)
- BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s))
- end
-
- def to_bool(value)
- case value
- when nil, /\A(false|f|no|n|0|)\z/i, false
- false
- else
- true
- end
- end
-
- def is_num(key)
- NUMBER_KEYS.include?(key.to_s)
- end
-
- def is_array(key)
- ARRAY_KEYS.include?(key.to_s)
- end
-
- def to_array(value)
- return [] unless value
- value.split(":").map(&:to_sym)
- end
-
- def array_to_s(array)
- array = Array(array)
- return nil if array.empty?
- array.join(":").tr(" ", ":")
- end
-
- def set_key(raw_key, value, hash, file)
- raw_key = raw_key.to_s
- value = array_to_s(value) if is_array(raw_key)
-
- key = key_for(raw_key)
-
- return if hash[key] == value
-
- hash[key] = value
- hash.delete(key) if value.nil?
-
- Validator.validate!(raw_key, converted_value(value, raw_key), hash)
-
- return unless file
- SharedHelpers.filesystem_access(file) do |p|
- FileUtils.mkdir_p(p.dirname)
- require "bundler/yaml_serializer"
- p.open("w") {|f| f.write(YAMLSerializer.dump(hash)) }
- end
- end
-
- def converted_value(value, key)
- if is_array(key)
- to_array(value)
- elsif value.nil?
- nil
- elsif is_bool(key) || value == "false"
- to_bool(value)
- elsif is_num(key)
- value.to_i
- else
- value.to_s
- end
- end
-
- def global_config_file
- if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
- Pathname.new(ENV["BUNDLE_CONFIG"])
- else
- begin
- Bundler.user_bundle_path.join("config")
- rescue PermissionError, GenericSystemCallError
- nil
- end
- end
- end
-
- def local_config_file
- 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|
- valid_file = file.exist? && !file.size.zero?
- return {} unless valid_file
- require "bundler/yaml_serializer"
- YAMLSerializer.load file.read
- end
- end
-
- PER_URI_OPTIONS = %w[
- fallback_timeout
- ].freeze
-
- NORMALIZE_URI_OPTIONS_PATTERN =
- /
- \A
- (\w+\.)? # optional prefix key
- (https?.*?) # URI
- (\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key
- \z
- /ix
-
- # TODO: duplicates Rubygems#normalize_uri
- # TODO: is this the correct place to validate mirror URIs?
- def self.normalize_uri(uri)
- uri = uri.to_s
- if uri =~ NORMALIZE_URI_OPTIONS_PATTERN
- prefix = $1
- uri = $2
- suffix = $3
- end
- uri = "#{uri}/" unless uri.end_with?("/")
- uri = URI(uri)
- unless uri.absolute?
- raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri)
- end
- "#{prefix}#{uri}#{suffix}"
- end
- end
-end
diff --git a/lib/bundler/settings/validator.rb b/lib/bundler/settings/validator.rb
deleted file mode 100644
index 9aa1627fb2..0000000000
--- a/lib/bundler/settings/validator.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Settings
- class Validator
- class Rule
- attr_reader :description
-
- def initialize(keys, description, &validate)
- @keys = keys
- @description = description
- @validate = validate
- end
-
- def validate!(key, value, settings)
- instance_exec(key, value, settings, &@validate)
- end
-
- def fail!(key, value, *reasons)
- reasons.unshift @description
- raise InvalidOption, "Setting `#{key}` to #{value.inspect} failed:\n#{reasons.map {|r| " - #{r}" }.join("\n")}"
- end
-
- def set(settings, key, value, *reasons)
- hash_key = k(key)
- return if settings[hash_key] == value
- reasons.unshift @description
- Bundler.ui.info "Setting `#{key}` to #{value.inspect}, since #{reasons.join(", ")}"
- if value.nil?
- settings.delete(hash_key)
- else
- settings[hash_key] = value
- end
- end
-
- def k(key)
- Bundler.settings.key_for(key)
- end
- end
-
- def self.rules
- @rules ||= Hash.new {|h, k| h[k] = [] }
- end
- private_class_method :rules
-
- def self.rule(keys, description, &blk)
- rule = Rule.new(keys, description, &blk)
- keys.each {|k| rules[k] << rule }
- end
- private_class_method :rule
-
- def self.validate!(key, value, settings)
- rules_to_validate = rules[key]
- rules_to_validate.each {|rule| rule.validate!(key, value, settings) }
- end
-
- rule %w[path path.system], "path and path.system are mutually exclusive" do |key, value, settings|
- if key == "path" && value
- set(settings, "path.system", nil)
- elsif key == "path.system" && value
- set(settings, :path, nil)
- end
- end
-
- rule %w[with without], "a group cannot be in both `with` & `without` simultaneously" do |key, value, settings|
- with = settings.fetch(k(:with), "").split(":").map(&:to_sym)
- without = settings.fetch(k(:without), "").split(":").map(&:to_sym)
-
- other_key = key == "with" ? :without : :with
- other_setting = key == "with" ? without : with
-
- conflicting = with & without
- if conflicting.any?
- fail!(key, value, "`#{other_key}` is current set to #{other_setting.inspect}", "the `#{conflicting.join("`, `")}` groups conflict")
- end
- end
- end
- end
-end
diff --git a/lib/bundler/setup.rb b/lib/bundler/setup.rb
deleted file mode 100644
index ac6a5bf861..0000000000
--- a/lib/bundler/setup.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/shared_helpers"
-
-if Bundler::SharedHelpers.in_bundle?
- require "bundler"
-
- if STDOUT.tty? || ENV["BUNDLER_FORCE_TTY"]
- begin
- Bundler.setup
- rescue Bundler::BundlerError => e
- puts "\e[31m#{e.message}\e[0m"
- puts e.backtrace.join("\n") if ENV["DEBUG"]
- if e.is_a?(Bundler::GemNotFound)
- puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
- end
- exit e.status_code
- end
- else
- Bundler.setup
- end
-
- # Add bundler to the load path after disabling system gems
- bundler_lib = File.expand_path("../..", __FILE__)
- $LOAD_PATH.unshift(bundler_lib) unless $LOAD_PATH.include?(bundler_lib)
-
- Bundler.ui = nil
-end
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
deleted file mode 100644
index 5566bc5832..0000000000
--- a/lib/bundler/shared_helpers.rb
+++ /dev/null
@@ -1,366 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/compatibility_guard"
-
-require "pathname"
-require "rubygems"
-
-require "bundler/version"
-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
- gemfile = find_gemfile
- raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
- Pathname.new(gemfile).untaint.expand_path.parent
- end
-
- def default_gemfile
- gemfile = find_gemfile(:order_matters)
- raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
- Pathname.new(gemfile).untaint.expand_path
- end
-
- def default_lockfile
- gemfile = default_gemfile
-
- case gemfile.basename.to_s
- when "gems.rb" then Pathname.new(gemfile.sub(/.rb$/, ".locked"))
- else Pathname.new("#{gemfile}.lock")
- end.untaint
- end
-
- def default_bundle_dir
- bundle_dir = find_directory(".bundle")
- return nil unless bundle_dir
-
- bundle_dir = Pathname.new(bundle_dir)
-
- global_bundle_dir = Bundler.user_home.join(".bundle")
- return nil if bundle_dir == global_bundle_dir
-
- bundle_dir
- end
-
- def in_bundle?
- find_gemfile
- end
-
- def chdir(dir, &blk)
- Bundler.rubygems.ext_lock.synchronize do
- Dir.chdir dir, &blk
- end
- end
-
- def pwd
- Bundler.rubygems.ext_lock.synchronize do
- Pathname.pwd
- end
- end
-
- def with_clean_git_env(&block)
- keys = %w[GIT_DIR GIT_WORK_TREE]
- old_env = keys.inject({}) do |h, k|
- h.update(k => ENV[k])
- end
-
- keys.each {|key| ENV.delete(key) }
-
- block.call
- ensure
- keys.each {|key| ENV[key] = old_env[key] }
- end
-
- def set_bundle_environment
- set_bundle_variables
- set_path
- set_rubyopt
- set_rubylib
- end
-
- # Rescues permissions errors raised by file system operations
- # (ie. Errno:EACCESS, Errno::EAGAIN) and raises more friendly errors instead.
- #
- # @param path [String] the path that the action will be attempted to
- # @param action [Symbol, #to_s] the type of operation that will be
- # performed. For example: :write, :read, :exec
- #
- # @yield path
- #
- # @raise [Bundler::PermissionError] if Errno:EACCES is raised in the
- # given block
- # @raise [Bundler::TemporaryResourceError] if Errno:EAGAIN is raised in the
- # given block
- #
- # @example
- # filesystem_access("vendor/cache", :write) do
- # FileUtils.mkdir_p("vendor/cache")
- # end
- #
- # @see {Bundler::PermissionError}
- def filesystem_access(path, action = :write, &block)
- # Use block.call instead of yield because of a bug in Ruby 2.2.2
- # See https://github.com/bundler/bundler/issues/5341 for details
- block.call(path.dup.untaint)
- rescue Errno::EACCES
- raise PermissionError.new(path, action)
- rescue Errno::EAGAIN
- raise TemporaryResourceError.new(path, action)
- rescue Errno::EPROTO
- raise VirtualProtocolError.new
- rescue Errno::ENOSPC
- raise NoSpaceOnDeviceError.new(path, action)
- rescue *[const_get_safely(:ENOTSUP, Errno)].compact
- raise OperationNotSupportedError.new(path, action)
- rescue Errno::EEXIST, Errno::ENOENT
- raise
- rescue SystemCallError => e
- raise GenericSystemCallError.new(e, "There was an error accessing `#{path}`.")
- end
-
- def const_get_safely(constant_name, namespace)
- const_in_namespace = namespace.constants.include?(constant_name.to_s) ||
- namespace.constants.include?(constant_name.to_sym)
- return nil unless const_in_namespace
- namespace.const_get(constant_name)
- end
-
- def major_deprecation(major_version, message)
- if Bundler.bundler_major_version >= major_version
- require "bundler/errors"
- raise DeprecatedError, "[REMOVED FROM #{major_version}.0] #{message}"
- end
-
- return unless 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}")
- 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
- end
- if multiple_gemfiles && Bundler.bundler_major_version == 1
- Bundler::SharedHelpers.major_deprecation 2, \
- "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}")
- end
-
- def trap(signal, override = false, &block)
- prior = Signal.trap(signal) do
- block.call
- prior.call unless override
- end
- end
-
- def ensure_same_dependencies(spec, old_deps, new_deps)
- new_deps = new_deps.reject {|d| d.type == :development }
- old_deps = old_deps.reject {|d| d.type == :development }
-
- without_type = proc {|d| Gem::Dependency.new(d.name, d.requirements_list.sort) }
- new_deps.map!(&without_type)
- old_deps.map!(&without_type)
-
- extra_deps = new_deps - old_deps
- return if extra_deps.empty?
-
- Bundler.ui.debug "#{spec.full_name} from #{spec.remote} has either corrupted API or lockfile dependencies" \
- " (was expecting #{old_deps.map(&:to_s)}, but the real spec has #{new_deps.map(&:to_s)})"
- raise APIResponseMismatchError,
- "Downloading #{spec.full_name} revealed dependencies not in the API or the lockfile (#{extra_deps.join(", ")})." \
- "\nEither installing with `--full-index` or running `bundle update #{spec.name}` should fix the problem."
- end
-
- def pretty_dependency(dep, print_source = false)
- msg = String.new(dep.name)
- msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
- if dep.is_a?(Bundler::Dependency)
- platform_string = dep.platforms.join(", ")
- msg << " " << platform_string if !platform_string.empty? && platform_string != Gem::Platform::RUBY
- end
- msg << " from the `#{dep.source}` source" if print_source && dep.source
- msg
- end
-
- def md5_available?
- return @md5_available if defined?(@md5_available)
- @md5_available = begin
- require "openssl"
- OpenSSL::Digest::MD5.digest("")
- true
- rescue LoadError
- true
- rescue OpenSSL::Digest::DigestError
- false
- end
- end
-
- def digest(name)
- require "digest"
- Digest(name)
- end
-
- private
-
- def validate_bundle_path
- path_separator = Bundler.rubygems.path_separator
- return unless Bundler.bundle_path.to_s.split(path_separator).size > 1
- message = "Your bundle path contains text matching #{path_separator.inspect}, " \
- "which is the path separator for your system. Bundler cannot " \
- "function correctly when the Bundle path contains the " \
- "system's PATH separator. Please change your " \
- "bundle path to not match #{path_separator.inspect}." \
- "\nYour current bundle path is '#{Bundler.bundle_path}'."
- raise Bundler::PathError, message
- end
-
- 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)
- end
-
- def gemfile_names
- ["Gemfile", "gems.rb"]
- end
-
- def find_file(*names)
- search_up(*names) do |filename|
- return filename if File.file?(filename)
- end
- end
-
- def find_directory(*names)
- search_up(*names) do |dirname|
- return dirname if File.directory?(dirname)
- end
- end
-
- def search_up(*names)
- previous = nil
- current = File.expand_path(SharedHelpers.pwd).untaint
-
- until !File.directory?(current) || current == previous
- if ENV["BUNDLE_SPEC_RUN"]
- # avoid stepping above the tmp directory when testing
- if !!(ENV["BUNDLE_RUBY"] && ENV["BUNDLE_GEM"])
- # for Ruby Core
- gemspec = "lib/bundler.gemspec"
- else
- gemspec = "bundler.gemspec"
- end
- return nil if File.file?(File.join(current, gemspec))
- end
-
- names.each do |name|
- filename = File.join(current, name)
- yield filename
- end
- previous = current
- current = File.expand_path("..", current)
- end
- end
-
- def set_env(key, value)
- raise ArgumentError, "new key #{key}" unless EnvironmentPreserver::BUNDLER_KEYS.include?(key)
- orig_key = "#{EnvironmentPreserver::BUNDLER_PREFIX}#{key}"
- orig = ENV[key]
- orig ||= EnvironmentPreserver::INTENTIONALLY_NIL
- ENV[orig_key] ||= orig
-
- ENV[key] = value
- end
- public :set_env
-
- def set_bundle_variables
- begin
- Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", Bundler.rubygems.bin_path("bundler", "bundle", VERSION)
- rescue Gem::GemNotFoundException
- if File.exist?(File.expand_path("../../../exe/bundle", __FILE__))
- Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", File.expand_path("../../../exe/bundle", __FILE__)
- else
- Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", File.expand_path("../../../../bin/bundle", __FILE__)
- end
- end
-
- # Set BUNDLE_GEMFILE
- Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile(:order_matters).to_s
- Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
- end
-
- def set_path
- validate_bundle_path
- paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR)
- paths.unshift "#{Bundler.bundle_path}/bin"
- Bundler::SharedHelpers.set_env "PATH", paths.uniq.join(File::PATH_SEPARATOR)
- end
-
- def set_rubyopt
- rubyopt = [ENV["RUBYOPT"]].compact
- return if !rubyopt.empty? && rubyopt.first =~ %r{-rbundler/setup}
- rubyopt.unshift %(-rbundler/setup)
- Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ")
- end
-
- def set_rubylib
- rubylib = (ENV["RUBYLIB"] || "").split(File::PATH_SEPARATOR)
- rubylib.unshift bundler_ruby_lib
- Bundler::SharedHelpers.set_env "RUBYLIB", rubylib.uniq.join(File::PATH_SEPARATOR)
- end
-
- def bundler_ruby_lib
- File.expand_path("../..", __FILE__)
- 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
-
- $LOAD_PATH.reject! do |p|
- next if File.expand_path(p).start_with?(bundler_lib)
- loaded_gem_paths.delete(p)
- end
- $LOAD_PATH.uniq!
- end
-
- def prints_major_deprecations?
- require "bundler"
- deprecation_release = Bundler::VERSION.split(".").drop(1).include?("99")
- return false if !deprecation_release && !Bundler.settings[:major_deprecations]
- require "bundler/deprecate"
- return false if Bundler::Deprecate.skip
- true
- end
-
- extend self
- end
-end
diff --git a/lib/bundler/similarity_detector.rb b/lib/bundler/similarity_detector.rb
deleted file mode 100644
index b7f3ee7afa..0000000000
--- a/lib/bundler/similarity_detector.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class SimilarityDetector
- SimilarityScore = Struct.new(:string, :distance)
-
- # initialize with an array of words to be matched against
- def initialize(corpus)
- @corpus = corpus
- end
-
- # return an array of words similar to 'word' from the corpus
- def similar_words(word, limit = 3)
- words_by_similarity = @corpus.map {|w| SimilarityScore.new(w, levenshtein_distance(word, w)) }
- words_by_similarity.select {|s| s.distance <= limit }.sort_by(&:distance).map(&:string)
- end
-
- # return the result of 'similar_words', concatenated into a list
- # (eg "a, b, or c")
- def similar_word_list(word, limit = 3)
- words = similar_words(word, limit)
- if words.length == 1
- words[0]
- elsif words.length > 1
- [words[0..-2].join(", "), words[-1]].join(" or ")
- end
- end
-
- protected
-
- # http://www.informit.com/articles/article.aspx?p=683059&seqNum=36
- def levenshtein_distance(this, that, ins = 2, del = 2, sub = 1)
- # ins, del, sub are weighted costs
- return nil if this.nil?
- return nil if that.nil?
- dm = [] # distance matrix
-
- # Initialize first row values
- dm[0] = (0..this.length).collect {|i| i * ins }
- fill = [0] * (this.length - 1)
-
- # Initialize first column values
- (1..that.length).each do |i|
- dm[i] = [i * del, fill.flatten]
- end
-
- # populate matrix
- (1..that.length).each do |i|
- (1..this.length).each do |j|
- # critical comparison
- 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
- ].min
- end
- end
-
- # The last value in matrix is the Levenshtein distance between the strings
- dm[that.length][this.length]
- end
- end
-end
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
deleted file mode 100644
index 5a1f05098b..0000000000
--- a/lib/bundler/source.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Source
- autoload :Gemspec, "bundler/source/gemspec"
- autoload :Git, "bundler/source/git"
- autoload :Metadata, "bundler/source/metadata"
- autoload :Path, "bundler/source/path"
- autoload :Rubygems, "bundler/source/rubygems"
-
- attr_accessor :dependency_names
-
- def unmet_deps
- specs.unmet_dependency_names
- end
-
- def version_message(spec)
- message = "#{spec.name} #{spec.version}"
- message += " (#{spec.platform})" if spec.platform != Gem::Platform::RUBY && !spec.platform.nil?
-
- if Bundler.locked_gems
- locked_spec = Bundler.locked_gems.specs.find {|s| s.name == spec.name }
- locked_spec_version = locked_spec.version if locked_spec
- if locked_spec_version && spec.version != locked_spec_version
- message += Bundler.ui.add_color(" (was #{locked_spec_version})", version_color(spec.version, locked_spec_version))
- end
- end
-
- message
- end
-
- def can_lock?(spec)
- spec.source == self
- end
-
- # it's possible that gems from one source depend on gems from some
- # other source, so now we download gemspecs and iterate over those
- # dependencies, looking for gems we don't have info on yet.
- def double_check_for(*); end
-
- def dependency_names_to_double_check
- specs.dependency_names
- end
-
- def include?(other)
- other == self
- end
-
- def inspect
- "#<#{self.class}:0x#{object_id} #{self}>"
- end
-
- def path?
- instance_of?(Bundler::Source::Path)
- end
-
- private
-
- def version_color(spec_version, locked_spec_version)
- if Gem::Version.correct?(spec_version) && Gem::Version.correct?(locked_spec_version)
- # display yellow if there appears to be a regression
- earlier_version?(spec_version, locked_spec_version) ? :yellow : :green
- else
- # default to green if the versions cannot be directly compared
- :green
- end
- end
-
- def earlier_version?(spec_version, locked_spec_version)
- Gem::Version.new(spec_version) < Gem::Version.new(locked_spec_version)
- end
-
- def print_using_message(message)
- if !message.include?("(was ") && Bundler.feature_flag.suppress_install_using_messages?
- Bundler.ui.debug message
- else
- Bundler.ui.info message
- end
- end
-
- def extension_cache_path(spec)
- return unless Bundler.feature_flag.global_gem_cache?
- return unless source_slug = extension_cache_slug(spec)
- Bundler.user_cache.join(
- "extensions", Gem::Platform.local.to_s, Bundler.ruby_scope,
- source_slug, spec.full_name
- )
- end
-
- def extension_cache_slug(_)
- nil
- end
- end
-end
diff --git a/lib/bundler/source/gemspec.rb b/lib/bundler/source/gemspec.rb
deleted file mode 100644
index 7e3447e776..0000000000
--- a/lib/bundler/source/gemspec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Source
- class Gemspec < Path
- attr_reader :gemspec
-
- def initialize(options)
- super
- @gemspec = options["gemspec"]
- end
-
- def as_path_source
- Path.new(options)
- end
- end
- end
-end
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
deleted file mode 100644
index a1a59ddce5..0000000000
--- a/lib/bundler/source/git.rb
+++ /dev/null
@@ -1,328 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/vendored_fileutils"
-require "uri"
-
-module Bundler
- class Source
- class Git < Path
- autoload :GitProxy, "bundler/source/git/git_proxy"
-
- attr_reader :uri, :ref, :branch, :options, :submodules
-
- def initialize(options)
- @options = options
- @glob = options["glob"] || DEFAULT_GLOB
-
- @allow_cached = false
- @allow_remote = false
-
- # Stringify options that could be set as symbols
- %w[ref branch tag revision].each {|k| options[k] = options[k].to_s if options[k] }
-
- @uri = options["uri"] || ""
- @branch = options["branch"]
- @ref = options["ref"] || options["branch"] || options["tag"] || "master"
- @submodules = options["submodules"]
- @name = options["name"]
- @version = options["version"].to_s.strip.gsub("-", ".pre.")
-
- @copied = false
- @local = false
- end
-
- def self.from_lock(options)
- new(options.merge("uri" => options.delete("remote")))
- end
-
- def to_lock
- out = String.new("GIT\n")
- out << " remote: #{@uri}\n"
- out << " revision: #{revision}\n"
- %w[ref branch tag submodules].each do |opt|
- out << " #{opt}: #{options[opt]}\n" if options[opt]
- end
- out << " glob: #{@glob}\n" unless @glob == DEFAULT_GLOB
- out << " specs:\n"
- end
-
- def hash
- [self.class, uri, ref, branch, name, version, submodules].hash
- end
-
- def eql?(other)
- other.is_a?(Git) && uri == other.uri && ref == other.ref &&
- branch == other.branch && name == other.name &&
- version == other.version && submodules == other.submodules
- end
-
- alias_method :==, :eql?
-
- def to_s
- at = if local?
- path
- elsif user_ref = options["ref"]
- if ref =~ /\A[a-z0-9]{4,}\z/i
- shortref_for_display(user_ref)
- else
- user_ref
- end
- else
- ref
- end
-
- rev = begin
- "@#{shortref_for_display(revision)}"
- rescue GitError
- nil
- end
-
- "#{uri} (at #{at}#{rev})"
- end
-
- def name
- File.basename(@uri, ".git")
- end
-
- # This is the path which is going to contain a specific
- # checkout of the git repository. When using local git
- # repos, this is set to the local repo.
- def install_path
- @install_path ||= begin
- git_scope = "#{base_name}-#{shortref_for_path(revision)}"
-
- path = Bundler.install_path.join(git_scope)
-
- if !path.exist? && Bundler.requires_sudo?
- Bundler.user_bundle_path.join(Bundler.ruby_scope).join(git_scope)
- else
- path
- end
- end
- end
-
- alias_method :path, :install_path
-
- def extension_dir_name
- "#{base_name}-#{shortref_for_path(revision)}"
- end
-
- def unlock!
- git_proxy.revision = nil
- options["revision"] = nil
-
- @unlocked = true
- end
-
- def local_override!(path)
- return false if local?
-
- 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"
- 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"
- end
-
- set_local!(path)
-
- # Create a new git proxy without the cached revision
- # so the Gemfile.lock always picks up the new revision.
- @git_proxy = GitProxy.new(path, uri, ref)
-
- if git_proxy.branch != options["branch"] && !Bundler.settings[:disable_local_branch_check]
- raise GitError, "Local override for #{name} at #{path} is using branch " \
- "#{git_proxy.branch} but Gemfile specifies #{options["branch"]}"
- end
-
- changed = cached_revision && cached_revision != git_proxy.revision
-
- if changed && !@unlocked && !git_proxy.contains?(cached_revision)
- raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \
- "but the current branch in your local override for #{name} does not contain such commit. " \
- "Please make sure your branch is up to date."
- end
-
- changed
- end
-
- def specs(*)
- set_local!(app_cache_path) if has_app_cache? && !local?
-
- if requires_checkout? && !@copied
- fetch
- git_proxy.copy_to(install_path, submodules)
- serialize_gemspecs_in(install_path)
- @copied = true
- end
-
- local_specs
- end
-
- def install(spec, options = {})
- force = options[:force]
-
- print_using_message "Using #{version_message(spec)} from #{self}"
-
- if (requires_checkout? && !@copied) || force
- Bundler.ui.debug " * Checking out revision: #{ref}"
- git_proxy.copy_to(install_path, submodules)
- serialize_gemspecs_in(install_path)
- @copied = true
- end
-
- generate_bin_options = { :disable_extensions => !Bundler.rubygems.spec_missing_extensions?(spec), :build_args => options[:build_args] }
- generate_bin(spec, generate_bin_options)
-
- requires_checkout? ? spec.post_install_message : nil
- end
-
- def cache(spec, custom_path = nil)
- app_cache_path = app_cache_path(custom_path)
- return unless Bundler.feature_flag.cache_all?
- return if path == app_cache_path
- cached!
- FileUtils.rm_rf(app_cache_path)
- git_proxy.checkout if requires_checkout?
- git_proxy.copy_to(app_cache_path, @submodules)
- serialize_gemspecs_in(app_cache_path)
- end
-
- def load_spec_files
- super
- rescue PathError => e
- Bundler.ui.trace e
- raise GitError, "#{self} is not yet checked out. Run `bundle install` first."
- end
-
- # This is the path which is going to contain a cache
- # of the git repository. When using the same git repository
- # across different projects, this cache will be shared.
- # When using local git repos, this is set to the local repo.
- def cache_path
- @cache_path ||= begin
- if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache?
- Bundler.user_cache
- else
- Bundler.bundle_path.join("cache", "bundler")
- end.join("git", git_scope)
- end
- end
-
- def app_cache_dirname
- "#{base_name}-#{shortref_for_path(cached_revision || revision)}"
- end
-
- def revision
- git_proxy.revision
- end
-
- def allow_git_ops?
- @allow_remote || @allow_cached
- end
-
- private
-
- def serialize_gemspecs_in(destination)
- destination = destination.expand_path(Bundler.root) if destination.relative?
- Dir["#{destination}/#{@glob}"].each do |spec_path|
- # Evaluate gemspecs and cache the result. Gemspecs
- # in git might require git or other dependencies.
- # The gemspecs we cache should already be evaluated.
- spec = Bundler.load_gemspec(spec_path)
- next unless spec
- Bundler.rubygems.set_installed_by_version(spec)
- Bundler.rubygems.validate(spec)
- File.open(spec_path, "wb") {|file| file.write(spec.to_ruby) }
- end
- end
-
- def set_local!(path)
- @local = true
- @local_specs = @git_proxy = nil
- @cache_path = @install_path = path
- end
-
- def has_app_cache?
- cached_revision && super
- end
-
- def local?
- @local
- end
-
- def requires_checkout?
- allow_git_ops? && !local?
- end
-
- def base_name
- File.basename(uri.sub(%r{^(\w+://)?([^/:]+:)?(//\w*/)?(\w*/)*}, ""), ".git")
- end
-
- def shortref_for_display(ref)
- ref[0..6]
- end
-
- def shortref_for_path(ref)
- ref[0..11]
- end
-
- def uri_hash
- if uri =~ %r{^\w+://(\w+@)?}
- # Downcase the domain component of the URI
- # and strip off a trailing slash, if one is present
- input = URI.parse(uri).normalize.to_s.sub(%r{/$}, "")
- else
- # If there is no URI scheme, assume it is an ssh/git URI
- input = uri
- end
- SharedHelpers.digest(:SHA1).hexdigest(input)
- end
-
- def cached_revision
- options["revision"]
- end
-
- def cached?
- cache_path.exist?
- end
-
- def git_proxy
- @git_proxy ||= GitProxy.new(cache_path, uri, ref, cached_revision, self)
- end
-
- def fetch
- git_proxy.checkout
- rescue GitError => e
- raise unless Bundler.feature_flag.allow_offline_install?
- Bundler.ui.warn "Using cached git data because of network errors:\n#{e}"
- end
-
- # no-op, since we validate when re-serializing the gemspec
- def validate_spec(_spec); end
-
- if Bundler.rubygems.stubs_provide_full_functionality?
- def load_gemspec(file)
- stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
- stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s.untaint
- StubSpecification.from_stub(stub)
- end
- end
-
- def git_scope
- "#{base_name}-#{uri_hash}"
- end
-
- def extension_cache_slug(_)
- extension_dir_name
- end
- end
- end
-end
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb
deleted file mode 100644
index c56dda66ea..0000000000
--- a/lib/bundler/source/git/git_proxy.rb
+++ /dev/null
@@ -1,257 +0,0 @@
-# frozen_string_literal: true
-
-require "shellwords"
-require "tempfile"
-module Bundler
- class Source
- class Git
- class GitNotInstalledError < GitError
- def initialize
- msg = String.new
- msg << "You need to install git to be able to use gems from git repositories. "
- msg << "For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git"
- super msg
- end
- end
-
- class GitNotAllowedError < GitError
- def initialize(command)
- msg = String.new
- msg << "Bundler is trying to run a `git #{command}` at runtime. You probably need to run `bundle install`. However, "
- msg << "this error message could probably be more useful. Please submit a ticket at http://github.com/bundler/bundler/issues "
- msg << "with steps to reproduce as well as the following\n\nCALLER: #{caller.join("\n")}"
- super msg
- end
- end
-
- class GitCommandError < GitError
- def initialize(command, path = nil, extra_info = nil)
- msg = String.new
- msg << "Git error: command `git #{command}` in directory #{SharedHelpers.pwd} has failed."
- msg << "\n#{extra_info}" if extra_info
- msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path && path.exist?
- super msg
- end
- end
-
- class MissingGitRevisionError < GitError
- def initialize(ref, repo)
- msg = "Revision #{ref} does not exist in the repository #{repo}. Maybe you misspelled it?"
- super msg
- end
- end
-
- # The GitProxy is responsible to interact with git repositories.
- # All actions required by the Git source is encapsulated in this
- # object.
- class GitProxy
- attr_accessor :path, :uri, :ref
- attr_writer :revision
-
- def initialize(path, uri, ref, revision = nil, git = nil)
- @path = path
- @uri = uri
- @ref = ref
- @revision = revision
- @git = git
- raise GitNotInstalledError.new if allow? && !Bundler.git_present?
- end
-
- def revision
- return @revision if @revision
-
- begin
- @revision ||= find_local_revision
- rescue GitCommandError
- raise MissingGitRevisionError.new(ref, URICredentialsFilter.credential_filtered_uri(uri))
- end
-
- @revision
- end
-
- def branch
- @branch ||= allowed_in_path do
- git("rev-parse --abbrev-ref HEAD").strip
- end
- end
-
- def contains?(commit)
- allowed_in_path do
- result = git_null("branch --contains #{commit}")
- $? == 0 && result =~ /^\* (.*)$/
- end
- end
-
- def version
- git("--version").match(/(git version\s*)?((\.?\d+)+).*/)[2]
- end
-
- def full_version
- git("--version").sub("git version", "").strip
- end
-
- def checkout
- return if path.exist? && has_revision_cached?
- extra_ref = "#{Shellwords.shellescape(ref)}:#{Shellwords.shellescape(ref)}" if ref && ref.start_with?("refs/")
-
- Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}"
-
- unless path.exist?
- SharedHelpers.filesystem_access(path.dirname) do |p|
- FileUtils.mkdir_p(p)
- end
- git_retry %(clone #{uri_escaped_with_configured_credentials} "#{path}" --bare --no-hardlinks --quiet)
- return unless extra_ref
- end
-
- in_path do
- git_retry %(fetch --force --quiet --tags #{uri_escaped_with_configured_credentials} "refs/heads/*:refs/heads/*" #{extra_ref})
- end
- end
-
- def copy_to(destination, submodules = false)
- # method 1
- unless File.exist?(destination.join(".git"))
- begin
- SharedHelpers.filesystem_access(destination.dirname) do |p|
- FileUtils.mkdir_p(p)
- end
- SharedHelpers.filesystem_access(destination) do |p|
- FileUtils.rm_rf(p)
- end
- git_retry %(clone --no-checkout --quiet "#{path}" "#{destination}")
- File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination)
- rescue Errno::EEXIST => e
- file_path = e.message[%r{.*?(/.*)}, 1]
- raise GitError, "Bundler could not install a gem because it needs to " \
- "create a directory, but a file exists - #{file_path}. Please delete " \
- "this file and try again."
- end
- end
- # method 2
- SharedHelpers.chdir(destination) do
- git_retry %(fetch --force --quiet --tags "#{path}")
- git "reset --hard #{@revision}"
-
- if submodules
- git_retry "submodule update --init --recursive"
- elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0")
- git_retry "submodule deinit --all --force"
- end
- end
- end
-
- private
-
- # TODO: Do not rely on /dev/null.
- # Given that open3 is not cross platform until Ruby 1.9.3,
- # the best solution is to pipe to /dev/null if it exists.
- # If it doesn't, everything will work fine, but the user
- # will get the $stderr messages as well.
- def git_null(command)
- git("#{command} 2>#{Bundler::NULL}", false)
- end
-
- def git_retry(command)
- Bundler::Retry.new("`git #{URICredentialsFilter.credential_filtered_string(command, uri)}`", GitNotAllowedError).attempts do
- git(command)
- end
- end
-
- def git(command, check_errors = true, error_msg = nil)
- command_with_no_credentials = URICredentialsFilter.credential_filtered_string(command, uri)
- raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
-
- out = SharedHelpers.with_clean_git_env do
- capture_and_filter_stderr(uri) { `git #{command}` }
- end
-
- stdout_with_no_credentials = URICredentialsFilter.credential_filtered_string(out, uri)
- raise GitCommandError.new(command_with_no_credentials, path, error_msg) if check_errors && !$?.success?
- stdout_with_no_credentials
- end
-
- def has_revision_cached?
- return unless @revision
- in_path { git("cat-file -e #{@revision}") }
- true
- rescue GitError
- false
- end
-
- def remove_cache
- FileUtils.rm_rf(path)
- end
-
- def find_local_revision
- allowed_in_path do
- git("rev-parse --verify #{Shellwords.shellescape(ref)}", true).strip
- end
- end
-
- # Escape the URI for git commands
- def uri_escaped_with_configured_credentials
- remote = configured_uri_for(uri)
- if Bundler::WINDOWS
- # Windows quoting requires double quotes only, with double quotes
- # inside the string escaped by being doubled.
- '"' + remote.gsub('"') { '""' } + '"'
- else
- # Bash requires single quoted strings, with the single quotes escaped
- # by ending the string, escaping the quote, and restarting the string.
- "'" + remote.gsub("'") { "'\\''" } + "'"
- end
- end
-
- # Adds credentials to the URI as Fetcher#configured_uri_for does
- def configured_uri_for(uri)
- if /https?:/ =~ uri
- remote = URI(uri)
- config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
- remote.userinfo ||= config_auth
- remote.to_s
- else
- uri
- end
- end
-
- def allow?
- @git ? @git.allow_git_ops? : true
- end
-
- def in_path(&blk)
- checkout unless path.exist?
- _ = URICredentialsFilter # load it before we chdir
- SharedHelpers.chdir(path, &blk)
- end
-
- def allowed_in_path
- return in_path { yield } if allow?
- raise GitError, "The git source #{uri} is not yet checked out. Please run `bundle install` before trying to start your application"
- end
-
- # TODO: Replace this with Open3 when upgrading to bundler 2
- # Similar to #git_null, as Open3 is not cross-platform,
- # a temporary way is to use Tempfile to capture the stderr.
- # When replacing this using Open3, make sure git_null is
- # also replaced by Open3, so stdout and stderr all got handled properly.
- def capture_and_filter_stderr(uri)
- return_value, captured_err = ""
- backup_stderr = STDERR.dup
- begin
- Tempfile.open("captured_stderr") do |f|
- STDERR.reopen(f)
- return_value = yield
- f.rewind
- captured_err = f.read
- end
- ensure
- STDERR.reopen backup_stderr
- end
- $stderr.puts URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
- return_value
- end
- end
- end
- end
-end
diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb
deleted file mode 100644
index 93909002c7..0000000000
--- a/lib/bundler/source/metadata.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Source
- 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 do |s|
- s.name = "bundler"
- s.version = VERSION
- s.platform = Gem::Platform::RUBY
- s.source = self
- s.authors = ["bundler team"]
- s.bindir = "exe"
- s.executables = %w[bundle]
- # can't point to the actual gemspec or else the require paths will be wrong
- s.loaded_from = File.expand_path("..", __FILE__)
- end
- if loaded_spec = nil && Bundler.rubygems.loaded_specs("bundler")
- idx << loaded_spec # this has to come after the fake gemspec, to override it
- elsif local_spec = Bundler.rubygems.find_name("bundler").find {|s| s.version.to_s == VERSION }
- idx << local_spec
- end
-
- idx.each {|s| s.source = self }
- end
- end
-
- def cached!; end
-
- def remote!; end
-
- def options
- {}
- end
-
- def install(spec, _opts = {})
- print_using_message "Using #{version_message(spec)}"
- nil
- end
-
- def to_s
- "the local ruby installation"
- end
-
- def ==(other)
- self.class == other.class
- end
- alias_method :eql?, :==
-
- def hash
- self.class.hash
- end
-
- def version_message(spec)
- "#{spec.name} #{spec.version}"
- end
- end
- end
-end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
deleted file mode 100644
index ed734bf549..0000000000
--- a/lib/bundler/source/path.rb
+++ /dev/null
@@ -1,249 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Source
- class Path < Source
- autoload :Installer, "bundler/source/path/installer"
-
- attr_reader :path, :options, :root_path, :original_path
- attr_writer :name
- attr_accessor :version
-
- protected :original_path
-
- DEFAULT_GLOB = "{,*,*/*}.gemspec".freeze
-
- def initialize(options)
- @options = options.dup
- @glob = options["glob"] || DEFAULT_GLOB
-
- @allow_cached = false
- @allow_remote = false
-
- @root_path = options["root_path"] || Bundler.root
-
- if options["path"]
- @path = Pathname.new(options["path"])
- @path = expand(@path) unless @path.relative?
- end
-
- @name = options["name"]
- @version = options["version"]
-
- # Stores the original path. If at any point we move to the
- # cached directory, we still have the original path to copy from.
- @original_path = @path
- end
-
- def remote!
- @local_specs = nil
- @allow_remote = true
- end
-
- def cached!
- @local_specs = nil
- @allow_cached = true
- end
-
- def self.from_lock(options)
- new(options.merge("path" => options.delete("remote")))
- end
-
- def to_lock
- out = String.new("PATH\n")
- out << " remote: #{lockfile_path}\n"
- out << " glob: #{@glob}\n" unless @glob == DEFAULT_GLOB
- out << " specs:\n"
- end
-
- def to_s
- "source at `#{@path}`"
- end
-
- def hash
- [self.class, expanded_path, version].hash
- end
-
- def eql?(other)
- return unless other.class == self.class
- expanded_original_path == other.expanded_original_path &&
- version == other.version
- end
-
- alias_method :==, :eql?
-
- def name
- File.basename(expanded_path.to_s)
- end
-
- def install(spec, options = {})
- print_using_message "Using #{version_message(spec)} from #{self}"
- generate_bin(spec, :disable_extensions => true)
- nil # no post-install message
- end
-
- def cache(spec, custom_path = nil)
- app_cache_path = app_cache_path(custom_path)
- return unless Bundler.feature_flag.cache_all?
- return if expand(@original_path).to_s.index(root_path.to_s + "/") == 0
-
- unless @original_path.exist?
- raise GemNotFound, "Can't cache gem #{version_message(spec)} because #{self} is missing!"
- end
-
- FileUtils.rm_rf(app_cache_path)
- FileUtils.cp_r("#{@original_path}/.", app_cache_path)
- FileUtils.touch(app_cache_path.join(".bundlecache"))
- end
-
- def local_specs(*)
- @local_specs ||= load_spec_files
- end
-
- def specs
- if has_app_cache?
- @path = app_cache_path
- @expanded_path = nil # Invalidate
- end
- local_specs
- end
-
- def app_cache_dirname
- name
- end
-
- def root
- Bundler.root
- end
-
- def expanded_original_path
- @expanded_original_path ||= expand(original_path)
- end
-
- private
-
- def expanded_path
- @expanded_path ||= expand(path)
- end
-
- def expand(somepath)
- somepath.expand_path(root_path)
- rescue ArgumentError => e
- Bundler.ui.debug(e)
- raise PathError, "There was an error while trying to use the path " \
- "`#{somepath}`.\nThe error message was: #{e.message}."
- end
-
- def lockfile_path
- return relative_path(original_path) if original_path.absolute?
- expand(original_path).relative_path_from(Bundler.root)
- end
-
- def app_cache_path(custom_path = nil)
- @app_cache_path ||= Bundler.app_cache(custom_path).join(app_cache_dirname)
- end
-
- def has_app_cache?
- SharedHelpers.in_bundle? && app_cache_path.exist?
- end
-
- def load_gemspec(file)
- return unless spec = Bundler.load_gemspec(file)
- Bundler.rubygems.set_installed_by_version(spec)
- spec
- end
-
- def validate_spec(spec)
- Bundler.rubygems.validate(spec)
- end
-
- def load_spec_files
- index = Index.new
-
- if File.directory?(expanded_path)
- # We sort depth-first since `<<` will override the earlier-found specs
- Dir["#{expanded_path}/#{@glob}"].sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
- next unless spec = load_gemspec(file)
- spec.source = self
-
- # Validation causes extension_dir to be calculated, which depends
- # on #source, so we validate here instead of load_gemspec
- validate_spec(spec)
- index << spec
- end
-
- if index.empty? && @name && @version
- index << Gem::Specification.new do |s|
- s.name = @name
- s.source = self
- s.version = Gem::Version.new(@version)
- s.platform = Gem::Platform::RUBY
- s.summary = "Fake gemspec for #{@name}"
- s.relative_loaded_from = "#{@name}.gemspec"
- s.authors = ["no one"]
- if expanded_path.join("bin").exist?
- executables = expanded_path.join("bin").children
- executables.reject! {|p| File.directory?(p) }
- s.executables = executables.map {|c| c.basename.to_s }
- end
- end
- end
- else
- message = String.new("The path `#{expanded_path}` ")
- message << if File.exist?(expanded_path)
- "is not a directory."
- else
- "does not exist."
- end
- raise PathError, message
- end
-
- index
- end
-
- def relative_path(path = self.path)
- if path.to_s.start_with?(root_path.to_s)
- return path.relative_path_from(root_path)
- end
- path
- end
-
- def generate_bin(spec, options = {})
- gem_dir = Pathname.new(spec.full_gem_path)
-
- # Some gem authors put absolute paths in their gemspec
- # and we have to save them from themselves
- spec.files = spec.files.map do |p|
- next p unless p =~ /\A#{Pathname::SEPARATOR_PAT}/
- next if File.directory?(p)
- begin
- Pathname.new(p).relative_path_from(gem_dir).to_s
- rescue ArgumentError
- p
- end
- end.compact
-
- installer = Path::Installer.new(
- spec,
- :env_shebang => false,
- :disable_extensions => options[:disable_extensions],
- :build_args => options[:build_args],
- :bundler_extension_cache_path => extension_cache_path(spec)
- )
- installer.post_install
- rescue Gem::InvalidSpecificationException => e
- Bundler.ui.warn "\n#{spec.name} at #{spec.full_gem_path} did not have a valid gemspec.\n" \
- "This prevents bundler from installing bins or native extensions, but " \
- "that may not affect its functionality."
-
- if !spec.extensions.empty? && !spec.email.empty?
- Bundler.ui.warn "If you need to use this package without installing it from a gem " \
- "repository, please contact #{spec.email} and ask them " \
- "to modify their .gemspec so it can work with `gem build`."
- end
-
- Bundler.ui.warn "The validation message from RubyGems was:\n #{e.message}"
- end
- end
- end
-end
diff --git a/lib/bundler/source/path/installer.rb b/lib/bundler/source/path/installer.rb
deleted file mode 100644
index a0357ffa39..0000000000
--- a/lib/bundler/source/path/installer.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Source
- class Path
- class Installer < Bundler::RubyGemsGemInstaller
- attr_reader :spec
-
- def initialize(spec, options = {})
- @options = options
- @spec = spec
- @gem_dir = Bundler.rubygems.path(spec.full_gem_path)
- @wrappers = true
- @env_shebang = true
- @format_executable = options[:format_executable] || false
- @build_args = options[:build_args] || Bundler.rubygems.build_args
- @gem_bin_dir = "#{Bundler.rubygems.gem_dir}/bin"
- @disable_extensions = options[:disable_extensions]
-
- if Bundler.requires_sudo?
- @tmp_dir = Bundler.tmp(spec.full_name).to_s
- @bin_dir = "#{@tmp_dir}/bin"
- else
- @bin_dir = @gem_bin_dir
- end
- end
-
- def post_install
- SharedHelpers.chdir(@gem_dir) do
- run_hooks(:pre_install)
-
- unless @disable_extensions
- build_extensions
- run_hooks(:post_build)
- end
-
- generate_bin unless spec.executables.nil? || spec.executables.empty?
-
- run_hooks(:post_install)
- end
- ensure
- Bundler.rm_rf(@tmp_dir) if Bundler.requires_sudo?
- end
-
- private
-
- def generate_bin
- super
-
- if Bundler.requires_sudo?
- SharedHelpers.filesystem_access(@gem_bin_dir) do |p|
- Bundler.mkdir_p(p)
- end
- spec.executables.each do |exe|
- Bundler.sudo "cp -R #{@bin_dir}/#{exe} #{@gem_bin_dir}"
- end
- end
- end
-
- def run_hooks(type)
- hooks_meth = "#{type}_hooks"
- return unless Gem.respond_to?(hooks_meth)
- Gem.send(hooks_meth).each do |hook|
- result = hook.call(self)
- next unless result == false
- location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
- message = "#{type} hook#{location} failed for #{spec.full_name}"
- raise InstallHookError, message
- end
- end
- end
- end
- end
-end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
deleted file mode 100644
index 3cf22a50f1..0000000000
--- a/lib/bundler/source/rubygems.rb
+++ /dev/null
@@ -1,530 +0,0 @@
-# frozen_string_literal: true
-
-require "uri"
-require "rubygems/user_interaction"
-
-module Bundler
- class Source
- class Rubygems < Source
- autoload :Remote, "bundler/source/rubygems/remote"
-
- # Use the API when installing less than X gems
- API_REQUEST_LIMIT = 500
- # Ask for X gems per API request
- API_REQUEST_SIZE = 50
-
- attr_reader :remotes, :caches
-
- def initialize(options = {})
- @options = options
- @remotes = []
- @dependency_names = []
- @allow_remote = false
- @allow_cached = false
- @caches = [cache_path, *Bundler.rubygems.gem_cache]
-
- Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
- end
-
- def remote!
- @specs = nil
- @allow_remote = true
- end
-
- def cached!
- @specs = nil
- @allow_cached = true
- end
-
- def hash
- @remotes.hash
- end
-
- def eql?(other)
- other.is_a?(Rubygems) && other.credless_remotes == credless_remotes
- end
-
- alias_method :==, :eql?
-
- def include?(o)
- o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
- end
-
- def can_lock?(spec)
- return super if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
- spec.source.is_a?(Rubygems)
- end
-
- def options
- { "remotes" => @remotes.map(&:to_s) }
- end
-
- def self.from_lock(options)
- new(options)
- end
-
- def to_lock
- out = String.new("GEM\n")
- remotes.reverse_each do |remote|
- out << " remote: #{suppress_configured_credentials remote}\n"
- end
- out << " specs:\n"
- end
-
- def to_s
- if remotes.empty?
- "locally installed gems"
- else
- remote_names = remotes.map(&:to_s).join(", ")
- "rubygems repository #{remote_names} or installed locally"
- end
- end
- alias_method :name, :to_s
-
- def specs
- @specs ||= begin
- # remote_specs usually generates a way larger Index than the other
- # sources, and large_idx.use small_idx is way faster than
- # small_idx.use large_idx.
- idx = @allow_remote ? remote_specs.dup : Index.new
- idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
- idx.use(installed_specs, :override_dupes)
- idx
- end
- end
-
- def install(spec, opts = {})
- force = opts[:force]
- ensure_builtin_gems_cached = opts[:ensure_builtin_gems_cached]
-
- if ensure_builtin_gems_cached && builtin_gem?(spec)
- if !cached_path(spec)
- cached_built_in_gem(spec) unless spec.remote
- force = true
- else
- spec.loaded_from = loaded_from(spec)
- end
- end
-
- if installed?(spec) && !force
- print_using_message "Using #{version_message(spec)}"
- return nil # no post-install message
- end
-
- # Download the gem to get the spec, because some specs that are returned
- # by rubygems.org are broken and wrong.
- if spec.remote
- # Check for this spec from other sources
- uris = [spec.remote.anonymized_uri]
- uris += remotes_for_spec(spec).map(&:anonymized_uri)
- 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)
- end
-
- unless Bundler.settings[:no_install]
- message = "Installing #{version_message(spec)}"
- message += " with native extensions" if spec.extensions.any?
- Bundler.ui.confirm message
-
- path = cached_gem(spec)
- if requires_sudo?
- install_path = Bundler.tmp(spec.full_name)
- bin_path = install_path.join("bin")
- else
- install_path = rubygems_dir
- bin_path = Bundler.system_bindir
- end
-
- installed_spec = nil
- Bundler.rubygems.preserve_paths do
- installed_spec = Bundler::RubyGemsGemInstaller.at(
- path,
- :install_dir => install_path.to_s,
- :bin_dir => bin_path.to_s,
- :ignore_dependencies => true,
- :wrappers => true,
- :env_shebang => true,
- :build_args => opts[:build_args],
- :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
- :bundler_extension_cache_path => extension_cache_path(spec)
- ).install
- end
- spec.full_gem_path = installed_spec.full_gem_path
-
- # SUDO HAX
- if requires_sudo?
- Bundler.rubygems.repository_subdirectories.each do |name|
- src = File.join(install_path, name, "*")
- dst = File.join(rubygems_dir, name)
- if name == "extensions" && Dir.glob(src).any?
- src = File.join(src, "*/*")
- ext_src = Dir.glob(src).first
- ext_src.gsub!(src[0..-6], "")
- dst = File.dirname(File.join(dst, ext_src))
- end
- SharedHelpers.filesystem_access(dst) do |p|
- Bundler.mkdir_p(p)
- end
- Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any?
- end
-
- spec.executables.each do |exe|
- SharedHelpers.filesystem_access(Bundler.system_bindir) do |p|
- Bundler.mkdir_p(p)
- end
- Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/"
- end
- end
- installed_spec.loaded_from = loaded_from(spec)
- end
- spec.loaded_from = loaded_from(spec)
-
- spec.post_install_message
- ensure
- Bundler.rm_rf(install_path) if requires_sudo?
- end
-
- def cache(spec, custom_path = nil)
- if builtin_gem?(spec)
- cached_path = cached_built_in_gem(spec)
- else
- cached_path = cached_gem(spec)
- end
- raise GemNotFound, "Missing gem file '#{spec.full_name}.gem'." unless cached_path
- return if File.dirname(cached_path) == Bundler.app_cache.to_s
- Bundler.ui.info " * #{File.basename(cached_path)}"
- FileUtils.cp(cached_path, Bundler.app_cache(custom_path))
- rescue Errno::EACCES => e
- Bundler.ui.debug(e)
- raise InstallError, e.message
- end
-
- def cached_built_in_gem(spec)
- cached_path = cached_path(spec)
- if cached_path.nil?
- remote_spec = remote_specs.search(spec).first
- if remote_spec
- cached_path = fetch_gem(remote_spec)
- else
- Bundler.ui.warn "#{spec.full_name} is built in to Ruby, and can't be cached because your Gemfile doesn't have any sources that contain it."
- end
- end
- cached_path
- end
-
- def add_remote(source)
- uri = normalize_uri(source)
- @remotes.unshift(uri) unless @remotes.include?(uri)
- end
-
- def equivalent_remotes?(other_remotes)
- other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
- end
-
- def replace_remotes(other_remotes, allow_equivalent = false)
- return false if other_remotes == @remotes
-
- equivalent = allow_equivalent && equivalent_remotes?(other_remotes)
-
- @remotes = []
- other_remotes.reverse_each do |r|
- add_remote r.to_s
- end
-
- !equivalent
- end
-
- def unmet_deps
- if @allow_remote && api_fetchers.any?
- remote_specs.unmet_dependency_names
- else
- []
- end
- end
-
- def fetchers
- @fetchers ||= remotes.map do |uri|
- remote = Source::Rubygems::Remote.new(uri)
- Bundler::Fetcher.new(remote)
- end
- end
-
- def double_check_for(unmet_dependency_names)
- return unless @allow_remote
- return unless api_fetchers.any?
-
- unmet_dependency_names = unmet_dependency_names.call
- unless unmet_dependency_names.nil?
- if api_fetchers.size <= 1
- # can't do this when there are multiple fetchers because then we might not fetch from _all_
- # of them
- unmet_dependency_names -= remote_specs.spec_names # avoid re-fetching things we've already gotten
- end
- return if unmet_dependency_names.empty?
- end
-
- Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}"
-
- fetch_names(api_fetchers, unmet_dependency_names, specs, false)
- end
-
- def dependency_names_to_double_check
- names = []
- remote_specs.each do |spec|
- case spec
- when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
- names.concat(spec.runtime_dependencies)
- when RemoteSpecification # from the full index
- return nil
- else
- raise "unhandled spec type (#{spec.inspect})"
- end
- end
- names.map!(&:name) if names
- names
- end
-
- protected
-
- def credless_remotes
- remotes.map(&method(:suppress_configured_credentials))
- end
-
- def remotes_for_spec(spec)
- specs.search_all(spec.name).inject([]) do |uris, s|
- uris << s.remote if s.remote
- uris
- end
- end
-
- def loaded_from(spec)
- "#{rubygems_dir}/specifications/#{spec.full_name}.gemspec"
- end
-
- def cached_gem(spec)
- cached_gem = cached_path(spec)
- unless cached_gem
- raise Bundler::GemNotFound, "Could not find #{spec.file_name} for installation"
- end
- cached_gem
- end
-
- def cached_path(spec)
- possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" }
- possibilities.find {|p| File.exist?(p) }
- end
-
- def normalize_uri(uri)
- uri = uri.to_s
- uri = "#{uri}/" unless uri =~ %r{/$}
- uri = URI(uri)
- raise ArgumentError, "The source must be an absolute URI. For example:\n" \
- "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(URI::HTTP) && uri.host.nil?)
- uri
- end
-
- def suppress_configured_credentials(remote)
- remote_nouser = remove_auth(remote)
- if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser]
- remote_nouser
- else
- remote
- end
- end
-
- def remove_auth(remote)
- remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
- end
-
- def installed_specs
- @installed_specs ||= Index.build do |idx|
- Bundler.rubygems.all_specs.reverse_each do |spec|
- next if spec.name == "bundler"
- spec.source = self
- if Bundler.rubygems.spec_missing_extensions?(spec, false)
- Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
- next
- end
- idx << spec
- end
- end
- end
-
- def cached_specs
- @cached_specs ||= begin
- idx = installed_specs.dup
-
- Dir["#{cache_path}/*.gem"].each do |gemfile|
- next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
- s ||= Bundler.rubygems.spec_from_gem(gemfile)
- s.source = self
- if Bundler.rubygems.spec_missing_extensions?(s, false)
- Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
- next
- end
- idx << s
- end
-
- idx
- end
- end
-
- def api_fetchers
- fetchers.select {|f| f.use_api && f.fetchers.first.api_fetcher? }
- end
-
- def remote_specs
- @remote_specs ||= Index.build do |idx|
- index_fetchers = fetchers - api_fetchers
-
- # gather lists from non-api sites
- fetch_names(index_fetchers, nil, idx, false)
-
- # because ensuring we have all the gems we need involves downloading
- # the gemspecs of those gems, if the non-api sites contain more than
- # about 500 gems, we treat all sites as non-api for speed.
- allow_api = idx.size < API_REQUEST_LIMIT && dependency_names.size < API_REQUEST_LIMIT
- Bundler.ui.debug "Need to query more than #{API_REQUEST_LIMIT} gems." \
- " Downloading full index instead..." unless allow_api
-
- fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
- end
- end
-
- def fetch_names(fetchers, dependency_names, index, override_dupes)
- fetchers.each do |f|
- if dependency_names
- Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
- index.use f.specs_with_retry(dependency_names, self), override_dupes
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- else
- Bundler.ui.info "Fetching source index from #{f.uri}"
- index.use f.specs_with_retry(nil, self), override_dupes
- end
- end
- end
-
- def fetch_gem(spec)
- return false unless spec.remote
-
- spec.fetch_platform
-
- download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
- gem_path = "#{rubygems_dir}/cache/#{spec.full_name}.gem"
-
- SharedHelpers.filesystem_access("#{download_path}/cache") do |p|
- FileUtils.mkdir_p(p)
- end
- download_gem(spec, download_path)
-
- if requires_sudo?
- SharedHelpers.filesystem_access("#{rubygems_dir}/cache") do |p|
- Bundler.mkdir_p(p)
- end
- Bundler.sudo "mv #{download_path}/cache/#{spec.full_name}.gem #{gem_path}"
- end
-
- gem_path
- ensure
- Bundler.rm_rf(download_path) if requires_sudo?
- end
-
- def builtin_gem?(spec)
- # Ruby 2.1, where all included gems have this summary
- return true if spec.summary =~ /is bundled with Ruby/
-
- # Ruby 2.0, where gemspecs are stored in specifications/default/
- spec.loaded_from && spec.loaded_from.include?("specifications/default/")
- end
-
- def installed?(spec)
- installed_specs[spec].any?
- end
-
- def requires_sudo?
- Bundler.requires_sudo?
- end
-
- def rubygems_dir
- Bundler.rubygems.gem_dir
- end
-
- def cache_path
- Bundler.app_cache
- end
-
- private
-
- # Checks if the requested spec exists in the global cache. If it does,
- # we copy it to the download path, and if it does not, we download it.
- #
- # @param [Specification] spec
- # the spec we want to download or retrieve from the cache.
- #
- # @param [String] download_path
- # the local directory the .gem will end up in.
- #
- def download_gem(spec, download_path)
- local_path = File.join(download_path, "cache/#{spec.full_name}.gem")
-
- if (cache_path = download_cache_path(spec)) && cache_path.file?
- SharedHelpers.filesystem_access(local_path) do
- FileUtils.cp(cache_path, local_path)
- end
- else
- uri = spec.remote.uri
- Bundler.ui.confirm("Fetching #{version_message(spec)}")
- Bundler.rubygems.download_gem(spec, uri, download_path)
- cache_globally(spec, local_path)
- end
- end
-
- # Checks if the requested spec exists in the global cache. If it does
- # not, we create the relevant global cache subdirectory if it does not
- # exist and copy the spec from the local cache to the global cache.
- #
- # @param [Specification] spec
- # the spec we want to copy to the global cache.
- #
- # @param [String] local_cache_path
- # the local directory from which we want to copy the .gem.
- #
- def cache_globally(spec, local_cache_path)
- return unless cache_path = download_cache_path(spec)
- return if cache_path.exist?
-
- SharedHelpers.filesystem_access(cache_path.dirname, &:mkpath)
- SharedHelpers.filesystem_access(cache_path) do
- FileUtils.cp(local_cache_path, cache_path)
- end
- end
-
- # Returns the global cache path of the calling Rubygems::Source object.
- #
- # Note that the Source determines the path's subdirectory. We use this
- # subdirectory in the global cache path so that gems with the same name
- # -- and possibly different versions -- from different sources are saved
- # to their respective subdirectories and do not override one another.
- #
- # @param [Gem::Specification] specification
- #
- # @return [Pathname] The global cache path.
- #
- def download_cache_path(spec)
- return unless Bundler.feature_flag.global_gem_cache?
- return unless remote = spec.remote
- return unless cache_slug = remote.cache_slug
-
- Bundler.user_cache.join("gems", cache_slug, spec.file_name)
- end
-
- def extension_cache_slug(spec)
- return unless remote = spec.remote
- remote.cache_slug
- end
- end
- end
-end
diff --git a/lib/bundler/source/rubygems/remote.rb b/lib/bundler/source/rubygems/remote.rb
deleted file mode 100644
index e73baaa992..0000000000
--- a/lib/bundler/source/rubygems/remote.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Source
- class Rubygems
- class Remote
- attr_reader :uri, :anonymized_uri, :original_uri
-
- def initialize(uri)
- orig_uri = uri
- uri = Bundler.settings.mirror_for(uri)
- @original_uri = orig_uri if orig_uri != uri
- fallback_auth = Bundler.settings.credentials_for(uri)
-
- @uri = apply_auth(uri, fallback_auth).freeze
- @anonymized_uri = remove_auth(@uri).freeze
- end
-
- # @return [String] A slug suitable for use as a cache key for this
- # remote.
- #
- def cache_slug
- @cache_slug ||= begin
- return nil unless SharedHelpers.md5_available?
-
- cache_uri = original_uri || uri
-
- uri_parts = [cache_uri.host, cache_uri.user, cache_uri.port, cache_uri.path]
- uri_digest = SharedHelpers.digest(:MD5).hexdigest(uri_parts.compact.join("."))
-
- uri_parts[-1] = uri_digest
- uri_parts.compact.join(".")
- end
- end
-
- def to_s
- "rubygems remote at #{anonymized_uri}"
- end
-
- private
-
- def apply_auth(uri, auth)
- if auth && uri.userinfo.nil?
- uri = uri.dup
- uri.userinfo = auth
- end
-
- uri
- rescue URI::InvalidComponentError
- error_message = "Please CGI escape your usernames and passwords before " \
- "setting them for authentication."
- raise HTTPError.new(error_message)
- end
-
- def remove_auth(uri)
- if uri.userinfo
- uri = uri.dup
- uri.user = uri.password = nil
- end
-
- uri
- end
- end
- end
- end
-end
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
deleted file mode 100644
index ac2adacb3d..0000000000
--- a/lib/bundler/source_list.rb
+++ /dev/null
@@ -1,186 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class SourceList
- attr_reader :path_sources,
- :git_sources,
- :plugin_sources,
- :global_rubygems_source,
- :metadata_source
-
- def initialize
- @path_sources = []
- @git_sources = []
- @plugin_sources = []
- @global_rubygems_source = nil
- @rubygems_aggregate = rubygems_aggregate_class.new
- @rubygems_sources = []
- @metadata_source = Source::Metadata.new
- end
-
- def add_path_source(options = {})
- if options["gemspec"]
- add_source_to_list Source::Gemspec.new(options), path_sources
- else
- add_source_to_list Source::Path.new(options), path_sources
- end
- end
-
- def add_git_source(options = {})
- add_source_to_list(Source::Git.new(options), git_sources).tap do |source|
- warn_on_git_protocol(source)
- end
- end
-
- def add_rubygems_source(options = {})
- add_source_to_list Source::Rubygems.new(options), @rubygems_sources
- end
-
- def add_plugin_source(source, options = {})
- add_source_to_list Plugin.source(source).new(options), @plugin_sources
- end
-
- def global_rubygems_source=(uri)
- if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
- @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
- @rubygems_aggregate.add_remote(uri)
- @rubygems_aggregate
- end
-
- def default_source
- global_rubygems_source || @rubygems_aggregate
- end
-
- def rubygems_sources
- @rubygems_sources + [default_source]
- end
-
- def rubygems_remotes
- rubygems_sources.map(&:remotes).flatten.uniq
- end
-
- def all_sources
- path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
- end
-
- def get(source)
- source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) }
- 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)
- else
- lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
- lock_sources << combine_rubygems_sources
- end
- end
-
- # Returns true if there are changes
- def replace_sources!(replacement_sources)
- return true if replacement_sources.empty?
-
- [path_sources, git_sources, plugin_sources].each do |source_list|
- source_list.map! do |source|
- replacement_sources.find {|s| s == source } || source
- end
- end
-
- replacement_rubygems = !Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? &&
- replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
- @rubygems_aggregate = replacement_rubygems if replacement_rubygems
-
- return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
- return true if replacement_rubygems && rubygems_remotes.to_set != replacement_rubygems.remotes.to_set
-
- false
- end
-
- def cached!
- all_sources.each(&:cached!)
- end
-
- def remote!
- all_sources.each(&:remote!)
- end
-
- def rubygems_primary_remotes
- @rubygems_aggregate.remotes
- end
-
- private
-
- def rubygems_aggregate_class
- Source::Rubygems
- end
-
- def add_source_to_list(source, list)
- list.unshift(source).uniq!
- source
- end
-
- def source_list_for(source)
- case source
- when Source::Git then git_sources
- when Source::Path then path_sources
- when Source::Rubygems then rubygems_sources
- when Plugin::API::Source then plugin_sources
- else raise ArgumentError, "Invalid source: #{source.inspect}"
- end
- end
-
- def combine_rubygems_sources
- Source::Rubygems.new("remotes" => rubygems_remotes)
- end
-
- def warn_on_git_protocol(source)
- return if Bundler.settings["git.allow_insecure"]
-
- 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` " \
- "protocol to keep your data secure."
- end
- end
-
- def equal_sources?(lock_sources, replacement_sources)
- lock_sources.to_set == replacement_sources.to_set
- end
-
- def equal_source?(source, other_source)
- source == other_source
- end
-
- def equivalent_source?(source, other_source)
- return false unless Bundler.settings[:allow_deployment_source_credential_changes] && source.is_a?(Source::Rubygems)
-
- equivalent_rubygems_sources?([source], [other_source])
- end
-
- def equivalent_sources?(lock_sources, replacement_sources)
- return false unless Bundler.settings[:allow_deployment_source_credential_changes]
-
- lock_rubygems_sources, lock_other_sources = lock_sources.partition {|s| s.is_a?(Source::Rubygems) }
- replacement_rubygems_sources, replacement_other_sources = replacement_sources.partition {|s| s.is_a?(Source::Rubygems) }
-
- equivalent_rubygems_sources?(lock_rubygems_sources, replacement_rubygems_sources) && equal_sources?(lock_other_sources, replacement_other_sources)
- end
-
- def equivalent_rubygems_sources?(lock_sources, replacement_sources)
- actual_remotes = replacement_sources.map(&:remotes).flatten.uniq
- lock_sources.all? {|s| s.equivalent_remotes?(actual_remotes) }
- end
- end
-end
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
deleted file mode 100644
index 7cd3021997..0000000000
--- a/lib/bundler/spec_set.rb
+++ /dev/null
@@ -1,189 +0,0 @@
-# frozen_string_literal: true
-
-require "tsort"
-require "forwardable"
-require "set"
-
-module Bundler
- class SpecSet
- extend Forwardable
- include TSort, Enumerable
-
- def_delegators :@specs, :<<, :length, :add, :remove, :size, :empty?
- def_delegators :sorted, :each
-
- def initialize(specs)
- @specs = specs
- end
-
- def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
- handled = Set.new
- deps = dependencies.dup
- specs = []
- skip += ["bundler"]
-
- loop do
- break unless dep = deps.shift
- next if !handled.add?(dep) || skip.include?(dep.name)
-
- if spec = spec_for_dependency(dep, match_current_platform)
- specs << spec
-
- spec.dependencies.each do |d|
- next if d.type == :development
- d = DepProxy.new(d, dep.__platform) unless match_current_platform
- deps << d
- end
- elsif check
- return false
- elsif raise_on_missing
- raise "Unable to find a spec satisfying #{dep} in the set. Perhaps the lockfile is corrupted?"
- end
- end
-
- if spec = lookup["bundler"].first
- specs << spec
- end
-
- check ? true : SpecSet.new(specs)
- end
-
- def valid_for?(deps)
- self.for(deps, [], true)
- end
-
- def [](key)
- key = key.name if key.respond_to?(:name)
- lookup[key].reverse
- end
-
- def []=(key, value)
- @specs << value
- @lookup = nil
- @sorted = nil
- value
- end
-
- def sort!
- self
- end
-
- def to_a
- sorted.dup
- end
-
- def to_hash
- lookup.dup
- end
-
- def materialize(deps, missing_specs = nil)
- materialized = self.for(deps, [], false, true, !missing_specs).to_a
- deps = materialized.map(&:name).uniq
- materialized.map! do |s|
- next s unless s.is_a?(LazySpecification)
- s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
- spec = s.__materialize__
- unless spec
- unless missing_specs
- raise GemNotFound, "Could not find #{s.full_name} in any of the sources"
- end
- missing_specs << s
- end
- spec
- end
- SpecSet.new(missing_specs ? materialized.compact : materialized)
- end
-
- # Materialize for all the specs in the spec set, regardless of what platform they're for
- # This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform)
- # @return [Array<Gem::Specification>]
- def materialized_for_all_platforms
- names = @specs.map(&:name).uniq
- @specs.map do |s|
- next s unless s.is_a?(LazySpecification)
- s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
- spec = s.__materialize__
- raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
- spec
- end
- end
-
- def merge(set)
- arr = sorted.dup
- set.each do |set_spec|
- full_name = set_spec.full_name
- next if arr.any? {|spec| spec.full_name == full_name }
- arr << set_spec
- end
- SpecSet.new(arr)
- end
-
- def find_by_name_and_platform(name, platform)
- @specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
- end
-
- def what_required(spec)
- unless req = find {|s| s.dependencies.any? {|d| d.type == :runtime && d.name == spec.name } }
- return [spec]
- end
- what_required(req) << spec
- end
-
- private
-
- def sorted
- rake = @specs.find {|s| s.name == "rake" }
- begin
- @sorted ||= ([rake] + tsort).compact.uniq
- rescue TSort::Cyclic => error
- cgems = extract_circular_gems(error)
- raise CyclicDependencyError, "Your bundle requires gems that depend" \
- " on each other, creating an infinite loop. Please remove either" \
- " gem '#{cgems[1]}' or gem '#{cgems[0]}' and try again."
- end
- end
-
- def extract_circular_gems(error)
- if Bundler.current_ruby.mri? && Bundler.current_ruby.on_19?
- error.message.scan(/(\w+) \([^)]/).flatten
- else
- error.message.scan(/@name="(.*?)"/).flatten
- end
- end
-
- def lookup
- @lookup ||= begin
- lookup = Hash.new {|h, k| h[k] = [] }
- Index.sort_specs(@specs).reverse_each do |s|
- lookup[s.name] << s
- end
- lookup
- end
- end
-
- def tsort_each_node
- # MUST sort by name for backwards compatibility
- @specs.sort_by(&:name).each {|s| yield s }
- end
-
- def spec_for_dependency(dep, match_current_platform)
- specs_for_platforms = lookup[dep.name]
- if match_current_platform
- Bundler.rubygems.platforms.reverse_each do |pl|
- match = GemHelpers.select_best_platform_match(specs_for_platforms, pl)
- return match if match
- end
- nil
- else
- GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
- end
- end
-
- def tsort_each_child(s)
- s.dependencies.sort_by(&:name).each do |d|
- next if d.type == :development
- lookup[d.name].each {|s2| yield s2 }
- end
- end
- end
-end
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
deleted file mode 100644
index 0dd024024a..0000000000
--- a/lib/bundler/stub_specification.rb
+++ /dev/null
@@ -1,108 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/remote_specification"
-
-module Bundler
- class StubSpecification < RemoteSpecification
- def self.from_stub(stub)
- return stub if stub.is_a?(Bundler::StubSpecification)
- spec = new(stub.name, stub.version, stub.platform, nil)
- spec.stub = stub
- spec
- end
-
- 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
- end
-
- def to_yaml
- _remote_specification.to_yaml
- end
-
- # @!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
- end
-
- def activated
- stub.activated
- end
-
- def activated=(activated)
- stub.instance_variable_set(:@activated, activated)
- end
-
- def default_gem
- stub.default_gem
- end
-
- def full_gem_path
- # deleted gems can have their stubs return nil, so in that case grab the
- # expired path from the full spec
- 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
-
- # 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
- end
-
- def loaded_from
- stub.loaded_from
- end
-
- if Bundler.rubygems.stubs_provide_full_functionality?
- def matches_for_glob(glob)
- stub.matches_for_glob(glob)
- end
- end
-
- def raw_require_paths
- stub.raw_require_paths
- end
-
- private
-
- def _remote_specification
- @_remote_specification ||= begin
- rs = stub.to_spec
- if rs.equal?(self) # happens when to_spec gets the spec from Gem.loaded_specs
- rs = Gem::Specification.load(loaded_from)
- Bundler.rubygems.stub_set_spec(stub, rs)
- end
-
- unless rs
- raise GemspecError, "The gemspec for #{full_name} at #{loaded_from}" \
- " was missing or broken. Try running `gem pristine #{name} -v #{version}`" \
- " to fix the cached spec."
- end
-
- rs.source = source
-
- rs
- end
- end
- end
-end
diff --git a/lib/bundler/templates/.document b/lib/bundler/templates/.document
deleted file mode 100644
index fb66f13c33..0000000000
--- a/lib/bundler/templates/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Ignore all files in this directory
diff --git a/lib/bundler/templates/Executable b/lib/bundler/templates/Executable
deleted file mode 100755
index 414a75898d..0000000000
--- a/lib/bundler/templates/Executable
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %>
-# frozen_string_literal: true
-
-#
-# This file was generated by Bundler.
-#
-# The application '<%= executable %>' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require "pathname"
-ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../<%= relative_gemfile_path %>",
- Pathname.new(__FILE__).realpath)
-
-bundle_binstub = File.expand_path("../bundle", __FILE__)
-
-if File.file?(bundle_binstub)
- if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
- load(bundle_binstub)
- else
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
-Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
- end
-end
-
-require "rubygems"
-require "bundler/setup"
-
-load Gem.bin_path("<%= spec.name %>", "<%= executable %>")
diff --git a/lib/bundler/templates/Executable.bundler b/lib/bundler/templates/Executable.bundler
deleted file mode 100644
index eeda90b584..0000000000
--- a/lib/bundler/templates/Executable.bundler
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %>
-# frozen_string_literal: true
-
-#
-# This file was generated by Bundler.
-#
-# The application '<%= executable %>' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require "rubygems"
-
-m = Module.new do
- module_function
-
- def invoked_as_script?
- File.expand_path($0) == File.expand_path(__FILE__)
- end
-
- def env_var_version
- ENV["BUNDLER_VERSION"]
- end
-
- def cli_arg_version
- return unless invoked_as_script? # don't want to hijack other binstubs
- return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
- bundler_version = nil
- update_index = nil
- ARGV.each_with_index do |a, i|
- if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
- bundler_version = a
- end
- next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
- bundler_version = $1 || ">= 0.a"
- update_index = i
- end
- bundler_version
- end
-
- def gemfile
- gemfile = ENV["BUNDLE_GEMFILE"]
- return gemfile if gemfile && !gemfile.empty?
-
- File.expand_path("../<%= relative_gemfile_path %>", __FILE__)
- end
-
- def lockfile
- lockfile =
- case File.basename(gemfile)
- when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
- else "#{gemfile}.lock"
- end
- File.expand_path(lockfile)
- end
-
- def lockfile_version
- return unless File.file?(lockfile)
- lockfile_contents = File.read(lockfile)
- return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
- Regexp.last_match(1)
- end
-
- def bundler_version
- @bundler_version ||= begin
- env_var_version || cli_arg_version ||
- lockfile_version || "#{Gem::Requirement.default}.a"
- end
- end
-
- def load_bundler!
- ENV["BUNDLE_GEMFILE"] ||= gemfile
-
- # must dup string for RG < 1.8 compatibility
- activate_bundler(bundler_version.dup)
- end
-
- def activate_bundler(bundler_version)
- if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
- bundler_version = "< 2"
- end
- gem_error = activation_error_handling do
- gem "bundler", bundler_version
- end
- return if gem_error.nil?
- require_error = activation_error_handling do
- require "bundler/version"
- end
- return if require_error.nil? && Gem::Requirement.new(bundler_version).satisfied_by?(Gem::Version.new(Bundler::VERSION))
- warn "Activating bundler (#{bundler_version}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_version}'`"
- exit 42
- end
-
- def activation_error_handling
- yield
- nil
- rescue StandardError, LoadError => e
- e
- end
-end
-
-m.load_bundler!
-
-if m.invoked_as_script?
- load Gem.bin_path("<%= spec.name %>", "<%= executable %>")
-end
diff --git a/lib/bundler/templates/Executable.standalone b/lib/bundler/templates/Executable.standalone
deleted file mode 100644
index 4bf0753f44..0000000000
--- a/lib/bundler/templates/Executable.standalone
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %>
-#
-# This file was generated by Bundler.
-#
-# The application '<%= executable %>' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require "pathname"
-path = Pathname.new(__FILE__)
-$:.unshift File.expand_path "../<%= standalone_path %>", path.realpath
-
-require "bundler/setup"
-load File.expand_path "../<%= executable_path %>", path.realpath
diff --git a/lib/bundler/templates/Gemfile b/lib/bundler/templates/Gemfile
deleted file mode 100644
index 1afd2cce67..0000000000
--- a/lib/bundler/templates/Gemfile
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-source "https://rubygems.org"
-
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
-
-# gem "rails"
diff --git a/lib/bundler/templates/gems.rb b/lib/bundler/templates/gems.rb
deleted file mode 100644
index 547cd6e8d9..0000000000
--- a/lib/bundler/templates/gems.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# frozen_string_literal: true
-
-# A sample gems.rb
-source "https://rubygems.org"
-
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
-
-# gem "rails"
diff --git a/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt b/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
deleted file mode 100644
index a3833d29d7..0000000000
--- a/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
+++ /dev/null
@@ -1,74 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, gender identity and expression, level of experience,
-nationality, personal appearance, race, religion, or sexual identity and
-orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment
-include:
-
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or
-advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
- professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at <%= config[:email] %>. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at [http://contributor-covenant.org/version/1/4][version]
-
-[homepage]: http://contributor-covenant.org
-[version]: http://contributor-covenant.org/version/1/4/
diff --git a/lib/bundler/templates/newgem/Gemfile.tt b/lib/bundler/templates/newgem/Gemfile.tt
deleted file mode 100644
index c114bd6665..0000000000
--- a/lib/bundler/templates/newgem/Gemfile.tt
+++ /dev/null
@@ -1,6 +0,0 @@
-source "https://rubygems.org"
-
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
-
-# Specify your gem's dependencies in <%= config[:name] %>.gemspec
-gemspec
diff --git a/lib/bundler/templates/newgem/LICENSE.txt.tt b/lib/bundler/templates/newgem/LICENSE.txt.tt
deleted file mode 100644
index 76ef4b0191..0000000000
--- a/lib/bundler/templates/newgem/LICENSE.txt.tt
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) <%= Time.now.year %> <%= config[:author] %>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/lib/bundler/templates/newgem/README.md.tt b/lib/bundler/templates/newgem/README.md.tt
deleted file mode 100644
index 868a0afe67..0000000000
--- a/lib/bundler/templates/newgem/README.md.tt
+++ /dev/null
@@ -1,47 +0,0 @@
-# <%= config[:constant_name] %>
-
-Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/<%= config[:namespaced_path] %>`. To experiment with that code, run `bin/console` for an interactive prompt.
-
-TODO: Delete this and the text above, and describe your gem
-
-## Installation
-
-Add this line to your application's Gemfile:
-
-```ruby
-gem '<%= config[:name] %>'
-```
-
-And then execute:
-
- $ bundle
-
-Or install it yourself as:
-
- $ gem install <%= config[:name] %>
-
-## Usage
-
-TODO: Write usage instructions here
-
-## Development
-
-After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test].sub('mini', '').sub('rspec', 'spec') %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %>
-
-To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
-
-## Contributing
-
-Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.<% end %>
-<% if config[:mit] -%>
-
-## License
-
-The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
-<% end -%>
-<% if config[:coc] -%>
-
-## Code of Conduct
-
-Everyone interacting in the <%= config[:constant_name] %> project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).
-<% end -%>
diff --git a/lib/bundler/templates/newgem/Rakefile.tt b/lib/bundler/templates/newgem/Rakefile.tt
deleted file mode 100644
index 099da6f3ec..0000000000
--- a/lib/bundler/templates/newgem/Rakefile.tt
+++ /dev/null
@@ -1,29 +0,0 @@
-require "bundler/gem_tasks"
-<% if config[:test] == "minitest" -%>
-require "rake/testtask"
-
-Rake::TestTask.new(:test) do |t|
- t.libs << "test"
- t.libs << "lib"
- t.test_files = FileList["test/**/*_test.rb"]
-end
-
-<% elsif config[:test] == "rspec" -%>
-require "rspec/core/rake_task"
-
-RSpec::Core::RakeTask.new(:spec)
-
-<% end -%>
-<% if config[:ext] -%>
-require "rake/extensiontask"
-
-task :build => :compile
-
-Rake::ExtensionTask.new("<%= config[:underscored_name] %>") do |ext|
- ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
-end
-
-task :default => [:clobber, :compile, :<%= config[:test_task] %>]
-<% else -%>
-task :default => :<%= config[:test_task] %>
-<% end -%>
diff --git a/lib/bundler/templates/newgem/bin/console.tt b/lib/bundler/templates/newgem/bin/console.tt
deleted file mode 100644
index a27f82430f..0000000000
--- a/lib/bundler/templates/newgem/bin/console.tt
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env ruby
-
-require "bundler/setup"
-require "<%= config[:namespaced_path] %>"
-
-# You can add fixtures and/or initialization code here to make experimenting
-# with your gem easier. You can also use a different console, if you like.
-
-# (If you use this, don't forget to add pry to your Gemfile!)
-# require "pry"
-# Pry.start
-
-require "irb"
-IRB.start(__FILE__)
diff --git a/lib/bundler/templates/newgem/bin/setup.tt b/lib/bundler/templates/newgem/bin/setup.tt
deleted file mode 100644
index dce67d860a..0000000000
--- a/lib/bundler/templates/newgem/bin/setup.tt
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-IFS=$'\n\t'
-set -vx
-
-bundle install
-
-# Do any other automated setup that you need to do here
diff --git a/lib/bundler/templates/newgem/exe/newgem.tt b/lib/bundler/templates/newgem/exe/newgem.tt
deleted file mode 100644
index a8339bb79f..0000000000
--- a/lib/bundler/templates/newgem/exe/newgem.tt
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-
-require "<%= config[:namespaced_path] %>"
diff --git a/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt b/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt
deleted file mode 100644
index 8cfc828f94..0000000000
--- a/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt
+++ /dev/null
@@ -1,3 +0,0 @@
-require "mkmf"
-
-create_makefile(<%= config[:makefile_path].inspect %>)
diff --git a/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt b/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt
deleted file mode 100644
index 8177c4d202..0000000000
--- a/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "<%= config[:underscored_name] %>.h"
-
-VALUE rb_m<%= config[:constant_array].join %>;
-
-void
-Init_<%= config[:underscored_name] %>(void)
-{
- rb_m<%= config[:constant_array].join %> = rb_define_module(<%= config[:constant_name].inspect %>);
-}
diff --git a/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt b/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt
deleted file mode 100644
index c6e420b66e..0000000000
--- a/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef <%= config[:underscored_name].upcase %>_H
-#define <%= config[:underscored_name].upcase %>_H 1
-
-#include "ruby.h"
-
-#endif /* <%= config[:underscored_name].upcase %>_H */
diff --git a/lib/bundler/templates/newgem/gitignore.tt b/lib/bundler/templates/newgem/gitignore.tt
deleted file mode 100644
index b1c9f9986c..0000000000
--- a/lib/bundler/templates/newgem/gitignore.tt
+++ /dev/null
@@ -1,20 +0,0 @@
-/.bundle/
-/.yardoc
-/_yardoc/
-/coverage/
-/doc/
-/pkg/
-/spec/reports/
-/tmp/
-<%- if config[:ext] -%>
-*.bundle
-*.so
-*.o
-*.a
-mkmf.log
-<%- end -%>
-<%- if config[:test] == "rspec" -%>
-
-# rspec failure tracking
-.rspec_status
-<%- end -%>
diff --git a/lib/bundler/templates/newgem/lib/newgem.rb.tt b/lib/bundler/templates/newgem/lib/newgem.rb.tt
deleted file mode 100644
index 7d8ad90ab0..0000000000
--- a/lib/bundler/templates/newgem/lib/newgem.rb.tt
+++ /dev/null
@@ -1,12 +0,0 @@
-require "<%= config[:namespaced_path] %>/version"
-<%- if config[:ext] -%>
-require "<%= config[:namespaced_path] %>/<%= config[:underscored_name] %>"
-<%- end -%>
-
-<%- config[:constant_array].each_with_index do |c, i| -%>
-<%= " " * i %>module <%= c %>
-<%- end -%>
-<%= " " * config[:constant_array].size %># Your code goes here...
-<%- (config[:constant_array].size-1).downto(0) do |i| -%>
-<%= " " * i %>end
-<%- end -%>
diff --git a/lib/bundler/templates/newgem/lib/newgem/version.rb.tt b/lib/bundler/templates/newgem/lib/newgem/version.rb.tt
deleted file mode 100644
index 389daf5048..0000000000
--- a/lib/bundler/templates/newgem/lib/newgem/version.rb.tt
+++ /dev/null
@@ -1,7 +0,0 @@
-<%- config[:constant_array].each_with_index do |c, i| -%>
-<%= " " * i %>module <%= c %>
-<%- end -%>
-<%= " " * config[:constant_array].size %>VERSION = "0.1.0"
-<%- (config[:constant_array].size-1).downto(0) do |i| -%>
-<%= " " * i %>end
-<%- end -%>
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
deleted file mode 100644
index 9a87a1374a..0000000000
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ /dev/null
@@ -1,49 +0,0 @@
-<%- if RUBY_VERSION < "2.0.0" -%>
-# coding: utf-8
-<%- end -%>
-
-lib = File.expand_path("../lib", __FILE__)
-$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
-require "<%= config[:namespaced_path] %>/version"
-
-Gem::Specification.new do |spec|
- spec.name = <%= config[:name].inspect %>
- spec.version = <%= config[:constant_name] %>::VERSION
- spec.authors = [<%= config[:author].inspect %>]
- spec.email = [<%= config[:email].inspect %>]
-
- spec.summary = %q{TODO: Write a short summary, because RubyGems requires one.}
- spec.description = %q{TODO: Write a longer description or delete this line.}
- spec.homepage = "TODO: Put your gem's website or public repo URL here."
-<%- if config[:mit] -%>
- 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'"
- else
- raise "RubyGems 2.0 or newer is required to protect against " \
- "public gem pushes."
- end
-
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
- f.match(%r{^(test|spec|features)/})
- end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
-<%- if config[:ext] -%>
- spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
-<%- end -%>
-
- spec.add_development_dependency "bundler", "~> <%= config[:bundler_version] %>"
- spec.add_development_dependency "rake", "~> 10.0"
-<%- if config[:ext] -%>
- spec.add_development_dependency "rake-compiler"
-<%- end -%>
-<%- if config[:test] -%>
- spec.add_development_dependency "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
-<%- end -%>
-end
diff --git a/lib/bundler/templates/newgem/rspec.tt b/lib/bundler/templates/newgem/rspec.tt
deleted file mode 100644
index 34c5164d9b..0000000000
--- a/lib/bundler/templates/newgem/rspec.tt
+++ /dev/null
@@ -1,3 +0,0 @@
---format documentation
---color
---require spec_helper
diff --git a/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt b/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt
deleted file mode 100644
index c63b487830..0000000000
--- a/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt
+++ /dev/null
@@ -1,9 +0,0 @@
-RSpec.describe <%= config[:constant_name] %> do
- it "has a version number" do
- expect(<%= config[:constant_name] %>::VERSION).not_to be nil
- end
-
- it "does something useful" do
- expect(false).to eq(true)
- end
-end
diff --git a/lib/bundler/templates/newgem/spec/spec_helper.rb.tt b/lib/bundler/templates/newgem/spec/spec_helper.rb.tt
deleted file mode 100644
index 805cf57e01..0000000000
--- a/lib/bundler/templates/newgem/spec/spec_helper.rb.tt
+++ /dev/null
@@ -1,14 +0,0 @@
-require "bundler/setup"
-require "<%= config[:namespaced_path] %>"
-
-RSpec.configure do |config|
- # Enable flags like --only-failures and --next-failure
- config.example_status_persistence_file_path = ".rspec_status"
-
- # Disable RSpec exposing methods globally on `Module` and `main`
- config.disable_monkey_patching!
-
- config.expect_with :rspec do |c|
- c.syntax = :expect
- end
-end
diff --git a/lib/bundler/templates/newgem/test/newgem_test.rb.tt b/lib/bundler/templates/newgem/test/newgem_test.rb.tt
deleted file mode 100644
index f2af9f90e0..0000000000
--- a/lib/bundler/templates/newgem/test/newgem_test.rb.tt
+++ /dev/null
@@ -1,11 +0,0 @@
-require "test_helper"
-
-class <%= config[:constant_name] %>Test < Minitest::Test
- def test_that_it_has_a_version_number
- refute_nil ::<%= config[:constant_name] %>::VERSION
- end
-
- def test_it_does_something_useful
- assert false
- end
-end
diff --git a/lib/bundler/templates/newgem/test/test_helper.rb.tt b/lib/bundler/templates/newgem/test/test_helper.rb.tt
deleted file mode 100644
index 725e3e4647..0000000000
--- a/lib/bundler/templates/newgem/test/test_helper.rb.tt
+++ /dev/null
@@ -1,4 +0,0 @@
-$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
-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
deleted file mode 100644
index fe0761cc23..0000000000
--- a/lib/bundler/templates/newgem/travis.yml.tt
+++ /dev/null
@@ -1,5 +0,0 @@
-sudo: false
-language: ruby
-rvm:
- - <%= RUBY_VERSION %>
-before_install: gem install bundler -v <%= Bundler::VERSION %>
diff --git a/lib/bundler/ui.rb b/lib/bundler/ui.rb
deleted file mode 100644
index 8138b30d38..0000000000
--- a/lib/bundler/ui.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module UI
- autoload :RGProxy, "bundler/ui/rg_proxy"
- autoload :Shell, "bundler/ui/shell"
- autoload :Silent, "bundler/ui/silent"
- end
-end
diff --git a/lib/bundler/ui/rg_proxy.rb b/lib/bundler/ui/rg_proxy.rb
deleted file mode 100644
index e2f98481db..0000000000
--- a/lib/bundler/ui/rg_proxy.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/ui"
-require "rubygems/user_interaction"
-
-module Bundler
- module UI
- class RGProxy < ::Gem::SilentUI
- def initialize(ui)
- @ui = ui
- super()
- end
-
- def say(message)
- @ui && @ui.debug(message)
- end
- end
- end
-end
diff --git a/lib/bundler/ui/shell.rb b/lib/bundler/ui/shell.rb
deleted file mode 100644
index 3b3b6bfb53..0000000000
--- a/lib/bundler/ui/shell.rb
+++ /dev/null
@@ -1,144 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/vendored_thor"
-
-module Bundler
- module UI
- class Shell
- LEVELS = %w[silent error warn confirm info debug].freeze
-
- attr_writer :shell
-
- def initialize(options = {})
- if options["no-color"] || !$stdout.tty?
- Thor::Base.shell = Thor::Shell::Basic
- end
- @shell = Thor::Base.shell.new
- @level = ENV["DEBUG"] ? "debug" : "info"
- @warning_history = []
- end
-
- def add_color(string, *color)
- @shell.set_color(string, *color)
- end
-
- def info(msg, newline = nil)
- tell_me(msg, nil, newline) if level("info")
- end
-
- def confirm(msg, newline = nil)
- tell_me(msg, :green, newline) if level("confirm")
- end
-
- def warn(msg, newline = nil)
- return unless level("warn")
- return if @warning_history.include? msg
- @warning_history << msg
-
- return tell_err(msg, :yellow, newline) if Bundler.feature_flag.error_on_stderr?
- tell_me(msg, :yellow, newline)
- end
-
- def error(msg, newline = nil)
- return unless level("error")
- return tell_err(msg, :red, newline) if Bundler.feature_flag.error_on_stderr?
- tell_me(msg, :red, newline)
- end
-
- def debug(msg, newline = nil)
- tell_me(msg, nil, newline) if debug?
- end
-
- def debug?
- level("debug")
- end
-
- def quiet?
- level("quiet")
- end
-
- def ask(msg)
- @shell.ask(msg)
- end
-
- def yes?(msg)
- @shell.yes?(msg)
- end
-
- def no?
- @shell.no?(msg)
- end
-
- def level=(level)
- raise ArgumentError unless LEVELS.include?(level.to_s)
- @level = level.to_s
- end
-
- def level(name = nil)
- return @level unless name
- unless index = LEVELS.index(name)
- raise "#{name.inspect} is not a valid level"
- end
- index <= LEVELS.index(@level)
- end
-
- def trace(e, newline = nil, force = false)
- return unless debug? || force
- msg = "#{e.class}: #{e.message}\n#{e.backtrace.join("\n ")}"
- tell_me(msg, nil, newline)
- end
-
- def silence(&blk)
- with_level("silent", &blk)
- end
-
- def unprinted_warnings
- []
- end
-
- private
-
- # valimism
- def tell_me(msg, color = nil, newline = nil)
- msg = word_wrap(msg) if newline.is_a?(Hash) && newline[:wrap]
- if newline.nil?
- @shell.say(msg, color)
- else
- @shell.say(msg, color, newline)
- end
- end
-
- def tell_err(message, color = nil, newline = nil)
- newline = message.to_s !~ /( |\t)\Z/ unless newline
- message = word_wrap(message) if newline.is_a?(Hash) && newline[:wrap]
-
- color = nil if color && !$stderr.tty?
-
- buffer = @shell.send(:prepare_message, message, *color)
- buffer << "\n" if newline && !message.to_s.end_with?("\n")
-
- @shell.send(:stderr).print(buffer)
- @shell.send(:stderr).flush
- end
-
- def strip_leading_spaces(text)
- spaces = text[/\A\s+/, 0]
- spaces ? text.gsub(/#{spaces}/, "") : text
- end
-
- def word_wrap(text, line_width = @shell.terminal_width)
- strip_leading_spaces(text).split("\n").collect do |line|
- line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
- end * "\n"
- end
-
- def with_level(level)
- original = @level
- @level = level
- yield
- ensure
- @level = original
- end
- end
- end
-end
diff --git a/lib/bundler/ui/silent.rb b/lib/bundler/ui/silent.rb
deleted file mode 100644
index dca1b2ac86..0000000000
--- a/lib/bundler/ui/silent.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module UI
- class Silent
- attr_writer :shell
-
- def initialize
- @warnings = []
- end
-
- def add_color(string, color)
- string
- end
-
- def info(message, newline = nil)
- end
-
- def confirm(message, newline = nil)
- end
-
- def warn(message, newline = nil)
- @warnings |= [message]
- end
-
- def error(message, newline = nil)
- end
-
- def debug(message, newline = nil)
- end
-
- def debug?
- false
- end
-
- def quiet?
- false
- end
-
- def ask(message)
- end
-
- def yes?(msg)
- raise "Cannot ask yes? with a silent shell"
- end
-
- def no?
- raise "Cannot ask no? with a silent shell"
- end
-
- def level=(name)
- end
-
- def level(name = nil)
- end
-
- def trace(message, newline = nil, force = false)
- end
-
- def silence
- yield
- end
-
- def unprinted_warnings
- @warnings
- end
- end
- end
-end
diff --git a/lib/bundler/uri_credentials_filter.rb b/lib/bundler/uri_credentials_filter.rb
deleted file mode 100644
index ee3692268c..0000000000
--- a/lib/bundler/uri_credentials_filter.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module URICredentialsFilter
- module_function
-
- def credential_filtered_uri(uri_to_anonymize)
- return uri_to_anonymize if uri_to_anonymize.nil?
- uri = uri_to_anonymize.dup
- uri = URI(uri.to_s) unless uri.is_a?(URI)
- if uri.userinfo
- # oauth authentication
- if uri.password == "x-oauth-basic" || uri.password == "x"
- # URI as string does not display with password if no user is set
- oauth_designation = uri.password
- uri.user = oauth_designation
- end
- uri.password = nil
- end
- return uri if uri_to_anonymize.is_a?(URI)
- return uri.to_s if uri_to_anonymize.is_a?(String)
- rescue URI::InvalidURIError # uri is not canonical uri scheme
- uri
- end
-
- def credential_filtered_string(str_to_filter, uri)
- return str_to_filter if uri.nil? || str_to_filter.nil?
- str_with_no_credentials = str_to_filter.dup
- anonymous_uri_str = credential_filtered_uri(uri).to_s
- uri_str = uri.to_s
- if anonymous_uri_str != uri_str
- str_with_no_credentials = str_with_no_credentials.gsub(uri_str, anonymous_uri_str)
- end
- str_with_no_credentials
- end
- end
-end
diff --git a/lib/bundler/vendor/fileutils/lib/fileutils.rb b/lib/bundler/vendor/fileutils/lib/fileutils.rb
deleted file mode 100644
index cc69740845..0000000000
--- a/lib/bundler/vendor/fileutils/lib/fileutils.rb
+++ /dev/null
@@ -1,1638 +0,0 @@
-# frozen_string_literal: true
-#
-# = fileutils.rb
-#
-# Copyright (c) 2000-2007 Minero Aoki
-#
-# This program is free software.
-# You can distribute/modify this program under the same terms of ruby.
-#
-# == module Bundler::FileUtils
-#
-# Namespace for several file utility methods for copying, moving, removing, etc.
-#
-# === Module Functions
-#
-# require 'bundler/vendor/fileutils/lib/fileutils'
-#
-# Bundler::FileUtils.cd(dir, options)
-# Bundler::FileUtils.cd(dir, options) {|dir| block }
-# Bundler::FileUtils.pwd()
-# Bundler::FileUtils.mkdir(dir, options)
-# Bundler::FileUtils.mkdir(list, options)
-# Bundler::FileUtils.mkdir_p(dir, options)
-# Bundler::FileUtils.mkdir_p(list, options)
-# Bundler::FileUtils.rmdir(dir, options)
-# Bundler::FileUtils.rmdir(list, options)
-# Bundler::FileUtils.ln(target, link, options)
-# Bundler::FileUtils.ln(targets, dir, options)
-# Bundler::FileUtils.ln_s(target, link, options)
-# Bundler::FileUtils.ln_s(targets, dir, options)
-# Bundler::FileUtils.ln_sf(target, link, options)
-# Bundler::FileUtils.cp(src, dest, options)
-# Bundler::FileUtils.cp(list, dir, options)
-# Bundler::FileUtils.cp_r(src, dest, options)
-# Bundler::FileUtils.cp_r(list, dir, options)
-# Bundler::FileUtils.mv(src, dest, options)
-# Bundler::FileUtils.mv(list, dir, options)
-# Bundler::FileUtils.rm(list, options)
-# Bundler::FileUtils.rm_r(list, options)
-# Bundler::FileUtils.rm_rf(list, options)
-# Bundler::FileUtils.install(src, dest, options)
-# Bundler::FileUtils.chmod(mode, list, options)
-# Bundler::FileUtils.chmod_R(mode, list, options)
-# Bundler::FileUtils.chown(user, group, list, options)
-# Bundler::FileUtils.chown_R(user, group, list, options)
-# Bundler::FileUtils.touch(list, options)
-#
-# The <tt>options</tt> parameter is a hash of options, taken from the list
-# <tt>:force</tt>, <tt>:noop</tt>, <tt>:preserve</tt>, and <tt>:verbose</tt>.
-# <tt>:noop</tt> means that no changes are made. The other three are obvious.
-# Each method documents the options that it honours.
-#
-# All methods that have the concept of a "source" file or directory can take
-# either one file or a list of files in that argument. See the method
-# documentation for examples.
-#
-# 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_file(src, dest, preserve = false, dereference = true)
-# Bundler::FileUtils.copy_stream(srcstream, deststream)
-# Bundler::FileUtils.remove_entry(path, force = false)
-# Bundler::FileUtils.remove_entry_secure(path, force = false)
-# Bundler::FileUtils.remove_file(path, force = false)
-# Bundler::FileUtils.compare_file(path_a, path_b)
-# Bundler::FileUtils.compare_stream(stream_a, stream_b)
-# Bundler::FileUtils.uptodate?(file, cmp_list)
-#
-# == module Bundler::FileUtils::Verbose
-#
-# This module has all methods of Bundler::FileUtils module, but it outputs messages
-# before acting. This equates to passing the <tt>:verbose</tt> flag to methods
-# in Bundler::FileUtils.
-#
-# == module Bundler::FileUtils::NoWrite
-#
-# This module has all methods of Bundler::FileUtils module, but never changes
-# files/directories. This equates to passing the <tt>:noop</tt> flag to methods
-# in Bundler::FileUtils.
-#
-# == module Bundler::FileUtils::DryRun
-#
-# This module has all methods of Bundler::FileUtils module, but never changes
-# 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:
- module_function name
- private_class_method name
- end
-
- #
- # Returns the name of the current directory.
- #
- def pwd
- Dir.pwd
- end
- module_function :pwd
-
- alias getwd pwd
- module_function :getwd
-
- #
- # 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.
- #
- # Bundler::FileUtils.cd('/', :verbose => true) # chdir and report it
- #
- # Bundler::FileUtils.cd('/') do # chdir
- # # ... # 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)
- fu_output_message 'cd -' if verbose and block
- end
- module_function :cd
-
- alias chdir cd
- module_function :chdir
-
- #
- # Returns true if +new+ is newer than all +old_list+.
- # Non-existent files are older than any file.
- #
- # Bundler::FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \
- # system 'make hello.o'
- #
- def uptodate?(new, old_list)
- return false unless File.exist?(new)
- new_time = File.mtime(new)
- old_list.each do |old|
- if File.exist?(old)
- return false unless new_time > File.mtime(old)
- end
- end
- true
- end
- module_function :uptodate?
-
- def remove_trailing_slash(dir) #:nodoc:
- dir == '/' ? dir : dir.chomp(?/)
- end
- private_module_function :remove_trailing_slash
-
- #
- # Creates one or more directories.
- #
- # Bundler::FileUtils.mkdir 'test'
- # Bundler::FileUtils.mkdir %w( tmp data )
- # Bundler::FileUtils.mkdir 'notexist', :noop => true # Does not really create.
- # Bundler::FileUtils.mkdir 'tmp', :mode => 0700
- #
- def mkdir(list, mode: nil, noop: nil, verbose: nil)
- list = fu_list(list)
- fu_output_message "mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
- return if noop
-
- list.each do |dir|
- fu_mkdir dir, mode
- end
- end
- module_function :mkdir
-
- #
- # Creates a directory and all its parent directories.
- # For example,
- #
- # Bundler::FileUtils.mkdir_p '/usr/local/lib/ruby'
- #
- # causes to make following directories, if it does not exist.
- #
- # * /usr
- # * /usr/local
- # * /usr/local/lib
- # * /usr/local/lib/ruby
- #
- # You can pass several directories at a time in a list.
- #
- def mkdir_p(list, mode: nil, noop: nil, verbose: nil)
- list = fu_list(list)
- fu_output_message "mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
- return *list if noop
-
- list.map {|path| remove_trailing_slash(path)}.each do |path|
- # optimize for the most common case
- begin
- fu_mkdir path, mode
- next
- rescue SystemCallError
- next if File.directory?(path)
- end
-
- stack = []
- until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/"
- stack.push path
- path = File.dirname(path)
- end
- stack.pop # root directory should exist
- stack.reverse_each do |dir|
- begin
- fu_mkdir dir, mode
- rescue SystemCallError
- raise unless File.directory?(dir)
- end
- end
- end
-
- return *list
- end
- module_function :mkdir_p
-
- alias mkpath mkdir_p
- alias makedirs mkdir_p
- module_function :mkpath
- module_function :makedirs
-
- def fu_mkdir(path, mode) #:nodoc:
- path = remove_trailing_slash(path)
- if mode
- Dir.mkdir path, mode
- File.chmod mode, path
- else
- Dir.mkdir path
- end
- end
- private_module_function :fu_mkdir
-
- #
- # Removes one or more directories.
- #
- # Bundler::FileUtils.rmdir 'somedir'
- # Bundler::FileUtils.rmdir %w(somedir anydir otherdir)
- # # Does not really remove directory; outputs message.
- # Bundler::FileUtils.rmdir 'somedir', :verbose => true, :noop => true
- #
- def rmdir(list, parents: nil, noop: nil, verbose: nil)
- list = fu_list(list)
- 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
- until (parent = File.dirname(dir)) == '.' or parent == dir
- dir = parent
- Dir.rmdir(dir)
- end
- end
- rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
- end
- end
- end
- module_function :rmdir
-
- #
- # :call-seq:
- # Bundler::FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil)
- # Bundler::FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
- # Bundler::FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
- #
- # In the first form, creates a hard link +link+ which points to +target+.
- # If +link+ already exists, raises Errno::EEXIST.
- # But if the :force option is set, overwrites +link+.
- #
- # Bundler::FileUtils.ln 'gcc', 'cc', verbose: true
- # Bundler::FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
- #
- # In the second form, creates a link +dir/target+ pointing to +target+.
- # In the third form, creates several hard links in the directory +dir+,
- # pointing to each item in +targets+.
- # If +dir+ is not a directory, raises Errno::ENOTDIR.
- #
- # Bundler::FileUtils.cd '/sbin'
- # Bundler::FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked.
- #
- def ln(src, dest, force: nil, noop: nil, verbose: nil)
- fu_output_message "ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
- return if noop
- fu_each_src_dest0(src, dest) do |s,d|
- remove_file d, true if force
- File.link s, d
- end
- end
- module_function :ln
-
- alias link ln
- module_function :link
-
- #
- # :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)
- #
- # In the first form, creates a symbolic link +link+ which points to +target+.
- # If +link+ already exists, raises Errno::EEXIST.
- # But if the :force option is set, overwrites +link+.
- #
- # Bundler::FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
- # Bundler::FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
- #
- # In the second form, creates a link +dir/target+ pointing to +target+.
- # In the third form, creates several symbolic links in the directory +dir+,
- # pointing to each item in +targets+.
- # If +dir+ is not a directory, raises Errno::ENOTDIR.
- #
- # Bundler::FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
- #
- def ln_s(src, dest, force: nil, noop: nil, verbose: nil)
- fu_output_message "ln -s#{force ? 'f' : ''} #{[src,dest].flatten.join ' '}" if verbose
- return if noop
- fu_each_src_dest0(src, dest) do |s,d|
- remove_file d, true if force
- File.symlink s, d
- end
- end
- module_function :ln_s
-
- alias symlink ln_s
- module_function :symlink
-
- #
- # :call-seq:
- # Bundler::FileUtils.ln_sf(*args)
- #
- # Same as
- #
- # Bundler::FileUtils.ln_s(*args, force: true)
- #
- def ln_sf(src, dest, noop: nil, verbose: nil)
- ln_s src, dest, force: true, noop: noop, verbose: verbose
- end
- module_function :ln_sf
-
- #
- # Copies a file content +src+ to +dest+. If +dest+ is a directory,
- # copies +src+ to +dest/src+.
- #
- # If +src+ is a list of files, then +dest+ must be a directory.
- #
- # Bundler::FileUtils.cp 'eval.c', 'eval.c.org'
- # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
- # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true
- # Bundler::FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
- #
- def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
- fu_output_message "cp#{preserve ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if verbose
- return if noop
- fu_each_src_dest(src, dest) do |s, d|
- copy_file s, d, preserve
- end
- end
- module_function :cp
-
- alias copy cp
- module_function :copy
-
- #
- # Copies +src+ to +dest+. If +src+ is a directory, this method copies
- # all its contents recursively. If +dest+ is a directory, copies
- # +src+ to +dest/src+.
- #
- # +src+ can be a list of files.
- #
- # # Installing Ruby library "mylib" under the site_ruby
- # Bundler::FileUtils.rm_r site_ruby + '/mylib', :force
- # Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib'
- #
- # # Examples of copying several files to target directory.
- # Bundler::FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
- # Bundler::FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', :noop => true, :verbose => true
- #
- # # If you want to copy all contents of a directory instead of the
- # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
- # # use following code.
- # Bundler::FileUtils.cp_r 'src/.', 'dest' # cp_r('src', 'dest') makes dest/src,
- # # but this doesn't.
- #
- def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil,
- dereference_root: true, remove_destination: nil)
- fu_output_message "cp -r#{preserve ? 'p' : ''}#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
- return if noop
- fu_each_src_dest(src, dest) do |s, d|
- copy_entry s, d, preserve, dereference_root, remove_destination
- end
- end
- module_function :cp_r
-
- #
- # Copies a file system entry +src+ to +dest+.
- # If +src+ is a directory, this method copies its contents recursively.
- # This method preserves file types, c.f. symlink, directory...
- # (FIFO, device files and etc. are not supported yet)
- #
- # Both of +src+ and +dest+ must be a path name.
- # +src+ must exist, +dest+ must not exist.
- #
- # If +preserve+ is true, this method preserves owner, group, and
- # modified time. Permissions are copied regardless +preserve+.
- #
- # If +dereference_root+ is true, this method dereference tree root.
- #
- # If +remove_destination+ is true, this method removes each destination file before copy.
- #
- 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)
- ent.copy destent.path
- end, proc do |ent|
- destent = Entry_.new(dest, ent.rel, false)
- ent.copy_metadata destent.path if preserve
- end)
- end
- module_function :copy_entry
-
- #
- # Copies file contents of +src+ to +dest+.
- # Both of +src+ and +dest+ must be a path name.
- #
- def copy_file(src, dest, preserve = false, dereference = true)
- ent = Entry_.new(src, nil, dereference)
- ent.copy_file dest
- ent.copy_metadata dest if preserve
- end
- module_function :copy_file
-
- #
- # Copies stream +src+ to +dest+.
- # +src+ must respond to #read(n) and
- # +dest+ must respond to #write(str).
- #
- def copy_stream(src, dest)
- IO.copy_stream(src, dest)
- end
- module_function :copy_stream
-
- #
- # Moves file(s) +src+ to +dest+. If +file+ and +dest+ exist on the different
- # disk partition, the file is copied then the original file is removed.
- #
- # Bundler::FileUtils.mv 'badname.rb', 'goodname.rb'
- # Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true # no error
- #
- # Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
- # Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
- #
- def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
- fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
- return if noop
- fu_each_src_dest(src, dest) do |s, d|
- destent = Entry_.new(d, nil, true)
- begin
- 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
- copy_entry s, d, true
- if secure
- remove_entry_secure s, force
- else
- remove_entry s, force
- end
- end
- rescue SystemCallError
- raise unless force
- end
- end
- end
- module_function :mv
-
- 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.
- #
- # Bundler::FileUtils.rm %w( junk.txt dust.txt )
- # Bundler::FileUtils.rm Dir.glob('*.so')
- # Bundler::FileUtils.rm 'NotExistFile', :force => true # never raises exception
- #
- def rm(list, force: nil, noop: nil, verbose: nil)
- list = fu_list(list)
- fu_output_message "rm#{force ? ' -f' : ''} #{list.join ' '}" if verbose
- return if noop
-
- list.each do |path|
- remove_file path, force
- end
- end
- module_function :rm
-
- alias remove rm
- module_function :remove
-
- #
- # Equivalent to
- #
- # Bundler::FileUtils.rm(list, :force => true)
- #
- def rm_f(list, noop: nil, verbose: nil)
- rm list, force: true, noop: noop, verbose: verbose
- end
- module_function :rm_f
-
- alias safe_unlink rm_f
- module_function :safe_unlink
-
- #
- # remove files +list+[0] +list+[1]... If +list+[n] is a directory,
- # removes its all contents recursively. This method ignores
- # StandardError when :force option is set.
- #
- # Bundler::FileUtils.rm_r Dir.glob('/tmp/*')
- # Bundler::FileUtils.rm_r 'some_dir', :force => true
- #
- # WARNING: This method causes local vulnerability
- # if one of parent directories or removing directory tree are world
- # writable (including /tmp, whose permission is 1777), and the current
- # process has strong privilege such as Unix super user (root), and the
- # system has symbolic link. For secure removing, read the documentation
- # of #remove_entry_secure carefully, and set :secure option to true.
- # Default is :secure=>false.
- #
- # NOTE: This method calls #remove_entry_secure if :secure option is set.
- # See also #remove_entry_secure.
- #
- def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
- list = fu_list(list)
- fu_output_message "rm -r#{force ? 'f' : ''} #{list.join ' '}" if verbose
- return if noop
- list.each do |path|
- if secure
- remove_entry_secure path, force
- else
- remove_entry path, force
- end
- end
- end
- module_function :rm_r
-
- #
- # Equivalent to
- #
- # Bundler::FileUtils.rm_r(list, :force => true)
- #
- # WARNING: This method causes local vulnerability.
- # Read the documentation of #rm_r first.
- #
- def rm_rf(list, noop: nil, verbose: nil, secure: nil)
- rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
- end
- module_function :rm_rf
-
- alias rmtree rm_rf
- module_function :rmtree
-
- #
- # This method removes a file system entry +path+. +path+ shall be a
- # regular file, a directory, or something. If +path+ is a directory,
- # remove it recursively. This method is required to avoid TOCTTOU
- # (time-of-check-to-time-of-use) local security vulnerability of #rm_r.
- # #rm_r causes security hole when:
- #
- # * Parent directory is world writable (including /tmp).
- # * Removing directory tree includes world writable directory.
- # * The system has symbolic link.
- #
- # To avoid this security hole, this method applies special preprocess.
- # If +path+ is a directory, this method chown(2) and chmod(2) all
- # removing directories. This requires the current process is the
- # owner of the removing whole directory tree, or is the super user (root).
- #
- # WARNING: You must ensure that *ALL* parent directories cannot be
- # moved by other untrusted users. For example, parent directories
- # should not be owned by untrusted users, and should not be world
- # writable except when the sticky bit set.
- #
- # WARNING: Only the owner of the removing directory tree, or Unix super
- # user (root) should invoke this method. Otherwise this method does not
- # work.
- #
- # 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
- #
- # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
- #
- def remove_entry_secure(path, force = false)
- unless fu_have_symlink?
- remove_entry path, force
- return
- end
- fullpath = File.expand_path(path)
- st = File.lstat(fullpath)
- unless st.directory?
- File.unlink fullpath
- return
- end
- # is a directory.
- parent_st = File.stat(File.dirname(fullpath))
- unless parent_st.world_writable?
- remove_entry path, force
- return
- end
- 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
- }
- # ---- tree root is frozen ----
- root = Entry_.new(path)
- root.preorder_traverse do |ent|
- if ent.directory?
- ent.chown euid, -1
- ent.chmod 0700
- end
- end
- root.postorder_traverse do |ent|
- begin
- ent.remove
- rescue
- raise unless force
- end
- end
- rescue
- raise unless force
- end
- module_function :remove_entry_secure
-
- def fu_have_symlink? #:nodoc:
- File.symlink nil, nil
- rescue NotImplementedError
- return false
- rescue TypeError
- return true
- end
- private_module_function :fu_have_symlink?
-
- def fu_stat_identical_entry?(a, b) #:nodoc:
- a.dev == b.dev and a.ino == b.ino
- end
- private_module_function :fu_stat_identical_entry?
-
- #
- # This method removes a file system entry +path+.
- # +path+ might be a regular file, a directory, or something.
- # If +path+ is a directory, remove it recursively.
- #
- # See also #remove_entry_secure.
- #
- def remove_entry(path, force = false)
- Entry_.new(path).postorder_traverse do |ent|
- begin
- ent.remove
- rescue
- raise unless force
- end
- end
- rescue
- raise unless force
- end
- module_function :remove_entry
-
- #
- # Removes a file +path+.
- # This method ignores StandardError if +force+ is true.
- #
- def remove_file(path, force = false)
- Entry_.new(path).remove_file
- rescue
- raise unless force
- end
- module_function :remove_file
-
- #
- # Removes a directory +dir+ and its contents recursively.
- # This method ignores StandardError if +force+ is true.
- #
- def remove_dir(path, force = false)
- remove_entry path, force # FIXME?? check if it is a directory
- end
- module_function :remove_dir
-
- #
- # Returns true if the contents of a file +a+ and a file +b+ are identical.
- #
- # Bundler::FileUtils.compare_file('somefile', 'somefile') #=> true
- # Bundler::FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false
- #
- def compare_file(a, b)
- return false unless File.size(a) == File.size(b)
- File.open(a, 'rb') {|fa|
- File.open(b, 'rb') {|fb|
- return compare_stream(fa, fb)
- }
- }
- end
- module_function :compare_file
-
- alias identical? compare_file
- alias cmp compare_file
- module_function :identical?
- module_function :cmp
-
- #
- # Returns true if the contents of a stream +a+ and +b+ are identical.
- #
- def compare_stream(a, b)
- bsize = fu_stream_blksize(a, b)
- sa = String.new(capacity: bsize)
- sb = String.new(capacity: bsize)
- begin
- a.read(bsize, sa)
- b.read(bsize, sb)
- return true if sa.empty? && sb.empty?
- end while sa == sb
- false
- end
- module_function :compare_stream
-
- #
- # If +src+ is not same as +dest+, copies it and changes the permission
- # mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+.
- # This method removes destination before copy.
- #
- # Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
- # Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
- #
- def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil,
- noop: nil, verbose: nil)
- if verbose
- msg = +"install -c"
- msg << ' -p' if preserve
- msg << ' -m ' << mode_to_s(mode) if mode
- msg << " -o #{owner}" if owner
- msg << " -g #{group}" if group
- msg << ' ' << [src,dest].flatten.join(' ')
- fu_output_message msg
- end
- return if noop
- uid = fu_get_uid(owner)
- gid = fu_get_gid(group)
- fu_each_src_dest(src, dest) do |s, d|
- st = File.stat(s)
- unless File.exist?(d) and compare_file(s, d)
- remove_file d, true
- copy_file s, d
- File.utime st.atime, st.mtime, d if preserve
- File.chmod fu_mode(mode, st), d if mode
- File.chown uid, gid, d if uid or gid
- end
- end
- end
- module_function :install
-
- def user_mask(target) #:nodoc:
- target.each_char.inject(0) do |mask, chr|
- case chr
- when "u"
- mask | 04700
- when "g"
- mask | 02070
- when "o"
- mask | 01007
- when "a"
- mask | 07777
- else
- raise ArgumentError, "invalid `who' symbol in file mode: #{chr}"
- end
- end
- end
- private_module_function :user_mask
-
- def apply_mask(mode, user_mask, op, mode_mask) #:nodoc:
- case op
- when '='
- (mode & ~user_mask) | (user_mask & mode_mask)
- when '+'
- mode | (user_mask & mode_mask)
- when '-'
- mode & ~(user_mask & mode_mask)
- end
- end
- private_module_function :apply_mask
-
- def symbolic_modes_to_i(mode_sym, path) #:nodoc:
- mode = if File::Stat === path
- path.mode
- else
- File.stat(path).mode
- end
- mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause|
- target, *actions = clause.split(/([=+-])/)
- raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty?
- target = 'a' if target.empty?
- user_mask = user_mask(target)
- actions.each_slice(2) do |op, perm|
- need_apply = op == '='
- mode_mask = (perm || '').each_char.inject(0) do |mask, chr|
- case chr
- when "r"
- mask | 0444
- when "w"
- mask | 0222
- when "x"
- mask | 0111
- when "X"
- if FileTest.directory? path
- mask | 0111
- else
- mask
- end
- when "s"
- mask | 06000
- when "t"
- mask | 01000
- when "u", "g", "o"
- if mask.nonzero?
- current_mode = apply_mask(current_mode, user_mask, op, mask)
- end
- need_apply = false
- copy_mask = user_mask(chr)
- (current_mode & copy_mask) / (copy_mask & 0111) * (user_mask & 0111)
- else
- raise ArgumentError, "invalid `perm' symbol in file mode: #{chr}"
- end
- end
-
- if mode_mask.nonzero? || need_apply
- current_mode = apply_mask(current_mode, user_mask, op, mode_mask)
- end
- end
- current_mode
- end
- end
- private_module_function :symbolic_modes_to_i
-
- def fu_mode(mode, path) #:nodoc:
- mode.is_a?(String) ? symbolic_modes_to_i(mode, path) : mode
- end
- private_module_function :fu_mode
-
- def mode_to_s(mode) #:nodoc:
- mode.is_a?(String) ? mode : "%o" % mode
- end
- private_module_function :mode_to_s
-
- #
- # Changes permission bits on the named files (in +list+) to the bit pattern
- # represented by +mode+.
- #
- # +mode+ is the symbolic and absolute mode can be used.
- #
- # Absolute mode is
- # Bundler::FileUtils.chmod 0755, 'somecommand'
- # Bundler::FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
- # Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true
- #
- # Symbolic mode is
- # Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand'
- # Bundler::FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
- # Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', :verbose => true
- #
- # "a" :: is user, group, other mask.
- # "u" :: is user's mask.
- # "g" :: is group's mask.
- # "o" :: is other's mask.
- # "w" :: is write permission.
- # "r" :: is read permission.
- # "x" :: is execute permission.
- # "X" ::
- # is execute permission for directories only, must be used in conjunction with "+"
- # "s" :: is uid, gid.
- # "t" :: is sticky bit.
- # "+" :: is added to a class given the specified mode.
- # "-" :: Is removed from a given class given mode.
- # "=" :: Is the exact nature of the class will be given a specified mode.
-
- def chmod(mode, list, noop: nil, verbose: nil)
- list = fu_list(list)
- fu_output_message sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if verbose
- return if noop
- list.each do |path|
- Entry_.new(path).chmod(fu_mode(mode, path))
- end
- end
- module_function :chmod
-
- #
- # Changes permission bits on the named files (in +list+)
- # to the bit pattern represented by +mode+.
- #
- # Bundler::FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
- # Bundler::FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
- #
- def chmod_R(mode, list, noop: nil, verbose: nil, force: nil)
- list = fu_list(list)
- fu_output_message sprintf('chmod -R%s %s %s',
- (force ? 'f' : ''),
- mode_to_s(mode), list.join(' ')) if verbose
- return if noop
- list.each do |root|
- Entry_.new(root).traverse do |ent|
- begin
- ent.chmod(fu_mode(mode, ent.path))
- rescue
- raise unless force
- end
- end
- end
- end
- module_function :chmod_R
-
- #
- # Changes owner and group on the named files (in +list+)
- # to the user +user+ and the group +group+. +user+ and +group+
- # may be an ID (Integer/String) or a name (String).
- # If +user+ or +group+ is nil, this method does not change
- # the attribute.
- #
- # Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
- # Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
- #
- def chown(user, group, list, noop: nil, verbose: nil)
- list = fu_list(list)
- fu_output_message sprintf('chown %s %s',
- (group ? "#{user}:#{group}" : user || ':'),
- list.join(' ')) if verbose
- return if noop
- uid = fu_get_uid(user)
- gid = fu_get_gid(group)
- list.each do |path|
- Entry_.new(path).chown uid, gid
- end
- end
- module_function :chown
-
- #
- # Changes owner and group on the named files (in +list+)
- # to the user +user+ and the group +group+ recursively.
- # +user+ and +group+ may be an ID (Integer/String) or
- # a name (String). If +user+ or +group+ is nil, this
- # method does not change the attribute.
- #
- # Bundler::FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
- # Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true
- #
- def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
- list = fu_list(list)
- fu_output_message sprintf('chown -R%s %s %s',
- (force ? 'f' : ''),
- (group ? "#{user}:#{group}" : user || ':'),
- list.join(' ')) if verbose
- return if noop
- uid = fu_get_uid(user)
- gid = fu_get_gid(group)
- list.each do |root|
- Entry_.new(root).traverse do |ent|
- begin
- ent.chown uid, gid
- rescue
- raise unless force
- end
- end
- end
- 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
- when Integer
- user
- when /\A\d+\z/
- user.to_i
- else
- Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
- end
- end
- private_module_function :fu_get_uid
-
- def fu_get_gid(group) #:nodoc:
- return nil unless group
- case group
- when Integer
- group
- when /\A\d+\z/
- group.to_i
- else
- Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
- end
- end
- private_module_function :fu_get_gid
-
- #
- # Updates modification time (mtime) and access time (atime) of file(s) in
- # +list+. Files are created if they don't exist.
- #
- # Bundler::FileUtils.touch 'timestamp'
- # Bundler::FileUtils.touch Dir.glob('*.c'); system 'make'
- #
- def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
- list = fu_list(list)
- t = mtime
- if verbose
- fu_output_message "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"
- end
- return if noop
- list.each do |path|
- created = nocreate
- begin
- File.utime(t, t, path)
- rescue Errno::ENOENT
- raise if created
- File.open(path, 'a') {
- ;
- }
- created = true
- retry if t
- end
- end
- end
- module_function :touch
-
- private
-
- module StreamUtils_
- private
-
- def fu_windows?
- /mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
- end
-
- def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
- IO.copy_stream(src, dest)
- end
-
- def fu_stream_blksize(*streams)
- streams.each do |s|
- next unless s.respond_to?(:stat)
- size = fu_blksize(s.stat)
- return size if size
- end
- fu_default_blksize()
- end
-
- def fu_blksize(st)
- s = st.blksize
- return nil unless s
- return nil if s == 0
- s
- end
-
- def fu_default_blksize
- 1024
- end
- end
-
- include StreamUtils_
- extend StreamUtils_
-
- class Entry_ #:nodoc: internal use only
- include StreamUtils_
-
- def initialize(a, b = nil, deref = false)
- @prefix = @rel = @path = nil
- if b
- @prefix = a
- @rel = b
- else
- @path = a
- end
- @deref = deref
- @stat = nil
- @lstat = nil
- end
-
- def inspect
- "\#<#{self.class} #{path()}>"
- end
-
- def path
- if @path
- File.path(@path)
- else
- join(@prefix, @rel)
- end
- end
-
- def prefix
- @prefix || @path
- end
-
- def rel
- @rel
- end
-
- def dereference?
- @deref
- end
-
- def exist?
- begin
- lstat
- true
- rescue Errno::ENOENT
- false
- end
- end
-
- def file?
- s = lstat!
- s and s.file?
- end
-
- def directory?
- s = lstat!
- s and s.directory?
- end
-
- def symlink?
- s = lstat!
- s and s.symlink?
- end
-
- def chardev?
- s = lstat!
- s and s.chardev?
- end
-
- def blockdev?
- s = lstat!
- s and s.blockdev?
- end
-
- def socket?
- s = lstat!
- s and s.socket?
- end
-
- def pipe?
- s = lstat!
- s and s.pipe?
- end
-
- S_IF_DOOR = 0xD000
-
- def door?
- s = lstat!
- s and (s.mode & 0xF000 == S_IF_DOOR)
- end
-
- 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)) }
- end
-
- def stat
- return @stat if @stat
- if lstat() and lstat().symlink?
- @stat = File.stat(path())
- else
- @stat = lstat()
- end
- @stat
- end
-
- def stat!
- return @stat if @stat
- if lstat! and lstat!.symlink?
- @stat = File.stat(path())
- else
- @stat = lstat!
- end
- @stat
- rescue SystemCallError
- nil
- end
-
- def lstat
- if dereference?
- @lstat ||= File.stat(path())
- else
- @lstat ||= File.lstat(path())
- end
- end
-
- def lstat!
- lstat()
- rescue SystemCallError
- nil
- end
-
- def chmod(mode)
- if symlink?
- File.lchmod mode, path() if have_lchmod?
- else
- File.chmod mode, path()
- end
- end
-
- def chown(uid, gid)
- if symlink?
- File.lchown uid, gid, path() if have_lchown?
- else
- File.chown uid, gid, path()
- end
- end
-
- def copy(dest)
- lstat
- case
- when file?
- copy_file dest
- when directory?
- if !File.exist?(dest) and descendant_directory?(dest, path)
- raise ArgumentError, "cannot copy directory %s to itself %s" % [path, dest]
- end
- begin
- Dir.mkdir dest
- rescue
- raise unless File.directory?(dest)
- end
- when symlink?
- File.symlink File.readlink(path()), dest
- when chardev?
- raise "cannot handle device file" unless File.respond_to?(:mknod)
- mknod dest, ?c, 0666, lstat().rdev
- when blockdev?
- raise "cannot handle device file" unless File.respond_to?(:mknod)
- mknod dest, ?b, 0666, lstat().rdev
- when socket?
- raise "cannot handle socket" unless File.respond_to?(:mknod)
- mknod dest, nil, lstat().mode, 0
- when pipe?
- raise "cannot handle FIFO" unless File.respond_to?(:mkfifo)
- mkfifo dest, 0666
- when door?
- raise "cannot handle door: #{path()}"
- else
- raise "unknown file type: #{path()}"
- end
- end
-
- def copy_file(dest)
- File.open(path()) do |s|
- File.open(dest, 'wb', s.stat.mode) do |f|
- IO.copy_stream(s, f)
- end
- end
- end
-
- def copy_metadata(path)
- st = lstat()
- if !st.symlink?
- File.utime st.atime, st.mtime, path
- end
- mode = st.mode
- begin
- if st.symlink?
- begin
- File.lchown st.uid, st.gid, path
- rescue NotImplementedError
- end
- else
- File.chown st.uid, st.gid, path
- end
- rescue Errno::EPERM, Errno::EACCES
- # clear setuid/setgid
- mode &= 01777
- end
- if st.symlink?
- begin
- File.lchmod mode, path
- rescue NotImplementedError
- end
- else
- File.chmod mode, path
- end
- end
-
- def remove
- if directory?
- remove_dir1
- else
- remove_file
- end
- end
-
- def remove_dir1
- platform_support {
- Dir.rmdir path().chomp(?/)
- }
- end
-
- def remove_file
- platform_support {
- File.unlink path
- }
- end
-
- def platform_support
- return yield unless fu_windows?
- first_time_p = true
- begin
- yield
- rescue Errno::ENOENT
- raise
- rescue => err
- if first_time_p
- first_time_p = false
- begin
- File.chmod 0700, path() # Windows does not have symlink
- retry
- rescue SystemCallError
- end
- end
- raise err
- end
- end
-
- def preorder_traverse
- stack = [self]
- while ent = stack.pop
- yield ent
- stack.concat ent.entries.reverse if ent.directory?
- end
- end
-
- alias traverse preorder_traverse
-
- def postorder_traverse
- if directory?
- entries().each do |ent|
- ent.postorder_traverse do |e|
- yield e
- end
- end
- end
- ensure
- yield self
- end
-
- def wrap_traverse(pre, post)
- pre.call self
- if directory?
- entries.each do |ent|
- ent.wrap_traverse pre, post
- end
- end
- post.call self
- end
-
- private
-
- $fileutils_rb_have_lchmod = nil
-
- def have_lchmod?
- # This is not MT-safe, but it does not matter.
- if $fileutils_rb_have_lchmod == nil
- $fileutils_rb_have_lchmod = check_have_lchmod?
- end
- $fileutils_rb_have_lchmod
- end
-
- def check_have_lchmod?
- return false unless File.respond_to?(:lchmod)
- File.lchmod 0
- return true
- rescue NotImplementedError
- return false
- end
-
- $fileutils_rb_have_lchown = nil
-
- def have_lchown?
- # This is not MT-safe, but it does not matter.
- if $fileutils_rb_have_lchown == nil
- $fileutils_rb_have_lchown = check_have_lchown?
- end
- $fileutils_rb_have_lchown
- end
-
- def check_have_lchown?
- return false unless File.respond_to?(:lchown)
- File.lchown nil, nil
- return true
- rescue NotImplementedError
- return false
- end
-
- def join(dir, base)
- return File.path(dir) if not base or base == '.'
- return File.path(base) if not dir or dir == '.'
- File.join(dir, base)
- end
-
- if File::ALT_SEPARATOR
- DIRECTORY_TERM = "(?=[/#{Regexp.quote(File::ALT_SEPARATOR)}]|\\z)"
- else
- DIRECTORY_TERM = "(?=/|\\z)"
- end
- SYSCASE = File::FNM_SYSCASE.nonzero? ? "-i" : ""
-
- def descendant_directory?(descendant, ascendant)
- /\A(?#{SYSCASE}:#{Regexp.quote(ascendant)})#{DIRECTORY_TERM}/ =~ File.dirname(descendant)
- end
- end # class Entry_
-
- def fu_list(arg) #:nodoc:
- [arg].flatten.map {|path| File.path(path) }
- end
- private_module_function :fu_list
-
- def fu_each_src_dest(src, dest) #:nodoc:
- fu_each_src_dest0(src, dest) do |s, d|
- raise ArgumentError, "same file: #{s} and #{d}" if fu_same?(s, d)
- yield s, d
- end
- end
- private_module_function :fu_each_src_dest
-
- def fu_each_src_dest0(src, dest) #:nodoc:
- if tmp = Array.try_convert(src)
- tmp.each do |s|
- s = File.path(s)
- yield s, File.join(dest, File.basename(s))
- end
- else
- src = File.path(src)
- if File.directory?(dest)
- yield src, File.join(dest, File.basename(src))
- else
- yield src, File.path(dest)
- end
- end
- end
- private_module_function :fu_each_src_dest0
-
- def fu_same?(a, b) #:nodoc:
- File.identical?(a, b)
- end
- private_module_function :fu_same?
-
- @fileutils_output = $stderr
- @fileutils_label = ''
-
- def fu_output_message(msg) #:nodoc:
- @fileutils_output ||= $stderr
- @fileutils_label ||= ''
- @fileutils_output.puts @fileutils_label + msg
- end
- private_module_function :fu_output_message
-
- # This hash table holds command options.
- OPT_TABLE = {} #:nodoc: internal use only
- (private_instance_methods & methods(false)).inject(OPT_TABLE) {|tbl, name|
- (tbl[name.to_s] = instance_method(name).parameters).map! {|t, n| n if t == :key}.compact!
- tbl
- }
-
- #
- # Returns an Array of method names which have any options.
- #
- # p Bundler::FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...]
- #
- def self.commands
- OPT_TABLE.keys
- end
-
- #
- # Returns an Array of option names.
- #
- # p Bundler::FileUtils.options #=> ["noop", "force", "verbose", "preserve", "mode"]
- #
- def self.options
- OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
- end
-
- #
- # Returns true if the method +mid+ have an option +opt+.
- #
- # p Bundler::FileUtils.have_option?(:cp, :noop) #=> true
- # p Bundler::FileUtils.have_option?(:rm, :force) #=> true
- # p Bundler::FileUtils.have_option?(:rm, :preserve) #=> false
- #
- def self.have_option?(mid, opt)
- li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}"
- li.include?(opt)
- end
-
- #
- # Returns an Array of option names of the method +mid+.
- #
- # p Bundler::FileUtils.options_of(:rm) #=> ["noop", "verbose", "force"]
- #
- def self.options_of(mid)
- OPT_TABLE[mid.to_s].map {|sym| sym.to_s }
- end
-
- #
- # Returns an Array of method names which have the option +opt+.
- #
- # p Bundler::FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
- #
- def self.collect_method(opt)
- OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
- end
-
- LOW_METHODS = singleton_methods(false) - collect_method(:noop).map(&:intern)
- module LowMethods
- private
- def _do_nothing(*)end
- ::Bundler::FileUtils::LOW_METHODS.map {|name| alias_method name, :_do_nothing}
- end
-
- METHODS = singleton_methods() - [:private_module_function,
- :commands, :options, :have_option?, :options_of, :collect_method]
-
- #
- # This module has all methods of Bundler::FileUtils module, but it outputs messages
- # before acting. This equates to passing the <tt>:verbose</tt> flag to
- # methods in Bundler::FileUtils.
- #
- module Verbose
- include Bundler::FileUtils
- @fileutils_output = $stderr
- @fileutils_label = ''
- names = ::Bundler::FileUtils.collect_method(:verbose)
- names.each do |name|
- module_eval(<<-EOS, __FILE__, __LINE__ + 1)
- def #{name}(*args, **options)
- super(*args, **options, verbose: true)
- end
- EOS
- end
- private(*names)
- extend self
- class << self
- public(*::Bundler::FileUtils::METHODS)
- end
- end
-
- #
- # This module has all methods of Bundler::FileUtils module, but never changes
- # files/directories. This equates to passing the <tt>:noop</tt> flag
- # to methods in Bundler::FileUtils.
- #
- module NoWrite
- include Bundler::FileUtils
- include LowMethods
- @fileutils_output = $stderr
- @fileutils_label = ''
- names = ::Bundler::FileUtils.collect_method(:noop)
- names.each do |name|
- module_eval(<<-EOS, __FILE__, __LINE__ + 1)
- def #{name}(*args, **options)
- super(*args, **options, noop: true)
- end
- EOS
- end
- private(*names)
- extend self
- class << self
- public(*::Bundler::FileUtils::METHODS)
- end
- end
-
- #
- # This module has all methods of Bundler::FileUtils module, but never changes
- # files/directories, with printing message before acting.
- # This equates to passing the <tt>:noop</tt> and <tt>:verbose</tt> flag
- # to methods in Bundler::FileUtils.
- #
- module DryRun
- include Bundler::FileUtils
- include LowMethods
- @fileutils_output = $stderr
- @fileutils_label = ''
- names = ::Bundler::FileUtils.collect_method(:noop)
- names.each do |name|
- module_eval(<<-EOS, __FILE__, __LINE__ + 1)
- def #{name}(*args, **options)
- super(*args, **options, noop: true, verbose: true)
- end
- EOS
- end
- private(*names)
- extend self
- class << self
- public(*::Bundler::FileUtils::METHODS)
- end
- end
-
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo.rb b/lib/bundler/vendor/molinillo/lib/molinillo.rb
deleted file mode 100644
index 9e2867144f..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/compatibility'
-require 'bundler/vendor/molinillo/lib/molinillo/gem_metadata'
-require 'bundler/vendor/molinillo/lib/molinillo/errors'
-require 'bundler/vendor/molinillo/lib/molinillo/resolver'
-require 'bundler/vendor/molinillo/lib/molinillo/modules/ui'
-require 'bundler/vendor/molinillo/lib/molinillo/modules/specification_provider'
-
-# Bundler::Molinillo is a generic dependency resolution algorithm.
-module Bundler::Molinillo
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb b/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb
deleted file mode 100644
index 3eba8e4083..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- # Hacks needed for old Ruby versions.
- module Compatibility
- module_function
-
- if [].respond_to?(:flat_map)
- # Flat map
- # @param [Enumerable] enum an enumerable object
- # @block the block to flat-map with
- # @return The enum, flat-mapped
- def flat_map(enum, &blk)
- enum.flat_map(&blk)
- end
- else
- # Flat map
- # @param [Enumerable] enum an enumerable object
- # @block the block to flat-map with
- # @return The enum, flat-mapped
- def flat_map(enum, &blk)
- enum.map(&blk).flatten(1)
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb b/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb
deleted file mode 100644
index bcacf35243..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- # @!visibility private
- module Delegates
- # Delegates all {Bundler::Molinillo::ResolutionState} methods to a `#state` property.
- module ResolutionState
- # (see Bundler::Molinillo::ResolutionState#name)
- def name
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.name
- end
-
- # (see Bundler::Molinillo::ResolutionState#requirements)
- def requirements
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.requirements
- end
-
- # (see Bundler::Molinillo::ResolutionState#activated)
- def activated
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.activated
- end
-
- # (see Bundler::Molinillo::ResolutionState#requirement)
- def requirement
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.requirement
- end
-
- # (see Bundler::Molinillo::ResolutionState#possibilities)
- def possibilities
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.possibilities
- end
-
- # (see Bundler::Molinillo::ResolutionState#depth)
- def depth
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.depth
- end
-
- # (see Bundler::Molinillo::ResolutionState#conflicts)
- def conflicts
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.conflicts
- end
-
- # (see Bundler::Molinillo::ResolutionState#unused_unwind_options)
- def unused_unwind_options
- current_state = state || Bundler::Molinillo::ResolutionState.empty
- current_state.unused_unwind_options
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb b/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb
deleted file mode 100644
index ec9c770a28..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- module Delegates
- # Delegates all {Bundler::Molinillo::SpecificationProvider} methods to a
- # `#specification_provider` property.
- module SpecificationProvider
- # (see Bundler::Molinillo::SpecificationProvider#search_for)
- def search_for(dependency)
- with_no_such_dependency_error_handling do
- specification_provider.search_for(dependency)
- end
- end
-
- # (see Bundler::Molinillo::SpecificationProvider#dependencies_for)
- def dependencies_for(specification)
- with_no_such_dependency_error_handling do
- specification_provider.dependencies_for(specification)
- end
- end
-
- # (see Bundler::Molinillo::SpecificationProvider#requirement_satisfied_by?)
- def requirement_satisfied_by?(requirement, activated, spec)
- with_no_such_dependency_error_handling do
- specification_provider.requirement_satisfied_by?(requirement, activated, spec)
- end
- end
-
- # (see Bundler::Molinillo::SpecificationProvider#name_for)
- def name_for(dependency)
- with_no_such_dependency_error_handling do
- specification_provider.name_for(dependency)
- end
- end
-
- # (see Bundler::Molinillo::SpecificationProvider#name_for_explicit_dependency_source)
- def name_for_explicit_dependency_source
- with_no_such_dependency_error_handling do
- specification_provider.name_for_explicit_dependency_source
- end
- end
-
- # (see Bundler::Molinillo::SpecificationProvider#name_for_locking_dependency_source)
- def name_for_locking_dependency_source
- with_no_such_dependency_error_handling do
- specification_provider.name_for_locking_dependency_source
- end
- end
-
- # (see Bundler::Molinillo::SpecificationProvider#sort_dependencies)
- def sort_dependencies(dependencies, activated, conflicts)
- with_no_such_dependency_error_handling do
- specification_provider.sort_dependencies(dependencies, activated, conflicts)
- end
- end
-
- # (see Bundler::Molinillo::SpecificationProvider#allow_missing?)
- def allow_missing?(dependency)
- with_no_such_dependency_error_handling do
- specification_provider.allow_missing?(dependency)
- end
- end
-
- private
-
- # Ensures any raised {NoSuchDependencyError} has its
- # {NoSuchDependencyError#required_by} set.
- # @yield
- def with_no_such_dependency_error_handling
- yield
- rescue NoSuchDependencyError => error
- if state
- vertex = activated.vertex_named(name_for(error.dependency))
- error.required_by += vertex.incoming_edges.map { |e| e.origin.name }
- error.required_by << name_for_explicit_dependency_source unless vertex.explicit_requirements.empty?
- end
- raise
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb
deleted file mode 100644
index 677a8bd916..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb
+++ /dev/null
@@ -1,223 +0,0 @@
-# frozen_string_literal: true
-
-require 'set'
-require 'tsort'
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/log'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex'
-
-module Bundler::Molinillo
- # A directed acyclic graph that is tuned to hold named dependencies
- class DependencyGraph
- include Enumerable
-
- # Enumerates through the vertices of the graph.
- # @return [Array<Vertex>] The graph's vertices.
- def each
- return vertices.values.each unless block_given?
- vertices.values.each { |v| yield v }
- end
-
- include TSort
-
- # @!visibility private
- alias tsort_each_node each
-
- # @!visibility private
- def tsort_each_child(vertex, &block)
- vertex.successors.each(&block)
- end
-
- # Topologically sorts the given vertices.
- # @param [Enumerable<Vertex>] vertices the vertices to be sorted, which must
- # all belong to the same graph.
- # @return [Array<Vertex>] The sorted vertices.
- def self.tsort(vertices)
- TSort.tsort(
- lambda { |b| vertices.each(&b) },
- lambda { |v, &b| (v.successors & vertices).each(&b) }
- )
- end
-
- # A directed edge of a {DependencyGraph}
- # @attr [Vertex] origin The origin of the directed edge
- # @attr [Vertex] destination The destination of the directed edge
- # @attr [Object] requirement The requirement the directed edge represents
- Edge = Struct.new(:origin, :destination, :requirement)
-
- # @return [{String => Vertex}] the vertices of the dependency graph, keyed
- # by {Vertex#name}
- attr_reader :vertices
-
- # @return [Log] the op log for this graph
- attr_reader :log
-
- # Initializes an empty dependency graph
- def initialize
- @vertices = {}
- @log = Log.new
- end
-
- # Tags the current state of the dependency as the given tag
- # @param [Object] tag an opaque tag for the current state of the graph
- # @return [Void]
- def tag(tag)
- log.tag(self, tag)
- end
-
- # Rewinds the graph to the state tagged as `tag`
- # @param [Object] tag the tag to rewind to
- # @return [Void]
- def rewind_to(tag)
- log.rewind_to(self, tag)
- end
-
- # Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
- # are properly copied.
- # @param [DependencyGraph] other the graph to copy.
- def initialize_copy(other)
- super
- @vertices = {}
- @log = other.log.dup
- traverse = lambda do |new_v, old_v|
- return if new_v.outgoing_edges.size == old_v.outgoing_edges.size
- old_v.outgoing_edges.each do |edge|
- destination = add_vertex(edge.destination.name, edge.destination.payload)
- add_edge_no_circular(new_v, destination, edge.requirement)
- traverse.call(destination, edge.destination)
- end
- end
- other.vertices.each do |name, vertex|
- new_vertex = add_vertex(name, vertex.payload, vertex.root?)
- new_vertex.explicit_requirements.replace(vertex.explicit_requirements)
- traverse.call(new_vertex, vertex)
- end
- end
-
- # @return [String] a string suitable for debugging
- def inspect
- "#{self.class}:#{vertices.values.inspect}"
- end
-
- # @param [Hash] options options for dot output.
- # @return [String] Returns a dot format representation of the graph
- def to_dot(options = {})
- edge_label = options.delete(:edge_label)
- raise ArgumentError, "Unknown options: #{options.keys}" unless options.empty?
-
- dot_vertices = []
- dot_edges = []
- vertices.each do |n, v|
- dot_vertices << " #{n} [label=\"{#{n}|#{v.payload}}\"]"
- v.outgoing_edges.each do |e|
- label = edge_label ? edge_label.call(e) : e.requirement
- dot_edges << " #{e.origin.name} -> #{e.destination.name} [label=#{label.to_s.dump}]"
- end
- end
-
- dot_vertices.uniq!
- dot_vertices.sort!
- dot_edges.uniq!
- dot_edges.sort!
-
- dot = dot_vertices.unshift('digraph G {').push('') + dot_edges.push('}')
- dot.join("\n")
- end
-
- # @return [Boolean] whether the two dependency graphs are equal, determined
- # by a recursive traversal of each {#root_vertices} and its
- # {Vertex#successors}
- def ==(other)
- return false unless other
- return true if equal?(other)
- vertices.each do |name, vertex|
- other_vertex = other.vertex_named(name)
- return false unless other_vertex
- return false unless vertex.payload == other_vertex.payload
- return false unless other_vertex.successors.to_set == vertex.successors.to_set
- end
- end
-
- # @param [String] name
- # @param [Object] payload
- # @param [Array<String>] parent_names
- # @param [Object] requirement the requirement that is requiring the child
- # @return [void]
- def add_child_vertex(name, payload, parent_names, requirement)
- root = !parent_names.delete(nil) { true }
- vertex = add_vertex(name, payload, root)
- vertex.explicit_requirements << requirement if root
- parent_names.each do |parent_name|
- parent_vertex = vertex_named(parent_name)
- add_edge(parent_vertex, vertex, requirement)
- end
- vertex
- end
-
- # Adds a vertex with the given name, or updates the existing one.
- # @param [String] name
- # @param [Object] payload
- # @return [Vertex] the vertex that was added to `self`
- def add_vertex(name, payload, root = false)
- log.add_vertex(self, name, payload, root)
- end
-
- # Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively
- # removing any non-root vertices that were orphaned in the process
- # @param [String] name
- # @return [Array<Vertex>] the vertices which have been detached
- def detach_vertex_named(name)
- log.detach_vertex_named(self, name)
- end
-
- # @param [String] name
- # @return [Vertex,nil] the vertex with the given name
- def vertex_named(name)
- vertices[name]
- end
-
- # @param [String] name
- # @return [Vertex,nil] the root vertex with the given name
- def root_vertex_named(name)
- vertex = vertex_named(name)
- vertex if vertex && vertex.root?
- end
-
- # Adds a new {Edge} to the dependency graph
- # @param [Vertex] origin
- # @param [Vertex] destination
- # @param [Object] requirement the requirement that this edge represents
- # @return [Edge] the added edge
- def add_edge(origin, destination, requirement)
- if destination.path_to?(origin)
- raise CircularDependencyError.new([origin, destination])
- end
- add_edge_no_circular(origin, destination, requirement)
- end
-
- # Deletes an {Edge} from the dependency graph
- # @param [Edge] edge
- # @return [Void]
- def delete_edge(edge)
- log.delete_edge(self, edge.origin.name, edge.destination.name, edge.requirement)
- end
-
- # Sets the payload of the vertex with the given name
- # @param [String] name the name of the vertex
- # @param [Object] payload the payload
- # @return [Void]
- def set_payload(name, payload)
- log.set_payload(self, name, payload)
- end
-
- private
-
- # Adds a new {Edge} to the dependency graph without checking for
- # circularity.
- # @param (see #add_edge)
- # @return (see #add_edge)
- def add_edge_no_circular(origin, destination, requirement)
- log.add_edge_no_circular(self, origin.name, destination.name, requirement)
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb
deleted file mode 100644
index c04c7eec9c..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- class DependencyGraph
- # An action that modifies a {DependencyGraph} that is reversible.
- # @abstract
- class Action
- # rubocop:disable Lint/UnusedMethodArgument
-
- # @return [Symbol] The name of the action.
- def self.action_name
- raise 'Abstract'
- end
-
- # Performs the action on the given graph.
- # @param [DependencyGraph] graph the graph to perform the action on.
- # @return [Void]
- def up(graph)
- raise 'Abstract'
- end
-
- # Reverses the action on the given graph.
- # @param [DependencyGraph] graph the graph to reverse the action on.
- # @return [Void]
- def down(graph)
- raise 'Abstract'
- end
-
- # @return [Action,Nil] The previous action
- attr_accessor :previous
-
- # @return [Action,Nil] The next action
- attr_accessor :next
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
deleted file mode 100644
index 9849aea2fe..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
-module Bundler::Molinillo
- class DependencyGraph
- # @!visibility private
- # (see DependencyGraph#add_edge_no_circular)
- class AddEdgeNoCircular < Action
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :add_vertex
- end
-
- # (see Action#up)
- def up(graph)
- edge = make_edge(graph)
- edge.origin.outgoing_edges << edge
- edge.destination.incoming_edges << edge
- edge
- end
-
- # (see Action#down)
- def down(graph)
- edge = make_edge(graph)
- delete_first(edge.origin.outgoing_edges, edge)
- delete_first(edge.destination.incoming_edges, edge)
- end
-
- # @!group AddEdgeNoCircular
-
- # @return [String] the name of the origin of the edge
- attr_reader :origin
-
- # @return [String] the name of the destination of the edge
- attr_reader :destination
-
- # @return [Object] the requirement that the edge represents
- attr_reader :requirement
-
- # @param [DependencyGraph] graph the graph to find vertices from
- # @return [Edge] The edge this action adds
- def make_edge(graph)
- Edge.new(graph.vertex_named(origin), graph.vertex_named(destination), requirement)
- end
-
- # Initialize an action to add an edge to a dependency graph
- # @param [String] origin the name of the origin of the edge
- # @param [String] destination the name of the destination of the edge
- # @param [Object] requirement the requirement that the edge represents
- def initialize(origin, destination, requirement)
- @origin = origin
- @destination = destination
- @requirement = requirement
- end
-
- private
-
- def delete_first(array, item)
- return unless index = array.index(item)
- array.delete_at(index)
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
deleted file mode 100644
index 0a1e08255b..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
-module Bundler::Molinillo
- class DependencyGraph
- # @!visibility private
- # (see DependencyGraph#add_vertex)
- class AddVertex < Action # :nodoc:
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :add_vertex
- end
-
- # (see Action#up)
- def up(graph)
- if existing = graph.vertices[name]
- @existing_payload = existing.payload
- @existing_root = existing.root
- end
- vertex = existing || Vertex.new(name, payload)
- graph.vertices[vertex.name] = vertex
- vertex.payload ||= payload
- vertex.root ||= root
- vertex
- end
-
- # (see Action#down)
- def down(graph)
- if defined?(@existing_payload)
- vertex = graph.vertices[name]
- vertex.payload = @existing_payload
- vertex.root = @existing_root
- else
- graph.vertices.delete(name)
- end
- end
-
- # @!group AddVertex
-
- # @return [String] the name of the vertex
- attr_reader :name
-
- # @return [Object] the payload for the vertex
- attr_reader :payload
-
- # @return [Boolean] whether the vertex is root or not
- attr_reader :root
-
- # Initialize an action to add a vertex to a dependency graph
- # @param [String] name the name of the vertex
- # @param [Object] payload the payload for the vertex
- # @param [Boolean] root whether the vertex is root or not
- def initialize(name, payload, root)
- @name = name
- @payload = payload
- @root = root
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
deleted file mode 100644
index 1d9f4b327d..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
-module Bundler::Molinillo
- class DependencyGraph
- # @!visibility private
- # (see DependencyGraph#delete_edge)
- class DeleteEdge < Action
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :delete_edge
- end
-
- # (see Action#up)
- def up(graph)
- edge = make_edge(graph)
- edge.origin.outgoing_edges.delete(edge)
- edge.destination.incoming_edges.delete(edge)
- end
-
- # (see Action#down)
- def down(graph)
- edge = make_edge(graph)
- edge.origin.outgoing_edges << edge
- edge.destination.incoming_edges << edge
- edge
- end
-
- # @!group DeleteEdge
-
- # @return [String] the name of the origin of the edge
- attr_reader :origin_name
-
- # @return [String] the name of the destination of the edge
- attr_reader :destination_name
-
- # @return [Object] the requirement that the edge represents
- attr_reader :requirement
-
- # @param [DependencyGraph] graph the graph to find vertices from
- # @return [Edge] The edge this action adds
- def make_edge(graph)
- Edge.new(
- graph.vertex_named(origin_name),
- graph.vertex_named(destination_name),
- requirement
- )
- end
-
- # Initialize an action to add an edge to a dependency graph
- # @param [String] origin_name the name of the origin of the edge
- # @param [String] destination_name the name of the destination of the edge
- # @param [Object] requirement the requirement that the edge represents
- def initialize(origin_name, destination_name, requirement)
- @origin_name = origin_name
- @destination_name = destination_name
- @requirement = requirement
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
deleted file mode 100644
index 385dcbdd06..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
-module Bundler::Molinillo
- class DependencyGraph
- # @!visibility private
- # @see DependencyGraph#detach_vertex_named
- class DetachVertexNamed < Action
- # @!group Action
-
- # (see Action#name)
- def self.action_name
- :add_vertex
- end
-
- # (see Action#up)
- def up(graph)
- return [] unless @vertex = graph.vertices.delete(name)
-
- removed_vertices = [@vertex]
- @vertex.outgoing_edges.each do |e|
- v = e.destination
- v.incoming_edges.delete(e)
- if !v.root? && v.incoming_edges.empty?
- removed_vertices.concat graph.detach_vertex_named(v.name)
- end
- end
-
- @vertex.incoming_edges.each do |e|
- v = e.origin
- v.outgoing_edges.delete(e)
- end
-
- removed_vertices
- end
-
- # (see Action#down)
- def down(graph)
- return unless @vertex
- graph.vertices[@vertex.name] = @vertex
- @vertex.outgoing_edges.each do |e|
- e.destination.incoming_edges << e
- end
- @vertex.incoming_edges.each do |e|
- e.origin.outgoing_edges << e
- end
- end
-
- # @!group DetachVertexNamed
-
- # @return [String] the name of the vertex to detach
- attr_reader :name
-
- # Initialize an action to detach a vertex from a dependency graph
- # @param [String] name the name of the vertex to detach
- def initialize(name)
- @name = name
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb
deleted file mode 100644
index 8582dd19c1..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag'
-
-module Bundler::Molinillo
- class DependencyGraph
- # A log for dependency graph actions
- class Log
- # Initializes an empty log
- def initialize
- @current_action = @first_action = nil
- end
-
- # @!macro [new] action
- # {include:DependencyGraph#$0}
- # @param [Graph] graph the graph to perform the action on
- # @param (see DependencyGraph#$0)
- # @return (see DependencyGraph#$0)
-
- # @macro action
- def tag(graph, tag)
- push_action(graph, Tag.new(tag))
- end
-
- # @macro action
- def add_vertex(graph, name, payload, root)
- push_action(graph, AddVertex.new(name, payload, root))
- end
-
- # @macro action
- def detach_vertex_named(graph, name)
- push_action(graph, DetachVertexNamed.new(name))
- end
-
- # @macro action
- def add_edge_no_circular(graph, origin, destination, requirement)
- push_action(graph, AddEdgeNoCircular.new(origin, destination, requirement))
- end
-
- # {include:DependencyGraph#delete_edge}
- # @param [Graph] graph the graph to perform the action on
- # @param [String] origin_name
- # @param [String] destination_name
- # @param [Object] requirement
- # @return (see DependencyGraph#delete_edge)
- def delete_edge(graph, origin_name, destination_name, requirement)
- push_action(graph, DeleteEdge.new(origin_name, destination_name, requirement))
- end
-
- # @macro action
- def set_payload(graph, name, payload)
- push_action(graph, SetPayload.new(name, payload))
- end
-
- # Pops the most recent action from the log and undoes the action
- # @param [DependencyGraph] graph
- # @return [Action] the action that was popped off the log
- def pop!(graph)
- return unless action = @current_action
- unless @current_action = action.previous
- @first_action = nil
- end
- action.down(graph)
- action
- end
-
- extend Enumerable
-
- # @!visibility private
- # Enumerates each action in the log
- # @yield [Action]
- def each
- return enum_for unless block_given?
- action = @first_action
- loop do
- break unless action
- yield action
- action = action.next
- end
- self
- end
-
- # @!visibility private
- # Enumerates each action in the log in reverse order
- # @yield [Action]
- def reverse_each
- return enum_for(:reverse_each) unless block_given?
- action = @current_action
- loop do
- break unless action
- yield action
- action = action.previous
- end
- self
- end
-
- # @macro action
- def rewind_to(graph, tag)
- loop do
- action = pop!(graph)
- raise "No tag #{tag.inspect} found" unless action
- break if action.class.action_name == :tag && action.tag == tag
- end
- end
-
- private
-
- # Adds the given action to the log, running the action
- # @param [DependencyGraph] graph
- # @param [Action] action
- # @return The value returned by `action.up`
- def push_action(graph, action)
- action.previous = @current_action
- @current_action.next = action if @current_action
- @current_action = action
- @first_action ||= action
- action.up(graph)
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb
deleted file mode 100644
index 37286d104a..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
-module Bundler::Molinillo
- class DependencyGraph
- # @!visibility private
- # @see DependencyGraph#set_payload
- class SetPayload < Action # :nodoc:
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :set_payload
- end
-
- # (see Action#up)
- def up(graph)
- vertex = graph.vertex_named(name)
- @old_payload = vertex.payload
- vertex.payload = payload
- end
-
- # (see Action#down)
- def down(graph)
- graph.vertex_named(name).payload = @old_payload
- end
-
- # @!group SetPayload
-
- # @return [String] the name of the vertex
- attr_reader :name
-
- # @return [Object] the payload for the vertex
- attr_reader :payload
-
- # Initialize an action to add set the payload for a vertex in a dependency
- # graph
- # @param [String] name the name of the vertex
- # @param [Object] payload the payload for the vertex
- def initialize(name, payload)
- @name = name
- @payload = payload
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb
deleted file mode 100644
index d6ad16e07a..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
-module Bundler::Molinillo
- class DependencyGraph
- # @!visibility private
- # @see DependencyGraph#tag
- class Tag < Action
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :tag
- end
-
- # (see Action#up)
- def up(_graph)
- end
-
- # (see Action#down)
- def down(_graph)
- end
-
- # @!group Tag
-
- # @return [Object] An opaque tag
- attr_reader :tag
-
- # Initialize an action to tag a state of a dependency graph
- # @param [Object] tag an opaque tag
- def initialize(tag)
- @tag = tag
- end
- end
- end
-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
deleted file mode 100644
index e4d016de24..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- class DependencyGraph
- # A vertex in a {DependencyGraph} that encapsulates a {#name} and a
- # {#payload}
- class Vertex
- # @return [String] the name of the vertex
- attr_accessor :name
-
- # @return [Object] the payload the vertex holds
- attr_accessor :payload
-
- # @return [Array<Object>] the explicit requirements that required
- # this vertex
- attr_reader :explicit_requirements
-
- # @return [Boolean] whether the vertex is considered a root vertex
- attr_accessor :root
- alias root? root
-
- # Initializes a vertex with the given name and payload.
- # @param [String] name see {#name}
- # @param [Object] payload see {#payload}
- def initialize(name, payload)
- @name = name.frozen? ? name : name.dup.freeze
- @payload = payload
- @explicit_requirements = []
- @outgoing_edges = []
- @incoming_edges = []
- end
-
- # @return [Array<Object>] all of the requirements that required
- # this vertex
- def requirements
- (incoming_edges.map(&:requirement) + explicit_requirements).uniq
- end
-
- # @return [Array<Edge>] the edges of {#graph} that have `self` as their
- # {Edge#origin}
- attr_accessor :outgoing_edges
-
- # @return [Array<Edge>] the edges of {#graph} that have `self` as their
- # {Edge#destination}
- attr_accessor :incoming_edges
-
- # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
- # `self` as their {Edge#destination}
- def predecessors
- incoming_edges.map(&:origin)
- end
-
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is a
- # {#descendent?}
- def recursive_predecessors
- vertices = predecessors
- vertices += Compatibility.flat_map(vertices, &:recursive_predecessors)
- vertices.uniq!
- vertices
- end
-
- # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
- # `self` as their {Edge#origin}
- def successors
- outgoing_edges.map(&:destination)
- end
-
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is an
- # {#ancestor?}
- def recursive_successors
- vertices = successors
- vertices += Compatibility.flat_map(vertices, &:recursive_successors)
- vertices.uniq!
- vertices
- end
-
- # @return [String] a string suitable for debugging
- def inspect
- "#{self.class}:#{name}(#{payload.inspect})"
- end
-
- # @return [Boolean] whether the two vertices are equal, determined
- # by a recursive traversal of each {Vertex#successors}
- def ==(other)
- return true if equal?(other)
- shallow_eql?(other) &&
- successors.to_set == other.successors.to_set
- end
-
- # @param [Vertex] other the other vertex to compare to
- # @return [Boolean] whether the two vertices are equal, determined
- # solely by {#name} and {#payload} equality
- def shallow_eql?(other)
- return true if equal?(other)
- other &&
- name == other.name &&
- payload == other.payload
- end
-
- alias eql? ==
-
- # @return [Fixnum] a hash for the vertex based upon its {#name}
- def hash
- name.hash
- end
-
- # Is there a path from `self` to `other` following edges in the
- # dependency graph?
- # @return true iff there is a path following edges within this {#graph}
- def path_to?(other)
- equal?(other) || successors.any? { |v| v.path_to?(other) }
- end
-
- alias descendent? path_to?
-
- # Is there a path from `other` to `self` following edges in the
- # dependency graph?
- # @return true iff there is a path following edges within this {#graph}
- def ancestor?(other)
- other.path_to?(self)
- end
-
- alias is_reachable_from? ancestor?
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb b/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb
deleted file mode 100644
index fb343250b1..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- # An error that occurred during the resolution process
- class ResolverError < StandardError; end
-
- # An error caused by searching for a dependency that is completely unknown,
- # i.e. has no versions available whatsoever.
- class NoSuchDependencyError < ResolverError
- # @return [Object] the dependency that could not be found
- attr_accessor :dependency
-
- # @return [Array<Object>] the specifications that depended upon {#dependency}
- attr_accessor :required_by
-
- # Initializes a new error with the given missing dependency.
- # @param [Object] dependency @see {#dependency}
- # @param [Array<Object>] required_by @see {#required_by}
- def initialize(dependency, required_by = [])
- @dependency = dependency
- @required_by = required_by
- super()
- end
-
- # The error message for the missing dependency, including the specifications
- # that had this dependency.
- def message
- sources = required_by.map { |r| "`#{r}`" }.join(' and ')
- message = "Unable to find a specification for `#{dependency}`"
- message += " depended upon by #{sources}" unless sources.empty?
- message
- end
- end
-
- # An error caused by attempting to fulfil a dependency that was circular
- #
- # @note This exception will be thrown iff a {Vertex} is added to a
- # {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
- # existing {DependencyGraph::Vertex}
- class CircularDependencyError < ResolverError
- # [Set<Object>] the dependencies responsible for causing the error
- attr_reader :dependencies
-
- # Initializes a new error with the given circular vertices.
- # @param [Array<DependencyGraph::Vertex>] vertices the vertices in the dependency
- # that caused the error
- def initialize(vertices)
- super "There is a circular dependency between #{vertices.map(&:name).join(' and ')}"
- @dependencies = vertices.map { |vertex| vertex.payload.possibilities.last }.to_set
- end
- end
-
- # An error caused by conflicts in version
- class VersionConflict < ResolverError
- # @return [{String => Resolution::Conflict}] the conflicts that caused
- # resolution to fail
- attr_reader :conflicts
-
- # @return [SpecificationProvider] the specification provider used during
- # resolution
- attr_reader :specification_provider
-
- # Initializes a new error with the given version conflicts.
- # @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
- # @param [SpecificationProvider] specification_provider see {#specification_provider}
- def initialize(conflicts, specification_provider)
- pairs = []
- Compatibility.flat_map(conflicts.values.flatten, &:requirements).each do |conflicting|
- conflicting.each do |source, conflict_requirements|
- conflict_requirements.each do |c|
- pairs << [c, source]
- end
- end
- end
-
- super "Unable to satisfy the following requirements:\n\n" \
- "#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"
-
- @conflicts = conflicts
- @specification_provider = specification_provider
- end
-
- require 'bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider'
- include Delegates::SpecificationProvider
-
- # @return [String] An error message that includes requirement trees,
- # which is much more detailed & customizable than the default message
- # @param [Hash] opts the options to create a message with.
- # @option opts [String] :solver_name The user-facing name of the solver
- # @option opts [String] :possibility_type The generic name of a possibility
- # @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees
- # @option opts [Proc] :printable_requirement A proc that pretty-prints requirements
- # @option opts [Proc] :additional_message_for_conflict A proc that appends additional
- # messages for each conflict
- # @option opts [Proc] :version_for_spec A proc that returns the version number for a
- # possibility
- def message_with_trees(opts = {})
- solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
- possibility_type = opts.delete(:possibility_type) { 'possibility named' }
- reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } }
- printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
- additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
- version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
-
- conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
- o << %(\n#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":\n)
- if conflict.locked_requirement
- o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
- o << %( #{printable_requirement.call(conflict.locked_requirement)}\n)
- o << %(\n)
- end
- o << %( In #{name_for_explicit_dependency_source}:\n)
- trees = reduce_trees.call(conflict.requirement_trees)
-
- o << trees.map do |tree|
- t = ''.dup
- depth = 2
- tree.each do |req|
- t << ' ' * depth << req.to_s
- unless tree.last == req
- if spec = conflict.activated_by_name[name_for(req)]
- t << %( was resolved to #{version_for_spec.call(spec)}, which)
- end
- t << %( depends on)
- end
- t << %(\n)
- depth += 1
- end
- t
- end.join("\n")
-
- additional_message_for_conflict.call(o, name, conflict)
-
- o
- end.strip
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb
deleted file mode 100644
index 3feb7be9b5..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- # The version of Bundler::Molinillo.
- VERSION = '0.6.4'.freeze
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb b/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb
deleted file mode 100644
index fa094c1981..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- # Provides information about specifcations and dependencies to the resolver,
- # allowing the {Resolver} class to remain generic while still providing power
- # and flexibility.
- #
- # This module contains the methods that users of Bundler::Molinillo must to implement,
- # using knowledge of their own model classes.
- module SpecificationProvider
- # Search for the specifications that match the given dependency.
- # The specifications in the returned array will be considered in reverse
- # order, so the latest version ought to be last.
- # @note This method should be 'pure', i.e. the return value should depend
- # only on the `dependency` parameter.
- #
- # @param [Object] dependency
- # @return [Array<Object>] the specifications that satisfy the given
- # `dependency`.
- def search_for(dependency)
- []
- end
-
- # Returns the dependencies of `specification`.
- # @note This method should be 'pure', i.e. the return value should depend
- # only on the `specification` parameter.
- #
- # @param [Object] specification
- # @return [Array<Object>] the dependencies that are required by the given
- # `specification`.
- def dependencies_for(specification)
- []
- end
-
- # Determines whether the given `requirement` is satisfied by the given
- # `spec`, in the context of the current `activated` dependency graph.
- #
- # @param [Object] requirement
- # @param [DependencyGraph] activated the current dependency graph in the
- # resolution process.
- # @param [Object] spec
- # @return [Boolean] whether `requirement` is satisfied by `spec` in the
- # context of the current `activated` dependency graph.
- def requirement_satisfied_by?(requirement, activated, spec)
- true
- end
-
- # Returns the name for the given `dependency`.
- # @note This method should be 'pure', i.e. the return value should depend
- # only on the `dependency` parameter.
- #
- # @param [Object] dependency
- # @return [String] the name for the given `dependency`.
- def name_for(dependency)
- dependency.to_s
- end
-
- # @return [String] the name of the source of explicit dependencies, i.e.
- # those passed to {Resolver#resolve} directly.
- def name_for_explicit_dependency_source
- 'user-specified dependency'
- end
-
- # @return [String] the name of the source of 'locked' dependencies, i.e.
- # those passed to {Resolver#resolve} directly as the `base`
- def name_for_locking_dependency_source
- 'Lockfile'
- end
-
- # Sort dependencies so that the ones that are easiest to resolve are first.
- # Easiest to resolve is (usually) defined by:
- # 1) Is this dependency already activated?
- # 2) How relaxed are the requirements?
- # 3) Are there any conflicts for this dependency?
- # 4) How many possibilities are there to satisfy this dependency?
- #
- # @param [Array<Object>] dependencies
- # @param [DependencyGraph] activated the current dependency graph in the
- # resolution process.
- # @param [{String => Array<Conflict>}] conflicts
- # @return [Array<Object>] a sorted copy of `dependencies`.
- def sort_dependencies(dependencies, activated, conflicts)
- dependencies.sort_by do |dependency|
- name = name_for(dependency)
- [
- activated.vertex_named(name).payload ? 0 : 1,
- conflicts[name] ? 0 : 1,
- ]
- end
- end
-
- # Returns whether this dependency, which has no possible matching
- # specifications, can safely be ignored.
- #
- # @param [Object] dependency
- # @return [Boolean] whether this dependency can safely be skipped.
- def allow_missing?(dependency)
- false
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb b/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb
deleted file mode 100644
index a166bc6991..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- # Conveys information about the resolution process to a user.
- module UI
- # The {IO} object that should be used to print output. `STDOUT`, by default.
- #
- # @return [IO]
- def output
- STDOUT
- end
-
- # Called roughly every {#progress_rate}, this method should convey progress
- # to the user.
- #
- # @return [void]
- def indicate_progress
- output.print '.' unless debug?
- end
-
- # How often progress should be conveyed to the user via
- # {#indicate_progress}, in seconds. A third of a second, by default.
- #
- # @return [Float]
- def progress_rate
- 0.33
- end
-
- # Called before resolution begins.
- #
- # @return [void]
- def before_resolution
- output.print 'Resolving dependencies...'
- end
-
- # Called after resolution ends (either successfully or with an error).
- # By default, prints a newline.
- #
- # @return [void]
- def after_resolution
- output.puts
- end
-
- # Conveys debug information to the user.
- #
- # @param [Integer] depth the current depth of the resolution process.
- # @return [void]
- def debug(depth = 0)
- if debug?
- debug_info = yield
- debug_info = debug_info.inspect unless debug_info.is_a?(String)
- debug_info = debug_info.split("\n").map { |s| ":#{depth.to_s.rjust 4}: #{s}" }
- output.puts debug_info
- end
- end
-
- # Whether or not debug messages should be printed.
- # By default, whether or not the `MOLINILLO_DEBUG` environment variable is
- # set.
- #
- # @return [Boolean]
- def debug?
- return @debug_mode if defined?(@debug_mode)
- @debug_mode = ENV['MOLINILLO_DEBUG']
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb b/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb
deleted file mode 100644
index 0eb665d17a..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb
+++ /dev/null
@@ -1,837 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- class Resolver
- # A specific resolution from a given {Resolver}
- class Resolution
- # A conflict that the resolution process encountered
- # @attr [Object] requirement the requirement that immediately led to the conflict
- # @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict
- # @attr [Object, nil] existing the existing spec that was in conflict with
- # the {#possibility}
- # @attr [Object] possibility_set the set of specs that was unable to be
- # activated due to a conflict.
- # @attr [Object] locked_requirement the relevant locking requirement.
- # @attr [Array<Array<Object>>] requirement_trees the different requirement
- # trees that led to every requirement for the conflicting name.
- # @attr [{String=>Object}] activated_by_name the already-activated specs.
- # @attr [Object] underlying_error an error that has occurred during resolution, and
- # will be raised at the end of it if no resolution is found.
- Conflict = Struct.new(
- :requirement,
- :requirements,
- :existing,
- :possibility_set,
- :locked_requirement,
- :requirement_trees,
- :activated_by_name,
- :underlying_error
- )
-
- class Conflict
- # @return [Object] a spec that was unable to be activated due to a conflict
- def possibility
- possibility_set && possibility_set.latest_version
- end
- end
-
- # A collection of possibility states that share the same dependencies
- # @attr [Array] dependencies the dependencies for this set of possibilities
- # @attr [Array] possibilities the possibilities
- PossibilitySet = Struct.new(:dependencies, :possibilities)
-
- class PossibilitySet
- # String representation of the possibility set, for debugging
- def to_s
- "[#{possibilities.join(', ')}]"
- end
-
- # @return [Object] most up-to-date dependency in the possibility set
- def latest_version
- possibilities.last
- end
- end
-
- # Details of the state to unwind to when a conflict occurs, and the cause of the unwind
- # @attr [Integer] state_index the index of the state to unwind to
- # @attr [Object] state_requirement the requirement of the state we're unwinding to
- # @attr [Array] requirement_tree for the requirement we're relaxing
- # @attr [Array] conflicting_requirements the requirements that combined to cause the conflict
- # @attr [Array] requirement_trees for the conflict
- # @attr [Array] requirements_unwound_to_instead array of unwind requirements that were chosen over this unwind
- UnwindDetails = Struct.new(
- :state_index,
- :state_requirement,
- :requirement_tree,
- :conflicting_requirements,
- :requirement_trees,
- :requirements_unwound_to_instead
- )
-
- class UnwindDetails
- include Comparable
-
- # We compare UnwindDetails when choosing which state to unwind to. If
- # two options have the same state_index we prefer the one most
- # removed from a requirement that caused the conflict. Both options
- # would unwind to the same state, but a `grandparent` option will
- # filter out fewer of its possibilities after doing so - where a state
- # is both a `parent` and a `grandparent` to requirements that have
- # caused a conflict this is the correct behaviour.
- # @param [UnwindDetail] other UnwindDetail to be compared
- # @return [Integer] integer specifying ordering
- def <=>(other)
- if state_index > other.state_index
- 1
- elsif state_index == other.state_index
- reversed_requirement_tree_index <=> other.reversed_requirement_tree_index
- else
- -1
- end
- end
-
- # @return [Integer] index of state requirement in reversed requirement tree
- # (the conflicting requirement itself will be at position 0)
- def reversed_requirement_tree_index
- @reversed_requirement_tree_index ||=
- if state_requirement
- requirement_tree.reverse.index(state_requirement)
- else
- 999_999
- end
- end
-
- # @return [Boolean] where the requirement of the state we're unwinding
- # to directly caused the conflict. Note: in this case, it is
- # impossible for the state we're unwinding to to be a parent of
- # any of the other conflicting requirements (or we would have
- # circularity)
- def unwinding_to_primary_requirement?
- requirement_tree.last == state_requirement
- end
-
- # @return [Array] array of sub-dependencies to avoid when choosing a
- # new possibility for the state we've unwound to. Only relevant for
- # non-primary unwinds
- def sub_dependencies_to_avoid
- @requirements_to_avoid ||=
- requirement_trees.map do |tree|
- index = tree.index(state_requirement)
- tree[index + 1] if index
- end.compact
- end
-
- # @return [Array] array of all the requirements that led to the need for
- # this unwind
- def all_requirements
- @all_requirements ||= requirement_trees.flatten(1)
- end
- end
-
- # @return [SpecificationProvider] the provider that knows about
- # dependencies, requirements, specifications, versions, etc.
- attr_reader :specification_provider
-
- # @return [UI] the UI that knows how to communicate feedback about the
- # resolution process back to the user
- attr_reader :resolver_ui
-
- # @return [DependencyGraph] the base dependency graph to which
- # dependencies should be 'locked'
- attr_reader :base
-
- # @return [Array] the dependencies that were explicitly required
- attr_reader :original_requested
-
- # Initializes a new resolution.
- # @param [SpecificationProvider] specification_provider
- # see {#specification_provider}
- # @param [UI] resolver_ui see {#resolver_ui}
- # @param [Array] requested see {#original_requested}
- # @param [DependencyGraph] base see {#base}
- def initialize(specification_provider, resolver_ui, requested, base)
- @specification_provider = specification_provider
- @resolver_ui = resolver_ui
- @original_requested = requested
- @base = base
- @states = []
- @iteration_counter = 0
- @parents_of = Hash.new { |h, k| h[k] = [] }
- end
-
- # Resolves the {#original_requested} dependencies into a full dependency
- # graph
- # @raise [ResolverError] if successful resolution is impossible
- # @return [DependencyGraph] the dependency graph of successfully resolved
- # dependencies
- def resolve
- start_resolution
-
- while state
- break if !state.requirement && state.requirements.empty?
- indicate_progress
- if state.respond_to?(:pop_possibility_state) # DependencyState
- debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
- state.pop_possibility_state.tap do |s|
- if s
- states.push(s)
- activated.tag(s)
- end
- end
- end
- process_topmost_state
- end
-
- resolve_activated_specs
- ensure
- end_resolution
- end
-
- # @return [Integer] the number of resolver iterations in between calls to
- # {#resolver_ui}'s {UI#indicate_progress} method
- attr_accessor :iteration_rate
- private :iteration_rate
-
- # @return [Time] the time at which resolution began
- attr_accessor :started_at
- private :started_at
-
- # @return [Array<ResolutionState>] the stack of states for the resolution
- attr_accessor :states
- private :states
-
- private
-
- # Sets up the resolution process
- # @return [void]
- def start_resolution
- @started_at = Time.now
-
- handle_missing_or_push_dependency_state(initial_state)
-
- debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
- resolver_ui.before_resolution
- end
-
- def resolve_activated_specs
- activated.vertices.each do |_, vertex|
- next unless vertex.payload
-
- latest_version = vertex.payload.possibilities.reverse_each.find do |possibility|
- vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
- end
-
- activated.set_payload(vertex.name, latest_version)
- end
- activated.freeze
- end
-
- # Ends the resolution process
- # @return [void]
- def end_resolution
- resolver_ui.after_resolution
- debug do
- "Finished resolution (#{@iteration_counter} steps) " \
- "(Took #{(ended_at = Time.now) - @started_at} seconds) (#{ended_at})"
- end
- debug { 'Unactivated: ' + Hash[activated.vertices.reject { |_n, v| v.payload }].keys.join(', ') } if state
- debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
- end
-
- require 'bundler/vendor/molinillo/lib/molinillo/state'
- require 'bundler/vendor/molinillo/lib/molinillo/modules/specification_provider'
-
- require 'bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state'
- require 'bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider'
-
- include Bundler::Molinillo::Delegates::ResolutionState
- include Bundler::Molinillo::Delegates::SpecificationProvider
-
- # Processes the topmost available {RequirementState} on the stack
- # @return [void]
- def process_topmost_state
- if possibility
- attempt_to_activate
- else
- create_conflict
- unwind_for_conflict
- end
- rescue CircularDependencyError => underlying_error
- create_conflict(underlying_error)
- unwind_for_conflict
- end
-
- # @return [Object] the current possibility that the resolution is trying
- # to activate
- def possibility
- possibilities.last
- end
-
- # @return [RequirementState] the current state the resolution is
- # operating upon
- def state
- states.last
- end
-
- # Creates the initial state for the resolution, based upon the
- # {#requested} dependencies
- # @return [DependencyState] the initial state for the resolution
- def initial_state
- graph = DependencyGraph.new.tap do |dg|
- original_requested.each do |requested|
- vertex = dg.add_vertex(name_for(requested), nil, true)
- vertex.explicit_requirements << requested
- end
- dg.tag(:initial_state)
- end
-
- requirements = sort_dependencies(original_requested, graph, {})
- initial_requirement = requirements.shift
- DependencyState.new(
- initial_requirement && name_for(initial_requirement),
- requirements,
- graph,
- initial_requirement,
- possibilities_for_requirement(initial_requirement, graph),
- 0,
- {},
- []
- )
- end
-
- # Unwinds the states stack because a conflict has been encountered
- # @return [void]
- def unwind_for_conflict
- details_for_unwind = build_details_for_unwind
- unwind_options = unused_unwind_options
- debug(depth) { "Unwinding for conflict: #{requirement} to #{details_for_unwind.state_index / 2}" }
- conflicts.tap do |c|
- sliced_states = states.slice!((details_for_unwind.state_index + 1)..-1)
- raise_error_unless_state(c)
- activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
- state.conflicts = c
- state.unused_unwind_options = unwind_options
- filter_possibilities_after_unwind(details_for_unwind)
- index = states.size - 1
- @parents_of.each { |_, a| a.reject! { |i| i >= index } }
- state.unused_unwind_options.reject! { |uw| uw.state_index >= index }
- end
- end
-
- # Raises a VersionConflict error, or any underlying error, if there is no
- # current state
- # @return [void]
- def raise_error_unless_state(conflicts)
- return if state
-
- error = conflicts.values.map(&:underlying_error).compact.first
- raise error || VersionConflict.new(conflicts, specification_provider)
- end
-
- # @return [UnwindDetails] Details of the nearest index to which we could unwind
- def build_details_for_unwind
- # Get the possible unwinds for the current conflict
- current_conflict = conflicts[name]
- binding_requirements = binding_requirements_for_conflict(current_conflict)
- unwind_details = unwind_options_for_requirements(binding_requirements)
-
- last_detail_for_current_unwind = unwind_details.sort.last
- current_detail = last_detail_for_current_unwind
-
- # Look for past conflicts that could be unwound to affect the
- # requirement tree for the current conflict
- relevant_unused_unwinds = unused_unwind_options.select do |alternative|
- intersecting_requirements =
- last_detail_for_current_unwind.all_requirements &
- alternative.requirements_unwound_to_instead
- next if intersecting_requirements.empty?
- # Find the highest index unwind whilst looping through
- current_detail = alternative if alternative > current_detail
- alternative
- end
-
- # Add the current unwind options to the `unused_unwind_options` array.
- # The "used" option will be filtered out during `unwind_for_conflict`.
- state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
-
- # Update the requirements_unwound_to_instead on any relevant unused unwinds
- relevant_unused_unwinds.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
- unwind_details.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
-
- current_detail
- end
-
- # @param [Array<Object>] array of requirements that combine to create a conflict
- # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
- # of resolving the passed requirements
- def unwind_options_for_requirements(binding_requirements)
- unwind_details = []
-
- trees = []
- binding_requirements.reverse_each do |r|
- partial_tree = [r]
- trees << partial_tree
- unwind_details << UnwindDetails.new(-1, nil, partial_tree, binding_requirements, trees, [])
-
- # If this requirement has alternative possibilities, check if any would
- # satisfy the other requirements that created this conflict
- requirement_state = find_state_for(r)
- if conflict_fixing_possibilities?(requirement_state, binding_requirements)
- unwind_details << UnwindDetails.new(
- states.index(requirement_state),
- r,
- partial_tree,
- binding_requirements,
- trees,
- []
- )
- end
-
- # Next, look at the parent of this requirement, and check if the requirement
- # could have been avoided if an alternative PossibilitySet had been chosen
- parent_r = parent_of(r)
- next if parent_r.nil?
- partial_tree.unshift(parent_r)
- requirement_state = find_state_for(parent_r)
- if requirement_state.possibilities.any? { |set| !set.dependencies.include?(r) }
- unwind_details << UnwindDetails.new(
- states.index(requirement_state),
- parent_r,
- partial_tree,
- binding_requirements,
- trees,
- []
- )
- end
-
- # Finally, look at the grandparent and up of this requirement, looking
- # for any possibilities that wouldn't create their parent requirement
- grandparent_r = parent_of(parent_r)
- until grandparent_r.nil?
- partial_tree.unshift(grandparent_r)
- requirement_state = find_state_for(grandparent_r)
- if requirement_state.possibilities.any? { |set| !set.dependencies.include?(parent_r) }
- unwind_details << UnwindDetails.new(
- states.index(requirement_state),
- grandparent_r,
- partial_tree,
- binding_requirements,
- trees,
- []
- )
- end
- parent_r = grandparent_r
- grandparent_r = parent_of(parent_r)
- end
- end
-
- unwind_details
- end
-
- # @param [DependencyState] state
- # @param [Array] array of requirements
- # @return [Boolean] whether or not the given state has any possibilities
- # that could satisfy the given requirements
- def conflict_fixing_possibilities?(state, binding_requirements)
- return false unless state
-
- state.possibilities.any? do |possibility_set|
- possibility_set.possibilities.any? do |poss|
- possibility_satisfies_requirements?(poss, binding_requirements)
- end
- end
- end
-
- # Filter's a state's possibilities to remove any that would not fix the
- # conflict we've just rewound from
- # @param [UnwindDetails] details of the conflict just unwound from
- # @return [void]
- def filter_possibilities_after_unwind(unwind_details)
- return unless state && !state.possibilities.empty?
-
- if unwind_details.unwinding_to_primary_requirement?
- filter_possibilities_for_primary_unwind(unwind_details)
- else
- filter_possibilities_for_parent_unwind(unwind_details)
- end
- end
-
- # Filter's a state's possibilities to remove any that would not satisfy
- # the requirements in the conflict we've just rewound from
- # @param [UnwindDetails] details of the conflict just unwound from
- # @return [void]
- def filter_possibilities_for_primary_unwind(unwind_details)
- unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
- unwinds_to_state << unwind_details
- unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements)
-
- state.possibilities.reject! do |possibility_set|
- possibility_set.possibilities.none? do |poss|
- unwind_requirement_sets.any? do |requirements|
- possibility_satisfies_requirements?(poss, requirements)
- end
- end
- end
- end
-
- # @param [Object] possibility a single possibility
- # @param [Array] requirements an array of requirements
- # @return [Boolean] whether the possibility satisfies all of the
- # given requirements
- def possibility_satisfies_requirements?(possibility, requirements)
- name = name_for(possibility)
-
- activated.tag(:swap)
- activated.set_payload(name, possibility) if activated.vertex_named(name)
- satisfied = requirements.all? { |r| requirement_satisfied_by?(r, activated, possibility) }
- activated.rewind_to(:swap)
-
- satisfied
- end
-
- # Filter's a state's possibilities to remove any that would (eventually)
- # create a requirement in the conflict we've just rewound from
- # @param [UnwindDetails] details of the conflict just unwound from
- # @return [void]
- def filter_possibilities_for_parent_unwind(unwind_details)
- unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
- unwinds_to_state << unwind_details
-
- primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
- parent_unwinds = unwinds_to_state.uniq - primary_unwinds
-
- allowed_possibility_sets = Compatibility.flat_map(primary_unwinds) do |unwind|
- states[unwind.state_index].possibilities.select do |possibility_set|
- possibility_set.possibilities.any? do |poss|
- possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
- end
- end
- end
-
- requirements_to_avoid = Compatibility.flat_map(parent_unwinds, &:sub_dependencies_to_avoid)
-
- state.possibilities.reject! do |possibility_set|
- !allowed_possibility_sets.include?(possibility_set) &&
- (requirements_to_avoid - possibility_set.dependencies).empty?
- end
- end
-
- # @param [Conflict] conflict
- # @return [Array] minimal array of requirements that would cause the passed
- # conflict to occur.
- def binding_requirements_for_conflict(conflict)
- return [conflict.requirement] if conflict.possibility.nil?
-
- possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
-
- # When there’s a `CircularDependency` error the conflicting requirement
- # (the one causing the circular) won’t be `conflict.requirement`
- # (which won’t be for the right state, because we won’t have created it,
- # because it’s circular).
- # We need to make sure we have that requirement in the conflict’s list,
- # otherwise we won’t be able to unwind properly, so we just return all
- # the requirements for the conflict.
- return possible_binding_requirements if conflict.underlying_error
-
- possibilities = search_for(conflict.requirement)
-
- # If all the requirements together don't filter out all possibilities,
- # then the only two requirements we need to consider are the initial one
- # (where the dependency's version was first chosen) and the last
- if binding_requirement_in_set?(nil, possible_binding_requirements, possibilities)
- return [conflict.requirement, requirement_for_existing_name(name_for(conflict.requirement))].compact
- end
-
- # Loop through the possible binding requirements, removing each one
- # that doesn't bind. Use a `reverse_each` as we want the earliest set of
- # binding requirements, and don't use `reject!` as we wish to refine the
- # array *on each iteration*.
- binding_requirements = possible_binding_requirements.dup
- possible_binding_requirements.reverse_each do |req|
- next if req == conflict.requirement
- unless binding_requirement_in_set?(req, binding_requirements, possibilities)
- binding_requirements -= [req]
- end
- end
-
- binding_requirements
- end
-
- # @param [Object] requirement we wish to check
- # @param [Array] array of requirements
- # @param [Array] array of possibilities the requirements will be used to filter
- # @return [Boolean] whether or not the given requirement is required to filter
- # out all elements of the array of possibilities.
- def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
- possibilities.any? do |poss|
- possibility_satisfies_requirements?(poss, possible_binding_requirements - [requirement])
- end
- end
-
- # @return [Object] the requirement that led to `requirement` being added
- # to the list of requirements.
- def parent_of(requirement)
- return unless requirement
- return unless index = @parents_of[requirement].last
- return unless parent_state = @states[index]
- parent_state.requirement
- end
-
- # @return [Object] the requirement that led to a version of a possibility
- # with the given name being activated.
- def requirement_for_existing_name(name)
- return nil unless vertex = activated.vertex_named(name)
- return nil unless vertex.payload
- states.find { |s| s.name == name }.requirement
- end
-
- # @return [ResolutionState] the state whose `requirement` is the given
- # `requirement`.
- def find_state_for(requirement)
- return nil unless requirement
- states.find { |i| requirement == i.requirement }
- end
-
- # @return [Conflict] a {Conflict} that reflects the failure to activate
- # the {#possibility} in conjunction with the current {#state}
- def create_conflict(underlying_error = nil)
- vertex = activated.vertex_named(name)
- locked_requirement = locked_requirement_named(name)
-
- requirements = {}
- unless vertex.explicit_requirements.empty?
- requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
- end
- requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
- vertex.incoming_edges.each do |edge|
- (requirements[edge.origin.payload.latest_version] ||= []).unshift(edge.requirement)
- end
-
- activated_by_name = {}
- activated.each { |v| activated_by_name[v.name] = v.payload.latest_version if v.payload }
- conflicts[name] = Conflict.new(
- requirement,
- requirements,
- vertex.payload && vertex.payload.latest_version,
- possibility,
- locked_requirement,
- requirement_trees,
- activated_by_name,
- underlying_error
- )
- end
-
- # @return [Array<Array<Object>>] The different requirement
- # trees that led to every requirement for the current spec.
- def requirement_trees
- vertex = activated.vertex_named(name)
- vertex.requirements.map { |r| requirement_tree_for(r) }
- end
-
- # @return [Array<Object>] the list of requirements that led to
- # `requirement` being required.
- def requirement_tree_for(requirement)
- tree = []
- while requirement
- tree.unshift(requirement)
- requirement = parent_of(requirement)
- end
- tree
- end
-
- # Indicates progress roughly once every second
- # @return [void]
- def indicate_progress
- @iteration_counter += 1
- @progress_rate ||= resolver_ui.progress_rate
- if iteration_rate.nil?
- if Time.now - started_at >= @progress_rate
- self.iteration_rate = @iteration_counter
- end
- end
-
- if iteration_rate && (@iteration_counter % iteration_rate) == 0
- resolver_ui.indicate_progress
- end
- end
-
- # Calls the {#resolver_ui}'s {UI#debug} method
- # @param [Integer] depth the depth of the {#states} stack
- # @param [Proc] block a block that yields a {#to_s}
- # @return [void]
- def debug(depth = 0, &block)
- resolver_ui.debug(depth, &block)
- end
-
- # Attempts to activate the current {#possibility}
- # @return [void]
- def attempt_to_activate
- debug(depth) { 'Attempting to activate ' + possibility.to_s }
- existing_vertex = activated.vertex_named(name)
- if existing_vertex.payload
- debug(depth) { "Found existing spec (#{existing_vertex.payload})" }
- attempt_to_filter_existing_spec(existing_vertex)
- else
- latest = possibility.latest_version
- # use reject!(!satisfied) for 1.8.7 compatibility
- possibility.possibilities.reject! do |possibility|
- !requirement_satisfied_by?(requirement, activated, possibility)
- end
- if possibility.latest_version.nil?
- # ensure there's a possibility for better error messages
- possibility.possibilities << latest if latest
- create_conflict
- unwind_for_conflict
- else
- activate_new_spec
- end
- end
- end
-
- # Attempts to update the existing vertex's `PossibilitySet` with a filtered version
- # @return [void]
- def attempt_to_filter_existing_spec(vertex)
- filtered_set = filtered_possibility_set(vertex)
- if !filtered_set.possibilities.empty?
- activated.set_payload(name, filtered_set)
- new_requirements = requirements.dup
- push_state_for_requirements(new_requirements, false)
- else
- create_conflict
- debug(depth) { "Unsatisfied by existing spec (#{vertex.payload})" }
- unwind_for_conflict
- end
- end
-
- # Generates a filtered version of the existing vertex's `PossibilitySet` using the
- # current state's `requirement`
- # @param [Object] existing vertex
- # @return [PossibilitySet] filtered possibility set
- def filtered_possibility_set(vertex)
- PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
- end
-
- # @param [String] requirement_name the spec name to search for
- # @return [Object] the locked spec named `requirement_name`, if one
- # is found on {#base}
- def locked_requirement_named(requirement_name)
- vertex = base.vertex_named(requirement_name)
- vertex && vertex.payload
- end
-
- # Add the current {#possibility} to the dependency graph of the current
- # {#state}
- # @return [void]
- def activate_new_spec
- conflicts.delete(name)
- debug(depth) { "Activated #{name} at #{possibility}" }
- activated.set_payload(name, possibility)
- require_nested_dependencies_for(possibility)
- end
-
- # Requires the dependencies that the recently activated spec has
- # @param [Object] activated_possibility the PossibilitySet that has just been
- # activated
- # @return [void]
- def require_nested_dependencies_for(possibility_set)
- nested_dependencies = dependencies_for(possibility_set.latest_version)
- debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
- nested_dependencies.each do |d|
- activated.add_child_vertex(name_for(d), nil, [name_for(possibility_set.latest_version)], d)
- parent_index = states.size - 1
- parents = @parents_of[d]
- parents << parent_index if parents.empty?
- end
-
- push_state_for_requirements(requirements + nested_dependencies, !nested_dependencies.empty?)
- end
-
- # Pushes a new {DependencyState} that encapsulates both existing and new
- # requirements
- # @param [Array] new_requirements
- # @return [void]
- def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
- new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
- new_requirement = nil
- loop do
- new_requirement = new_requirements.shift
- break if new_requirement.nil? || states.none? { |s| s.requirement == new_requirement }
- end
- new_name = new_requirement ? name_for(new_requirement) : ''.freeze
- possibilities = possibilities_for_requirement(new_requirement)
- handle_missing_or_push_dependency_state DependencyState.new(
- new_name, new_requirements, new_activated,
- new_requirement, possibilities, depth, conflicts.dup, unused_unwind_options.dup
- )
- end
-
- # Checks a proposed requirement with any existing locked requirement
- # before generating an array of possibilities for it.
- # @param [Object] the proposed requirement
- # @return [Array] possibilities
- def possibilities_for_requirement(requirement, activated = self.activated)
- return [] unless requirement
- if locked_requirement_named(name_for(requirement))
- return locked_requirement_possibility_set(requirement, activated)
- end
-
- group_possibilities(search_for(requirement))
- end
-
- # @param [Object] the proposed requirement
- # @return [Array] possibility set containing only the locked requirement, if any
- def locked_requirement_possibility_set(requirement, activated = self.activated)
- all_possibilities = search_for(requirement)
- locked_requirement = locked_requirement_named(name_for(requirement))
-
- # Longwinded way to build a possibilities array with either the locked
- # requirement or nothing in it. Required, since the API for
- # locked_requirement isn't guaranteed.
- locked_possibilities = all_possibilities.select do |possibility|
- requirement_satisfied_by?(locked_requirement, activated, possibility)
- end
-
- group_possibilities(locked_possibilities)
- end
-
- # Build an array of PossibilitySets, with each element representing a group of
- # dependency versions that all have the same sub-dependency version constraints
- # and are contiguous.
- # @param [Array] an array of possibilities
- # @return [Array] an array of possibility sets
- def group_possibilities(possibilities)
- possibility_sets = []
- current_possibility_set = nil
-
- possibilities.reverse_each do |possibility|
- dependencies = dependencies_for(possibility)
- if current_possibility_set && current_possibility_set.dependencies == dependencies
- current_possibility_set.possibilities.unshift(possibility)
- else
- possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
- current_possibility_set = possibility_sets.first
- end
- end
-
- possibility_sets
- end
-
- # Pushes a new {DependencyState}.
- # If the {#specification_provider} says to
- # {SpecificationProvider#allow_missing?} that particular requirement, and
- # there are no possibilities for that requirement, then `state` is not
- # pushed, and the vertex in {#activated} is removed, and we continue
- # resolving the remaining requirements.
- # @param [DependencyState] state
- # @return [void]
- def handle_missing_or_push_dependency_state(state)
- if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement)
- state.activated.detach_vertex_named(state.name)
- push_state_for_requirements(state.requirements.dup, false, state.activated)
- else
- states.push(state).tap { activated.tag(state) }
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb b/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb
deleted file mode 100644
index 7d36858778..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph'
-
-module Bundler::Molinillo
- # This class encapsulates a dependency resolver.
- # The resolver is responsible for determining which set of dependencies to
- # activate, with feedback from the {#specification_provider}
- #
- #
- class Resolver
- require 'bundler/vendor/molinillo/lib/molinillo/resolution'
-
- # @return [SpecificationProvider] the specification provider used
- # in the resolution process
- attr_reader :specification_provider
-
- # @return [UI] the UI module used to communicate back to the user
- # during the resolution process
- attr_reader :resolver_ui
-
- # Initializes a new resolver.
- # @param [SpecificationProvider] specification_provider
- # see {#specification_provider}
- # @param [UI] resolver_ui
- # see {#resolver_ui}
- def initialize(specification_provider, resolver_ui)
- @specification_provider = specification_provider
- @resolver_ui = resolver_ui
- end
-
- # Resolves the requested dependencies into a {DependencyGraph},
- # locking to the base dependency graph (if specified)
- # @param [Array] requested an array of 'requested' dependencies that the
- # {#specification_provider} can understand
- # @param [DependencyGraph,nil] base the base dependency graph to which
- # dependencies should be 'locked'
- def resolve(requested, base = DependencyGraph.new)
- Resolution.new(specification_provider,
- resolver_ui,
- requested,
- base).
- resolve
- end
- end
-end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/state.rb b/lib/bundler/vendor/molinillo/lib/molinillo/state.rb
deleted file mode 100644
index 68fa1f54e3..0000000000
--- a/lib/bundler/vendor/molinillo/lib/molinillo/state.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler::Molinillo
- # A state that a {Resolution} can be in
- # @attr [String] name the name of the current requirement
- # @attr [Array<Object>] requirements currently unsatisfied requirements
- # @attr [DependencyGraph] activated the graph of activated dependencies
- # @attr [Object] requirement the current requirement
- # @attr [Object] possibilities the possibilities to satisfy the current requirement
- # @attr [Integer] depth the depth of the resolution
- # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name
- # @attr [Array<UnwindDetails>] unused_unwind_options unwinds for previous conflicts that weren't explored
- ResolutionState = Struct.new(
- :name,
- :requirements,
- :activated,
- :requirement,
- :possibilities,
- :depth,
- :conflicts,
- :unused_unwind_options
- )
-
- class ResolutionState
- # Returns an empty resolution state
- # @return [ResolutionState] an empty state
- def self.empty
- new(nil, [], DependencyGraph.new, nil, nil, 0, {}, [])
- end
- end
-
- # A state that encapsulates a set of {#requirements} with an {Array} of
- # possibilities
- class DependencyState < ResolutionState
- # Removes a possibility from `self`
- # @return [PossibilityState] a state with a single possibility,
- # the possibility that was removed from `self`
- def pop_possibility_state
- PossibilityState.new(
- name,
- requirements.dup,
- activated,
- requirement,
- [possibilities.pop],
- depth + 1,
- conflicts.dup,
- unused_unwind_options.dup
- ).tap do |state|
- state.activated.tag(state)
- end
- end
- end
-
- # A state that encapsulates a single possibility to fulfill the given
- # {#requirement}
- class PossibilityState < ResolutionState
- end
-end
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb
deleted file mode 100644
index e5e09080c2..0000000000
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'net/protocol'
-
-##
-# Aaron Patterson's monkeypatch (accepted into 1.9.1) to fix Net::HTTP's speed
-# problems.
-#
-# http://gist.github.com/251244
-
-class Net::BufferedIO #:nodoc:
- alias :old_rbuf_fill :rbuf_fill
-
- def rbuf_fill
- if @io.respond_to? :read_nonblock then
- begin
- @rbuf << @io.read_nonblock(65536)
- rescue Errno::EWOULDBLOCK, Errno::EAGAIN => e
- retry if IO.select [@io], nil, nil, @read_timeout
- raise Timeout::Error, e.message
- end
- else # SSL sockets do not have read_nonblock
- timeout @read_timeout do
- @rbuf << @io.sysread(65536)
- end
- end
- end
-end if RUBY_VERSION < '1.9'
-
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
deleted file mode 100644
index 7cbca5bc06..0000000000
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
+++ /dev/null
@@ -1,1233 +0,0 @@
-require 'net/http'
-begin
- require 'net/https'
-rescue LoadError
- # net/https or openssl
-end if RUBY_VERSION < '1.9' # but only for 1.8
-require 'bundler/vendor/net-http-persistent/lib/net/http/faster'
-require 'uri'
-require 'cgi' # for escaping
-
-begin
- require 'net/http/pipeline'
-rescue LoadError
-end
-
-autoload :OpenSSL, 'openssl'
-
-##
-# Persistent connections for Net::HTTP
-#
-# Bundler::Persistent::Net::HTTP::Persistent maintains persistent connections across all the
-# servers you wish to talk to. For each host:port you communicate with a
-# single persistent connection is created.
-#
-# Multiple Bundler::Persistent::Net::HTTP::Persistent objects will share the same set of
-# connections.
-#
-# For each thread you start a new connection will be created. A
-# Bundler::Persistent::Net::HTTP::Persistent connection will not be shared across threads.
-#
-# You can shut down the HTTP connections when done by calling #shutdown. You
-# should name your Bundler::Persistent::Net::HTTP::Persistent object if you intend to call this
-# method.
-#
-# Example:
-#
-# require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
-#
-# uri = URI 'http://example.com/awesome/web/service'
-#
-# http = Bundler::Persistent::Net::HTTP::Persistent.new 'my_app_name'
-#
-# # perform a GET
-# response = http.request uri
-#
-# # or
-#
-# get = Net::HTTP::Get.new uri.request_uri
-# response = http.request get
-#
-# # create a POST
-# post_uri = uri + 'create'
-# post = Net::HTTP::Post.new post_uri.path
-# post.set_form_data 'some' => 'cool data'
-#
-# # perform the POST, the URI is always required
-# response http.request post_uri, post
-#
-# Note that for GET, HEAD and other requests that do not have a body you want
-# to use URI#request_uri not URI#path. The request_uri contains the query
-# params which are sent in the body for other requests.
-#
-# == SSL
-#
-# SSL connections are automatically created depending upon the scheme of the
-# URI. SSL connections are automatically verified against the default
-# certificate store for your computer. You can override this by changing
-# verify_mode or by specifying an alternate cert_store.
-#
-# Here are the SSL settings, see the individual methods for documentation:
-#
-# #certificate :: This client's certificate
-# #ca_file :: The certificate-authority
-# #cert_store :: An SSL certificate store
-# #private_key :: The client's SSL private key
-# #reuse_ssl_sessions :: Reuse a previously opened SSL session for a new
-# connection
-# #ssl_version :: Which specific SSL version to use
-# #verify_callback :: For server certificate verification
-# #verify_mode :: How connections should be verified
-#
-# == Proxies
-#
-# A proxy can be set through #proxy= or at initialization time by providing a
-# second argument to ::new. The proxy may be the URI of the proxy server or
-# <code>:ENV</code> which will consult environment variables.
-#
-# See #proxy= and #proxy_from_env for details.
-#
-# == Headers
-#
-# Headers may be specified for use in every request. #headers are appended to
-# any headers on the request. #override_headers replace existing headers on
-# the request.
-#
-# The difference between the two can be seen in setting the User-Agent. Using
-# <code>http.headers['User-Agent'] = 'MyUserAgent'</code> will send "Ruby,
-# MyUserAgent" while <code>http.override_headers['User-Agent'] =
-# 'MyUserAgent'</code> will send "MyUserAgent".
-#
-# == Tuning
-#
-# === Segregation
-#
-# By providing an application name to ::new you can separate your connections
-# from the connections of other applications.
-#
-# === Idle Timeout
-#
-# If a connection hasn't been used for this number of seconds it will automatically be
-# reset upon the next use to avoid attempting to send to a closed connection.
-# The default value is 5 seconds. nil means no timeout. Set through #idle_timeout.
-#
-# Reducing this value may help avoid the "too many connection resets" error
-# when sending non-idempotent requests while increasing this value will cause
-# fewer round-trips.
-#
-# === Read Timeout
-#
-# The amount of time allowed between reading two chunks from the socket. Set
-# through #read_timeout
-#
-# === Max Requests
-#
-# The number of requests that should be made before opening a new connection.
-# Typically many keep-alive capable servers tune this to 100 or less, so the
-# 101st request will fail with ECONNRESET. If unset (default), this value has no
-# effect, if set, connections will be reset on the request after max_requests.
-#
-# === Open Timeout
-#
-# The amount of time to wait for a connection to be opened. Set through
-# #open_timeout.
-#
-# === Socket Options
-#
-# Socket options may be set on newly-created connections. See #socket_options
-# for details.
-#
-# === Non-Idempotent Requests
-#
-# By default non-idempotent requests will not be retried per RFC 2616. By
-# setting retry_change_requests to true requests will automatically be retried
-# once.
-#
-# Only do this when you know that retrying a POST or other non-idempotent
-# request is safe for your application and will not create duplicate
-# resources.
-#
-# The recommended way to handle non-idempotent requests is the following:
-#
-# require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
-#
-# uri = URI 'http://example.com/awesome/web/service'
-# post_uri = uri + 'create'
-#
-# http = Bundler::Persistent::Net::HTTP::Persistent.new 'my_app_name'
-#
-# post = Net::HTTP::Post.new post_uri.path
-# # ... fill in POST request
-#
-# begin
-# response = http.request post_uri, post
-# rescue Bundler::Persistent::Net::HTTP::Persistent::Error
-#
-# # POST failed, make a new request to verify the server did not process
-# # the request
-# exists_uri = uri + '...'
-# response = http.get exists_uri
-#
-# # Retry if it failed
-# retry if response.code == '404'
-# end
-#
-# The method of determining if the resource was created or not is unique to
-# the particular service you are using. Of course, you will want to add
-# protection from infinite looping.
-#
-# === Connection Termination
-#
-# If you are done using the Bundler::Persistent::Net::HTTP::Persistent instance you may shut down
-# all the connections in the current thread with #shutdown. This is not
-# recommended for normal use, it should only be used when it will be several
-# minutes before you make another HTTP request.
-#
-# If you are using multiple threads, call #shutdown in each thread when the
-# thread is done making requests. If you don't call shutdown, that's OK.
-# Ruby will automatically garbage collect and shutdown your HTTP connections
-# when the thread terminates.
-
-class Bundler::Persistent::Net::HTTP::Persistent
-
- ##
- # The beginning of Time
-
- EPOCH = Time.at 0 # :nodoc:
-
- ##
- # Is OpenSSL available? This test works with autoload
-
- HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
-
- ##
- # The version of Bundler::Persistent::Net::HTTP::Persistent you are using
-
- VERSION = '2.9.4'
-
- ##
- # Exceptions rescued for automatic retry on ruby 2.0.0. This overlaps with
- # the exception list for ruby 1.x.
-
- RETRIED_EXCEPTIONS = [ # :nodoc:
- (Net::ReadTimeout if Net.const_defined? :ReadTimeout),
- IOError,
- EOFError,
- Errno::ECONNRESET,
- Errno::ECONNABORTED,
- Errno::EPIPE,
- (OpenSSL::SSL::SSLError if HAVE_OPENSSL),
- Timeout::Error,
- ].compact
-
- ##
- # Error class for errors raised by Bundler::Persistent::Net::HTTP::Persistent. Various
- # SystemCallErrors are re-raised with a human-readable message under this
- # class.
-
- class Error < StandardError; end
-
- ##
- # Use this method to detect the idle timeout of the host at +uri+. The
- # value returned can be used to configure #idle_timeout. +max+ controls the
- # maximum idle timeout to detect.
- #
- # After
- #
- # Idle timeout detection is performed by creating a connection then
- # performing a HEAD request in a loop until the connection terminates
- # waiting one additional second per loop.
- #
- # NOTE: This may not work on ruby > 1.9.
-
- def self.detect_idle_timeout uri, max = 10
- uri = URI uri unless URI::Generic === uri
- uri += '/'
-
- req = Net::HTTP::Head.new uri.request_uri
-
- http = new 'net-http-persistent detect_idle_timeout'
-
- connection = http.connection_for uri
-
- sleep_time = 0
-
- loop do
- response = connection.request req
-
- $stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG
-
- unless Net::HTTPOK === response then
- raise Error, "bad response code #{response.code} detecting idle timeout"
- end
-
- break if sleep_time >= max
-
- sleep_time += 1
-
- $stderr.puts "sleeping #{sleep_time}" if $DEBUG
- sleep sleep_time
- end
- rescue
- # ignore StandardErrors, we've probably found the idle timeout.
- ensure
- http.shutdown
-
- return sleep_time unless $!
- end
-
- ##
- # This client's OpenSSL::X509::Certificate
-
- attr_reader :certificate
-
- # For Net::HTTP parity
- alias cert certificate
-
- ##
- # An SSL certificate authority. Setting this will set verify_mode to
- # VERIFY_PEER.
-
- attr_reader :ca_file
-
- ##
- # An SSL certificate store. Setting this will override the default
- # certificate store. See verify_mode for more information.
-
- attr_reader :cert_store
-
- ##
- # Sends debug_output to this IO via Net::HTTP#set_debug_output.
- #
- # Never use this method in production code, it causes a serious security
- # hole.
-
- attr_accessor :debug_output
-
- ##
- # Current connection generation
-
- attr_reader :generation # :nodoc:
-
- ##
- # Where this instance's connections live in the thread local variables
-
- attr_reader :generation_key # :nodoc:
-
- ##
- # Headers that are added to every request using Net::HTTP#add_field
-
- attr_reader :headers
-
- ##
- # Maps host:port to an HTTP version. This allows us to enable version
- # specific features.
-
- attr_reader :http_versions
-
- ##
- # Maximum time an unused connection can remain idle before being
- # automatically closed.
-
- attr_accessor :idle_timeout
-
- ##
- # Maximum number of requests on a connection before it is considered expired
- # and automatically closed.
-
- attr_accessor :max_requests
-
- ##
- # The value sent in the Keep-Alive header. Defaults to 30. Not needed for
- # HTTP/1.1 servers.
- #
- # This may not work correctly for HTTP/1.0 servers
- #
- # This method may be removed in a future version as RFC 2616 does not
- # require this header.
-
- attr_accessor :keep_alive
-
- ##
- # A name for this connection. Allows you to keep your connections apart
- # from everybody else's.
-
- attr_reader :name
-
- ##
- # Seconds to wait until a connection is opened. See Net::HTTP#open_timeout
-
- attr_accessor :open_timeout
-
- ##
- # Headers that are added to every request using Net::HTTP#[]=
-
- attr_reader :override_headers
-
- ##
- # This client's SSL private key
-
- attr_reader :private_key
-
- # For Net::HTTP parity
- alias key private_key
-
- ##
- # The URL through which requests will be proxied
-
- attr_reader :proxy_uri
-
- ##
- # List of host suffixes which will not be proxied
-
- attr_reader :no_proxy
-
- ##
- # Seconds to wait until reading one block. See Net::HTTP#read_timeout
-
- attr_accessor :read_timeout
-
- ##
- # Where this instance's request counts live in the thread local variables
-
- attr_reader :request_key # :nodoc:
-
- ##
- # By default SSL sessions are reused to avoid extra SSL handshakes. Set
- # this to false if you have problems communicating with an HTTPS server
- # like:
- #
- # SSL_connect [...] read finished A: unexpected message (OpenSSL::SSL::SSLError)
-
- attr_accessor :reuse_ssl_sessions
-
- ##
- # An array of options for Socket#setsockopt.
- #
- # By default the TCP_NODELAY option is set on sockets.
- #
- # To set additional options append them to this array:
- #
- # http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
-
- attr_reader :socket_options
-
- ##
- # Current SSL connection generation
-
- attr_reader :ssl_generation # :nodoc:
-
- ##
- # Where this instance's SSL connections live in the thread local variables
-
- attr_reader :ssl_generation_key # :nodoc:
-
- ##
- # SSL version to use.
- #
- # By default, the version will be negotiated automatically between client
- # and server. Ruby 1.9 and newer only.
-
- attr_reader :ssl_version if RUBY_VERSION > '1.9'
-
- ##
- # Where this instance's last-use times live in the thread local variables
-
- attr_reader :timeout_key # :nodoc:
-
- ##
- # SSL verification callback. Used when ca_file is set.
-
- attr_reader :verify_callback
-
- ##
- # HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER which verifies
- # the server certificate.
- #
- # If no ca_file or cert_store is set the default system certificate store is
- # used.
- #
- # You can use +verify_mode+ to override any default values.
-
- attr_reader :verify_mode
-
- ##
- # Enable retries of non-idempotent requests that change data (e.g. POST
- # requests) when the server has disconnected.
- #
- # This will in the worst case lead to multiple requests with the same data,
- # but it may be useful for some applications. Take care when enabling
- # this option to ensure it is safe to POST or perform other non-idempotent
- # requests to the server.
-
- attr_accessor :retry_change_requests
-
- ##
- # Creates a new Bundler::Persistent::Net::HTTP::Persistent.
- #
- # Set +name+ to keep your connections apart from everybody else's. Not
- # required currently, but highly recommended. Your library name should be
- # good enough. This parameter will be required in a future version.
- #
- # +proxy+ may be set to a URI::HTTP or :ENV to pick up proxy options from
- # the environment. See proxy_from_env for details.
- #
- # In order to use a URI for the proxy you may need to do some extra work
- # beyond URI parsing if the proxy requires a password:
- #
- # proxy = URI 'http://proxy.example'
- # proxy.user = 'AzureDiamond'
- # proxy.password = 'hunter2'
-
- def initialize name = nil, proxy = nil
- @name = name
-
- @debug_output = nil
- @proxy_uri = nil
- @no_proxy = []
- @headers = {}
- @override_headers = {}
- @http_versions = {}
- @keep_alive = 30
- @open_timeout = nil
- @read_timeout = nil
- @idle_timeout = 5
- @max_requests = nil
- @socket_options = []
-
- @socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
- Socket.const_defined? :TCP_NODELAY
-
- key = ['net_http_persistent', name].compact
- @generation_key = [key, 'generations' ].join('_').intern
- @ssl_generation_key = [key, 'ssl_generations'].join('_').intern
- @request_key = [key, 'requests' ].join('_').intern
- @timeout_key = [key, 'timeouts' ].join('_').intern
-
- @certificate = nil
- @ca_file = nil
- @private_key = nil
- @ssl_version = nil
- @verify_callback = nil
- @verify_mode = nil
- @cert_store = nil
-
- @generation = 0 # incremented when proxy URI changes
- @ssl_generation = 0 # incremented when SSL session variables change
-
- if HAVE_OPENSSL then
- @verify_mode = OpenSSL::SSL::VERIFY_PEER
- @reuse_ssl_sessions = OpenSSL::SSL.const_defined? :Session
- end
-
- @retry_change_requests = false
-
- @ruby_1 = RUBY_VERSION < '2'
- @retried_on_ruby_2 = !@ruby_1
-
- self.proxy = proxy if proxy
- end
-
- ##
- # Sets this client's OpenSSL::X509::Certificate
-
- def certificate= certificate
- @certificate = certificate
-
- reconnect_ssl
- end
-
- # For Net::HTTP parity
- alias cert= certificate=
-
- ##
- # Sets the SSL certificate authority file.
-
- def ca_file= file
- @ca_file = file
-
- reconnect_ssl
- end
-
- ##
- # Overrides the default SSL certificate store used for verifying
- # connections.
-
- def cert_store= store
- @cert_store = store
-
- reconnect_ssl
- end
-
- ##
- # Finishes all connections on the given +thread+ that were created before
- # the given +generation+ in the threads +generation_key+ list.
- #
- # See #shutdown for a bunch of scary warning about misusing this method.
-
- def cleanup(generation, thread = Thread.current,
- generation_key = @generation_key) # :nodoc:
- timeouts = thread[@timeout_key]
-
- (0...generation).each do |old_generation|
- next unless thread[generation_key]
-
- conns = thread[generation_key].delete old_generation
-
- conns.each_value do |conn|
- finish conn, thread
-
- timeouts.delete conn.object_id if timeouts
- end if conns
- end
- end
-
- ##
- # Creates a new connection for +uri+
-
- def connection_for uri
- Thread.current[@generation_key] ||= Hash.new { |h,k| h[k] = {} }
- Thread.current[@ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
- Thread.current[@request_key] ||= Hash.new 0
- Thread.current[@timeout_key] ||= Hash.new EPOCH
-
- use_ssl = uri.scheme.downcase == 'https'
-
- if use_ssl then
- raise Bundler::Persistent::Net::HTTP::Persistent::Error, 'OpenSSL is not available' unless
- HAVE_OPENSSL
-
- ssl_generation = @ssl_generation
-
- ssl_cleanup ssl_generation
-
- connections = Thread.current[@ssl_generation_key][ssl_generation]
- else
- generation = @generation
-
- cleanup generation
-
- connections = Thread.current[@generation_key][generation]
- end
-
- net_http_args = [uri.host, uri.port]
- connection_id = net_http_args.join ':'
-
- if @proxy_uri and not proxy_bypass? uri.host, uri.port then
- connection_id << @proxy_connection_id
- net_http_args.concat @proxy_args
- else
- net_http_args.concat [nil, nil, nil, nil]
- end
-
- connection = connections[connection_id]
-
- unless connection = connections[connection_id] then
- connections[connection_id] = http_class.new(*net_http_args)
- connection = connections[connection_id]
- ssl connection if use_ssl
- else
- reset connection if expired? connection
- end
-
- start connection unless connection.started?
-
- connection.read_timeout = @read_timeout if @read_timeout
- connection.keep_alive_timeout = @idle_timeout if @idle_timeout && connection.respond_to?(:keep_alive_timeout=)
-
- connection
- rescue Errno::ECONNREFUSED
- address = connection.proxy_address || connection.address
- port = connection.proxy_port || connection.port
-
- raise Error, "connection refused: #{address}:#{port}"
- rescue Errno::EHOSTDOWN
- address = connection.proxy_address || connection.address
- port = connection.proxy_port || connection.port
-
- raise Error, "host down: #{address}:#{port}"
- end
-
- ##
- # Returns an error message containing the number of requests performed on
- # this connection
-
- def error_message connection
- requests = Thread.current[@request_key][connection.object_id] - 1 # fixup
- last_use = Thread.current[@timeout_key][connection.object_id]
-
- age = Time.now - last_use
-
- "after #{requests} requests on #{connection.object_id}, " \
- "last used #{age} seconds ago"
- end
-
- ##
- # URI::escape wrapper
-
- def escape str
- CGI.escape str if str
- end
-
- ##
- # URI::unescape wrapper
-
- def unescape str
- CGI.unescape str if str
- end
-
-
- ##
- # Returns true if the connection should be reset due to an idle timeout, or
- # maximum request count, false otherwise.
-
- def expired? connection
- requests = Thread.current[@request_key][connection.object_id]
- return true if @max_requests && requests >= @max_requests
- return false unless @idle_timeout
- return true if @idle_timeout.zero?
-
- last_used = Thread.current[@timeout_key][connection.object_id]
-
- Time.now - last_used > @idle_timeout
- end
-
- ##
- # Starts the Net::HTTP +connection+
-
- def start connection
- connection.set_debug_output @debug_output if @debug_output
- connection.open_timeout = @open_timeout if @open_timeout
-
- connection.start
-
- socket = connection.instance_variable_get :@socket
-
- if socket then # for fakeweb
- @socket_options.each do |option|
- socket.io.setsockopt(*option)
- end
- end
- end
-
- ##
- # Finishes the Net::HTTP +connection+
-
- def finish connection, thread = Thread.current
- if requests = thread[@request_key] then
- requests.delete connection.object_id
- end
-
- connection.finish
- rescue IOError
- end
-
- def http_class # :nodoc:
- if RUBY_VERSION > '2.0' then
- Net::HTTP
- elsif [:Artifice, :FakeWeb, :WebMock].any? { |klass|
- Object.const_defined?(klass)
- } or not @reuse_ssl_sessions then
- Net::HTTP
- else
- Bundler::Persistent::Net::HTTP::Persistent::SSLReuse
- end
- end
-
- ##
- # Returns the HTTP protocol version for +uri+
-
- def http_version uri
- @http_versions["#{uri.host}:#{uri.port}"]
- end
-
- ##
- # Is +req+ idempotent according to RFC 2616?
-
- def idempotent? req
- case req
- when Net::HTTP::Delete, Net::HTTP::Get, Net::HTTP::Head,
- Net::HTTP::Options, Net::HTTP::Put, Net::HTTP::Trace then
- true
- end
- end
-
- ##
- # Is the request +req+ idempotent or is retry_change_requests allowed.
- #
- # If +retried_on_ruby_2+ is true, true will be returned if we are on ruby,
- # retry_change_requests is allowed and the request is not idempotent.
-
- def can_retry? req, retried_on_ruby_2 = false
- return @retry_change_requests && !idempotent?(req) if retried_on_ruby_2
-
- @retry_change_requests || idempotent?(req)
- end
-
- if RUBY_VERSION > '1.9' then
- ##
- # Workaround for missing Net::HTTPHeader#connection_close? on Ruby 1.8
-
- def connection_close? header
- header.connection_close?
- end
-
- ##
- # Workaround for missing Net::HTTPHeader#connection_keep_alive? on Ruby 1.8
-
- def connection_keep_alive? header
- header.connection_keep_alive?
- end
- else
- ##
- # Workaround for missing Net::HTTPRequest#connection_close? on Ruby 1.8
-
- def connection_close? header
- header['connection'] =~ /close/ or header['proxy-connection'] =~ /close/
- end
-
- ##
- # Workaround for missing Net::HTTPRequest#connection_keep_alive? on Ruby
- # 1.8
-
- def connection_keep_alive? header
- header['connection'] =~ /keep-alive/ or
- header['proxy-connection'] =~ /keep-alive/
- end
- end
-
- ##
- # Deprecated in favor of #expired?
-
- def max_age # :nodoc:
- return Time.now + 1 unless @idle_timeout
-
- Time.now - @idle_timeout
- end
-
- ##
- # Adds "http://" to the String +uri+ if it is missing.
-
- def normalize_uri uri
- (uri =~ /^https?:/) ? uri : "http://#{uri}"
- end
-
- ##
- # Pipelines +requests+ to the HTTP server at +uri+ yielding responses if a
- # block is given. Returns all responses received.
- #
- # See
- # Net::HTTP::Pipeline[http://docs.seattlerb.org/net-http-pipeline/Net/HTTP/Pipeline.html]
- # for further details.
- #
- # Only if <tt>net-http-pipeline</tt> was required before
- # <tt>net-http-persistent</tt> #pipeline will be present.
-
- def pipeline uri, requests, &block # :yields: responses
- connection = connection_for uri
-
- connection.pipeline requests, &block
- end
-
- ##
- # Sets this client's SSL private key
-
- def private_key= key
- @private_key = key
-
- reconnect_ssl
- end
-
- # For Net::HTTP parity
- alias key= private_key=
-
- ##
- # Sets the proxy server. The +proxy+ may be the URI of the proxy server,
- # the symbol +:ENV+ which will read the proxy from the environment or nil to
- # disable use of a proxy. See #proxy_from_env for details on setting the
- # proxy from the environment.
- #
- # If the proxy URI is set after requests have been made, the next request
- # will shut-down and re-open all connections.
- #
- # The +no_proxy+ query parameter can be used to specify hosts which shouldn't
- # be reached via proxy; if set it should be a comma separated list of
- # hostname suffixes, optionally with +:port+ appended, for example
- # <tt>example.com,some.host:8080</tt>.
-
- def proxy= proxy
- @proxy_uri = case proxy
- when :ENV then proxy_from_env
- when URI::HTTP then proxy
- when nil then # ignore
- else raise ArgumentError, 'proxy must be :ENV or a URI::HTTP'
- end
-
- @no_proxy.clear
-
- if @proxy_uri then
- @proxy_args = [
- @proxy_uri.host,
- @proxy_uri.port,
- unescape(@proxy_uri.user),
- unescape(@proxy_uri.password),
- ]
-
- @proxy_connection_id = [nil, *@proxy_args].join ':'
-
- if @proxy_uri.query then
- @no_proxy = CGI.parse(@proxy_uri.query)['no_proxy'].join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? }
- end
- end
-
- reconnect
- reconnect_ssl
- end
-
- ##
- # Creates a URI for an HTTP proxy server from ENV variables.
- #
- # If +HTTP_PROXY+ is set a proxy will be returned.
- #
- # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the URI is given the
- # indicated user and password unless HTTP_PROXY contains either of these in
- # the URI.
- #
- # The +NO_PROXY+ ENV variable can be used to specify hosts which shouldn't
- # be reached via proxy; if set it should be a comma separated list of
- # hostname suffixes, optionally with +:port+ appended, for example
- # <tt>example.com,some.host:8080</tt>. When set to <tt>*</tt> no proxy will
- # be returned.
- #
- # For Windows users, lowercase ENV variables are preferred over uppercase ENV
- # variables.
-
- def proxy_from_env
- env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
-
- return nil if env_proxy.nil? or env_proxy.empty?
-
- uri = URI normalize_uri env_proxy
-
- env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
-
- # '*' is special case for always bypass
- return nil if env_no_proxy == '*'
-
- if env_no_proxy then
- uri.query = "no_proxy=#{escape(env_no_proxy)}"
- end
-
- unless uri.user or uri.password then
- uri.user = escape ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']
- uri.password = escape ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']
- end
-
- uri
- end
-
- ##
- # Returns true when proxy should by bypassed for host.
-
- def proxy_bypass? host, port
- host = host.downcase
- host_port = [host, port].join ':'
-
- @no_proxy.each do |name|
- return true if host[-name.length, name.length] == name or
- host_port[-name.length, name.length] == name
- end
-
- false
- end
-
- ##
- # Forces reconnection of HTTP connections.
-
- def reconnect
- @generation += 1
- end
-
- ##
- # Forces reconnection of SSL connections.
-
- def reconnect_ssl
- @ssl_generation += 1
- end
-
- ##
- # Finishes then restarts the Net::HTTP +connection+
-
- def reset connection
- Thread.current[@request_key].delete connection.object_id
- Thread.current[@timeout_key].delete connection.object_id
-
- finish connection
-
- start connection
- rescue Errno::ECONNREFUSED
- e = Error.new "connection refused: #{connection.address}:#{connection.port}"
- e.set_backtrace $@
- raise e
- rescue Errno::EHOSTDOWN
- e = Error.new "host down: #{connection.address}:#{connection.port}"
- e.set_backtrace $@
- raise e
- end
-
- ##
- # Makes a request on +uri+. If +req+ is nil a Net::HTTP::Get is performed
- # against +uri+.
- #
- # If a block is passed #request behaves like Net::HTTP#request (the body of
- # the response will not have been read).
- #
- # +req+ must be a Net::HTTPRequest subclass (see Net::HTTP for a list).
- #
- # If there is an error and the request is idempotent according to RFC 2616
- # it will be retried automatically.
-
- def request uri, req = nil, &block
- retried = false
- bad_response = false
-
- req = request_setup req || uri
-
- connection = connection_for uri
- connection_id = connection.object_id
-
- begin
- Thread.current[@request_key][connection_id] += 1
- response = connection.request req, &block
-
- if connection_close?(req) or
- (response.http_version <= '1.0' and
- not connection_keep_alive?(response)) or
- connection_close?(response) then
- connection.finish
- end
- rescue Net::HTTPBadResponse => e
- message = error_message connection
-
- finish connection
-
- raise Error, "too many bad responses #{message}" if
- bad_response or not can_retry? req
-
- bad_response = true
- retry
- rescue *RETRIED_EXCEPTIONS => e # retried on ruby 2
- request_failed e, req, connection if
- retried or not can_retry? req, @retried_on_ruby_2
-
- reset connection
-
- retried = true
- retry
- rescue Errno::EINVAL, Errno::ETIMEDOUT => e # not retried on ruby 2
- request_failed e, req, connection if retried or not can_retry? req
-
- reset connection
-
- retried = true
- retry
- rescue Exception => e
- finish connection
-
- raise
- ensure
- Thread.current[@timeout_key][connection_id] = Time.now
- end
-
- @http_versions["#{uri.host}:#{uri.port}"] ||= response.http_version
-
- response
- end
-
- ##
- # Raises an Error for +exception+ which resulted from attempting the request
- # +req+ on the +connection+.
- #
- # Finishes the +connection+.
-
- def request_failed exception, req, connection # :nodoc:
- due_to = "(due to #{exception.message} - #{exception.class})"
- message = "too many connection resets #{due_to} #{error_message connection}"
-
- finish connection
-
-
- raise Error, message, exception.backtrace
- end
-
- ##
- # Creates a GET request if +req_or_uri+ is a URI and adds headers to the
- # request.
- #
- # Returns the request.
-
- def request_setup req_or_uri # :nodoc:
- req = if URI === req_or_uri then
- Net::HTTP::Get.new req_or_uri.request_uri
- else
- req_or_uri
- end
-
- @headers.each do |pair|
- req.add_field(*pair)
- end
-
- @override_headers.each do |name, value|
- req[name] = value
- end
-
- unless req['Connection'] then
- req.add_field 'Connection', 'keep-alive'
- req.add_field 'Keep-Alive', @keep_alive
- end
-
- req
- end
-
- ##
- # Shuts down all connections for +thread+.
- #
- # Uses the current thread by default.
- #
- # If you've used Bundler::Persistent::Net::HTTP::Persistent across multiple threads you should
- # call this in each thread when you're done making HTTP requests.
- #
- # *NOTE*: Calling shutdown for another thread can be dangerous!
- #
- # If the thread is still using the connection it may cause an error! It is
- # best to call #shutdown in the thread at the appropriate time instead!
-
- def shutdown thread = Thread.current
- generation = reconnect
- cleanup generation, thread, @generation_key
-
- ssl_generation = reconnect_ssl
- cleanup ssl_generation, thread, @ssl_generation_key
-
- thread[@request_key] = nil
- thread[@timeout_key] = nil
- end
-
- ##
- # Shuts down all connections in all threads
- #
- # *NOTE*: THIS METHOD IS VERY DANGEROUS!
- #
- # Do not call this method if other threads are still using their
- # connections! Call #shutdown at the appropriate time instead!
- #
- # Use this method only as a last resort!
-
- def shutdown_in_all_threads
- Thread.list.each do |thread|
- shutdown thread
- end
-
- nil
- end
-
- ##
- # Enables SSL on +connection+
-
- def ssl connection
- connection.use_ssl = true
-
- connection.ssl_version = @ssl_version if @ssl_version
-
- connection.verify_mode = @verify_mode
-
- if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and
- not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then
- warn <<-WARNING
- !!!SECURITY WARNING!!!
-
-The SSL HTTP connection to:
-
- #{connection.address}:#{connection.port}
-
- !!!MAY NOT BE VERIFIED!!!
-
-On your platform your OpenSSL implementation is broken.
-
-There is no difference between the values of VERIFY_NONE and VERIFY_PEER.
-
-This means that attempting to verify the security of SSL connections may not
-work. This exposes you to man-in-the-middle exploits, snooping on the
-contents of your connection and other dangers to the security of your data.
-
-To disable this warning define the following constant at top-level in your
-application:
-
- I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG = nil
-
- WARNING
- end
-
- if @ca_file then
- connection.ca_file = @ca_file
- connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
- connection.verify_callback = @verify_callback if @verify_callback
- end
-
- if @certificate and @private_key then
- connection.cert = @certificate
- connection.key = @private_key
- end
-
- connection.cert_store = if @cert_store then
- @cert_store
- else
- store = OpenSSL::X509::Store.new
- store.set_default_paths
- store
- end
- end
-
- ##
- # Finishes all connections that existed before the given SSL parameter
- # +generation+.
-
- def ssl_cleanup generation # :nodoc:
- cleanup generation, Thread.current, @ssl_generation_key
- end
-
- ##
- # SSL version to use
-
- def ssl_version= ssl_version
- @ssl_version = ssl_version
-
- reconnect_ssl
- end if RUBY_VERSION > '1.9'
-
- ##
- # Sets the HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER.
- #
- # Setting this to VERIFY_NONE is a VERY BAD IDEA and should NEVER be used.
- # Securely transfer the correct certificate and update the default
- # certificate store or set the ca file instead.
-
- def verify_mode= verify_mode
- @verify_mode = verify_mode
-
- reconnect_ssl
- end
-
- ##
- # SSL verification callback.
-
- def verify_callback= callback
- @verify_callback = callback
-
- reconnect_ssl
- end
-
-end
-
-require 'bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse'
-
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb
deleted file mode 100644
index 1b6b789f6d..0000000000
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-##
-# This Net::HTTP subclass adds SSL session reuse and Server Name Indication
-# (SNI) RFC 3546.
-#
-# DO NOT DEPEND UPON THIS CLASS
-#
-# This class is an implementation detail and is subject to change or removal
-# at any time.
-
-class Bundler::Persistent::Net::HTTP::Persistent::SSLReuse < Net::HTTP
-
- @is_proxy_class = false
- @proxy_addr = nil
- @proxy_port = nil
- @proxy_user = nil
- @proxy_pass = nil
-
- def initialize address, port = nil # :nodoc:
- super
-
- @ssl_session = nil
- end
-
- ##
- # From ruby trunk r33086 including http://redmine.ruby-lang.org/issues/5341
-
- def connect # :nodoc:
- D "opening connection to #{conn_address()}..."
- s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
- D "opened"
- if use_ssl?
- ssl_parameters = Hash.new
- iv_list = instance_variables
- SSL_ATTRIBUTES.each do |name|
- ivname = "@#{name}".intern
- if iv_list.include?(ivname) and
- value = instance_variable_get(ivname)
- ssl_parameters[name] = value
- end
- end
- unless @ssl_context then
- @ssl_context = OpenSSL::SSL::SSLContext.new
- @ssl_context.set_params(ssl_parameters)
- end
- s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
- s.sync_close = true
- end
- @socket = Net::BufferedIO.new(s)
- @socket.read_timeout = @read_timeout
- @socket.continue_timeout = @continue_timeout if
- @socket.respond_to? :continue_timeout
- @socket.debug_output = @debug_output
- if use_ssl?
- begin
- if proxy?
- @socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
- @address, @port, HTTPVersion)
- @socket.writeline "Host: #{@address}:#{@port}"
- if proxy_user
- credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
- credential.delete!("\r\n")
- @socket.writeline "Proxy-Authorization: Basic #{credential}"
- end
- @socket.writeline ''
- Net::HTTPResponse.read_new(@socket).value
- end
- s.session = @ssl_session if @ssl_session
- # Server Name Indication (SNI) RFC 3546
- s.hostname = @address if s.respond_to? :hostname=
- timeout(@open_timeout) { s.connect }
- if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
- s.post_connection_check(@address)
- end
- @ssl_session = s.session
- rescue => exception
- D "Conn close because of connect error #{exception}"
- @socket.close if @socket and not @socket.closed?
- raise exception
- end
- end
- on_connect
- end if RUBY_VERSION > '1.9'
-
- ##
- # From ruby_1_8_7 branch r29865 including a modified
- # http://redmine.ruby-lang.org/issues/5341
-
- def connect # :nodoc:
- D "opening connection to #{conn_address()}..."
- s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
- D "opened"
- if use_ssl?
- unless @ssl_context.verify_mode
- warn "warning: peer certificate won't be verified in this SSL session"
- @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
- end
- s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
- s.sync_close = true
- end
- @socket = Net::BufferedIO.new(s)
- @socket.read_timeout = @read_timeout
- @socket.debug_output = @debug_output
- if use_ssl?
- if proxy?
- @socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
- @address, @port, HTTPVersion)
- @socket.writeline "Host: #{@address}:#{@port}"
- if proxy_user
- credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
- credential.delete!("\r\n")
- @socket.writeline "Proxy-Authorization: Basic #{credential}"
- end
- @socket.writeline ''
- Net::HTTPResponse.read_new(@socket).value
- end
- s.session = @ssl_session if @ssl_session
- s.connect
- if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
- s.post_connection_check(@address)
- end
- @ssl_session = s.session
- end
- on_connect
- end if RUBY_VERSION < '1.9'
-
- private :connect
-
-end
-
diff --git a/lib/bundler/vendor/thor/lib/thor.rb b/lib/bundler/vendor/thor/lib/thor.rb
deleted file mode 100644
index 999e8b7e61..0000000000
--- a/lib/bundler/vendor/thor/lib/thor.rb
+++ /dev/null
@@ -1,509 +0,0 @@
-require "set"
-require "bundler/vendor/thor/lib/thor/base"
-
-class Bundler::Thor
- class << self
- # Allows for custom "Command" package naming.
- #
- # === Parameters
- # name<String>
- # options<Hash>
- #
- def package_name(name, _ = {})
- @package_name = name.nil? || name == "" ? nil : name
- end
-
- # Sets the default command when thor is executed without an explicit command to be called.
- #
- # ==== Parameters
- # meth<Symbol>:: name of the default command
- #
- def default_command(meth = nil)
- if meth
- @default_command = meth == :none ? "help" : meth.to_s
- else
- @default_command ||= from_superclass(:default_command, "help")
- end
- end
- alias_method :default_task, :default_command
-
- # Registers another Bundler::Thor subclass as a command.
- #
- # ==== Parameters
- # klass<Class>:: Bundler::Thor subclass to register
- # command<String>:: Subcommand name to use
- # usage<String>:: Short usage for the subcommand
- # description<String>:: Description for the subcommand
- def register(klass, subcommand_name, usage, description, options = {})
- if klass <= Bundler::Thor::Group
- desc usage, description, options
- define_method(subcommand_name) { |*args| invoke(klass, args) }
- else
- desc usage, description, options
- subcommand subcommand_name, klass
- end
- end
-
- # Defines the usage and the description of the next command.
- #
- # ==== Parameters
- # usage<String>
- # description<String>
- # options<String>
- #
- def desc(usage, description, options = {})
- if options[:for]
- command = find_and_refresh_command(options[:for])
- command.usage = usage if usage
- command.description = description if description
- else
- @usage = usage
- @desc = description
- @hide = options[:hide] || false
- end
- end
-
- # Defines the long description of the next command.
- #
- # ==== Parameters
- # long description<String>
- #
- def long_desc(long_description, options = {})
- if options[:for]
- command = find_and_refresh_command(options[:for])
- command.long_description = long_description if long_description
- else
- @long_desc = long_description
- end
- end
-
- # Maps an input to a command. If you define:
- #
- # map "-T" => "list"
- #
- # Running:
- #
- # thor -T
- #
- # Will invoke the list command.
- #
- # ==== Parameters
- # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command.
- #
- def map(mappings = nil)
- @map ||= from_superclass(:map, {})
-
- if mappings
- mappings.each do |key, value|
- if key.respond_to?(:each)
- key.each { |subkey| @map[subkey] = value }
- else
- @map[key] = value
- end
- end
- end
-
- @map
- end
-
- # Declares the options for the next command to be declared.
- #
- # ==== Parameters
- # Hash[Symbol => Object]:: The hash key is the name of the option and the value
- # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
- # or :required (string). If you give a value, the type of the value is used.
- #
- def method_options(options = nil)
- @method_options ||= {}
- build_options(options, @method_options) if options
- @method_options
- end
-
- alias_method :options, :method_options
-
- # Adds an option to the set of method options. If :for is given as option,
- # it allows you to change the options from a previous defined command.
- #
- # def previous_command
- # # magic
- # end
- #
- # method_option :foo => :bar, :for => :previous_command
- #
- # def next_command
- # # magic
- # end
- #
- # ==== Parameters
- # name<Symbol>:: The name of the argument.
- # options<Hash>:: Described below.
- #
- # ==== Options
- # :desc - Description for the argument.
- # :required - If the argument is required or not.
- # :default - Default value for this argument. It cannot be required and have default values.
- # :aliases - Aliases for this option.
- # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
- # :banner - String to show on usage notes.
- # :hide - If you want to hide this option from the help.
- #
- def method_option(name, options = {})
- scope = if options[:for]
- find_and_refresh_command(options[:for]).options
- else
- method_options
- end
-
- build_option(name, options, scope)
- end
- alias_method :option, :method_option
-
- # Prints help information for the given command.
- #
- # ==== Parameters
- # shell<Bundler::Thor::Shell>
- # command_name<String>
- #
- def command_help(shell, command_name)
- meth = normalize_command_name(command_name)
- command = all_commands[meth]
- handle_no_command_error(meth) unless command
-
- shell.say "Usage:"
- shell.say " #{banner(command)}"
- shell.say
- class_options_help(shell, nil => command.options.values)
- if command.long_description
- shell.say "Description:"
- shell.print_wrapped(command.long_description, :indent => 2)
- else
- shell.say command.description
- end
- end
- alias_method :task_help, :command_help
-
- # Prints help information for this class.
- #
- # ==== Parameters
- # shell<Bundler::Thor::Shell>
- #
- def help(shell, subcommand = false)
- list = printable_commands(true, subcommand)
- Bundler::Thor::Util.thor_classes_in(self).each do |klass|
- list += klass.printable_commands(false)
- end
- list.sort! { |a, b| a[0] <=> b[0] }
-
- if defined?(@package_name) && @package_name
- shell.say "#{@package_name} commands:"
- else
- shell.say "Commands:"
- end
-
- shell.print_table(list, :indent => 2, :truncate => true)
- shell.say
- class_options_help(shell)
- end
-
- # Returns commands ready to be printed.
- def printable_commands(all = true, subcommand = false)
- (all ? all_commands : commands).map do |_, command|
- next if command.hidden?
- item = []
- item << banner(command, false, subcommand)
- item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "")
- item
- end.compact
- end
- alias_method :printable_tasks, :printable_commands
-
- def subcommands
- @subcommands ||= from_superclass(:subcommands, [])
- end
- alias_method :subtasks, :subcommands
-
- def subcommand_classes
- @subcommand_classes ||= {}
- end
-
- def subcommand(subcommand, subcommand_class)
- subcommands << subcommand.to_s
- subcommand_class.subcommand_help subcommand
- subcommand_classes[subcommand.to_s] = subcommand_class
-
- define_method(subcommand) do |*args|
- args, opts = Bundler::Thor::Arguments.split(args)
- invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}]
- invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h")
- invoke subcommand_class, *invoke_args
- end
- subcommand_class.commands.each do |_meth, command|
- command.ancestor_name = subcommand
- end
- end
- alias_method :subtask, :subcommand
-
- # Extend check unknown options to accept a hash of conditions.
- #
- # === Parameters
- # options<Hash>: A hash containing :only and/or :except keys
- def check_unknown_options!(options = {})
- @check_unknown_options ||= {}
- options.each do |key, value|
- if value
- @check_unknown_options[key] = Array(value)
- else
- @check_unknown_options.delete(key)
- end
- end
- @check_unknown_options
- end
-
- # Overwrite check_unknown_options? to take subcommands and options into account.
- def check_unknown_options?(config) #:nodoc:
- options = check_unknown_options
- return false unless options
-
- command = config[:current_command]
- return true unless command
-
- name = command.name
-
- if subcommands.include?(name)
- false
- elsif options[:except]
- !options[:except].include?(name.to_sym)
- elsif options[:only]
- options[:only].include?(name.to_sym)
- else
- true
- end
- end
-
- # Stop parsing of options as soon as an unknown option or a regular
- # argument is encountered. All remaining arguments are passed to the command.
- # This is useful if you have a command that can receive arbitrary additional
- # options, and where those additional options should not be handled by
- # Bundler::Thor.
- #
- # ==== Example
- #
- # To better understand how this is useful, let's consider a command that calls
- # an external command. A user may want to pass arbitrary options and
- # arguments to that command. The command itself also accepts some options,
- # which should be handled by Bundler::Thor.
- #
- # class_option "verbose", :type => :boolean
- # stop_on_unknown_option! :exec
- # check_unknown_options! :except => :exec
- #
- # desc "exec", "Run a shell command"
- # def exec(*args)
- # puts "diagnostic output" if options[:verbose]
- # Kernel.exec(*args)
- # end
- #
- # Here +exec+ can be called with +--verbose+ to get diagnostic output,
- # e.g.:
- #
- # $ thor exec --verbose echo foo
- # diagnostic output
- # foo
- #
- # But if +--verbose+ is given after +echo+, it is passed to +echo+ instead:
- #
- # $ thor exec echo --verbose foo
- # --verbose foo
- #
- # ==== Parameters
- # Symbol ...:: A list of commands that should be affected.
- def stop_on_unknown_option!(*command_names)
- stop_on_unknown_option.merge(command_names)
- end
-
- def stop_on_unknown_option?(command) #:nodoc:
- command && stop_on_unknown_option.include?(command.name.to_sym)
- end
-
- # Disable the check for required options for the given commands.
- # This is useful if you have a command that does not need the required options
- # to work, like help.
- #
- # ==== Parameters
- # Symbol ...:: A list of commands that should be affected.
- def disable_required_check!(*command_names)
- disable_required_check.merge(command_names)
- end
-
- def disable_required_check?(command) #:nodoc:
- command && disable_required_check.include?(command.name.to_sym)
- end
-
- protected
-
- def stop_on_unknown_option #:nodoc:
- @stop_on_unknown_option ||= Set.new
- end
-
- # help command has the required check disabled by default.
- def disable_required_check #:nodoc:
- @disable_required_check ||= Set.new([:help])
- end
-
- # The method responsible for dispatching given the args.
- def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength
- meth ||= retrieve_command_name(given_args)
- command = all_commands[normalize_command_name(meth)]
-
- if !command && config[:invoked_via_subcommand]
- # We're a subcommand and our first argument didn't match any of our
- # commands. So we put it back and call our default command.
- given_args.unshift(meth)
- command = all_commands[normalize_command_name(default_command)]
- end
-
- if command
- args, opts = Bundler::Thor::Options.split(given_args)
- if stop_on_unknown_option?(command) && !args.empty?
- # given_args starts with a non-option, so we treat everything as
- # ordinary arguments
- args.concat opts
- opts.clear
- end
- else
- args = given_args
- opts = nil
- command = dynamic_command_class.new(meth)
- end
-
- opts = given_opts || opts || []
- config[:current_command] = command
- config[:command_options] = command.options
-
- instance = new(args, opts, config)
- yield instance if block_given?
- args = instance.args
- trailing = args[Range.new(arguments.size, -1)]
- instance.invoke_command(command, trailing || [])
- end
-
- # The banner for this class. You can customize it if you are invoking the
- # thor class by another ways which is not the Bundler::Thor::Runner. It receives
- # the command that is going to be invoked and a boolean which indicates if
- # the namespace should be displayed as arguments.
- #
- def banner(command, namespace = nil, subcommand = false)
- "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
- end
-
- def baseclass #:nodoc:
- Bundler::Thor
- end
-
- def dynamic_command_class #:nodoc:
- Bundler::Thor::DynamicCommand
- end
-
- def create_command(meth) #:nodoc:
- @usage ||= nil
- @desc ||= nil
- @long_desc ||= nil
- @hide ||= nil
-
- if @usage && @desc
- base_class = @hide ? Bundler::Thor::HiddenCommand : Bundler::Thor::Command
- commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
- @usage, @desc, @long_desc, @method_options, @hide = nil
- true
- elsif all_commands[meth] || meth == "method_missing"
- true
- else
- puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " \
- "Call desc if you want this method to be available as command or declare it inside a " \
- "no_commands{} block. Invoked from #{caller[1].inspect}."
- false
- end
- end
- alias_method :create_task, :create_command
-
- def initialize_added #:nodoc:
- class_options.merge!(method_options)
- @method_options = nil
- end
-
- # Retrieve the command name from given args.
- def retrieve_command_name(args) #:nodoc:
- meth = args.first.to_s unless args.empty?
- args.shift if meth && (map[meth] || meth !~ /^\-/)
- end
- alias_method :retrieve_task_name, :retrieve_command_name
-
- # receives a (possibly nil) command name and returns a name that is in
- # the commands hash. In addition to normalizing aliases, this logic
- # will determine if a shortened command is an unambiguous substring of
- # a command or alias.
- #
- # +normalize_command_name+ also converts names like +animal-prison+
- # into +animal_prison+.
- def normalize_command_name(meth) #:nodoc:
- return default_command.to_s.tr("-", "_") unless meth
-
- possibilities = find_command_possibilities(meth)
- raise AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" if possibilities.size > 1
-
- if possibilities.empty?
- meth ||= default_command
- elsif map[meth]
- meth = map[meth]
- else
- meth = possibilities.first
- end
-
- meth.to_s.tr("-", "_") # treat foo-bar as foo_bar
- end
- alias_method :normalize_task_name, :normalize_command_name
-
- # this is the logic that takes the command name passed in by the user
- # and determines whether it is an unambiguous substrings of a command or
- # alias name.
- def find_command_possibilities(meth)
- len = meth.to_s.length
- possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
- unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
-
- if possibilities.include?(meth)
- [meth]
- elsif unique_possibilities.size == 1
- unique_possibilities
- else
- possibilities
- end
- end
- alias_method :find_task_possibilities, :find_command_possibilities
-
- def subcommand_help(cmd)
- desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
- class_eval "
- def help(command = nil, subcommand = true); super; end
-"
- end
- alias_method :subtask_help, :subcommand_help
- end
-
- include Bundler::Thor::Base
-
- map HELP_MAPPINGS => :help
-
- desc "help [COMMAND]", "Describe available commands or one specific command"
- def help(command = nil, subcommand = false)
- if command
- if self.class.subcommands.include? command
- self.class.subcommand_classes[command].help(shell, true)
- else
- self.class.command_help(shell, command)
- end
- else
- self.class.help(shell, subcommand)
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb
deleted file mode 100644
index e6698572a9..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/actions.rb
+++ /dev/null
@@ -1,321 +0,0 @@
-require "uri"
-require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
-require "bundler/vendor/thor/lib/thor/actions/create_file"
-require "bundler/vendor/thor/lib/thor/actions/create_link"
-require "bundler/vendor/thor/lib/thor/actions/directory"
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
-require "bundler/vendor/thor/lib/thor/actions/file_manipulation"
-require "bundler/vendor/thor/lib/thor/actions/inject_into_file"
-
-class Bundler::Thor
- module Actions
- attr_accessor :behavior
-
- def self.included(base) #:nodoc:
- base.extend ClassMethods
- end
-
- module ClassMethods
- # Hold source paths for one Bundler::Thor instance. source_paths_for_search is the
- # method responsible to gather source_paths from this current class,
- # inherited paths and the source root.
- #
- def source_paths
- @_source_paths ||= []
- end
-
- # Stores and return the source root for this class
- def source_root(path = nil)
- @_source_root = path if path
- @_source_root ||= nil
- end
-
- # Returns the source paths in the following order:
- #
- # 1) This class source paths
- # 2) Source root
- # 3) Parents source paths
- #
- def source_paths_for_search
- paths = []
- paths += source_paths
- paths << source_root if source_root
- paths += from_superclass(:source_paths, [])
- paths
- end
-
- # Add runtime options that help actions execution.
- #
- def add_runtime_options!
- class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
- :desc => "Overwrite files that already exist"
-
- class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
- :desc => "Run but do not make any changes"
-
- class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
- :desc => "Suppress status output"
-
- class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
- :desc => "Skip files that already exist"
- end
- end
-
- # Extends initializer to add more configuration options.
- #
- # ==== Configuration
- # behavior<Symbol>:: The actions default behavior. Can be :invoke or :revoke.
- # It also accepts :force, :skip and :pretend to set the behavior
- # and the respective option.
- #
- # destination_root<String>:: The root directory needed for some actions.
- #
- def initialize(args = [], options = {}, config = {})
- self.behavior = case config[:behavior].to_s
- when "force", "skip"
- _cleanup_options_and_set(options, config[:behavior])
- :invoke
- when "revoke"
- :revoke
- else
- :invoke
- end
-
- super
- self.destination_root = config[:destination_root]
- end
-
- # Wraps an action object and call it accordingly to the thor class behavior.
- #
- def action(instance) #:nodoc:
- if behavior == :revoke
- instance.revoke!
- else
- instance.invoke!
- end
- end
-
- # Returns the root for this thor class (also aliased as destination root).
- #
- def destination_root
- @destination_stack.last
- end
-
- # Sets the root for this thor class. Relatives path are added to the
- # directory where the script was invoked and expanded.
- #
- def destination_root=(root)
- @destination_stack ||= []
- @destination_stack[0] = File.expand_path(root || "")
- end
-
- # Returns the given path relative to the absolute root (ie, root where
- # the script started).
- #
- def relative_to_original_destination_root(path, remove_dot = true)
- path = path.dup
- if path.gsub!(@destination_stack[0], ".")
- remove_dot ? (path[2..-1] || "") : path
- else
- path
- end
- end
-
- # Holds source paths in instance so they can be manipulated.
- #
- def source_paths
- @source_paths ||= self.class.source_paths_for_search
- end
-
- # Receives a file or directory and search for it in the source paths.
- #
- def find_in_source_paths(file)
- possible_files = [file, file + TEMPLATE_EXTNAME]
- relative_root = relative_to_original_destination_root(destination_root, false)
-
- source_paths.each do |source|
- possible_files.each do |f|
- source_file = File.expand_path(f, File.join(source, relative_root))
- return source_file if File.exist?(source_file)
- end
- end
-
- message = "Could not find #{file.inspect} in any of your source paths. ".dup
-
- unless self.class.source_root
- message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
- end
-
- message << if source_paths.empty?
- "Currently you have no source paths."
- else
- "Your current source paths are: \n#{source_paths.join("\n")}"
- end
-
- raise Error, message
- end
-
- # Do something in the root or on a provided subfolder. If a relative path
- # is given it's referenced from the current root. The full path is yielded
- # to the block you provide. The path is set back to the previous path when
- # the method exits.
- #
- # ==== Parameters
- # dir<String>:: the directory to move to.
- # config<Hash>:: give :verbose => true to log and use padding.
- #
- def inside(dir = "", config = {}, &block)
- verbose = config.fetch(:verbose, false)
- pretend = options[:pretend]
-
- say_status :inside, dir, verbose
- shell.padding += 1 if verbose
- @destination_stack.push File.expand_path(dir, destination_root)
-
- # If the directory doesnt exist and we're not pretending
- if !File.exist?(destination_root) && !pretend
- require "fileutils"
- FileUtils.mkdir_p(destination_root)
- end
-
- if pretend
- # In pretend mode, just yield down to the block
- block.arity == 1 ? yield(destination_root) : yield
- else
- require "fileutils"
- FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield }
- end
-
- @destination_stack.pop
- shell.padding -= 1 if verbose
- end
-
- # Goes to the root and execute the given block.
- #
- def in_root
- inside(@destination_stack.first) { yield }
- end
-
- # Loads an external file and execute it in the instance binding.
- #
- # ==== Parameters
- # path<String>:: The path to the file to execute. Can be a web address or
- # a relative path from the source root.
- #
- # ==== Examples
- #
- # apply "http://gist.github.com/103208"
- #
- # apply "recipes/jquery.rb"
- #
- def apply(path, config = {})
- verbose = config.fetch(:verbose, true)
- is_uri = path =~ %r{^https?\://}
- path = find_in_source_paths(path) unless is_uri
-
- say_status :apply, path, verbose
- shell.padding += 1 if verbose
-
- contents = if is_uri
- open(path, "Accept" => "application/x-thor-template", &:read)
- else
- open(path, &:read)
- end
-
- instance_eval(contents, path)
- shell.padding -= 1 if verbose
- end
-
- # Executes a command returning the contents of the command.
- #
- # ==== Parameters
- # command<String>:: the command to be executed.
- # config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with
- # to append an executable to command execution.
- #
- # ==== Example
- #
- # inside('vendor') do
- # run('ln -s ~/edge rails')
- # end
- #
- def run(command, config = {})
- return unless behavior == :invoke
-
- destination = relative_to_original_destination_root(destination_root, false)
- desc = "#{command} from #{destination.inspect}"
-
- if config[:with]
- desc = "#{File.basename(config[:with].to_s)} #{desc}"
- command = "#{config[:with]} #{command}"
- end
-
- say_status :run, desc, config.fetch(:verbose, true)
-
- unless options[:pretend]
- config[:capture] ? `#{command}` : system(command.to_s)
- end
- end
-
- # Executes a ruby script (taking into account WIN32 platform quirks).
- #
- # ==== Parameters
- # command<String>:: the command to be executed.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- def run_ruby_script(command, config = {})
- return unless behavior == :invoke
- run command, config.merge(:with => Bundler::Thor::Util.ruby_command)
- end
-
- # Run a thor command. A hash of options can be given and it's converted to
- # switches.
- #
- # ==== Parameters
- # command<String>:: the command to be invoked
- # args<Array>:: arguments to the command
- # config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output.
- # Other options are given as parameter to Bundler::Thor.
- #
- #
- # ==== Examples
- #
- # thor :install, "http://gist.github.com/103208"
- # #=> thor install http://gist.github.com/103208
- #
- # thor :list, :all => true, :substring => 'rails'
- # #=> thor list --all --substring=rails
- #
- def thor(command, *args)
- config = args.last.is_a?(Hash) ? args.pop : {}
- verbose = config.key?(:verbose) ? config.delete(:verbose) : true
- pretend = config.key?(:pretend) ? config.delete(:pretend) : false
- capture = config.key?(:capture) ? config.delete(:capture) : false
-
- args.unshift(command)
- args.push Bundler::Thor::Options.to_switches(config)
- command = args.join(" ").strip
-
- run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
- end
-
- protected
-
- # Allow current root to be shared between invocations.
- #
- def _shared_configuration #:nodoc:
- super.merge!(:destination_root => destination_root)
- end
-
- def _cleanup_options_and_set(options, key) #:nodoc:
- case options
- when Array
- %w(--force -f --skip -s).each { |i| options.delete(i) }
- options << "--#{key}"
- when Hash
- [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
- options.merge!(key => true)
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
deleted file mode 100644
index 97d22d9bbd..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
+++ /dev/null
@@ -1,104 +0,0 @@
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
-
-class Bundler::Thor
- module Actions
- # Create a new file relative to the destination root with the given data,
- # which is the return value of a block or a data string.
- #
- # ==== Parameters
- # destination<String>:: the relative path to the destination root.
- # data<String|NilClass>:: the data to append to the file.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Examples
- #
- # create_file "lib/fun_party.rb" do
- # hostname = ask("What is the virtual hostname I should use?")
- # "vhost.name = #{hostname}"
- # end
- #
- # create_file "config/apache.conf", "your apache config"
- #
- def create_file(destination, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- data = args.first
- action CreateFile.new(self, destination, block || data.to_s, config)
- end
- alias_method :add_file, :create_file
-
- # CreateFile is a subset of Template, which instead of rendering a file with
- # ERB, it gets the content from the user.
- #
- class CreateFile < EmptyDirectory #:nodoc:
- attr_reader :data
-
- def initialize(base, destination, data, config = {})
- @data = data
- super(base, destination, config)
- end
-
- # Checks if the content of the file at the destination is identical to the rendered result.
- #
- # ==== Returns
- # Boolean:: true if it is identical, false otherwise.
- #
- def identical?
- exists? && File.binread(destination) == render
- end
-
- # Holds the content to be added to the file.
- #
- def render
- @render ||= if data.is_a?(Proc)
- data.call
- else
- data
- end
- end
-
- def invoke!
- invoke_with_conflict_check do
- require "fileutils"
- FileUtils.mkdir_p(File.dirname(destination))
- File.open(destination, "wb") { |f| f.write render }
- end
- given_destination
- end
-
- protected
-
- # Now on conflict we check if the file is identical or not.
- #
- def on_conflict_behavior(&block)
- if identical?
- say_status :identical, :blue
- else
- options = base.options.merge(config)
- force_or_skip_or_conflict(options[:force], options[:skip], &block)
- end
- end
-
- # If force is true, run the action, otherwise check if it's not being
- # skipped. If both are false, show the file_collision menu, if the menu
- # returns true, force it, otherwise skip.
- #
- def force_or_skip_or_conflict(force, skip, &block)
- if force
- say_status :force, :yellow
- yield unless pretend?
- elsif skip
- say_status :skip, :yellow
- else
- say_status :conflict, :red
- force_or_skip_or_conflict(force_on_collision?, true, &block)
- end
- end
-
- # Shows the file collision menu to the user and gets the result.
- #
- def force_on_collision?
- base.shell.file_collision(destination) { render }
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb b/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb
deleted file mode 100644
index 3a664401b4..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-require "bundler/vendor/thor/lib/thor/actions/create_file"
-
-class Bundler::Thor
- module Actions
- # Create a new file relative to the destination root from the given source.
- #
- # ==== Parameters
- # destination<String>:: the relative path to the destination root.
- # source<String|NilClass>:: the relative path to the source root.
- # config<Hash>:: give :verbose => false to not log the status.
- # :: give :symbolic => false for hard link.
- #
- # ==== Examples
- #
- # create_link "config/apache.conf", "/etc/apache.conf"
- #
- def create_link(destination, *args)
- config = args.last.is_a?(Hash) ? args.pop : {}
- source = args.first
- action CreateLink.new(self, destination, source, config)
- end
- alias_method :add_link, :create_link
-
- # CreateLink is a subset of CreateFile, which instead of taking a block of
- # data, just takes a source string from the user.
- #
- class CreateLink < CreateFile #:nodoc:
- attr_reader :data
-
- # Checks if the content of the file at the destination is identical to the rendered result.
- #
- # ==== Returns
- # Boolean:: true if it is identical, false otherwise.
- #
- def identical?
- exists? && File.identical?(render, destination)
- end
-
- def invoke!
- invoke_with_conflict_check do
- require "fileutils"
- FileUtils.mkdir_p(File.dirname(destination))
- # Create a symlink by default
- config[:symbolic] = true if config[:symbolic].nil?
- File.unlink(destination) if exists?
- if config[:symbolic]
- File.symlink(render, destination)
- else
- File.link(render, destination)
- end
- end
- given_destination
- end
-
- def exists?
- super || File.symlink?(destination)
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb b/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
deleted file mode 100644
index f555f7b7e0..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
-
-class Bundler::Thor
- module Actions
- # Copies recursively the files from source directory to root directory.
- # If any of the files finishes with .tt, it's considered to be a template
- # and is placed in the destination without the extension .tt. If any
- # empty directory is found, it's copied and all .empty_directory files are
- # ignored. If any file name is wrapped within % signs, the text within
- # the % signs will be executed as a method and replaced with the returned
- # value. Let's suppose a doc directory with the following files:
- #
- # doc/
- # components/.empty_directory
- # README
- # rdoc.rb.tt
- # %app_name%.rb
- #
- # When invoked as:
- #
- # directory "doc"
- #
- # It will create a doc directory in the destination with the following
- # files (assuming that the `app_name` method returns the value "blog"):
- #
- # doc/
- # components/
- # README
- # rdoc.rb
- # blog.rb
- #
- # <b>Encoded path note:</b> Since Bundler::Thor internals use Object#respond_to? to check if it can
- # expand %something%, this `something` should be a public method in the class calling
- # #directory. If a method is private, Bundler::Thor stack raises PrivateMethodEncodedError.
- #
- # ==== Parameters
- # source<String>:: the relative path to the source root.
- # destination<String>:: the relative path to the destination root.
- # config<Hash>:: give :verbose => false to not log the status.
- # If :recursive => false, does not look for paths recursively.
- # If :mode => :preserve, preserve the file mode from the source.
- # If :exclude_pattern => /regexp/, prevents copying files that match that regexp.
- #
- # ==== Examples
- #
- # directory "doc"
- # directory "doc", "docs", :recursive => false
- #
- def directory(source, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- destination = args.first || source
- action Directory.new(self, source, destination || source, config, &block)
- end
-
- class Directory < EmptyDirectory #:nodoc:
- attr_reader :source
-
- def initialize(base, source, destination = nil, config = {}, &block)
- @source = File.expand_path(base.find_in_source_paths(source.to_s))
- @block = block
- super(base, destination, {:recursive => true}.merge(config))
- end
-
- def invoke!
- base.empty_directory given_destination, config
- execute!
- end
-
- def revoke!
- execute!
- end
-
- protected
-
- def execute!
- lookup = Util.escape_globs(source)
- lookup = config[:recursive] ? File.join(lookup, "**") : lookup
- lookup = file_level_lookup(lookup)
-
- files(lookup).sort.each do |file_source|
- next if File.directory?(file_source)
- next if config[:exclude_pattern] && file_source.match(config[:exclude_pattern])
- file_destination = File.join(given_destination, file_source.gsub(source, "."))
- file_destination.gsub!("/./", "/")
-
- case file_source
- when /\.empty_directory$/
- dirname = File.dirname(file_destination).gsub(%r{/\.$}, "")
- next if dirname == given_destination
- base.empty_directory(dirname, config)
- when /#{TEMPLATE_EXTNAME}$/
- base.template(file_source, file_destination[0..-4], config, &@block)
- else
- base.copy_file(file_source, file_destination, config, &@block)
- end
- end
- end
-
- if RUBY_VERSION < "2.0"
- def file_level_lookup(previous_lookup)
- File.join(previous_lookup, "{*,.[a-z]*}")
- end
-
- def files(lookup)
- Dir[lookup]
- end
- else
- def file_level_lookup(previous_lookup)
- File.join(previous_lookup, "*")
- end
-
- def files(lookup)
- Dir.glob(lookup, File::FNM_DOTMATCH)
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb b/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb
deleted file mode 100644
index 284d92c19a..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb
+++ /dev/null
@@ -1,143 +0,0 @@
-class Bundler::Thor
- module Actions
- # Creates an empty directory.
- #
- # ==== Parameters
- # destination<String>:: the relative path to the destination root.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Examples
- #
- # empty_directory "doc"
- #
- def empty_directory(destination, config = {})
- action EmptyDirectory.new(self, destination, config)
- end
-
- # Class which holds create directory logic. This is the base class for
- # other actions like create_file and directory.
- #
- # This implementation is based in Templater actions, created by Jonas Nicklas
- # and Michael S. Klishin under MIT LICENSE.
- #
- class EmptyDirectory #:nodoc:
- attr_reader :base, :destination, :given_destination, :relative_destination, :config
-
- # Initializes given the source and destination.
- #
- # ==== Parameters
- # base<Bundler::Thor::Base>:: A Bundler::Thor::Base instance
- # source<String>:: Relative path to the source of this file
- # destination<String>:: Relative path to the destination of this file
- # config<Hash>:: give :verbose => false to not log the status.
- #
- def initialize(base, destination, config = {})
- @base = base
- @config = {:verbose => true}.merge(config)
- self.destination = destination
- end
-
- # Checks if the destination file already exists.
- #
- # ==== Returns
- # Boolean:: true if the file exists, false otherwise.
- #
- def exists?
- ::File.exist?(destination)
- end
-
- def invoke!
- invoke_with_conflict_check do
- require "fileutils"
- ::FileUtils.mkdir_p(destination)
- end
- end
-
- def revoke!
- say_status :remove, :red
- require "fileutils"
- ::FileUtils.rm_rf(destination) if !pretend? && exists?
- given_destination
- end
-
- protected
-
- # Shortcut for pretend.
- #
- def pretend?
- base.options[:pretend]
- end
-
- # Sets the absolute destination value from a relative destination value.
- # It also stores the given and relative destination. Let's suppose our
- # script is being executed on "dest", it sets the destination root to
- # "dest". The destination, given_destination and relative_destination
- # are related in the following way:
- #
- # inside "bar" do
- # empty_directory "baz"
- # end
- #
- # destination #=> dest/bar/baz
- # relative_destination #=> bar/baz
- # given_destination #=> baz
- #
- def destination=(destination)
- return unless destination
- @given_destination = convert_encoded_instructions(destination.to_s)
- @destination = ::File.expand_path(@given_destination, base.destination_root)
- @relative_destination = base.relative_to_original_destination_root(@destination)
- end
-
- # Filenames in the encoded form are converted. If you have a file:
- #
- # %file_name%.rb
- #
- # It calls #file_name from the base and replaces %-string with the
- # return value (should be String) of #file_name:
- #
- # user.rb
- #
- # The method referenced can be either public or private.
- #
- def convert_encoded_instructions(filename)
- filename.gsub(/%(.*?)%/) do |initial_string|
- method = $1.strip
- base.respond_to?(method, true) ? base.send(method) : initial_string
- end
- end
-
- # Receives a hash of options and just execute the block if some
- # conditions are met.
- #
- def invoke_with_conflict_check(&block)
- if exists?
- on_conflict_behavior(&block)
- else
- yield unless pretend?
- say_status :create, :green
- end
-
- destination
- rescue Errno::EISDIR, Errno::EEXIST
- on_file_clash_behavior
- end
-
- def on_file_clash_behavior
- say_status :file_clash, :red
- end
-
- # What to do when the destination file already exists.
- #
- def on_conflict_behavior
- say_status :exist, :blue
- end
-
- # Shortcut to say_status shell method.
- #
- def say_status(status, color)
- base.shell.say_status status, relative_destination, color if config[:verbose]
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
deleted file mode 100644
index 4c83bebc86..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
+++ /dev/null
@@ -1,364 +0,0 @@
-require "erb"
-
-class Bundler::Thor
- module Actions
- # Copies the file from the relative source to the relative destination. If
- # the destination is not given it's assumed to be equal to the source.
- #
- # ==== Parameters
- # source<String>:: the relative path to the source root.
- # destination<String>:: the relative path to the destination root.
- # config<Hash>:: give :verbose => false to not log the status, and
- # :mode => :preserve, to preserve the file mode from the source.
-
- #
- # ==== Examples
- #
- # copy_file "README", "doc/README"
- #
- # copy_file "doc/README"
- #
- def copy_file(source, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- destination = args.first || source
- source = File.expand_path(find_in_source_paths(source.to_s))
-
- create_file destination, nil, config do
- content = File.binread(source)
- content = yield(content) if block
- content
- end
- if config[:mode] == :preserve
- mode = File.stat(source).mode
- chmod(destination, mode, config)
- end
- end
-
- # Links the file from the relative source to the relative destination. If
- # the destination is not given it's assumed to be equal to the source.
- #
- # ==== Parameters
- # source<String>:: the relative path to the source root.
- # destination<String>:: the relative path to the destination root.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Examples
- #
- # link_file "README", "doc/README"
- #
- # link_file "doc/README"
- #
- def link_file(source, *args)
- config = args.last.is_a?(Hash) ? args.pop : {}
- destination = args.first || source
- source = File.expand_path(find_in_source_paths(source.to_s))
-
- create_link destination, source, config
- end
-
- # Gets the content at the given address and places it at the given relative
- # destination. If a block is given instead of destination, the content of
- # the url is yielded and used as location.
- #
- # ==== Parameters
- # source<String>:: the address of the given content.
- # destination<String>:: the relative path to the destination root.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Examples
- #
- # get "http://gist.github.com/103208", "doc/README"
- #
- # get "http://gist.github.com/103208" do |content|
- # content.split("\n").first
- # end
- #
- def get(source, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- destination = args.first
-
- if source =~ %r{^https?\://}
- require "open-uri"
- else
- source = File.expand_path(find_in_source_paths(source.to_s))
- end
-
- render = open(source) { |input| input.binmode.read }
-
- destination ||= if block_given?
- block.arity == 1 ? yield(render) : yield
- else
- File.basename(source)
- end
-
- create_file destination, render, config
- end
-
- # Gets an ERB template at the relative source, executes it and makes a copy
- # at the relative destination. If the destination is not given it's assumed
- # to be equal to the source removing .tt from the filename.
- #
- # ==== Parameters
- # source<String>:: the relative path to the source root.
- # destination<String>:: the relative path to the destination root.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Examples
- #
- # template "README", "doc/README"
- #
- # template "doc/README"
- #
- def template(source, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "")
-
- source = File.expand_path(find_in_source_paths(source.to_s))
- 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|
- erb.filename = source
- end.result(context)
- content = yield(content) if block
- content
- end
- end
-
- # Changes the mode of the given file or directory.
- #
- # ==== Parameters
- # mode<Integer>:: the file mode
- # path<String>:: the name of the file to change mode
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Example
- #
- # chmod "script/server", 0755
- #
- def chmod(path, mode, config = {})
- return unless behavior == :invoke
- path = File.expand_path(path, destination_root)
- say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
- unless options[:pretend]
- require "fileutils"
- FileUtils.chmod_R(mode, path)
- end
- end
-
- # Prepend text to a file. Since it depends on insert_into_file, it's reversible.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # data<String>:: the data to prepend to the file, can be also given as a block.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Example
- #
- # prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"'
- #
- # prepend_to_file 'config/environments/test.rb' do
- # 'config.gem "rspec"'
- # end
- #
- def prepend_to_file(path, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- config[:after] = /\A/
- insert_into_file(path, *(args << config), &block)
- end
- alias_method :prepend_file, :prepend_to_file
-
- # Append text to a file. Since it depends on insert_into_file, it's reversible.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # data<String>:: the data to append to the file, can be also given as a block.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Example
- #
- # append_to_file 'config/environments/test.rb', 'config.gem "rspec"'
- #
- # append_to_file 'config/environments/test.rb' do
- # 'config.gem "rspec"'
- # end
- #
- def append_to_file(path, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- config[:before] = /\z/
- insert_into_file(path, *(args << config), &block)
- end
- alias_method :append_file, :append_to_file
-
- # Injects text right after the class definition. Since it depends on
- # insert_into_file, it's reversible.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # klass<String|Class>:: the class to be manipulated
- # data<String>:: the data to append to the class, can be also given as a block.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Examples
- #
- # inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
- #
- # inject_into_class "app/controllers/application_controller.rb", ApplicationController do
- # " filter_parameter :password\n"
- # end
- #
- def inject_into_class(path, klass, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- config[:after] = /class #{klass}\n|class #{klass} .*\n/
- insert_into_file(path, *(args << config), &block)
- end
-
- # Injects text right after the module definition. Since it depends on
- # insert_into_file, it's reversible.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # module_name<String|Class>:: the module to be manipulated
- # data<String>:: the data to append to the class, can be also given as a block.
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Examples
- #
- # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper, " def help; 'help'; end\n"
- #
- # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper do
- # " def help; 'help'; end\n"
- # end
- #
- def inject_into_module(path, module_name, *args, &block)
- config = args.last.is_a?(Hash) ? args.pop : {}
- config[:after] = /module #{module_name}\n|module #{module_name} .*\n/
- insert_into_file(path, *(args << config), &block)
- end
-
- # Run a regular expression replacement on a file.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # flag<Regexp|String>:: the regexp or string to be replaced
- # replacement<String>:: the replacement, can be also given as a block
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Example
- #
- # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
- #
- # gsub_file 'README', /rake/, :green do |match|
- # match << " no more. Use thor!"
- # end
- #
- def gsub_file(path, flag, *args, &block)
- return unless behavior == :invoke
- config = args.last.is_a?(Hash) ? args.pop : {}
-
- path = File.expand_path(path, destination_root)
- say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
-
- unless options[:pretend]
- content = File.binread(path)
- content.gsub!(flag, *args, &block)
- File.open(path, "wb") { |file| file.write(content) }
- end
- end
-
- # Uncomment all lines matching a given regex. It will leave the space
- # which existed before the comment hash in tact but will remove any spacing
- # between the comment hash and the beginning of the line.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # flag<Regexp|String>:: the regexp or string used to decide which lines to uncomment
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Example
- #
- # uncomment_lines 'config/initializers/session_store.rb', /active_record/
- #
- def uncomment_lines(path, flag, *args)
- flag = flag.respond_to?(:source) ? flag.source : flag
-
- gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args)
- end
-
- # Comment all lines matching a given regex. It will leave the space
- # which existed before the beginning of the line in tact and will insert
- # a single space after the comment hash.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # flag<Regexp|String>:: the regexp or string used to decide which lines to comment
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Example
- #
- # comment_lines 'config/initializers/session_store.rb', /cookie_store/
- #
- def comment_lines(path, flag, *args)
- flag = flag.respond_to?(:source) ? flag.source : flag
-
- gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
- end
-
- # Removes a file at the given location.
- #
- # ==== Parameters
- # path<String>:: path of the file to be changed
- # config<Hash>:: give :verbose => false to not log the status.
- #
- # ==== Example
- #
- # remove_file 'README'
- # remove_file 'app/controllers/application_controller.rb'
- #
- def remove_file(path, config = {})
- return unless behavior == :invoke
- path = File.expand_path(path, destination_root)
-
- say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
- if !options[:pretend] && File.exist?(path)
- require "fileutils"
- ::FileUtils.rm_rf(path)
- end
- end
- alias_method :remove_dir, :remove_file
-
- attr_accessor :output_buffer
- private :output_buffer, :output_buffer=
-
- private
-
- def concat(string)
- @output_buffer.concat(string)
- end
-
- def capture(*args)
- with_output_buffer { yield(*args) }
- end
-
- def with_output_buffer(buf = "".dup) #:nodoc:
- raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen?
- old_buffer = output_buffer
- self.output_buffer = buf
- yield
- output_buffer
- ensure
- self.output_buffer = old_buffer
- end
-
- # Bundler::Thor::Actions#capture depends on what kind of buffer is used in ERB.
- # Thus CapturableERB fixes ERB to use String buffer.
- class CapturableERB < ERB
- def set_eoutvar(compiler, eoutvar = "_erbout")
- compiler.put_cmd = "#{eoutvar}.concat"
- compiler.insert_cmd = "#{eoutvar}.concat"
- compiler.pre_cmd = ["#{eoutvar} = ''.dup"]
- compiler.post_cmd = [eoutvar]
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
deleted file mode 100644
index 349b26ff65..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
-
-class Bundler::Thor
- module Actions
- # Injects the given content into a file. Different from gsub_file, this
- # method is reversible.
- #
- # ==== Parameters
- # destination<String>:: Relative path to the destination root
- # data<String>:: Data to add to the file. Can be given as a block.
- # config<Hash>:: give :verbose => false to not log the status and the flag
- # for injection (:after or :before) or :force => true for
- # insert two or more times the same content.
- #
- # ==== Examples
- #
- # insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
- #
- # insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
- # gems = ask "Which gems would you like to add?"
- # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
- # end
- #
- def insert_into_file(destination, *args, &block)
- data = block_given? ? block : args.shift
- config = args.shift
- action InjectIntoFile.new(self, destination, data, config)
- end
- alias_method :inject_into_file, :insert_into_file
-
- class InjectIntoFile < EmptyDirectory #:nodoc:
- attr_reader :replacement, :flag, :behavior
-
- def initialize(base, destination, data, config)
- super(base, destination, {:verbose => true}.merge(config))
-
- @behavior, @flag = if @config.key?(:after)
- [:after, @config.delete(:after)]
- else
- [:before, @config.delete(:before)]
- end
-
- @replacement = data.is_a?(Proc) ? data.call : data
- @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
- end
-
- def invoke!
- say_status :invoke
-
- content = if @behavior == :after
- '\0' + replacement
- else
- replacement + '\0'
- end
-
- if exists?
- replace!(/#{flag}/, content, config[:force])
- else
- unless pretend?
- raise Bundler::Thor::Error, "The file #{ destination } does not appear to exist"
- end
- end
- end
-
- def revoke!
- say_status :revoke
-
- regexp = if @behavior == :after
- content = '\1\2'
- /(#{flag})(.*)(#{Regexp.escape(replacement)})/m
- else
- content = '\2\3'
- /(#{Regexp.escape(replacement)})(.*)(#{flag})/m
- end
-
- replace!(regexp, content, true)
- end
-
- protected
-
- def say_status(behavior)
- status = if behavior == :invoke
- if flag == /\A/
- :prepend
- elsif flag == /\z/
- :append
- else
- :insert
- end
- else
- :subtract
- end
-
- super(status, config[:verbose])
- end
-
- # Adds the content to the file.
- #
- def replace!(regexp, string, force)
- return if pretend?
- content = File.read(destination)
- if force || !content.include?(replacement)
- content.gsub!(regexp, string)
- File.open(destination, "wb") { |file| file.write(content) }
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/base.rb b/lib/bundler/vendor/thor/lib/thor/base.rb
deleted file mode 100644
index 9bd1077170..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/base.rb
+++ /dev/null
@@ -1,679 +0,0 @@
-require "bundler/vendor/thor/lib/thor/command"
-require "bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access"
-require "bundler/vendor/thor/lib/thor/core_ext/ordered_hash"
-require "bundler/vendor/thor/lib/thor/error"
-require "bundler/vendor/thor/lib/thor/invocation"
-require "bundler/vendor/thor/lib/thor/parser"
-require "bundler/vendor/thor/lib/thor/shell"
-require "bundler/vendor/thor/lib/thor/line_editor"
-require "bundler/vendor/thor/lib/thor/util"
-
-class Bundler::Thor
- autoload :Actions, "bundler/vendor/thor/lib/thor/actions"
- autoload :RakeCompat, "bundler/vendor/thor/lib/thor/rake_compat"
- autoload :Group, "bundler/vendor/thor/lib/thor/group"
-
- # Shortcuts for help.
- HELP_MAPPINGS = %w(-h -? --help -D)
-
- # Bundler::Thor methods that should not be overwritten by the user.
- THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root
- action add_file create_file in_root inside run run_ruby_script)
-
- TEMPLATE_EXTNAME = ".tt"
-
- module Base
- attr_accessor :options, :parent_options, :args
-
- # It receives arguments in an Array and two hashes, one for options and
- # other for configuration.
- #
- # Notice that it does not check if all required arguments were supplied.
- # It should be done by the parser.
- #
- # ==== Parameters
- # args<Array[Object]>:: An array of objects. The objects are applied to their
- # respective accessors declared with <tt>argument</tt>.
- #
- # options<Hash>:: An options hash that will be available as self.options.
- # The hash given is converted to a hash with indifferent
- # access, magic predicates (options.skip?) and then frozen.
- #
- # config<Hash>:: Configuration for this Bundler::Thor class.
- #
- def initialize(args = [], local_options = {}, config = {})
- parse_options = self.class.class_options
-
- # The start method splits inbound arguments at the first argument
- # that looks like an option (starts with - or --). It then calls
- # new, passing in the two halves of the arguments Array as the
- # first two parameters.
-
- command_options = config.delete(:command_options) # hook for start
- parse_options = parse_options.merge(command_options) if command_options
- if local_options.is_a?(Array)
- array_options = local_options
- hash_options = {}
- else
- # Handle the case where the class was explicitly instantiated
- # with pre-parsed options.
- array_options = []
- hash_options = local_options
- end
-
- # Let Bundler::Thor::Options parse the options first, so it can remove
- # declared options from the array. This will leave us with
- # a list of arguments that weren't declared.
- stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
- disable_required_check = self.class.disable_required_check? config[:current_command]
- opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check)
- self.options = opts.parse(array_options)
- self.options = config[:class_options].merge(options) if config[:class_options]
-
- # If unknown options are disallowed, make sure that none of the
- # remaining arguments looks like an option.
- opts.check_unknown! if self.class.check_unknown_options?(config)
-
- # Add the remaining arguments from the options parser to the
- # arguments passed in to initialize. Then remove any positional
- # arguments declared using #argument (this is primarily used
- # by Bundler::Thor::Group). Tis will leave us with the remaining
- # positional arguments.
- to_parse = args
- to_parse += opts.remaining unless self.class.strict_args_position?(config)
-
- thor_args = Bundler::Thor::Arguments.new(self.class.arguments)
- thor_args.parse(to_parse).each { |k, v| __send__("#{k}=", v) }
- @args = thor_args.remaining
- end
-
- class << self
- def included(base) #:nodoc:
- base.extend ClassMethods
- base.send :include, Invocation
- base.send :include, Shell
- end
-
- # Returns the classes that inherits from Bundler::Thor or Bundler::Thor::Group.
- #
- # ==== Returns
- # Array[Class]
- #
- def subclasses
- @subclasses ||= []
- end
-
- # Returns the files where the subclasses are kept.
- #
- # ==== Returns
- # Hash[path<String> => Class]
- #
- def subclass_files
- @subclass_files ||= Hash.new { |h, k| h[k] = [] }
- 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.
- #
- def register_klass_file(klass) #:nodoc:
- file = caller[1].match(/(.*):\d+/)[1]
- Bundler::Thor::Base.subclasses << klass unless Bundler::Thor::Base.subclasses.include?(klass)
-
- file_subclasses = Bundler::Thor::Base.subclass_files[File.expand_path(file)]
- file_subclasses << klass unless file_subclasses.include?(klass)
- end
- end
-
- module ClassMethods
- def attr_reader(*) #:nodoc:
- no_commands { super }
- end
-
- def attr_writer(*) #:nodoc:
- no_commands { super }
- end
-
- def attr_accessor(*) #:nodoc:
- no_commands { super }
- end
-
- # If you want to raise an error for unknown options, call check_unknown_options!
- # This is disabled by default to allow dynamic invocations.
- def check_unknown_options!
- @check_unknown_options = true
- end
-
- def check_unknown_options #:nodoc:
- @check_unknown_options ||= from_superclass(:check_unknown_options, false)
- end
-
- def check_unknown_options?(config) #:nodoc:
- !!check_unknown_options
- end
-
- # If you want to raise an error when the default value of an option does not match
- # the type call check_default_type!
- # This is disabled by default for compatibility.
- def check_default_type!
- @check_default_type = true
- end
-
- def check_default_type #:nodoc:
- @check_default_type ||= from_superclass(:check_default_type, false)
- end
-
- def check_default_type? #:nodoc:
- !!check_default_type
- end
-
- # If true, option parsing is suspended as soon as an unknown option or a
- # regular argument is encountered. All remaining arguments are passed to
- # the command as regular arguments.
- def stop_on_unknown_option?(command_name) #:nodoc:
- false
- end
-
- # If true, option set will not suspend the execution of the command when
- # a required option is not provided.
- def disable_required_check?(command_name) #:nodoc:
- false
- end
-
- # If you want only strict string args (useful when cascading thor classes),
- # call strict_args_position! This is disabled by default to allow dynamic
- # invocations.
- def strict_args_position!
- @strict_args_position = true
- end
-
- def strict_args_position #:nodoc:
- @strict_args_position ||= from_superclass(:strict_args_position, false)
- end
-
- def strict_args_position?(config) #:nodoc:
- !!strict_args_position
- end
-
- # Adds an argument to the class and creates an attr_accessor for it.
- #
- # Arguments are different from options in several aspects. The first one
- # is how they are parsed from the command line, arguments are retrieved
- # from position:
- #
- # thor command NAME
- #
- # Instead of:
- #
- # thor command --name=NAME
- #
- # Besides, arguments are used inside your code as an accessor (self.argument),
- # while options are all kept in a hash (self.options).
- #
- # Finally, arguments cannot have type :default or :boolean but can be
- # optional (supplying :optional => :true or :required => false), although
- # you cannot have a required argument after a non-required argument. If you
- # try it, an error is raised.
- #
- # ==== Parameters
- # name<Symbol>:: The name of the argument.
- # options<Hash>:: Described below.
- #
- # ==== Options
- # :desc - Description for the argument.
- # :required - If the argument is required or not.
- # :optional - If the argument is optional or not.
- # :type - The type of the argument, can be :string, :hash, :array, :numeric.
- # :default - Default value for this argument. It cannot be required and have default values.
- # :banner - String to show on usage notes.
- #
- # ==== Errors
- # ArgumentError:: Raised if you supply a required argument after a non required one.
- #
- def argument(name, options = {})
- is_thor_reserved_word?(name, :argument)
- no_commands { attr_accessor name }
-
- required = if options.key?(:optional)
- !options[:optional]
- elsif options.key?(:required)
- options[:required]
- else
- options[:default].nil?
- end
-
- remove_argument name
-
- if required
- arguments.each do |argument|
- next if argument.required?
- raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " \
- "the non-required argument #{argument.human_name.inspect}."
- end
- end
-
- options[:required] = required
-
- arguments << Bundler::Thor::Argument.new(name, options)
- end
-
- # Returns this class arguments, looking up in the ancestors chain.
- #
- # ==== Returns
- # Array[Bundler::Thor::Argument]
- #
- def arguments
- @arguments ||= from_superclass(:arguments, [])
- end
-
- # Adds a bunch of options to the set of class options.
- #
- # class_options :foo => false, :bar => :required, :baz => :string
- #
- # If you prefer more detailed declaration, check class_option.
- #
- # ==== Parameters
- # Hash[Symbol => Object]
- #
- def class_options(options = nil)
- @class_options ||= from_superclass(:class_options, {})
- build_options(options, @class_options) if options
- @class_options
- end
-
- # Adds an option to the set of class options
- #
- # ==== Parameters
- # name<Symbol>:: The name of the argument.
- # options<Hash>:: Described below.
- #
- # ==== Options
- # :desc:: -- Description for the argument.
- # :required:: -- If the argument is required or not.
- # :default:: -- Default value for this argument.
- # :group:: -- The group for this options. Use by class options to output options in different levels.
- # :aliases:: -- Aliases for this option. <b>Note:</b> Bundler::Thor follows a convention of one-dash-one-letter options. Thus aliases like "-something" wouldn't be parsed; use either "\--something" or "-s" instead.
- # :type:: -- The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
- # :banner:: -- String to show on usage notes.
- # :hide:: -- If you want to hide this option from the help.
- #
- def class_option(name, options = {})
- build_option(name, options, class_options)
- end
-
- # Removes a previous defined argument. If :undefine is given, undefine
- # accessors as well.
- #
- # ==== Parameters
- # names<Array>:: Arguments to be removed
- #
- # ==== Examples
- #
- # remove_argument :foo
- # remove_argument :foo, :bar, :baz, :undefine => true
- #
- def remove_argument(*names)
- options = names.last.is_a?(Hash) ? names.pop : {}
-
- names.each do |name|
- arguments.delete_if { |a| a.name == name.to_s }
- undef_method name, "#{name}=" if options[:undefine]
- end
- end
-
- # Removes a previous defined class option.
- #
- # ==== Parameters
- # names<Array>:: Class options to be removed
- #
- # ==== Examples
- #
- # remove_class_option :foo
- # remove_class_option :foo, :bar, :baz
- #
- def remove_class_option(*names)
- names.each do |name|
- class_options.delete(name)
- end
- end
-
- # Defines the group. This is used when thor list is invoked so you can specify
- # that only commands from a pre-defined group will be shown. Defaults to standard.
- #
- # ==== Parameters
- # name<String|Symbol>
- #
- def group(name = nil)
- if name
- @group = name.to_s
- else
- @group ||= from_superclass(:group, "standard")
- end
- end
-
- # Returns the commands for this Bundler::Thor class.
- #
- # ==== Returns
- # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
- # objects as values.
- #
- def commands
- @commands ||= Bundler::Thor::CoreExt::OrderedHash.new
- end
- alias_method :tasks, :commands
-
- # Returns the commands for this Bundler::Thor class and all subclasses.
- #
- # ==== Returns
- # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
- # objects as values.
- #
- def all_commands
- @all_commands ||= from_superclass(:all_commands, Bundler::Thor::CoreExt::OrderedHash.new)
- @all_commands.merge!(commands)
- end
- alias_method :all_tasks, :all_commands
-
- # Removes a given command from this Bundler::Thor class. This is usually done if you
- # are inheriting from another class and don't want it to be available
- # anymore.
- #
- # By default it only remove the mapping to the command. But you can supply
- # :undefine => true to undefine the method from the class as well.
- #
- # ==== Parameters
- # name<Symbol|String>:: The name of the command to be removed
- # options<Hash>:: You can give :undefine => true if you want commands the method
- # to be undefined from the class as well.
- #
- def remove_command(*names)
- options = names.last.is_a?(Hash) ? names.pop : {}
-
- names.each do |name|
- commands.delete(name.to_s)
- all_commands.delete(name.to_s)
- undef_method name if options[:undefine]
- end
- end
- alias_method :remove_task, :remove_command
-
- # All methods defined inside the given block are not added as commands.
- #
- # So you can do:
- #
- # class MyScript < Bundler::Thor
- # no_commands do
- # def this_is_not_a_command
- # end
- # end
- # end
- #
- # You can also add the method and remove it from the command list:
- #
- # class MyScript < Bundler::Thor
- # def this_is_not_a_command
- # end
- # remove_command :this_is_not_a_command
- # end
- #
- def no_commands
- @no_commands = true
- yield
- ensure
- @no_commands = false
- end
- alias_method :no_tasks, :no_commands
-
- # Sets the namespace for the Bundler::Thor or Bundler::Thor::Group class. By default the
- # namespace is retrieved from the class name. If your Bundler::Thor class is named
- # Scripts::MyScript, the help method, for example, will be called as:
- #
- # thor scripts:my_script -h
- #
- # If you change the namespace:
- #
- # namespace :my_scripts
- #
- # You change how your commands are invoked:
- #
- # thor my_scripts -h
- #
- # Finally, if you change your namespace to default:
- #
- # namespace :default
- #
- # Your commands can be invoked with a shortcut. Instead of:
- #
- # thor :my_command
- #
- def namespace(name = nil)
- if name
- @namespace = name.to_s
- else
- @namespace ||= Bundler::Thor::Util.namespace_from_thor_class(self)
- end
- end
-
- # Parses the command and options from the given args, instantiate the class
- # and invoke the command. This method is used when the arguments must be parsed
- # from an array. If you are inside Ruby and want to use a Bundler::Thor class, you
- # can simply initialize it:
- #
- # script = MyScript.new(args, options, config)
- # script.invoke(:command, first_arg, second_arg, third_arg)
- #
- def start(given_args = ARGV, config = {})
- config[:shell] ||= Bundler::Thor::Base.shell.new
- 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?
- 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)
- end
-
- # Allows to use private methods from parent in child classes as commands.
- #
- # ==== Parameters
- # names<Array>:: Method names to be used as commands
- #
- # ==== Examples
- #
- # public_command :foo
- # public_command :foo, :bar, :baz
- #
- def public_command(*names)
- names.each do |name|
- class_eval "def #{name}(*); super end"
- end
- end
- 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}."
- end
- alias_method :handle_no_task_error, :handle_no_command_error
-
- def handle_argument_error(command, error, args, arity) #:nodoc:
- name = [command.ancestor_name, command.name].compact.join(" ")
- msg = "ERROR: \"#{basename} #{name}\" was called with ".dup
- msg << "no arguments" if args.empty?
- msg << "arguments " << args.inspect unless args.empty?
- msg << "\nUsage: #{banner(command).inspect}"
- raise InvocationError, msg
- end
-
- protected
-
- # Prints the class options per group. If an option does not belong to
- # any group, it's printed as Class option.
- #
- def class_options_help(shell, groups = {}) #:nodoc:
- # Group options by group
- class_options.each do |_, value|
- groups[value.group] ||= []
- groups[value.group] << value
- end
-
- # Deal with default group
- global_options = groups.delete(nil) || []
- print_options(shell, global_options)
-
- # Print all others
- groups.each do |group_name, options|
- print_options(shell, options, group_name)
- end
- end
-
- # Receives a set of options and print them.
- def print_options(shell, options, group_name = nil)
- return if options.empty?
-
- list = []
- padding = options.map { |o| o.aliases.size }.max.to_i * 4
-
- options.each do |option|
- next if option.hide
- item = [option.usage(padding)]
- item.push(option.description ? "# #{option.description}" : "")
-
- list << item
- list << ["", "# Default: #{option.default}"] if option.show_default?
- list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum
- end
-
- shell.say(group_name ? "#{group_name} options:" : "Options:")
- shell.print_table(list, :indent => 2)
- shell.say ""
- end
-
- # Raises an error if the word given is a Bundler::Thor reserved word.
- def is_thor_reserved_word?(word, type) #:nodoc:
- return false unless THOR_RESERVED_WORDS.include?(word.to_s)
- raise "#{word.inspect} is a Bundler::Thor reserved word and cannot be defined as #{type}"
- end
-
- # Build an option and adds it to the given scope.
- #
- # ==== Parameters
- # name<Symbol>:: The name of the argument.
- # options<Hash>:: Described in both class_option and method_option.
- # scope<Hash>:: Options hash that is being built up
- def build_option(name, options, scope) #:nodoc:
- scope[name] = Bundler::Thor::Option.new(name, options.merge(:check_default_type => check_default_type?))
- end
-
- # Receives a hash of options, parse them and add to the scope. This is a
- # fast way to set a bunch of options:
- #
- # build_options :foo => true, :bar => :required, :baz => :string
- #
- # ==== Parameters
- # Hash[Symbol => Object]
- def build_options(options, scope) #:nodoc:
- options.each do |key, value|
- scope[key] = Bundler::Thor::Option.parse(key, value)
- end
- end
-
- # Finds a command with the given name. If the command belongs to the current
- # class, just return it, otherwise dup it and add the fresh copy to the
- # current command hash.
- def find_and_refresh_command(name) #:nodoc:
- if commands[name.to_s]
- commands[name.to_s]
- elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition
- commands[name.to_s] = command.clone
- else
- raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
- end
- end
- alias_method :find_and_refresh_task, :find_and_refresh_command
-
- # Everytime someone inherits from a Bundler::Thor class, register the klass
- # and file into baseclass.
- def inherited(klass)
- Bundler::Thor::Base.register_klass_file(klass)
- klass.instance_variable_set(:@no_commands, false)
- end
-
- # Fire this callback whenever a method is added. Added methods are
- # tracked as commands by invoking the create_command method.
- def method_added(meth)
- meth = meth.to_s
-
- if meth == "initialize"
- initialize_added
- return
- end
-
- # Return if it's not a public instance method
- return unless public_method_defined?(meth.to_sym)
-
- @no_commands ||= false
- return if @no_commands || !create_command(meth)
-
- is_thor_reserved_word?(meth, :command)
- Bundler::Thor::Base.register_klass_file(self)
- end
-
- # Retrieves a value from superclass. If it reaches the baseclass,
- # returns default.
- def from_superclass(method, default = nil)
- if self == baseclass || !superclass.respond_to?(method, true)
- default
- else
- value = superclass.send(method)
-
- # Ruby implements `dup` on Object, but raises a `TypeError`
- # if the method is called on immediates. As a result, we
- # don't have a good way to check whether dup will succeed
- # without calling it and rescuing the TypeError.
- begin
- value.dup
- rescue TypeError
- value
- end
-
- end
- end
-
- # A flag that makes the process exit with status 1 if any error happens.
- def exit_on_failure?
- false
- end
-
- #
- # The basename of the program invoking the thor class.
- #
- def basename
- File.basename($PROGRAM_NAME).split(" ").first
- end
-
- # SIGNATURE: Sets the baseclass. This is where the superclass lookup
- # finishes.
- def baseclass #:nodoc:
- end
-
- # SIGNATURE: Creates a new command if valid_command? is true. This method is
- # called when a new method is added to the class.
- def create_command(meth) #:nodoc:
- end
- alias_method :create_task, :create_command
-
- # SIGNATURE: Defines behavior when the initialize method is added to the
- # class.
- def initialize_added #:nodoc:
- end
-
- # SIGNATURE: The hook invoked by start.
- def dispatch(command, given_args, given_opts, config) #:nodoc:
- raise NotImplementedError
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/command.rb b/lib/bundler/vendor/thor/lib/thor/command.rb
deleted file mode 100644
index c636948e5d..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/command.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-class Bundler::Thor
- class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
- FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
-
- def initialize(name, description, long_description, usage, options = nil)
- super(name.to_s, description, long_description, usage, options || {})
- end
-
- def initialize_copy(other) #:nodoc:
- super(other)
- self.options = other.options.dup if other.options
- end
-
- def hidden?
- false
- end
-
- # By default, a command invokes a method in the thor class. You can change this
- # implementation to create custom commands.
- def run(instance, args = [])
- arity = nil
-
- if private_method?(instance)
- instance.class.handle_no_command_error(name)
- elsif public_method?(instance)
- arity = instance.method(name).arity
- instance.__send__(name, *args)
- elsif local_method?(instance, :method_missing)
- instance.__send__(:method_missing, name.to_sym, *args)
- else
- instance.class.handle_no_command_error(name)
- end
- rescue ArgumentError => e
- handle_argument_error?(instance, e, caller) ? instance.class.handle_argument_error(self, e, args, arity) : (raise e)
- rescue NoMethodError => e
- handle_no_method_error?(instance, e, caller) ? instance.class.handle_no_command_error(name) : (raise e)
- end
-
- # Returns the formatted usage by injecting given required arguments
- # and required options into the given usage.
- def formatted_usage(klass, namespace = true, subcommand = false)
- if ancestor_name
- formatted = "#{ancestor_name} ".dup # add space
- elsif namespace
- namespace = klass.namespace
- formatted = "#{namespace.gsub(/^(default)/, '')}:".dup
- end
- formatted ||= "#{klass.namespace.split(':').last} ".dup if subcommand
-
- formatted ||= "".dup
-
- # Add usage with required arguments
- formatted << if klass && !klass.arguments.empty?
- usage.to_s.gsub(/^#{name}/) do |match|
- match << " " << klass.arguments.map(&:usage).compact.join(" ")
- end
- else
- usage.to_s
- end
-
- # Add required options
- formatted << " #{required_options}"
-
- # Strip and go!
- formatted.strip
- end
-
- protected
-
- def not_debugging?(instance)
- !(instance.class.respond_to?(:debugging) && instance.class.debugging)
- end
-
- def required_options
- @required_options ||= options.map { |_, o| o.usage if o.required? }.compact.sort.join(" ")
- end
-
- # Given a target, checks if this class name is a public method.
- def public_method?(instance) #:nodoc:
- !(instance.public_methods & [name.to_s, name.to_sym]).empty?
- end
-
- def private_method?(instance)
- !(instance.private_methods & [name.to_s, name.to_sym]).empty?
- end
-
- def local_method?(instance, name)
- methods = instance.public_methods(false) + instance.private_methods(false) + instance.protected_methods(false)
- !(methods & [name.to_s, name.to_sym]).empty?
- end
-
- def sans_backtrace(backtrace, caller) #:nodoc:
- saned = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) || (frame =~ %r{^kernel/} && RUBY_ENGINE =~ /rbx/) }
- saned - caller
- end
-
- def handle_argument_error?(instance, error, caller)
- not_debugging?(instance) && (error.message =~ /wrong number of arguments/ || error.message =~ /given \d*, expected \d*/) && begin
- saned = sans_backtrace(error.backtrace, caller)
- # Ruby 1.9 always include the called method in the backtrace
- saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9")
- end
- end
-
- def handle_no_method_error?(instance, error, caller)
- not_debugging?(instance) &&
- error.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/
- end
- end
- Task = Command
-
- # A command that is hidden in help messages but still invocable.
- class HiddenCommand < Command
- def hidden?
- true
- end
- end
- HiddenTask = HiddenCommand
-
- # A dynamic command that handles method missing scenarios.
- class DynamicCommand < Command
- def initialize(name, options = nil)
- super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options)
- end
-
- def run(instance, args = [])
- if (instance.methods & [name.to_s, name.to_sym]).empty?
- super
- else
- instance.class.handle_no_command_error(name)
- end
- end
- end
- DynamicTask = DynamicCommand
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb
deleted file mode 100644
index c167aa33b8..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-class Bundler::Thor
- module CoreExt #:nodoc:
- # A hash with indifferent access and magic predicates.
- #
- # hash = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true
- #
- # hash[:foo] #=> 'bar'
- # hash['foo'] #=> 'bar'
- # hash.foo? #=> true
- #
- class HashWithIndifferentAccess < ::Hash #:nodoc:
- def initialize(hash = {})
- super()
- hash.each do |key, value|
- self[convert_key(key)] = value
- end
- end
-
- def [](key)
- super(convert_key(key))
- end
-
- def []=(key, value)
- super(convert_key(key), value)
- end
-
- def delete(key)
- super(convert_key(key))
- end
-
- def fetch(key, *args)
- super(convert_key(key), *args)
- end
-
- def key?(key)
- super(convert_key(key))
- end
-
- def values_at(*indices)
- indices.map { |key| self[convert_key(key)] }
- end
-
- def merge(other)
- dup.merge!(other)
- end
-
- def merge!(other)
- other.each do |key, value|
- self[convert_key(key)] = value
- end
- self
- end
-
- def reverse_merge(other)
- self.class.new(other).merge(self)
- end
-
- def reverse_merge!(other_hash)
- replace(reverse_merge(other_hash))
- end
-
- def replace(other_hash)
- super(other_hash)
- end
-
- # Convert to a Hash with String keys.
- def to_hash
- Hash.new(default).merge!(self)
- end
-
- protected
-
- def convert_key(key)
- key.is_a?(Symbol) ? key.to_s : key
- end
-
- # Magic predicates. For instance:
- #
- # options.force? # => !!options['force']
- # options.shebang # => "/usr/lib/local/ruby"
- # options.test_framework?(:rspec) # => options[:test_framework] == :rspec
- #
- def method_missing(method, *args)
- method = method.to_s
- if method =~ /^(\w+)\?$/
- if args.empty?
- !!self[$1]
- else
- self[$1] == args.first
- end
- else
- self[method]
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb
deleted file mode 100644
index 0f6e2e0af2..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class IO #:nodoc:
- class << self
- unless method_defined? :binread
- def binread(file, *args)
- raise ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3
- File.open(file, "rb") do |f|
- f.read(*args)
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb
deleted file mode 100644
index 76f1e43c65..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-class Bundler::Thor
- module CoreExt
- class OrderedHash < ::Hash
- if RUBY_VERSION < "1.9"
- def initialize(*args, &block)
- super
- @keys = []
- end
-
- def initialize_copy(other)
- super
- # make a deep copy of keys
- @keys = other.keys
- end
-
- def []=(key, value)
- @keys << key unless key?(key)
- super
- end
-
- def delete(key)
- if key? key
- index = @keys.index(key)
- @keys.delete_at index
- end
- super
- end
-
- def delete_if
- super
- sync_keys!
- self
- end
-
- alias_method :reject!, :delete_if
-
- def reject(&block)
- dup.reject!(&block)
- end
-
- def keys
- @keys.dup
- end
-
- def values
- @keys.map { |key| self[key] }
- end
-
- def to_hash
- self
- end
-
- def to_a
- @keys.map { |key| [key, self[key]] }
- end
-
- def each_key
- return to_enum(:each_key) unless block_given?
- @keys.each { |key| yield(key) }
- self
- end
-
- def each_value
- return to_enum(:each_value) unless block_given?
- @keys.each { |key| yield(self[key]) }
- self
- end
-
- def each
- return to_enum(:each) unless block_given?
- @keys.each { |key| yield([key, self[key]]) }
- self
- end
-
- def each_pair
- return to_enum(:each_pair) unless block_given?
- @keys.each { |key| yield(key, self[key]) }
- self
- end
-
- alias_method :select, :find_all
-
- def clear
- super
- @keys.clear
- self
- end
-
- def shift
- k = @keys.first
- v = delete(k)
- [k, v]
- end
-
- def merge!(other_hash)
- if block_given?
- other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
- else
- other_hash.each { |k, v| self[k] = v }
- end
- self
- end
-
- alias_method :update, :merge!
-
- def merge(other_hash, &block)
- dup.merge!(other_hash, &block)
- end
-
- # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
- def replace(other)
- super
- @keys = other.keys
- self
- end
-
- def inspect
- "#<#{self.class} #{super}>"
- end
-
- private
-
- def sync_keys!
- @keys.delete_if { |k| !key?(k) }
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/error.rb b/lib/bundler/vendor/thor/lib/thor/error.rb
deleted file mode 100644
index 2f816081f3..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/error.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-class Bundler::Thor
- # 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.
- #
- # Errors that are caused by the developer, like declaring a method which
- # overwrites a thor keyword, SHOULD NOT raise a Bundler::Thor::Error. This way, we
- # ensure that developer errors are shown with full backtrace.
- class Error < StandardError
- end
-
- # Raised when a command was not found.
- class UndefinedCommandError < Error
- end
- UndefinedTaskError = UndefinedCommandError
-
- class AmbiguousCommandError < Error
- end
- AmbiguousTaskError = AmbiguousCommandError
-
- # Raised when a command was found, but not invoked properly.
- class InvocationError < Error
- end
-
- class UnknownArgumentError < Error
- end
-
- class RequiredArgumentMissingError < InvocationError
- end
-
- class MalformattedArgumentError < InvocationError
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/group.rb b/lib/bundler/vendor/thor/lib/thor/group.rb
deleted file mode 100644
index 05ddc10cd3..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/group.rb
+++ /dev/null
@@ -1,281 +0,0 @@
-require "bundler/vendor/thor/lib/thor/base"
-
-# Bundler::Thor has a special class called Bundler::Thor::Group. The main difference to Bundler::Thor class
-# is that it invokes all commands at once. It also include some methods that allows
-# invocations to be done at the class method, which are not available to Bundler::Thor
-# commands.
-class Bundler::Thor::Group
- class << self
- # The description for this Bundler::Thor::Group. If none is provided, but a source root
- # exists, tries to find the USAGE one folder above it, otherwise searches
- # in the superclass.
- #
- # ==== Parameters
- # description<String>:: The description for this Bundler::Thor::Group.
- #
- def desc(description = nil)
- if description
- @desc = description
- else
- @desc ||= from_superclass(:desc, nil)
- end
- end
-
- # Prints help information.
- #
- # ==== Options
- # short:: When true, shows only usage.
- #
- def help(shell)
- shell.say "Usage:"
- shell.say " #{banner}\n"
- shell.say
- class_options_help(shell)
- shell.say desc if desc
- end
-
- # Stores invocations for this class merging with superclass values.
- #
- def invocations #:nodoc:
- @invocations ||= from_superclass(:invocations, {})
- end
-
- # Stores invocation blocks used on invoke_from_option.
- #
- def invocation_blocks #:nodoc:
- @invocation_blocks ||= from_superclass(:invocation_blocks, {})
- end
-
- # Invoke the given namespace or class given. It adds an instance
- # method that will invoke the klass and command. You can give a block to
- # configure how it will be invoked.
- #
- # The namespace/class given will have its options showed on the help
- # usage. Check invoke_from_option for more information.
- #
- def invoke(*names, &block)
- options = names.last.is_a?(Hash) ? names.pop : {}
- verbose = options.fetch(:verbose, true)
-
- names.each do |name|
- invocations[name] = false
- invocation_blocks[name] = block if block_given?
-
- class_eval <<-METHOD, __FILE__, __LINE__
- def _invoke_#{name.to_s.gsub(/\W/, '_')}
- klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
-
- if klass
- say_status :invoke, #{name.inspect}, #{verbose.inspect}
- block = self.class.invocation_blocks[#{name.inspect}]
- _invoke_for_class_method klass, command, &block
- else
- say_status :error, %(#{name.inspect} [not found]), :red
- end
- end
- METHOD
- end
- end
-
- # Invoke a thor class based on the value supplied by the user to the
- # given option named "name". A class option must be created before this
- # method is invoked for each name given.
- #
- # ==== Examples
- #
- # class GemGenerator < Bundler::Thor::Group
- # class_option :test_framework, :type => :string
- # invoke_from_option :test_framework
- # end
- #
- # ==== Boolean options
- #
- # In some cases, you want to invoke a thor class if some option is true or
- # false. This is automatically handled by invoke_from_option. Then the
- # option name is used to invoke the generator.
- #
- # ==== Preparing for invocation
- #
- # In some cases you want to customize how a specified hook is going to be
- # invoked. You can do that by overwriting the class method
- # prepare_for_invocation. The class method must necessarily return a klass
- # and an optional command.
- #
- # ==== Custom invocations
- #
- # You can also supply a block to customize how the option is going to be
- # invoked. The block receives two parameters, an instance of the current
- # class and the klass to be invoked.
- #
- def invoke_from_option(*names, &block)
- options = names.last.is_a?(Hash) ? names.pop : {}
- verbose = options.fetch(:verbose, :white)
-
- names.each do |name|
- unless class_options.key?(name)
- raise ArgumentError, "You have to define the option #{name.inspect} " \
- "before setting invoke_from_option."
- end
-
- invocations[name] = true
- invocation_blocks[name] = block if block_given?
-
- class_eval <<-METHOD, __FILE__, __LINE__
- def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
- return unless options[#{name.inspect}]
-
- value = options[#{name.inspect}]
- value = #{name.inspect} if TrueClass === value
- klass, command = self.class.prepare_for_invocation(#{name.inspect}, value)
-
- if klass
- say_status :invoke, value, #{verbose.inspect}
- block = self.class.invocation_blocks[#{name.inspect}]
- _invoke_for_class_method klass, command, &block
- else
- say_status :error, %(\#{value} [not found]), :red
- end
- end
- METHOD
- end
- end
-
- # Remove a previously added invocation.
- #
- # ==== Examples
- #
- # remove_invocation :test_framework
- #
- def remove_invocation(*names)
- names.each do |name|
- remove_command(name)
- remove_class_option(name)
- invocations.delete(name)
- invocation_blocks.delete(name)
- end
- end
-
- # Overwrite class options help to allow invoked generators options to be
- # shown recursively when invoking a generator.
- #
- def class_options_help(shell, groups = {}) #:nodoc:
- get_options_from_invocations(groups, class_options) do |klass|
- klass.send(:get_options_from_invocations, groups, class_options)
- end
- super(shell, groups)
- end
-
- # Get invocations array and merge options from invocations. Those
- # options are added to group_options hash. Options that already exists
- # in base_options are not added twice.
- #
- def get_options_from_invocations(group_options, base_options) #:nodoc: # rubocop:disable MethodLength
- invocations.each do |name, from_option|
- value = if from_option
- option = class_options[name]
- option.type == :boolean ? name : option.default
- else
- name
- end
- next unless value
-
- klass, _ = prepare_for_invocation(name, value)
- next unless klass && klass.respond_to?(:class_options)
-
- value = value.to_s
- human_name = value.respond_to?(:classify) ? value.classify : value
-
- group_options[human_name] ||= []
- group_options[human_name] += klass.class_options.values.select do |class_option|
- base_options[class_option.name.to_sym].nil? && class_option.group.nil? &&
- !group_options.values.flatten.any? { |i| i.name == class_option.name }
- end
-
- yield klass if block_given?
- end
- end
-
- # Returns commands ready to be printed.
- def printable_commands(*)
- item = []
- item << banner
- item << (desc ? "# #{desc.gsub(/\s+/m, ' ')}" : "")
- [item]
- end
- alias_method :printable_tasks, :printable_commands
-
- def handle_argument_error(command, error, _args, arity) #:nodoc:
- msg = "#{basename} #{command.name} takes #{arity} argument".dup
- msg << "s" if arity > 1
- msg << ", but it should not."
- raise error, msg
- end
-
- protected
-
- # The method responsible for dispatching given the args.
- def dispatch(command, given_args, given_opts, config) #:nodoc:
- if Bundler::Thor::HELP_MAPPINGS.include?(given_args.first)
- help(config[:shell])
- return
- end
-
- args, opts = Bundler::Thor::Options.split(given_args)
- opts = given_opts || opts
-
- instance = new(args, opts, config)
- yield instance if block_given?
-
- if command
- instance.invoke_command(all_commands[command])
- else
- instance.invoke_all
- end
- end
-
- # The banner for this class. You can customize it if you are invoking the
- # thor class by another ways which is not the Bundler::Thor::Runner.
- def banner
- "#{basename} #{self_command.formatted_usage(self, false)}"
- end
-
- # Represents the whole class as a command.
- def self_command #:nodoc:
- Bundler::Thor::DynamicCommand.new(namespace, class_options)
- end
- alias_method :self_task, :self_command
-
- def baseclass #:nodoc:
- Bundler::Thor::Group
- end
-
- def create_command(meth) #:nodoc:
- commands[meth.to_s] = Bundler::Thor::Command.new(meth, nil, nil, nil, nil)
- true
- end
- alias_method :create_task, :create_command
- end
-
- include Bundler::Thor::Base
-
-protected
-
- # Shortcut to invoke with padding and block handling. Use internally by
- # invoke and invoke_from_option class methods.
- def _invoke_for_class_method(klass, command = nil, *args, &block) #:nodoc:
- with_padding do
- if block
- case block.arity
- when 3
- yield(self, klass, command)
- when 2
- yield(self, klass)
- when 1
- instance_exec(klass, &block)
- end
- else
- invoke klass, command, *args
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/invocation.rb b/lib/bundler/vendor/thor/lib/thor/invocation.rb
deleted file mode 100644
index 866d2212a7..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/invocation.rb
+++ /dev/null
@@ -1,177 +0,0 @@
-class Bundler::Thor
- module Invocation
- def self.included(base) #:nodoc:
- base.extend ClassMethods
- end
-
- module ClassMethods
- # This method is responsible for receiving a name and find the proper
- # class and command for it. The key is an optional parameter which is
- # available only in class methods invocations (i.e. in Bundler::Thor::Group).
- def prepare_for_invocation(key, name) #:nodoc:
- case name
- when Symbol, String
- Bundler::Thor::Util.find_class_and_command_by_namespace(name.to_s, !key)
- else
- name
- end
- end
- end
-
- # Make initializer aware of invocations and the initialization args.
- def initialize(args = [], options = {}, config = {}, &block) #:nodoc:
- @_invocations = config[:invocations] || Hash.new { |h, k| h[k] = [] }
- @_initializer = [args, options, config]
- super
- end
-
- # Make the current command chain accessible with in a Bundler::Thor-(sub)command
- def current_command_chain
- @_invocations.values.flatten.map(&:to_sym)
- end
-
- # Receives a name and invokes it. The name can be a string (either "command" or
- # "namespace:command"), a Bundler::Thor::Command, a Class or a Bundler::Thor instance. If the
- # command cannot be guessed by name, it can also be supplied as second argument.
- #
- # You can also supply the arguments, options and configuration values for
- # the command to be invoked, if none is given, the same values used to
- # initialize the invoker are used to initialize the invoked.
- #
- # When no name is given, it will invoke the default command of the current class.
- #
- # ==== Examples
- #
- # class A < Bundler::Thor
- # def foo
- # invoke :bar
- # invoke "b:hello", ["Erik"]
- # end
- #
- # def bar
- # invoke "b:hello", ["Erik"]
- # end
- # end
- #
- # class B < Bundler::Thor
- # def hello(name)
- # puts "hello #{name}"
- # end
- # end
- #
- # You can notice that the method "foo" above invokes two commands: "bar",
- # which belongs to the same class and "hello" which belongs to the class B.
- #
- # By using an invocation system you ensure that a command is invoked only once.
- # In the example above, invoking "foo" will invoke "b:hello" just once, even
- # if it's invoked later by "bar" method.
- #
- # When class A invokes class B, all arguments used on A initialization are
- # supplied to B. This allows lazy parse of options. Let's suppose you have
- # some rspec commands:
- #
- # class Rspec < Bundler::Thor::Group
- # class_option :mock_framework, :type => :string, :default => :rr
- #
- # def invoke_mock_framework
- # invoke "rspec:#{options[:mock_framework]}"
- # end
- # end
- #
- # As you noticed, it invokes the given mock framework, which might have its
- # own options:
- #
- # class Rspec::RR < Bundler::Thor::Group
- # class_option :style, :type => :string, :default => :mock
- # end
- #
- # Since it's not rspec concern to parse mock framework options, when RR
- # is invoked all options are parsed again, so RR can extract only the options
- # that it's going to use.
- #
- # If you want Rspec::RR to be initialized with its own set of options, you
- # have to do that explicitly:
- #
- # invoke "rspec:rr", [], :style => :foo
- #
- # Besides giving an instance, you can also give a class to invoke:
- #
- # invoke Rspec::RR, [], :style => :foo
- #
- def invoke(name = nil, *args)
- if name.nil?
- warn "[Bundler::Thor] Calling invoke() without argument is deprecated. Please use invoke_all instead.\n#{caller.join("\n")}"
- return invoke_all
- end
-
- args.unshift(nil) if args.first.is_a?(Array) || args.first.nil?
- command, args, opts, config = args
-
- klass, command = _retrieve_class_and_command(name, command)
- raise "Missing Bundler::Thor class for invoke #{name}" unless klass
- raise "Expected Bundler::Thor class, got #{klass}" unless klass <= Bundler::Thor::Base
-
- args, opts, config = _parse_initialization_options(args, opts, config)
- klass.send(:dispatch, command, args, opts, config) do |instance|
- instance.parent_options = options
- end
- end
-
- # Invoke the given command if the given args.
- def invoke_command(command, *args) #:nodoc:
- current = @_invocations[self.class]
-
- unless current.include?(command.name)
- current << command.name
- command.run(self, *args)
- end
- end
- alias_method :invoke_task, :invoke_command
-
- # Invoke all commands for the current instance.
- def invoke_all #:nodoc:
- self.class.all_commands.map { |_, command| invoke_command(command) }
- end
-
- # Invokes using shell padding.
- def invoke_with_padding(*args)
- with_padding { invoke(*args) }
- end
-
- protected
-
- # Configuration values that are shared between invocations.
- def _shared_configuration #:nodoc:
- {:invocations => @_invocations}
- end
-
- # This method simply retrieves the class and command to be invoked.
- # If the name is nil or the given name is a command in the current class,
- # use the given name and return self as class. Otherwise, call
- # prepare_for_invocation in the current class.
- def _retrieve_class_and_command(name, sent_command = nil) #:nodoc:
- if name.nil?
- [self.class, nil]
- elsif self.class.all_commands[name.to_s]
- [self.class, name.to_s]
- else
- klass, command = self.class.prepare_for_invocation(nil, name)
- [klass, command || sent_command]
- end
- end
- alias_method :_retrieve_class_and_task, :_retrieve_class_and_command
-
- # Initialize klass using values stored in the @_initializer.
- def _parse_initialization_options(args, opts, config) #:nodoc:
- stored_args, stored_opts, stored_config = @_initializer
-
- args ||= stored_args.dup
- opts ||= stored_opts.dup
-
- config ||= {}
- config = stored_config.merge(_shared_configuration).merge!(config)
-
- [args, opts, config]
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor.rb b/lib/bundler/vendor/thor/lib/thor/line_editor.rb
deleted file mode 100644
index ce81a17484..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/line_editor.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require "bundler/vendor/thor/lib/thor/line_editor/basic"
-require "bundler/vendor/thor/lib/thor/line_editor/readline"
-
-class Bundler::Thor
- module LineEditor
- def self.readline(prompt, options = {})
- best_available.new(prompt, options).readline
- end
-
- def self.best_available
- [
- Bundler::Thor::LineEditor::Readline,
- Bundler::Thor::LineEditor::Basic
- ].detect(&:available?)
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb b/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb
deleted file mode 100644
index 0adb2b3137..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-class Bundler::Thor
- module LineEditor
- class Basic
- attr_reader :prompt, :options
-
- def self.available?
- true
- end
-
- def initialize(prompt, options)
- @prompt = prompt
- @options = options
- end
-
- def readline
- $stdout.print(prompt)
- get_input
- end
-
- private
-
- def get_input
- if echo?
- $stdin.gets
- else
- # Lazy-load io/console since it is gem-ified as of 2.3
- require "io/console" if RUBY_VERSION > "1.9.2"
- $stdin.noecho(&:gets)
- end
- end
-
- def echo?
- options.fetch(:echo, true)
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb b/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb
deleted file mode 100644
index dd39cff35d..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-begin
- require "readline"
-rescue LoadError
-end
-
-class Bundler::Thor
- module LineEditor
- class Readline < Basic
- def self.available?
- Object.const_defined?(:Readline)
- end
-
- def readline
- if echo?
- ::Readline.completion_append_character = nil
- # Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil.
- if complete = completion_proc
- ::Readline.completion_proc = complete
- end
- ::Readline.readline(prompt, add_to_history?)
- else
- super
- end
- end
-
- private
-
- def add_to_history?
- options.fetch(:add_to_history, true)
- end
-
- def completion_proc
- if use_path_completion?
- proc { |text| PathCompletion.new(text).matches }
- elsif completion_options.any?
- proc do |text|
- completion_options.select { |option| option.start_with?(text) }
- end
- end
- end
-
- def completion_options
- options.fetch(:limited_to, [])
- end
-
- def use_path_completion?
- options.fetch(:path, false)
- end
-
- class PathCompletion
- attr_reader :text
- private :text
-
- def initialize(text)
- @text = text
- end
-
- def matches
- relative_matches
- end
-
- private
-
- def relative_matches
- absolute_matches.map { |path| path.sub(base_path, "") }
- end
-
- def absolute_matches
- Dir[glob_pattern].map do |path|
- if File.directory?(path)
- "#{path}/"
- else
- path
- end
- end
- end
-
- def glob_pattern
- "#{base_path}#{text}*"
- end
-
- def base_path
- "#{Dir.pwd}/"
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/parser.rb b/lib/bundler/vendor/thor/lib/thor/parser.rb
deleted file mode 100644
index 08f80e565d..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/parser.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-require "bundler/vendor/thor/lib/thor/parser/argument"
-require "bundler/vendor/thor/lib/thor/parser/arguments"
-require "bundler/vendor/thor/lib/thor/parser/option"
-require "bundler/vendor/thor/lib/thor/parser/options"
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/argument.rb b/lib/bundler/vendor/thor/lib/thor/parser/argument.rb
deleted file mode 100644
index dfe7398583..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/parser/argument.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-class Bundler::Thor
- class Argument #:nodoc:
- VALID_TYPES = [:numeric, :hash, :array, :string]
-
- attr_reader :name, :description, :enum, :required, :type, :default, :banner
- alias_method :human_name, :name
-
- def initialize(name, options = {})
- class_name = self.class.name.split("::").last
-
- type = options[:type]
-
- raise ArgumentError, "#{class_name} name can't be nil." if name.nil?
- raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
-
- @name = name.to_s
- @description = options[:desc]
- @required = options.key?(:required) ? options[:required] : true
- @type = (type || :string).to_sym
- @default = options[:default]
- @banner = options[:banner] || default_banner
- @enum = options[:enum]
-
- validate! # Trigger specific validations
- end
-
- def usage
- required? ? banner : "[#{banner}]"
- end
-
- def required?
- required
- end
-
- def show_default?
- case default
- when Array, String, Hash
- !default.empty?
- else
- default
- end
- end
-
- protected
-
- def validate!
- raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
- raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array)
- end
-
- def valid_type?(type)
- self.class::VALID_TYPES.include?(type.to_sym)
- end
-
- def default_banner
- case type
- when :boolean
- nil
- when :string, :default
- human_name.upcase
- when :numeric
- "N"
- when :hash
- "key:value"
- when :array
- "one two three"
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
deleted file mode 100644
index 1fd790f4b7..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
+++ /dev/null
@@ -1,175 +0,0 @@
-class Bundler::Thor
- class Arguments #:nodoc: # rubocop:disable ClassLength
- NUMERIC = /[-+]?(\d*\.\d+|\d+)/
-
- # Receives an array of args and returns two arrays, one with arguments
- # and one with switches.
- #
- def self.split(args)
- arguments = []
-
- args.each do |item|
- break if item =~ /^-/
- arguments << item
- end
-
- [arguments, args[Range.new(arguments.size, -1)]]
- end
-
- def self.parse(*args)
- to_parse = args.pop
- new(*args).parse(to_parse)
- end
-
- # Takes an array of Bundler::Thor::Argument objects.
- #
- def initialize(arguments = [])
- @assigns = {}
- @non_assigned_required = []
- @switches = arguments
-
- arguments.each do |argument|
- if !argument.default.nil?
- @assigns[argument.human_name] = argument.default
- elsif argument.required?
- @non_assigned_required << argument
- end
- end
- end
-
- def parse(args)
- @pile = args.dup
-
- @switches.each do |argument|
- break unless peek
- @non_assigned_required.delete(argument)
- @assigns[argument.human_name] = send(:"parse_#{argument.type}", argument.human_name)
- end
-
- check_requirement!
- @assigns
- end
-
- def remaining
- @pile
- end
-
- private
-
- def no_or_skip?(arg)
- arg =~ /^--(no|skip)-([-\w]+)$/
- $2
- end
-
- def last?
- @pile.empty?
- end
-
- def peek
- @pile.first
- end
-
- def shift
- @pile.shift
- end
-
- def unshift(arg)
- if arg.is_a?(Array)
- @pile = arg + @pile
- else
- @pile.unshift(arg)
- end
- end
-
- def current_is_value?
- peek && peek.to_s !~ /^-/
- end
-
- # Runs through the argument array getting strings that contains ":" and
- # mark it as a hash:
- #
- # [ "name:string", "age:integer" ]
- #
- # Becomes:
- #
- # { "name" => "string", "age" => "integer" }
- #
- def parse_hash(name)
- return shift if peek.is_a?(Hash)
- hash = {}
-
- while current_is_value? && peek.include?(":")
- key, value = shift.split(":", 2)
- raise MalformattedArgumentError, "You can't specify '#{key}' more than once in option '#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}" if hash.include? key
- hash[key] = value
- end
- hash
- end
-
- # Runs through the argument array getting all strings until no string is
- # found or a switch is found.
- #
- # ["a", "b", "c"]
- #
- # And returns it as an array:
- #
- # ["a", "b", "c"]
- #
- def parse_array(name)
- return shift if peek.is_a?(Array)
- array = []
- array << shift while current_is_value?
- array
- end
-
- # Check if the peek is numeric format and return a Float or Integer.
- # Check if the peek is included in enum if enum is provided.
- # Otherwise raises an error.
- #
- def parse_numeric(name)
- return shift if peek.is_a?(Numeric)
-
- unless peek =~ NUMERIC && $& == peek
- raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
- end
-
- value = $&.index(".") ? shift.to_f : shift.to_i
- if @switches.is_a?(Hash) && switch = @switches[name]
- if switch.enum && !switch.enum.include?(value)
- raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
- end
- end
- value
- end
-
- # Parse string:
- # for --string-arg, just return the current value in the pile
- # for --no-string-arg, nil
- # Check if the peek is included in enum if enum is provided. Otherwise raises an error.
- #
- def parse_string(name)
- if no_or_skip?(name)
- nil
- else
- value = shift
- if @switches.is_a?(Hash) && switch = @switches[name]
- if switch.enum && !switch.enum.include?(value)
- raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
- end
- end
- value
- end
- end
-
- # Raises an error if @non_assigned_required array is not empty.
- #
- def check_requirement!
- return if @non_assigned_required.empty?
- names = @non_assigned_required.map do |o|
- o.respond_to?(:switch_name) ? o.switch_name : o.human_name
- end.join("', '")
- class_name = self.class.name.split("::").last.downcase
- raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/option.rb b/lib/bundler/vendor/thor/lib/thor/parser/option.rb
deleted file mode 100644
index 85169b56c8..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/parser/option.rb
+++ /dev/null
@@ -1,146 +0,0 @@
-class Bundler::Thor
- class Option < Argument #:nodoc:
- attr_reader :aliases, :group, :lazy_default, :hide
-
- VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
-
- def initialize(name, options = {})
- @check_default_type = options[:check_default_type]
- options[:required] = false unless options.key?(:required)
- super
- @lazy_default = options[:lazy_default]
- @group = options[:group].to_s.capitalize if options[:group]
- @aliases = Array(options[:aliases])
- @hide = options[:hide]
- end
-
- # This parse quick options given as method_options. It makes several
- # assumptions, but you can be more specific using the option method.
- #
- # parse :foo => "bar"
- # #=> Option foo with default value bar
- #
- # parse [:foo, :baz] => "bar"
- # #=> Option foo with default value bar and alias :baz
- #
- # parse :foo => :required
- # #=> Required option foo without default value
- #
- # parse :foo => 2
- # #=> Option foo with default value 2 and type numeric
- #
- # parse :foo => :numeric
- # #=> Option foo without default value and type numeric
- #
- # parse :foo => true
- # #=> Option foo with default value true and type boolean
- #
- # The valid types are :boolean, :numeric, :hash, :array and :string. If none
- # is given a default type is assumed. This default type accepts arguments as
- # string (--foo=value) or booleans (just --foo).
- #
- # By default all options are optional, unless :required is given.
- #
- def self.parse(key, value)
- if key.is_a?(Array)
- name, *aliases = key
- else
- name = key
- aliases = []
- end
-
- name = name.to_s
- default = value
-
- type = case value
- when Symbol
- default = nil
- if VALID_TYPES.include?(value)
- value
- elsif required = (value == :required) # rubocop:disable AssignmentInCondition
- :string
- end
- when TrueClass, FalseClass
- :boolean
- when Numeric
- :numeric
- when Hash, Array, String
- value.class.name.downcase.to_sym
- end
-
- new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
- end
-
- def switch_name
- @switch_name ||= dasherized? ? name : dasherize(name)
- end
-
- def human_name
- @human_name ||= dasherized? ? undasherize(name) : name
- end
-
- def usage(padding = 0)
- sample = if banner && !banner.to_s.empty?
- "#{switch_name}=#{banner}".dup
- else
- switch_name
- end
-
- sample = "[#{sample}]".dup unless required?
-
- if boolean?
- sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
- end
-
- if aliases.empty?
- (" " * padding) << sample
- else
- "#{aliases.join(', ')}, #{sample}"
- end
- end
-
- VALID_TYPES.each do |type|
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def #{type}?
- self.type == #{type.inspect}
- end
- RUBY
- end
-
- protected
-
- def validate!
- raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
- validate_default_type! if @check_default_type
- end
-
- def validate_default_type!
- default_type = case @default
- when nil
- return
- when TrueClass, FalseClass
- required? ? :string : :boolean
- when Numeric
- :numeric
- when Symbol
- :string
- when Hash, Array, String
- @default.class.name.downcase.to_sym
- end
-
- raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
- end
-
- def dasherized?
- name.index("-") == 0
- end
-
- def undasherize(str)
- str.sub(/^-{1,2}/, "")
- end
-
- def dasherize(str)
- (str.length > 1 ? "--" : "-") + str.tr("_", "-")
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/options.rb b/lib/bundler/vendor/thor/lib/thor/parser/options.rb
deleted file mode 100644
index 70f6366842..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb
+++ /dev/null
@@ -1,221 +0,0 @@
-class Bundler::Thor
- class Options < Arguments #:nodoc: # rubocop:disable ClassLength
- LONG_RE = /^(--\w+(?:-\w+)*)$/
- SHORT_RE = /^(-[a-z])$/i
- EQ_RE = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
- SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args
- SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i
- OPTS_END = "--".freeze
-
- # Receives a hash and makes it switches.
- def self.to_switches(options)
- options.map do |key, value|
- case value
- when true
- "--#{key}"
- when Array
- "--#{key} #{value.map(&:inspect).join(' ')}"
- when Hash
- "--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}"
- when nil, false
- nil
- else
- "--#{key} #{value.inspect}"
- end
- end.compact.join(" ")
- end
-
- # Takes a hash of Bundler::Thor::Option and a hash with defaults.
- #
- # If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
- # an unknown option or a regular argument.
- def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false)
- @stop_on_unknown = stop_on_unknown
- @disable_required_check = disable_required_check
- options = hash_options.values
- super(options)
-
- # Add defaults
- defaults.each do |key, value|
- @assigns[key.to_s] = value
- @non_assigned_required.delete(hash_options[key])
- end
-
- @shorts = {}
- @switches = {}
- @extra = []
-
- options.each do |option|
- @switches[option.switch_name] = option
-
- option.aliases.each do |short|
- name = short.to_s.sub(/^(?!\-)/, "-")
- @shorts[name] ||= option.switch_name
- end
- end
- end
-
- def remaining
- @extra
- end
-
- def peek
- return super unless @parsing_options
-
- result = super
- if result == OPTS_END
- shift
- @parsing_options = false
- super
- else
- result
- end
- end
-
- def parse(args) # rubocop:disable MethodLength
- @pile = args.dup
- @parsing_options = true
-
- while peek
- if parsing_options?
- match, is_switch = current_is_switch?
- shifted = shift
-
- if is_switch
- case shifted
- when SHORT_SQ_RE
- unshift($1.split("").map { |f| "-#{f}" })
- next
- when EQ_RE, SHORT_NUM
- unshift($2)
- switch = $1
- when LONG_RE, SHORT_RE
- switch = $1
- end
-
- switch = normalize_switch(switch)
- option = switch_option(switch)
- @assigns[option.human_name] = parse_peek(switch, option)
- elsif @stop_on_unknown
- @parsing_options = false
- @extra << shifted
- @extra << shift while peek
- break
- elsif match
- @extra << shifted
- @extra << shift while peek && peek !~ /^-/
- else
- @extra << shifted
- end
- else
- @extra << shift
- end
- end
-
- check_requirement! unless @disable_required_check
-
- assigns = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
- assigns.freeze
- assigns
- end
-
- def check_unknown!
- # 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?
- end
-
- protected
-
- # Check if the current value in peek is a registered switch.
- #
- # Two booleans are returned. The first is true if the current value
- # starts with a hyphen; the second is true if it is a registered switch.
- def current_is_switch?
- case peek
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
- [true, switch?($1)]
- when SHORT_SQ_RE
- [true, $1.split("").any? { |f| switch?("-#{f}") }]
- else
- [false, false]
- end
- end
-
- def current_is_switch_formatted?
- case peek
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE
- true
- else
- false
- end
- end
-
- def current_is_value?
- peek && (!parsing_options? || super)
- end
-
- def switch?(arg)
- switch_option(normalize_switch(arg))
- end
-
- def switch_option(arg)
- if match = no_or_skip?(arg) # rubocop:disable AssignmentInCondition
- @switches[arg] || @switches["--#{match}"]
- else
- @switches[arg]
- end
- end
-
- # Check if the given argument is actually a shortcut.
- #
- def normalize_switch(arg)
- (@shorts[arg] || arg).tr("_", "-")
- end
-
- def parsing_options?
- peek
- @parsing_options
- end
-
- # Parse boolean values which can be given as --foo=true, --foo or --no-foo.
- #
- def parse_boolean(switch)
- if current_is_value?
- if ["true", "TRUE", "t", "T", true].include?(peek)
- shift
- true
- elsif ["false", "FALSE", "f", "F", false].include?(peek)
- shift
- false
- else
- !no_or_skip?(switch)
- end
- else
- @switches.key?(switch) || !no_or_skip?(switch)
- end
- end
-
- # Parse the value at the peek analyzing if it requires an input or not.
- #
- def parse_peek(switch, option)
- if parsing_options? && (current_is_switch_formatted? || last?)
- if option.boolean?
- # No problem for boolean types
- elsif no_or_skip?(switch)
- return nil # User set value to nil
- elsif option.string? && !option.required?
- # Return the default if there is one, else the human name
- return option.lazy_default || option.default || option.human_name
- elsif option.lazy_default
- return option.lazy_default
- else
- raise MalformattedArgumentError, "No value provided for option '#{switch}'"
- end
- end
-
- @non_assigned_required.delete(option)
- send(:"parse_#{option.type}", switch)
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb b/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
deleted file mode 100644
index 60282e2991..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-require "rake"
-require "rake/dsl_definition"
-
-class Bundler::Thor
- # Adds a compatibility layer to your Bundler::Thor classes which allows you to use
- # rake package tasks. For example, to use rspec rake tasks, one can do:
- #
- # require 'bundler/vendor/thor/lib/thor/rake_compat'
- # require 'rspec/core/rake_task'
- #
- # class Default < Bundler::Thor
- # include Bundler::Thor::RakeCompat
- #
- # RSpec::Core::RakeTask.new(:spec) do |t|
- # t.spec_opts = ['--options', './.rspec']
- # t.spec_files = FileList['spec/**/*_spec.rb']
- # end
- # end
- #
- module RakeCompat
- include Rake::DSL if defined?(Rake::DSL)
-
- def self.rake_classes
- @rake_classes ||= []
- end
-
- def self.included(base)
- # Hack. Make rakefile point to invoker, so rdoc task is generated properly.
- rakefile = File.basename(caller[0].match(/(.*):\d+/)[1])
- Rake.application.instance_variable_set(:@rakefile, rakefile)
- rake_classes << base
- end
- end
-end
-
-# override task on (main), for compatibility with Rake 0.9
-instance_eval do
- alias rake_namespace namespace
-
- def task(*)
- task = super
-
- if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
- non_namespaced_name = task.name.split(":").last
-
- description = non_namespaced_name
- description << task.arg_names.map { |n| n.to_s.upcase }.join(" ")
- description.strip!
-
- klass.desc description, Rake.application.last_description || non_namespaced_name
- Rake.application.last_description = nil
- klass.send :define_method, non_namespaced_name do |*args|
- Rake::Task[task.name.to_sym].invoke(*args)
- end
- end
-
- task
- end
-
- def namespace(name)
- if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
- const_name = Bundler::Thor::Util.camel_case(name.to_s).to_sym
- klass.const_set(const_name, Class.new(Bundler::Thor))
- new_klass = klass.const_get(const_name)
- Bundler::Thor::RakeCompat.rake_classes << new_klass
- end
-
- super
- Bundler::Thor::RakeCompat.rake_classes.pop
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb
deleted file mode 100644
index b110b8d478..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/runner.rb
+++ /dev/null
@@ -1,324 +0,0 @@
-require "bundler/vendor/thor/lib/thor"
-require "bundler/vendor/thor/lib/thor/group"
-require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
-
-require "yaml"
-require "digest"
-require "pathname"
-
-class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength
- map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
-
- def self.banner(command, all = false, subcommand = false)
- "thor " + command.formatted_usage(self, all, subcommand)
- end
-
- def self.exit_on_failure?
- true
- end
-
- # Override Bundler::Thor#help so it can give information about any class and any method.
- #
- def help(meth = nil)
- if meth && !respond_to?(meth)
- initialize_thorfiles(meth)
- klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
- self.class.handle_no_command_error(command, false) if klass.nil?
- klass.start(["-h", command].compact, :shell => shell)
- else
- super
- end
- end
-
- # If a command is not found on Bundler::Thor::Runner, method missing is invoked and
- # Bundler::Thor::Runner is then responsible for finding the command in all classes.
- #
- def method_missing(meth, *args)
- meth = meth.to_s
- initialize_thorfiles(meth)
- klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
- self.class.handle_no_command_error(command, false) if klass.nil?
- args.unshift(command) if command
- klass.start(args, :shell => shell)
- end
-
- desc "install NAME", "Install an optionally named Bundler::Thor file into your system commands"
- method_options :as => :string, :relative => :boolean, :force => :boolean
- def install(name) # rubocop:disable MethodLength
- initialize_thorfiles
-
- # If a directory name is provided as the argument, look for a 'main.thor'
- # command in said directory.
- begin
- if File.directory?(File.expand_path(name))
- base = File.join(name, "main.thor")
- package = :directory
- contents = open(base, &:read)
- else
- base = name
- package = :file
- contents = open(name, &:read)
- end
- rescue OpenURI::HTTPError
- raise Error, "Error opening URI '#{name}'"
- rescue Errno::ENOENT
- raise Error, "Error opening file '#{name}'"
- end
-
- say "Your Bundler::Thorfile contains:"
- say contents
-
- unless options["force"]
- return false if no?("Do you wish to continue [y/N]?")
- end
-
- as = options["as"] || begin
- first_line = contents.split("\n")[0]
- (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil
- end
-
- unless as
- basename = File.basename(name)
- as = ask("Please specify a name for #{name} in the system repository [#{basename}]:")
- as = basename if as.empty?
- end
-
- location = if options[:relative] || name =~ %r{^https?://}
- name
- else
- File.expand_path(name)
- end
-
- thor_yaml[as] = {
- :filename => Digest(:MD5).hexdigest(name + as),
- :location => location,
- :namespaces => Bundler::Thor::Util.namespaces_in_content(contents, base)
- }
-
- save_yaml(thor_yaml)
- say "Storing thor file in your system repository"
- destination = File.join(thor_root, thor_yaml[as][:filename])
-
- if package == :file
- File.open(destination, "w") { |f| f.puts contents }
- else
- require "fileutils"
- FileUtils.cp_r(name, destination)
- end
-
- thor_yaml[as][:filename] # Indicate success
- end
-
- desc "version", "Show Bundler::Thor version"
- def version
- require "bundler/vendor/thor/lib/thor/version"
- say "Bundler::Thor #{Bundler::Thor::VERSION}"
- end
-
- desc "uninstall NAME", "Uninstall a named Bundler::Thor module"
- def uninstall(name)
- raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
- say "Uninstalling #{name}."
- require "fileutils"
- FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s))
-
- thor_yaml.delete(name)
- save_yaml(thor_yaml)
-
- puts "Done."
- end
-
- desc "update NAME", "Update a Bundler::Thor file from its original location"
- def update(name)
- raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
-
- say "Updating '#{name}' from #{thor_yaml[name][:location]}"
-
- old_filename = thor_yaml[name][:filename]
- self.options = options.merge("as" => name)
-
- if File.directory? File.expand_path(name)
- require "fileutils"
- FileUtils.rm_rf(File.join(thor_root, old_filename))
-
- thor_yaml.delete(old_filename)
- save_yaml(thor_yaml)
-
- filename = install(name)
- else
- filename = install(thor_yaml[name][:location])
- end
-
- File.delete(File.join(thor_root, old_filename)) unless filename == old_filename
- end
-
- desc "installed", "List the installed Bundler::Thor modules and commands"
- method_options :internal => :boolean
- def installed
- initialize_thorfiles(nil, true)
- display_klasses(true, options["internal"])
- end
-
- desc "list [SEARCH]", "List the available thor commands (--substring means .*SEARCH)"
- method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
- def list(search = "")
- initialize_thorfiles
-
- search = ".*#{search}" if options["substring"]
- search = /^#{search}.*/i
- group = options[:group] || "standard"
-
- klasses = Bundler::Thor::Base.subclasses.select do |k|
- (options[:all] || k.group == group) && k.namespace =~ search
- end
-
- display_klasses(false, false, klasses)
- end
-
-private
-
- def thor_root
- Bundler::Thor::Util.thor_root
- end
-
- def thor_yaml
- @thor_yaml ||= begin
- yaml_file = File.join(thor_root, "thor.yml")
- yaml = YAML.load_file(yaml_file) if File.exist?(yaml_file)
- yaml || {}
- end
- end
-
- # Save the yaml file. If none exists in thor root, creates one.
- #
- def save_yaml(yaml)
- yaml_file = File.join(thor_root, "thor.yml")
-
- unless File.exist?(yaml_file)
- require "fileutils"
- FileUtils.mkdir_p(thor_root)
- yaml_file = File.join(thor_root, "thor.yml")
- FileUtils.touch(yaml_file)
- end
-
- File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
- end
-
- # Load the Bundler::Thorfiles. If relevant_to is supplied, looks for specific files
- # in the thor_root instead of loading them all.
- #
- # By default, it also traverses the current path until find Bundler::Thor files, as
- # described in thorfiles. This look up can be skipped by supplying
- # skip_lookup true.
- #
- def initialize_thorfiles(relevant_to = nil, skip_lookup = false)
- thorfiles(relevant_to, skip_lookup).each do |f|
- Bundler::Thor::Util.load_thorfile(f, nil, options[:debug]) unless Bundler::Thor::Base.subclass_files.keys.include?(File.expand_path(f))
- end
- end
-
- # Finds Bundler::Thorfiles by traversing from your current directory down to the root
- # directory of your system. If at any time we find a Bundler::Thor file, we stop.
- #
- # We also ensure that system-wide Bundler::Thorfiles are loaded first, so local
- # Bundler::Thorfiles can override them.
- #
- # ==== Example
- #
- # If we start at /Users/wycats/dev/thor ...
- #
- # 1. /Users/wycats/dev/thor
- # 2. /Users/wycats/dev
- # 3. /Users/wycats <-- we find a Bundler::Thorfile here, so we stop
- #
- # Suppose we start at c:\Documents and Settings\james\dev\thor ...
- #
- # 1. c:\Documents and Settings\james\dev\thor
- # 2. c:\Documents and Settings\james\dev
- # 3. c:\Documents and Settings\james
- # 4. c:\Documents and Settings
- # 5. c:\ <-- no Bundler::Thorfiles found!
- #
- def thorfiles(relevant_to = nil, skip_lookup = false)
- thorfiles = []
-
- unless skip_lookup
- Pathname.pwd.ascend do |path|
- thorfiles = Bundler::Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten
- break unless thorfiles.empty?
- end
- end
-
- files = (relevant_to ? thorfiles_relevant_to(relevant_to) : Bundler::Thor::Util.thor_root_glob)
- files += thorfiles
- files -= ["#{thor_root}/thor.yml"]
-
- files.map! do |file|
- File.directory?(file) ? File.join(file, "main.thor") : file
- end
- end
-
- # Load Bundler::Thorfiles relevant to the given method. If you provide "foo:bar" it
- # will load all thor files in the thor.yaml that has "foo" e "foo:bar"
- # namespaces registered.
- #
- def thorfiles_relevant_to(meth)
- lookup = [meth, meth.split(":")[0...-1].join(":")]
-
- files = thor_yaml.select do |_, v|
- v[:namespaces] && !(v[:namespaces] & lookup).empty?
- end
-
- files.map { |_, v| File.join(thor_root, (v[:filename]).to_s) }
- end
-
- # Display information about the given klasses. If with_module is given,
- # it shows a table with information extracted from the yaml file.
- #
- def display_klasses(with_modules = false, show_internal = false, klasses = Bundler::Thor::Base.subclasses)
- klasses -= [Bundler::Thor, Bundler::Thor::Runner, Bundler::Thor::Group] unless show_internal
-
- raise Error, "No Bundler::Thor commands available" if klasses.empty?
- show_modules if with_modules && !thor_yaml.empty?
-
- list = Hash.new { |h, k| h[k] = [] }
- groups = klasses.select { |k| k.ancestors.include?(Bundler::Thor::Group) }
-
- # Get classes which inherit from Bundler::Thor
- (klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_commands(false) }
-
- # Get classes which inherit from Bundler::Thor::Base
- groups.map! { |k| k.printable_commands(false).first }
- list["root"] = groups
-
- # Order namespaces with default coming first
- list = list.sort { |a, b| a[0].sub(/^default/, "") <=> b[0].sub(/^default/, "") }
- list.each { |n, commands| display_commands(n, commands) unless commands.empty? }
- end
-
- def display_commands(namespace, list) #:nodoc:
- list.sort! { |a, b| a[0] <=> b[0] }
-
- say shell.set_color(namespace, :blue, true)
- say "-" * namespace.size
-
- print_table(list, :truncate => true)
- say
- end
- alias_method :display_tasks, :display_commands
-
- def show_modules #:nodoc:
- info = []
- labels = %w(Modules Namespaces)
-
- info << labels
- info << ["-" * labels[0].size, "-" * labels[1].size]
-
- thor_yaml.each do |name, hash|
- info << [name, hash[:namespaces].join(", ")]
- end
-
- print_table info
- say ""
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell.rb b/lib/bundler/vendor/thor/lib/thor/shell.rb
deleted file mode 100644
index e945549324..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-require "rbconfig"
-
-class Bundler::Thor
- module Base
- class << self
- attr_writer :shell
-
- # Returns the shell used in all Bundler::Thor classes. If you are in a Unix platform
- # it will use a colored log, otherwise it will use a basic one without color.
- #
- def shell
- @shell ||= if ENV["THOR_SHELL"] && !ENV["THOR_SHELL"].empty?
- Bundler::Thor::Shell.const_get(ENV["THOR_SHELL"])
- elsif RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ && !ENV["ANSICON"]
- Bundler::Thor::Shell::Basic
- else
- Bundler::Thor::Shell::Color
- end
- end
- end
- end
-
- module Shell
- SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width]
- attr_writer :shell
-
- autoload :Basic, "bundler/vendor/thor/lib/thor/shell/basic"
- autoload :Color, "bundler/vendor/thor/lib/thor/shell/color"
- autoload :HTML, "bundler/vendor/thor/lib/thor/shell/html"
-
- # Add shell to initialize config values.
- #
- # ==== Configuration
- # shell<Object>:: An instance of the shell to be used.
- #
- # ==== Examples
- #
- # class MyScript < Bundler::Thor
- # argument :first, :type => :numeric
- # end
- #
- # MyScript.new [1.0], { :foo => :bar }, :shell => Bundler::Thor::Shell::Basic.new
- #
- def initialize(args = [], options = {}, config = {})
- super
- self.shell = config[:shell]
- shell.base ||= self if shell.respond_to?(:base)
- end
-
- # Holds the shell for the given Bundler::Thor instance. If no shell is given,
- # it gets a default shell from Bundler::Thor::Base.shell.
- def shell
- @shell ||= Bundler::Thor::Base.shell.new
- end
-
- # Common methods that are delegated to the shell.
- SHELL_DELEGATED_METHODS.each do |method|
- module_eval <<-METHOD, __FILE__, __LINE__
- def #{method}(*args,&block)
- shell.#{method}(*args,&block)
- end
- METHOD
- end
-
- # Yields the given block with padding.
- def with_padding
- shell.padding += 1
- yield
- ensure
- shell.padding -= 1
- end
-
- protected
-
- # Allow shell to be shared between invocations.
- #
- def _shared_configuration #:nodoc:
- super.merge!(:shell => shell)
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
deleted file mode 100644
index 5162390efd..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
+++ /dev/null
@@ -1,437 +0,0 @@
-class Bundler::Thor
- module Shell
- class Basic
- attr_accessor :base
- attr_reader :padding
-
- # Initialize base, mute and padding to nil.
- #
- def initialize #:nodoc:
- @base = nil
- @mute = false
- @padding = 0
- @always_force = false
- end
-
- # Mute everything that's inside given block
- #
- def mute
- @mute = true
- yield
- ensure
- @mute = false
- end
-
- # Check if base is muted
- #
- def mute?
- @mute
- end
-
- # Sets the output padding, not allowing less than zero values.
- #
- def padding=(value)
- @padding = [0, value].max
- end
-
- # Sets the output padding while executing a block and resets it.
- #
- def indent(count = 1)
- orig_padding = padding
- self.padding = padding + count
- yield
- self.padding = orig_padding
- end
-
- # Asks something to the user and receives a response.
- #
- # 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
- # must be given and re-asked the question.
- #
- # If asking for sensitive information, the :echo option can be set
- # to false to mask user input from $stdin.
- #
- # If the required input is a path, then set the path option to
- # true. This will enable tab completion for file paths relative
- # to the current working directory on systems that support
- # Readline.
- #
- # ==== Example
- # ask("What is your name?")
- #
- # ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
- #
- # ask("What is your password?", :echo => false)
- #
- # ask("Where should the file be saved?", :path => true)
- #
- def ask(statement, *args)
- options = args.last.is_a?(Hash) ? args.pop : {}
- color = args.first
-
- if options[:limited_to]
- ask_filtered(statement, color, options)
- else
- ask_simply(statement, color, options)
- end
- end
-
- # Say (print) something to the user. If the sentence ends with a whitespace
- # or tab character, a new line is not appended (print + flush). Otherwise
- # are passed straight to puts (behavior got from Highline).
- #
- # ==== Example
- # say("I know you knew that.")
- #
- def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
- buffer = prepare_message(message, *color)
- buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")
-
- stdout.print(buffer)
- stdout.flush
- end
-
- # Say a status with the given color and appends the message. Since this
- # method is used frequently by actions, it allows nil or false to be given
- # in log_status, avoiding the message from being shown. If a Symbol is
- # given in log_status, it's used as the color.
- #
- def say_status(status, message, log_status = true)
- return if quiet? || log_status == false
- spaces = " " * (padding + 1)
- color = log_status.is_a?(Symbol) ? log_status : :green
-
- status = status.to_s.rjust(12)
- status = set_color status, color, true if color
-
- buffer = "#{status}#{spaces}#{message}"
- buffer = "#{buffer}\n" unless buffer.end_with?("\n")
-
- stdout.print(buffer)
- stdout.flush
- end
-
- # Make a question the to user and returns true if the user replies "y" or
- # "yes".
- #
- def yes?(statement, color = nil)
- !!(ask(statement, color, :add_to_history => false) =~ is?(:yes))
- end
-
- # Make a question the to user and returns true if the user replies "n" or
- # "no".
- #
- def no?(statement, color = nil)
- !!(ask(statement, color, :add_to_history => false) =~ is?(:no))
- end
-
- # Prints values in columns
- #
- # ==== Parameters
- # Array[String, String, ...]
- #
- def print_in_columns(array)
- return if array.empty?
- colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
- array.each_with_index do |value, index|
- # Don't output trailing spaces when printing the last column
- if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
- stdout.puts value
- else
- stdout.printf("%-#{colwidth}s", value)
- end
- end
- end
-
- # Prints a table.
- #
- # ==== Parameters
- # Array[Array[String, String, ...]]
- #
- # ==== Options
- # indent<Integer>:: Indent the first column by indent value.
- # colwidth<Integer>:: Force the first column to colwidth spaces wide.
- #
- def print_table(array, options = {}) # rubocop:disable MethodLength
- return if array.empty?
-
- formats = []
- indent = options[:indent].to_i
- colwidth = options[:colwidth]
- options[:truncate] = terminal_width if options[:truncate] == true
-
- formats << "%-#{colwidth + 2}s".dup if colwidth
- start = colwidth ? 1 : 0
-
- colcount = array.max { |a, b| a.size <=> b.size }.size
-
- maximas = []
-
- start.upto(colcount - 1) do |index|
- maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
- maximas << maxima
- formats << if index == colcount - 1
- # Don't output 2 trailing spaces when printing the last column
- "%-s".dup
- else
- "%-#{maxima + 2}s".dup
- end
- end
-
- formats[0] = formats[0].insert(0, " " * indent)
- formats << "%s"
-
- array.each do |row|
- sentence = "".dup
-
- row.each_with_index do |column, index|
- maxima = maximas[index]
-
- f = if column.is_a?(Numeric)
- if index == row.size - 1
- # Don't output 2 trailing spaces when printing the last column
- "%#{maxima}s"
- else
- "%#{maxima}s "
- end
- else
- formats[index]
- end
- sentence << f % column.to_s
- end
-
- sentence = truncate(sentence, options[:truncate]) if options[:truncate]
- stdout.puts sentence
- end
- end
-
- # Prints a long string, word-wrapping the text to the current width of the
- # terminal display. Ideal for printing heredocs.
- #
- # ==== Parameters
- # String
- #
- # ==== Options
- # indent<Integer>:: Indent each line of the printed paragraph by indent value.
- #
- def print_wrapped(message, options = {})
- indent = options[:indent] || 0
- width = terminal_width - indent
- 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
-
- paras.each do |para|
- para.split("\n").each do |line|
- stdout.puts line.insert(0, " " * indent)
- end
- stdout.puts unless para == paras.last
- end
- end
-
- # Deals with file collision and returns true if the file should be
- # overwritten and false otherwise. If a block is given, it uses the block
- # response as the content for the diff.
- #
- # ==== Parameters
- # destination<String>:: the destination file to solve conflicts
- # block<Proc>:: an optional block that returns the value to be used in diff
- #
- def file_collision(destination)
- return true if @always_force
- options = block_given? ? "[Ynaqdh]" : "[Ynaqh]"
-
- loop do
- answer = ask(
- %[Overwrite #{destination}? (enter "h" for help) #{options}],
- :add_to_history => false
- )
-
- case answer
- when nil
- say ""
- return true
- when is?(:yes), is?(:force), ""
- return true
- when is?(:no), is?(:skip)
- return false
- when is?(:always)
- return @always_force = true
- when is?(:quit)
- say "Aborting..."
- raise SystemExit
- when is?(:diff)
- show_diff(destination, yield) if block_given?
- say "Retrying..."
- else
- say file_collision_help
- end
- end
- end
-
- # This code was copied from Rake, available under MIT-LICENSE
- # Copyright (c) 2003, 2004 Jim Weirich
- def terminal_width
- result = if ENV["THOR_COLUMNS"]
- ENV["THOR_COLUMNS"].to_i
- else
- unix? ? dynamic_width : 80
- end
- result < 10 ? 80 : result
- rescue
- 80
- end
-
- # Called if something goes wrong during the execution. This is used by Bundler::Thor
- # internally and should not be used inside your scripts. If something went
- # wrong, you can always raise an exception. If you raise a Bundler::Thor::Error, it
- # will be rescued and wrapped in the method below.
- #
- def error(statement)
- stderr.puts statement
- end
-
- # Apply color to the given string with optional bold. Disabled in the
- # Bundler::Thor::Shell::Basic class.
- #
- def set_color(string, *) #:nodoc:
- string
- end
-
- protected
-
- def prepare_message(message, *color)
- spaces = " " * padding
- spaces + set_color(message.to_s, *color)
- end
-
- def can_display_colors?
- false
- end
-
- def lookup_color(color)
- return color unless color.is_a?(Symbol)
- self.class.const_get(color.to_s.upcase)
- end
-
- def stdout
- $stdout
- end
-
- def stderr
- $stderr
- end
-
- def is?(value) #:nodoc:
- value = value.to_s
-
- if value.size == 1
- /\A#{value}\z/i
- else
- /\A(#{value}|#{value[0, 1]})\z/i
- end
- end
-
- def file_collision_help #:nodoc:
- <<-HELP
- Y - yes, overwrite
- n - no, do not overwrite
- a - all, overwrite this and all others
- q - quit, abort
- d - diff, show the differences between the old and the new
- h - help, show this help
- HELP
- end
-
- def show_diff(destination, content) #:nodoc:
- diff_cmd = ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u"
-
- require "tempfile"
- Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp|
- temp.write content
- temp.rewind
- system %(#{diff_cmd} "#{destination}" "#{temp.path}")
- end
- end
-
- def quiet? #:nodoc:
- mute? || (base && base.options[:quiet])
- end
-
- # Calculate the dynamic width of the terminal
- def dynamic_width
- @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
- end
-
- def dynamic_width_stty
- `stty size 2>/dev/null`.split[1].to_i
- end
-
- def dynamic_width_tput
- `tput cols 2>/dev/null`.to_i
- end
-
- def unix?
- RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
- end
-
- def truncate(string, width)
- as_unicode do
- chars = string.chars.to_a
- if chars.length <= width
- chars.join
- else
- chars[0, width - 3].join + "..."
- end
- end
- end
-
- if "".respond_to?(:encode)
- def as_unicode
- yield
- end
- else
- def as_unicode
- old = $KCODE
- $KCODE = "U"
- yield
- ensure
- $KCODE = old
- end
- end
-
- def ask_simply(statement, color, options)
- default = options[:default]
- message = [statement, ("(#{default})" if default), nil].uniq.join(" ")
- message = prepare_message(message, *color)
- result = Bundler::Thor::LineEditor.readline(message, options)
-
- return unless result
-
- result = result.strip
-
- if default && result == ""
- default
- else
- result
- end
- end
-
- def ask_filtered(statement, color, options)
- answer_set = options[:limited_to]
- correct_answer = nil
- until correct_answer
- answers = answer_set.join(", ")
- answer = ask_simply("#{statement} [#{answers}]", color, options)
- correct_answer = answer_set.include?(answer) ? answer : nil
- say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
- end
- correct_answer
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/color.rb b/lib/bundler/vendor/thor/lib/thor/shell/color.rb
deleted file mode 100644
index da289cb50c..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell/color.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-require "bundler/vendor/thor/lib/thor/shell/basic"
-
-class Bundler::Thor
- module Shell
- # Inherit from Bundler::Thor::Shell::Basic and add set_color behavior. Check
- # Bundler::Thor::Shell::Basic to see all available methods.
- #
- class Color < Basic
- # Embed in a String to clear all previous ANSI sequences.
- CLEAR = "\e[0m"
- # The start of an ANSI bold sequence.
- BOLD = "\e[1m"
-
- # Set the terminal's foreground ANSI color to black.
- BLACK = "\e[30m"
- # Set the terminal's foreground ANSI color to red.
- RED = "\e[31m"
- # Set the terminal's foreground ANSI color to green.
- GREEN = "\e[32m"
- # Set the terminal's foreground ANSI color to yellow.
- YELLOW = "\e[33m"
- # Set the terminal's foreground ANSI color to blue.
- BLUE = "\e[34m"
- # Set the terminal's foreground ANSI color to magenta.
- MAGENTA = "\e[35m"
- # Set the terminal's foreground ANSI color to cyan.
- CYAN = "\e[36m"
- # Set the terminal's foreground ANSI color to white.
- WHITE = "\e[37m"
-
- # Set the terminal's background ANSI color to black.
- ON_BLACK = "\e[40m"
- # Set the terminal's background ANSI color to red.
- ON_RED = "\e[41m"
- # Set the terminal's background ANSI color to green.
- ON_GREEN = "\e[42m"
- # Set the terminal's background ANSI color to yellow.
- ON_YELLOW = "\e[43m"
- # Set the terminal's background ANSI color to blue.
- ON_BLUE = "\e[44m"
- # Set the terminal's background ANSI color to magenta.
- ON_MAGENTA = "\e[45m"
- # Set the terminal's background ANSI color to cyan.
- ON_CYAN = "\e[46m"
- # Set the terminal's background ANSI color to white.
- ON_WHITE = "\e[47m"
-
- # Set color by using a string or one of the defined constants. If a third
- # option is set to true, it also adds bold to the string. This is based
- # on Highline implementation and it automatically appends CLEAR to the end
- # of the returned String.
- #
- # Pass foreground, background and bold options to this method as
- # symbols.
- #
- # Example:
- #
- # set_color "Hi!", :red, :on_white, :bold
- #
- # The available colors are:
- #
- # :bold
- # :black
- # :red
- # :green
- # :yellow
- # :blue
- # :magenta
- # :cyan
- # :white
- # :on_black
- # :on_red
- # :on_green
- # :on_yellow
- # :on_blue
- # :on_magenta
- # :on_cyan
- # :on_white
- def set_color(string, *colors)
- if colors.compact.empty? || !can_display_colors?
- string
- elsif colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
- ansi_colors = colors.map { |color| lookup_color(color) }
- "#{ansi_colors.join}#{string}#{CLEAR}"
- else
- # The old API was `set_color(color, bold=boolean)`. We
- # continue to support the old API because you should never
- # break old APIs unnecessarily :P
- foreground, bold = colors
- foreground = self.class.const_get(foreground.to_s.upcase) if foreground.is_a?(Symbol)
-
- bold = bold ? BOLD : ""
- "#{bold}#{foreground}#{string}#{CLEAR}"
- end
- end
-
- protected
-
- def can_display_colors?
- stdout.tty?
- end
-
- # Overwrite show_diff to show diff with colors if Diff::LCS is
- # available.
- #
- def show_diff(destination, content) #:nodoc:
- if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
- actual = File.binread(destination).to_s.split("\n")
- content = content.to_s.split("\n")
-
- Diff::LCS.sdiff(actual, content).each do |diff|
- output_diff_line(diff)
- end
- else
- super
- end
- end
-
- def output_diff_line(diff) #:nodoc:
- case diff.action
- when "-"
- say "- #{diff.old_element.chomp}", :red, true
- when "+"
- say "+ #{diff.new_element.chomp}", :green, true
- when "!"
- say "- #{diff.old_element.chomp}", :red, true
- say "+ #{diff.new_element.chomp}", :green, true
- else
- say " #{diff.old_element.chomp}", nil, true
- end
- end
-
- # Check if Diff::LCS is loaded. If it is, use it to create pretty output
- # for diff.
- #
- def diff_lcs_loaded? #:nodoc:
- return true if defined?(Diff::LCS)
- return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
-
- @diff_lcs_loaded = begin
- require "diff/lcs"
- true
- rescue LoadError
- false
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/html.rb b/lib/bundler/vendor/thor/lib/thor/shell/html.rb
deleted file mode 100644
index 83d2054988..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell/html.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-require "bundler/vendor/thor/lib/thor/shell/basic"
-
-class Bundler::Thor
- module Shell
- # Inherit from Bundler::Thor::Shell::Basic and add set_color behavior. Check
- # Bundler::Thor::Shell::Basic to see all available methods.
- #
- class HTML < Basic
- # The start of an HTML bold sequence.
- BOLD = "font-weight: bold"
-
- # Set the terminal's foreground HTML color to black.
- BLACK = "color: black"
- # Set the terminal's foreground HTML color to red.
- RED = "color: red"
- # Set the terminal's foreground HTML color to green.
- GREEN = "color: green"
- # Set the terminal's foreground HTML color to yellow.
- YELLOW = "color: yellow"
- # Set the terminal's foreground HTML color to blue.
- BLUE = "color: blue"
- # Set the terminal's foreground HTML color to magenta.
- MAGENTA = "color: magenta"
- # Set the terminal's foreground HTML color to cyan.
- CYAN = "color: cyan"
- # Set the terminal's foreground HTML color to white.
- WHITE = "color: white"
-
- # Set the terminal's background HTML color to black.
- ON_BLACK = "background-color: black"
- # Set the terminal's background HTML color to red.
- ON_RED = "background-color: red"
- # Set the terminal's background HTML color to green.
- ON_GREEN = "background-color: green"
- # Set the terminal's background HTML color to yellow.
- ON_YELLOW = "background-color: yellow"
- # Set the terminal's background HTML color to blue.
- ON_BLUE = "background-color: blue"
- # Set the terminal's background HTML color to magenta.
- ON_MAGENTA = "background-color: magenta"
- # Set the terminal's background HTML color to cyan.
- ON_CYAN = "background-color: cyan"
- # Set the terminal's background HTML color to white.
- ON_WHITE = "background-color: white"
-
- # Set color by using a string or one of the defined constants. If a third
- # option is set to true, it also adds bold to the string. This is based
- # on Highline implementation and it automatically appends CLEAR to the end
- # of the returned String.
- #
- def set_color(string, *colors)
- if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
- html_colors = colors.map { |color| lookup_color(color) }
- "<span style=\"#{html_colors.join('; ')};\">#{string}</span>"
- else
- color, bold = colors
- html_color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
- styles = [html_color]
- styles << BOLD if bold
- "<span style=\"#{styles.join('; ')};\">#{string}</span>"
- end
- end
-
- # Ask something to the user and receives a response.
- #
- # ==== Example
- # ask("What is your name?")
- #
- # TODO: Implement #ask for Bundler::Thor::Shell::HTML
- def ask(statement, color = nil)
- raise NotImplementedError, "Implement #ask for Bundler::Thor::Shell::HTML"
- end
-
- protected
-
- def can_display_colors?
- true
- end
-
- # Overwrite show_diff to show diff with colors if Diff::LCS is
- # available.
- #
- def show_diff(destination, content) #:nodoc:
- if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
- actual = File.binread(destination).to_s.split("\n")
- content = content.to_s.split("\n")
-
- Diff::LCS.sdiff(actual, content).each do |diff|
- output_diff_line(diff)
- end
- else
- super
- end
- end
-
- def output_diff_line(diff) #:nodoc:
- case diff.action
- when "-"
- say "- #{diff.old_element.chomp}", :red, true
- when "+"
- say "+ #{diff.new_element.chomp}", :green, true
- when "!"
- say "- #{diff.old_element.chomp}", :red, true
- say "+ #{diff.new_element.chomp}", :green, true
- else
- say " #{diff.old_element.chomp}", nil, true
- end
- end
-
- # Check if Diff::LCS is loaded. If it is, use it to create pretty output
- # for diff.
- #
- def diff_lcs_loaded? #:nodoc:
- return true if defined?(Diff::LCS)
- return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
-
- @diff_lcs_loaded = begin
- require "diff/lcs"
- true
- rescue LoadError
- false
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/util.rb b/lib/bundler/vendor/thor/lib/thor/util.rb
deleted file mode 100644
index 5d03177a28..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/util.rb
+++ /dev/null
@@ -1,268 +0,0 @@
-require "rbconfig"
-
-class Bundler::Thor
- module Sandbox #:nodoc:
- end
-
- # This module holds several utilities:
- #
- # 1) Methods to convert thor namespaces to constants and vice-versa.
- #
- # Bundler::Thor::Util.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz"
- #
- # 2) Loading thor files and sandboxing:
- #
- # Bundler::Thor::Util.load_thorfile("~/.thor/foo")
- #
- module Util
- class << self
- # Receives a namespace and search for it in the Bundler::Thor::Base subclasses.
- #
- # ==== Parameters
- # namespace<String>:: The namespace to search for.
- #
- def find_by_namespace(namespace)
- namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/
- Bundler::Thor::Base.subclasses.detect { |klass| klass.namespace == namespace }
- 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
- # removing the sandbox namespace.
- #
- # This method should not be used in general because it's used to deal with
- # older versions of Bundler::Thor. On current versions, if you need to get the
- # namespace from a class, just call namespace on it.
- #
- # ==== Parameters
- # constant<Object>:: The constant to be converted to the thor path.
- #
- # ==== Returns
- # String:: If we receive Foo::Bar::Baz it returns "foo:bar:baz"
- #
- def namespace_from_thor_class(constant)
- constant = constant.to_s.gsub(/^Bundler::Thor::Sandbox::/, "")
- constant = snake_case(constant).squeeze(":")
- constant
- end
-
- # Given the contents, evaluate it inside the sandbox and returns the
- # namespaces defined in the sandbox.
- #
- # ==== Parameters
- # contents<String>
- #
- # ==== Returns
- # Array[Object]
- #
- def namespaces_in_content(contents, file = __FILE__)
- old_constants = Bundler::Thor::Base.subclasses.dup
- Bundler::Thor::Base.subclasses.clear
-
- load_thorfile(file, contents)
-
- new_constants = Bundler::Thor::Base.subclasses.dup
- Bundler::Thor::Base.subclasses.replace(old_constants)
-
- new_constants.map!(&:namespace)
- new_constants.compact!
- new_constants
- end
-
- # Returns the thor classes declared inside the given class.
- #
- def thor_classes_in(klass)
- stringfied_constants = klass.constants.map(&:to_s)
- Bundler::Thor::Base.subclasses.select do |subclass|
- next unless subclass.name
- stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", ""))
- end
- end
-
- # Receives a string and convert it to snake case. SnakeCase returns snake_case.
- #
- # ==== Parameters
- # String
- #
- # ==== Returns
- # String
- #
- def snake_case(str)
- return str.downcase if str =~ /^[A-Z_]+$/
- str.gsub(/\B[A-Z]/, '_\&').squeeze("_") =~ /_*(.*)/
- $+.downcase
- end
-
- # Receives a string and convert it to camel case. camel_case returns CamelCase.
- #
- # ==== Parameters
- # String
- #
- # ==== Returns
- # String
- #
- def camel_case(str)
- return str if str !~ /_/ && str =~ /[A-Z]+.*/
- str.split("_").map(&:capitalize).join
- end
-
- # Receives a namespace and tries to retrieve a Bundler::Thor or Bundler::Thor::Group class
- # from it. It first searches for a class using the all the given namespace,
- # if it's not found, removes the highest entry and searches for the class
- # again. If found, returns the highest entry as the class name.
- #
- # ==== Examples
- #
- # class Foo::Bar < Bundler::Thor
- # def baz
- # end
- # end
- #
- # class Baz::Foo < Bundler::Thor::Group
- # end
- #
- # Bundler::Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default command
- # Bundler::Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil
- # Bundler::Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz"
- #
- # ==== Parameters
- # namespace<String>
- #
- def find_class_and_command_by_namespace(namespace, fallback = true)
- if namespace.include?(":") # look for a namespaced command
- pieces = namespace.split(":")
- command = pieces.pop
- klass = Bundler::Thor::Util.find_by_namespace(pieces.join(":"))
- end
- unless klass # look for a Bundler::Thor::Group with the right name
- klass = Bundler::Thor::Util.find_by_namespace(namespace)
- command = nil
- end
- if !klass && fallback # try a command in the default namespace
- command = namespace
- klass = Bundler::Thor::Util.find_by_namespace("")
- end
- [klass, command]
- end
- alias_method :find_class_and_task_by_namespace, :find_class_and_command_by_namespace
-
- # Receives a path and load the thor file in the path. The file is evaluated
- # inside the sandbox to avoid namespacing conflicts.
- #
- def load_thorfile(path, content = nil, debug = false)
- content ||= File.binread(path)
-
- begin
- Bundler::Thor::Sandbox.class_eval(content, path)
- rescue StandardError => e
- $stderr.puts("WARNING: unable to load thorfile #{path.inspect}: #{e.message}")
- if debug
- $stderr.puts(*e.backtrace)
- else
- $stderr.puts(e.backtrace.first)
- end
- end
- end
-
- def user_home
- @@user_home ||= if ENV["HOME"]
- ENV["HOME"]
- elsif ENV["USERPROFILE"]
- ENV["USERPROFILE"]
- elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"]
- File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"])
- elsif ENV["APPDATA"]
- ENV["APPDATA"]
- else
- begin
- File.expand_path("~")
- rescue
- if File::ALT_SEPARATOR
- "C:/"
- else
- "/"
- end
- end
- end
- end
-
- # Returns the root where thor files are located, depending on the OS.
- #
- def thor_root
- File.join(user_home, ".thor").tr('\\', "/")
- end
-
- # Returns the files in the thor root. On Windows thor_root will be something
- # like this:
- #
- # C:\Documents and Settings\james\.thor
- #
- # If we don't #gsub the \ character, Dir.glob will fail.
- #
- def thor_root_glob
- files = Dir["#{escape_globs(thor_root)}/*"]
-
- files.map! do |file|
- File.directory?(file) ? File.join(file, "main.thor") : file
- end
- end
-
- # Where to look for Bundler::Thor files.
- #
- def globs_for(path)
- path = escape_globs(path)
- ["#{path}/Bundler::Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
- end
-
- # Return the path to the ruby interpreter taking into account multiple
- # installations and windows extensions.
- #
- def ruby_command
- @ruby_command ||= begin
- ruby_name = RbConfig::CONFIG["ruby_install_name"]
- ruby = File.join(RbConfig::CONFIG["bindir"], ruby_name)
- ruby << RbConfig::CONFIG["EXEEXT"]
-
- # avoid using different name than ruby (on platforms supporting links)
- if ruby_name != "ruby" && File.respond_to?(:readlink)
- begin
- alternate_ruby = File.join(RbConfig::CONFIG["bindir"], "ruby")
- alternate_ruby << RbConfig::CONFIG["EXEEXT"]
-
- # ruby is a symlink
- if File.symlink? alternate_ruby
- linked_ruby = File.readlink alternate_ruby
-
- # symlink points to 'ruby_install_name'
- ruby = alternate_ruby if linked_ruby == ruby_name || linked_ruby == ruby
- end
- rescue NotImplementedError # rubocop:disable HandleExceptions
- # just ignore on windows
- end
- end
-
- # escape string in case path to ruby executable contain spaces.
- ruby.sub!(/.*\s.*/m, '"\&"')
- ruby
- end
- end
-
- # Returns a string that has had any glob characters escaped.
- # The glob characters are `* ? { } [ ]`.
- #
- # ==== Examples
- #
- # Bundler::Thor::Util.escape_globs('[apps]') # => '\[apps\]'
- #
- # ==== Parameters
- # String
- #
- # ==== Returns
- # String
- #
- def escape_globs(path)
- path.to_s.gsub(/[*?{}\[\]]/, '\\\\\\&')
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/version.rb b/lib/bundler/vendor/thor/lib/thor/version.rb
deleted file mode 100644
index df8f18821a..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/version.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Bundler::Thor
- VERSION = "0.20.0"
-end
diff --git a/lib/bundler/vendored_fileutils.rb b/lib/bundler/vendored_fileutils.rb
deleted file mode 100644
index d14e98baf7..0000000000
--- a/lib/bundler/vendored_fileutils.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler; end
-if RUBY_VERSION >= "2.4"
- require "bundler/vendor/fileutils/lib/fileutils"
-else
- # the version we vendor is 2.4+
- require "fileutils"
-end
diff --git a/lib/bundler/vendored_molinillo.rb b/lib/bundler/vendored_molinillo.rb
deleted file mode 100644
index 061b634f72..0000000000
--- a/lib/bundler/vendored_molinillo.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler; end
-require "bundler/vendor/molinillo/lib/molinillo"
diff --git a/lib/bundler/vendored_persistent.rb b/lib/bundler/vendored_persistent.rb
deleted file mode 100644
index de9c42fcc1..0000000000
--- a/lib/bundler/vendored_persistent.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-# We forcibly require OpenSSL, because net/http/persistent will only autoload
-# it. On some Rubies, autoload fails but explicit require succeeds.
-begin
- require "openssl"
-rescue LoadError
- # some Ruby builds don't have OpenSSL
-end
-module Bundler
- module Persistent
- module Net
- module HTTP
- end
- end
- end
-end
-require "bundler/vendor/net-http-persistent/lib/net/http/persistent"
-
-module Bundler
- class PersistentHTTP < Persistent::Net::HTTP::Persistent
- def connection_for(uri)
- connection = super
- warn_old_tls_version_rubygems_connection(uri, connection)
- connection
- end
-
- def warn_old_tls_version_rubygems_connection(uri, connection)
- return unless connection.use_ssl?
- return unless (uri.host || "").end_with?("rubygems.org")
-
- socket = connection.instance_variable_get(:@socket)
- return unless socket
- socket_io = socket.io
- return unless socket_io.respond_to?(:ssl_version)
- ssl_version = socket_io.ssl_version
-
- case ssl_version
- when /TLSv([\d\.]+)/
- version = Gem::Version.new($1)
- if version < Gem::Version.new("1.2")
- Bundler.ui.warn \
- "Warning: Your Ruby version is compiled against a copy of OpenSSL that is very old. " \
- "Starting in January 2018, RubyGems.org will refuse connection requests from these " \
- "very old versions of OpenSSL. If you will need to continue installing gems after " \
- "January 2018, please follow this guide to upgrade: http://ruby.to/tls-outdated.",
- :wrap => true
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendored_thor.rb b/lib/bundler/vendored_thor.rb
deleted file mode 100644
index 8cca090f55..0000000000
--- a/lib/bundler/vendored_thor.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- def self.require_thor_actions
- Kernel.send(:require, "bundler/vendor/thor/lib/thor/actions")
- end
-end
-require "bundler/vendor/thor/lib/thor"
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
deleted file mode 100644
index 87b648681a..0000000000
--- a/lib/bundler/version.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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 = "1.16.1" unless defined?(::Bundler::VERSION)
-
- def self.overwrite_loaded_gem_version
- begin
- require "rubygems"
- rescue LoadError
- return
- end
- return unless bundler_spec = Gem.loaded_specs["bundler"]
- return if bundler_spec.version == VERSION
- bundler_spec.version = Bundler::VERSION
- end
- private_class_method :overwrite_loaded_gem_version
- overwrite_loaded_gem_version
-
- def self.bundler_major_version
- @bundler_major_version ||= VERSION.split(".").first.to_i
- end
-end
diff --git a/lib/bundler/version_ranges.rb b/lib/bundler/version_ranges.rb
deleted file mode 100644
index ec25716cde..0000000000
--- a/lib/bundler/version_ranges.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module VersionRanges
- NEq = Struct.new(:version)
- ReqR = Struct.new(:left, :right)
- class ReqR
- Endpoint = Struct.new(:version, :inclusive)
- def to_s
- "#{left.inclusive ? "[" : "("}#{left.version}, #{right.version}#{right.inclusive ? "]" : ")"}"
- end
- INFINITY = Object.new.freeze
- ZERO = Gem::Version.new("0.a")
-
- def cover?(v)
- return false if left.inclusive && left.version > v
- return false if !left.inclusive && left.version >= v
-
- if right.version != INFINITY
- return false if right.inclusive && right.version < v
- return false if !right.inclusive && right.version <= v
- end
-
- true
- end
-
- def empty?
- left.version == right.version && !(left.inclusive && right.inclusive)
- end
-
- def single?
- left.version == right.version
- end
-
- UNIVERSAL = ReqR.new(ReqR::Endpoint.new(Gem::Version.new("0.a"), true), ReqR::Endpoint.new(ReqR::INFINITY, false)).freeze
- end
-
- def self.for_many(requirements)
- requirements = requirements.map(&:requirements).flatten(1).map {|r| r.join(" ") }
- requirements << ">= 0.a" if requirements.empty?
- requirement = Gem::Requirement.new(requirements)
- self.for(requirement)
- end
-
- def self.for(requirement)
- ranges = requirement.requirements.map do |op, v|
- case op
- when "=" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(v, true))
- when "!=" then NEq.new(v)
- when ">=" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(ReqR::INFINITY, false))
- when ">" then ReqR.new(ReqR::Endpoint.new(v, false), ReqR::Endpoint.new(ReqR::INFINITY, false))
- when "<" then ReqR.new(ReqR::Endpoint.new(ReqR::ZERO, true), ReqR::Endpoint.new(v, false))
- when "<=" then ReqR.new(ReqR::Endpoint.new(ReqR::ZERO, true), ReqR::Endpoint.new(v, true))
- when "~>" then ReqR.new(ReqR::Endpoint.new(v, true), ReqR::Endpoint.new(v.bump, false))
- else raise "unknown version op #{op} in requirement #{requirement}"
- end
- 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)]
- end
-
- def self.empty?(ranges, neqs)
- !ranges.reduce(ReqR::UNIVERSAL) do |last_range, curr_range|
- next false unless last_range
- 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)
- when -1 then next false
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vlad.rb b/lib/bundler/vlad.rb
deleted file mode 100644
index 68181e7db8..0000000000
--- a/lib/bundler/vlad.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require "bundler/shared_helpers"
-Bundler::SharedHelpers.major_deprecation 2,
- "The Bundler task for Vlad"
-
-# Vlad task for Bundler.
-#
-# Add "require 'bundler/vlad'" in your Vlad deploy.rb, and
-# include the vlad:bundle:install task in your vlad:deploy task.
-require "bundler/deployment"
-
-include Rake::DSL if defined? Rake::DSL
-
-namespace :vlad do
- Bundler::Deployment.define_task(Rake::RemoteTask, :remote_task, :roles => :app)
-end
diff --git a/lib/bundler/worker.rb b/lib/bundler/worker.rb
deleted file mode 100644
index e91cfa7805..0000000000
--- a/lib/bundler/worker.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-# frozen_string_literal: true
-
-require "thread"
-
-module Bundler
- class Worker
- POISON = Object.new
-
- class WrappedException < StandardError
- attr_reader :exception
- def initialize(exn)
- @exception = exn
- end
- end
-
- # @return [String] the name of the worker
- attr_reader :name
-
- # Creates a worker pool of specified size
- #
- # @param size [Integer] Size of pool
- # @param name [String] name the name of the worker
- # @param func [Proc] job to run in inside the worker pool
- def initialize(size, name, func)
- @name = name
- @request_queue = Queue.new
- @response_queue = Queue.new
- @func = func
- @size = size
- @threads = nil
- SharedHelpers.trap("INT") { abort_threads }
- end
-
- # Enqueue a request to be executed in the worker pool
- #
- # @param obj [String] mostly it is name of spec that should be downloaded
- def enq(obj)
- create_threads unless @threads
- @request_queue.enq obj
- end
-
- # Retrieves results of job function being executed in worker pool
- def deq
- result = @response_queue.deq
- raise result.exception if result.is_a?(WrappedException)
- result
- end
-
- def stop
- stop_threads
- end
-
- private
-
- def process_queue(i)
- loop do
- obj = @request_queue.deq
- break if obj.equal? POISON
- @response_queue.enq apply_func(obj, i)
- end
- end
-
- def apply_func(obj, i)
- @func.call(obj, i)
- rescue Exception => e
- WrappedException.new(e)
- end
-
- # Stop the worker threads by sending a poison object down the request queue
- # so as worker threads after retrieving it, shut themselves down
- def stop_threads
- return unless @threads
- @threads.each { @request_queue.enq POISON }
- @threads.each(&:join)
- @threads = nil
- end
-
- def abort_threads
- return unless @threads
- Bundler.ui.debug("\n#{caller.join("\n")}")
- @threads.each(&:exit)
- exit 1
- end
-
- def create_threads
- creation_errors = []
-
- @threads = Array.new(@size) do |i|
- begin
- Thread.start { process_queue(i) }.tap do |thread|
- thread.name = "#{name} Worker ##{i}" if thread.respond_to?(:name=)
- end
- rescue ThreadError => e
- creation_errors << e
- nil
- end
- end.compact
-
- return if creation_errors.empty?
-
- message = "Failed to create threads for the #{name} worker: #{creation_errors.map(&:to_s).uniq.join(", ")}"
- raise ThreadCreationError, message if @threads.empty?
- Bundler.ui.info message
- end
- end
-end
diff --git a/lib/bundler/yaml_serializer.rb b/lib/bundler/yaml_serializer.rb
deleted file mode 100644
index 0fd81c40ef..0000000000
--- a/lib/bundler/yaml_serializer.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- # A stub yaml serializer that can handle only hashes and strings (as of now).
- module YAMLSerializer
- module_function
-
- def dump(hash)
- yaml = String.new("---")
- yaml << dump_hash(hash)
- end
-
- def dump_hash(hash)
- yaml = String.new("\n")
- hash.each do |k, v|
- yaml << k << ":"
- if v.is_a?(Hash)
- yaml << dump_hash(v).gsub(/^(?!$)/, " ") # indent all non-empty lines
- elsif v.is_a?(Array) # Expected to be array of strings
- yaml << "\n- " << v.map {|s| s.to_s.gsub(/\s+/, " ").inspect }.join("\n- ") << "\n"
- else
- yaml << " " << v.to_s.gsub(/\s+/, " ").inspect << "\n"
- end
- end
- yaml
- end
-
- ARRAY_REGEX = /
- ^
- (?:[ ]*-[ ]) # '- ' before array items
- (['"]?) # optional opening quote
- (.*) # value
- \1 # matching closing quote
- $
- /xo
-
- HASH_REGEX = /
- ^
- ([ ]*) # indentations
- (.+) # 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
-
- def load(str)
- res = {}
- stack = [res]
- last_hash = nil
- last_empty_key = nil
- str.split(/\r?\n/).each do |line|
- if match = HASH_REGEX.match(line)
- indent, key, quote, val = match.captures
- key = convert_to_backward_compatible_key(key)
- depth = indent.scan(/ /).length
- if quote.empty? && val.empty?
- new_hash = {}
- stack[depth][key] = new_hash
- stack[depth + 1] = new_hash
- last_empty_key = key
- last_hash = stack[depth]
- else
- stack[depth][key] = val
- end
- elsif match = ARRAY_REGEX.match(line)
- _, val = match.captures
- last_hash[last_empty_key] = [] unless last_hash[last_empty_key].is_a?(Array)
-
- last_hash[last_empty_key].push(val)
- end
- end
- res
- end
-
- # for settings' keys
- def convert_to_backward_compatible_key(key)
- key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z}
- key = key.gsub(".", "__") if key.include?(".")
- key
- end
-
- class << self
- private :dump_hash, :convert_to_backward_compatible_key
- end
- end
-end