diff options
146 files changed, 4682 insertions, 456 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb index 3b494a6cdf..df345539c8 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -50,7 +50,6 @@ module Bundler autoload :FeatureFlag, File.expand_path("bundler/feature_flag", __dir__) autoload :GemHelper, File.expand_path("bundler/gem_helper", __dir__) autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__) - autoload :GemRemoteFetcher, File.expand_path("bundler/gem_remote_fetcher", __dir__) autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__) autoload :Graph, File.expand_path("bundler/graph", __dir__) autoload :Index, File.expand_path("bundler/index", __dir__) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index d7f749a672..443458f2d9 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -783,7 +783,7 @@ module Bundler return unless SharedHelpers.md5_available? latest = Fetcher::CompactIndex. - new(nil, Source::Rubygems::Remote.new(URI("https://rubygems.org")), nil). + new(nil, Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org")), nil). send(:compact_index_client). instance_variable_get(:@cache). dependencies("bundler"). diff --git a/lib/bundler/cli/config.rb b/lib/bundler/cli/config.rb index 78e035aa02..8d2aba0916 100644 --- a/lib/bundler/cli/config.rb +++ b/lib/bundler/cli/config.rb @@ -25,7 +25,7 @@ module Bundler ["config", "get", ARGV[1]] end - SharedHelpers.major_deprecation 2, + SharedHelpers.major_deprecation 3, "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead." Base.new(options, name, value, self).run diff --git a/lib/bundler/cli/exec.rb b/lib/bundler/cli/exec.rb index 0a1edbdbbd..2bace6e77d 100644 --- a/lib/bundler/cli/exec.rb +++ b/lib/bundler/cli/exec.rb @@ -25,12 +25,12 @@ module Bundler 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) + return with_verbose_rubygems { kernel_load(bin_path, *args) } end - kernel_exec(bin_path, *args) + with_verbose_rubygems { kernel_exec(bin_path, *args) } else # exec using the given command - kernel_exec(cmd, *args) + with_verbose_rubygems { kernel_exec(cmd, *args) } end end @@ -89,5 +89,14 @@ module Bundler first_line = File.open(file, "rb") {|f| f.read(possibilities.map(&:size).max) } possibilities.any? {|shebang| first_line.start_with?(shebang) } end + + def with_verbose_rubygems + old_ui = Gem::DefaultUserInteraction.ui + Gem::DefaultUserInteraction.ui = nil + + yield + ensure + Gem::DefaultUserInteraction.ui = old_ui + end end end diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb index afd386bd54..529dd9c94d 100644 --- a/lib/bundler/cli/update.rb +++ b/lib/bundler/cli/update.rb @@ -22,7 +22,7 @@ module Bundler if Bundler.feature_flag.update_requires_all_flag? raise InvalidOption, "To update everything, pass the `--all` flag." end - SharedHelpers.major_deprecation 2, "Pass --all to `bundle update` to update everything" + SharedHelpers.major_deprecation 3, "Pass --all to `bundle update` to update everything" elsif !full_update && options[:all] raise InvalidOption, "Cannot specify --all along with specific options." end diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb index 5e1932e626..01739ec4aa 100644 --- a/lib/bundler/feature_flag.rb +++ b/lib/bundler/feature_flag.rb @@ -46,7 +46,7 @@ module Bundler settings_flag(:specific_platform) { bundler_3_mode? } settings_flag(:suppress_install_using_messages) { bundler_3_mode? } settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? } - settings_flag(:update_requires_all_flag) { bundler_3_mode? } + settings_flag(:update_requires_all_flag) { bundler_4_mode? } settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? } settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install } diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 7bda26770b..caf33bcfc9 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -97,7 +97,7 @@ module Bundler spec -= [nil, "ruby", ""] spec_file_name = "#{spec.join "-"}.gemspec" - uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz") + uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz") if uri.scheme == "file" path = Bundler.rubygems.correct_for_windows_path(uri.path) Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path)) @@ -244,7 +244,7 @@ module Bundler con = PersistentHTTP.new :name => "bundler", :proxy => :ENV if gem_proxy = Bundler.rubygems.configuration[:http_proxy] - con.proxy = URI.parse(gem_proxy) if gem_proxy != :no_proxy + con.proxy = Bundler::URI.parse(gem_proxy) if gem_proxy != :no_proxy end if remote_uri.scheme == "https" diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb index 73f125af91..498852c174 100644 --- a/lib/bundler/fetcher/downloader.rb +++ b/lib/bundler/fetcher/downloader.rb @@ -21,7 +21,7 @@ module Bundler when Net::HTTPSuccess, Net::HTTPNotModified response when Net::HTTPRedirection - new_uri = URI.parse(response["location"]) + new_uri = Bundler::URI.parse(response["location"]) if new_uri.host == uri.host new_uri.user = uri.user new_uri.password = uri.password diff --git a/lib/bundler/fetcher/index.rb b/lib/bundler/fetcher/index.rb index d2ad657fe6..034a225198 100644 --- a/lib/bundler/fetcher/index.rb +++ b/lib/bundler/fetcher/index.rb @@ -28,7 +28,7 @@ module Bundler spec -= [nil, "ruby", ""] spec_file_name = "#{spec.join "-"}.gemspec" - uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz") + uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz") if uri.scheme == "file" path = Bundler.rubygems.correct_for_windows_path(uri.path) Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path)) diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb index 273573e820..080697b02c 100644 --- a/lib/bundler/friendly_errors.rb +++ b/lib/bundler/friendly_errors.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "cgi" require_relative "vendored_thor" module Bundler @@ -114,6 +113,7 @@ module Bundler def issues_url(exception) message = exception.message.lines.first.tr(":", " ").chomp message = message.split("-").first if exception.is_a?(Errno) + require "cgi" "https://github.com/bundler/bundler/search?q=" \ "#{CGI.escape(message)}&type=Issues" end diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb index 46a6643233..7d4e382be8 100644 --- a/lib/bundler/gem_helper.rb +++ b/lib/bundler/gem_helper.rb @@ -73,8 +73,7 @@ module Bundler def build_gem file_name = nil - gem = ENV["GEM_COMMAND"] ? ENV["GEM_COMMAND"] : "gem" - sh("#{gem} build -V #{spec_path}".shellsplit) do + sh("#{gem_command} build -V #{spec_path}".shellsplit) 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") @@ -85,11 +84,10 @@ module Bundler def install_gem(built_gem_path = nil, local = false) built_gem_path ||= build_gem - gem = ENV["GEM_COMMAND"] ? ENV["GEM_COMMAND"] : "gem" - cmd = "#{gem} install #{built_gem_path}" + cmd = "#{gem_command} install #{built_gem_path}" cmd += " --local" if local - out, status = sh_with_status(cmd.shellsplit) - unless status.success? && out[/Successfully installed/] + _, status = sh_with_status(cmd.shellsplit) + unless status.success? raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" end Bundler.ui.confirm "#{name} (#{version}) installed." @@ -98,13 +96,13 @@ module Bundler protected def rubygem_push(path) - gem_command = %W[gem push #{path}] - gem_command << "--key" << gem_key if gem_key - gem_command << "--host" << allowed_push_host if allowed_push_host + cmd = %W[#{gem_command} push #{path}] + cmd << "--key" << gem_key if gem_key + cmd << "--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_with_input(gem_command) + sh_with_input(cmd) Bundler.ui.confirm "Pushed #{name} #{version} to #{gem_push_host}" end @@ -211,5 +209,9 @@ module Bundler def gem_push? !%w[n no nil false off 0].include?(ENV["gem_push"].to_s.downcase) end + + def gem_command + ENV["GEM_COMMAND"] ? ENV["GEM_COMMAND"] : "gem" + end end end diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb index 152d7d3f60..5b2ddb7db6 100644 --- a/lib/bundler/inline.rb +++ b/lib/bundler/inline.rb @@ -37,43 +37,48 @@ def gemfile(install = false, options = {}, &gemfile) ui.level = "silent" if opts.delete(:quiet) raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty? - old_root = Bundler.method(:root) - bundler_module = class << Bundler; self; end - bundler_module.send(:remove_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) + begin + old_root = Bundler.method(:root) + bundler_module = class << Bundler; self; end + bundler_module.send(:remove_method, :root) + def Bundler.root + Bundler::SharedHelpers.pwd.expand_path + end + old_gemfile = ENV["BUNDLE_GEMFILE"] + Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile" - Bundler.settings.temporary(:frozen => false) do - definition = builder.to_definition(nil, true) - def definition.lock(*); end - definition.validate_runtime! + Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins? + builder = Bundler::Dsl.new + builder.instance_eval(&gemfile) - missing_specs = proc do - definition.missing_specs? - end + Bundler.settings.temporary(:frozen => false) do + definition = builder.to_definition(nil, true) + def definition.lock(*); end + definition.validate_runtime! - Bundler.ui = install ? ui : Bundler::UI::Silent.new - if install || missing_specs.call - Bundler.settings.temporary(:inline => true, :disable_platform_warnings => 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}" + Bundler.ui = install ? ui : Bundler::UI::Silent.new + if install || definition.missing_specs? + Bundler.settings.temporary(:inline => true, :disable_platform_warnings => 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 + end + ensure + if bundler_module + bundler_module.send(:remove_method, :root) + bundler_module.send(:define_method, :root, old_root) end - runtime = Bundler::Runtime.new(nil, definition) - runtime.setup.require - end -ensure - if bundler_module - bundler_module.send(:remove_method, :root) - bundler_module.send(:define_method, :root, old_root) + if old_gemfile + ENV["BUNDLE_GEMFILE"] = old_gemfile + else + ENV.delete("BUNDLE_GEMFILE") + end end end diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index cbd04b2c90..32c8bb9557 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "uri" require_relative "match_platform" module Bundler diff --git a/lib/bundler/mirror.rb b/lib/bundler/mirror.rb index b15190e7e5..0e554bcc3f 100644 --- a/lib/bundler/mirror.rb +++ b/lib/bundler/mirror.rb @@ -47,7 +47,7 @@ module Bundler def fetch_valid_mirror_for(uri) downcased = uri.to_s.downcase - mirror = @mirrors[downcased] || @mirrors[URI(downcased).host] || Mirror.new(uri) + mirror = @mirrors[downcased] || @mirrors[Bundler::URI(downcased).host] || Mirror.new(uri) mirror.validate!(@prober) mirror = Mirror.new(uri) unless mirror.valid? mirror @@ -74,7 +74,7 @@ module Bundler @uri = if uri.nil? nil else - URI(uri.to_s) + Bundler::URI(uri.to_s) end @valid = nil end @@ -126,7 +126,7 @@ module Bundler if uri == "all" @all = true else - @uri = URI(uri).absolute? ? Settings.normalize_uri(uri) : uri + @uri = Bundler::URI(uri).absolute? ? Settings.normalize_uri(uri) : uri end @value = value end diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb index 3a2ca2f04d..56e97f4aa4 100644 --- a/lib/bundler/plugin/api/source.rb +++ b/lib/bundler/plugin/api/source.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "uri" - module Bundler module Plugin class API @@ -108,7 +106,7 @@ module Bundler def install_path @install_path ||= begin - base_name = File.basename(URI.parse(uri).normalize.path) + base_name = File.basename(Bundler::URI.parse(uri).normalize.path) gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}") end @@ -170,7 +168,7 @@ module Bundler # # This is used by `app_cache_path` def app_cache_dirname - base_name = File.basename(URI.parse(uri).normalize.path) + base_name = File.basename(Bundler::URI.parse(uri).normalize.path) "#{base_name}-#{uri_hash}" end diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb index 23e1234330..f87a09b9a6 100644 --- a/lib/bundler/remote_specification.rb +++ b/lib/bundler/remote_specification.rb @@ -1,7 +1,5 @@ # 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 diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index c4950d14e8..bb63209632 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -247,12 +247,6 @@ module Bundler EXT_LOCK end - def fetch_prerelease_specs - fetch_specs(false, true) - rescue Gem::RemoteFetcher::FetchError - {} # if we can't download them, there aren't any - end - def with_build_args(args) ext_lock.synchronize do old_args = build_args @@ -531,8 +525,8 @@ module Bundler end end - def fetch_specs(source, remote, name) - path = source + "#{name}.#{Gem.marshal_version}.gz" + def fetch_specs(remote, name) + path = remote.uri.to_s + "#{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) @@ -543,10 +537,8 @@ module Bundler 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 = fetch_specs(remote, "specs") + pres = fetch_specs(remote, "prerelease_specs") || [] specs.concat(pres) end @@ -564,7 +556,7 @@ module Bundler require "resolv" proxy = configuration[:http_proxy] dns = Resolv::DNS.new - Bundler::GemRemoteFetcher.new(proxy, dns) + Gem::RemoteFetcher.new(proxy, dns) end def gem_from_path(path, policy = nil) diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index 2074070e3e..afbb02397c 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "uri" - module Bundler class Settings autoload :Mirror, File.expand_path("mirror", __dir__) @@ -152,7 +150,11 @@ module Bundler end def mirror_for(uri) - uri = URI(uri.to_s) unless uri.is_a?(URI) + if uri.is_a?(String) + require_relative "vendored_uri" + uri = Bundler::URI(uri) + end + gem_mirrors.for(uri.to_s).uri end @@ -421,7 +423,8 @@ module Bundler suffix = $3 end uri = "#{uri}/" unless uri.end_with?("/") - uri = URI(uri) + require_relative "vendored_uri" + uri = Bundler::URI(uri) unless uri.absolute? raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri) end diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb index 736f5bb546..7c1533ad90 100644 --- a/lib/bundler/source/git.rb +++ b/lib/bundler/source/git.rb @@ -1,14 +1,13 @@ # frozen_string_literal: true require_relative "../vendored_fileutils" -require "uri" module Bundler class Source class Git < Path autoload :GitProxy, File.expand_path("git/git_proxy", __dir__) - attr_reader :uri, :ref, :branch, :options, :submodules + attr_reader :uri, :ref, :branch, :options, :glob, :submodules def initialize(options) @options = options @@ -48,13 +47,14 @@ module Bundler end def hash - [self.class, uri, ref, branch, name, version, submodules].hash + [self.class, uri, ref, branch, name, version, glob, 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 + version == other.version && glob == other.glob && + submodules == other.submodules end alias_method :==, :eql? @@ -284,7 +284,7 @@ module Bundler 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{/$}, "") + input = Bundler::URI.parse(uri).normalize.to_s.sub(%r{/$}, "") else # If there is no URI scheme, assume it is an ssh/git URI input = uri diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb index 2a4d7138a4..7612eb16c6 100644 --- a/lib/bundler/source/git/git_proxy.rb +++ b/lib/bundler/source/git/git_proxy.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "open3" require "shellwords" module Bundler @@ -218,7 +217,7 @@ module Bundler # Adds credentials to the URI as Fetcher#configured_uri_for does def configured_uri_for(uri) if /https?:/ =~ uri - remote = URI(uri) + remote = Bundler::URI(uri) config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host] remote.userinfo ||= config_auth remote.to_s @@ -243,12 +242,14 @@ module Bundler end def capture_and_filter_stderr(uri, cmd) + require "open3" return_value, captured_err, status = Open3.capture3(cmd) Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty? [return_value, status] end def capture_and_ignore_stderr(cmd) + require "open3" return_value, _, status = Open3.capture3(cmd) [return_value, status] end diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index 103faa6b80..6c0de204e7 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "uri" require "rubygems/user_interaction" module Bundler @@ -328,9 +327,10 @@ module Bundler def normalize_uri(uri) uri = uri.to_s uri = "#{uri}/" unless uri =~ %r{/$} - uri = URI(uri) + require_relative "../vendored_uri" + uri = Bundler::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?) + "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(Bundler::URI::HTTP) && uri.host.nil?) uri end diff --git a/lib/bundler/source/rubygems/remote.rb b/lib/bundler/source/rubygems/remote.rb index 7558b2cc3f..45ea61acb2 100644 --- a/lib/bundler/source/rubygems/remote.rb +++ b/lib/bundler/source/rubygems/remote.rb @@ -48,7 +48,7 @@ module Bundler end uri - rescue URI::InvalidComponentError + rescue Bundler::URI::InvalidComponentError error_message = "Please CGI escape your usernames and passwords before " \ "setting them for authentication." raise HTTPError.new(error_message) diff --git a/lib/bundler/uri_credentials_filter.rb b/lib/bundler/uri_credentials_filter.rb index ee3692268c..9b9e9c2799 100644 --- a/lib/bundler/uri_credentials_filter.rb +++ b/lib/bundler/uri_credentials_filter.rb @@ -7,7 +7,11 @@ module Bundler 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.is_a?(String) + require_relative "vendored_uri" + uri = Bundler::URI(uri) + end + if uri.userinfo # oauth authentication if uri.password == "x-oauth-basic" || uri.password == "x" @@ -17,9 +21,9 @@ module Bundler 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 + rescue Bundler::URI::InvalidURIError # uri is not canonical uri scheme uri end diff --git a/lib/bundler/vendor/fileutils/lib/fileutils.rb b/lib/bundler/vendor/fileutils/lib/fileutils.rb index c1988dceab..8f8faf30c8 100644 --- a/lib/bundler/vendor/fileutils/lib/fileutils.rb +++ b/lib/bundler/vendor/fileutils/lib/fileutils.rb @@ -6,8 +6,6 @@ rescue LoadError # for make mjit-headers end -require_relative "fileutils/version" - # # = fileutils.rb # @@ -104,6 +102,7 @@ require_relative "fileutils/version" # <tt>:verbose</tt> flags to methods in Bundler::FileUtils. # module Bundler::FileUtils + VERSION = "1.4.1" def self.private_module_function(name) #:nodoc: module_function name @@ -1300,7 +1299,8 @@ module Bundler::FileUtils .reject {|n| n == '.' or n == '..' } end - files.map {|n| Entry_.new(prefix(), join(rel(), n.tap{|x| x.untaint if RUBY_VERSION < "2.7" })) } + untaint = RUBY_VERSION < '2.7' + files.map {|n| Entry_.new(prefix(), join(rel(), untaint ? n.untaint : n)) } end def stat 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 index 327cb0f8c2..e9c4c3e89e 100644 --- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb @@ -1,5 +1,5 @@ require 'net/http' -require 'uri' +require_relative '../../../../uri/lib/uri' require 'cgi' # for escaping require_relative '../../../../connection_pool/lib/connection_pool' @@ -31,7 +31,7 @@ autoload :OpenSSL, 'openssl' # # require 'bundler/vendor/net-http-persistent/lib/net/http/persistent' # -# uri = URI 'http://example.com/awesome/web/service' +# uri = Bundler::URI 'http://example.com/awesome/web/service' # # http = Bundler::Persistent::Net::HTTP::Persistent.new name: 'my_app_name' # @@ -48,17 +48,17 @@ autoload :OpenSSL, 'openssl' # post = Net::HTTP::Post.new post_uri.path # post.set_form_data 'some' => 'cool data' # -# # perform the POST, the URI is always required +# # perform the POST, the Bundler::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 +# to use Bundler::URI#request_uri not Bundler::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 +# Bundler::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. # @@ -81,7 +81,7 @@ autoload :OpenSSL, 'openssl' # == 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 +# second argument to ::new. The proxy may be the Bundler::URI of the proxy server or # <code>:ENV</code> which will consult environment variables. # # See #proxy= and #proxy_from_env for details. @@ -150,7 +150,7 @@ autoload :OpenSSL, 'openssl' # # require 'bundler/vendor/net-http-persistent/lib/net/http/persistent' # -# uri = URI 'http://example.com/awesome/web/service' +# uri = Bundler::URI 'http://example.com/awesome/web/service' # post_uri = uri + 'create' # # http = Bundler::Persistent::Net::HTTP::Persistent.new name: 'my_app_name' @@ -249,7 +249,7 @@ class Bundler::Persistent::Net::HTTP::Persistent # 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 = Bundler::URI uri unless Bundler::URI::Generic === uri uri += '/' req = Net::HTTP::Head.new uri.request_uri @@ -513,13 +513,13 @@ class Bundler::Persistent::Net::HTTP::Persistent # 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 + # +proxy+ may be set to a Bundler::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: + # In order to use a Bundler::URI for the proxy you may need to do some extra work + # beyond Bundler::URI parsing if the proxy requires a password: # - # proxy = URI 'http://proxy.example' + # proxy = Bundler::URI 'http://proxy.example' # proxy.user = 'AzureDiamond' # proxy.password = 'hunter2' # @@ -566,7 +566,7 @@ class Bundler::Persistent::Net::HTTP::Persistent @verify_mode = nil @cert_store = nil - @generation = 0 # incremented when proxy URI changes + @generation = 0 # incremented when proxy Bundler::URI changes if HAVE_OPENSSL then @verify_mode = OpenSSL::SSL::VERIFY_PEER @@ -688,14 +688,14 @@ class Bundler::Persistent::Net::HTTP::Persistent end ## - # URI::escape wrapper + # Bundler::URI::escape wrapper def escape str CGI.escape str if str end ## - # URI::unescape wrapper + # Bundler::URI::unescape wrapper def unescape str CGI.unescape str if str @@ -803,12 +803,12 @@ class Bundler::Persistent::Net::HTTP::Persistent alias key= private_key= ## - # Sets the proxy server. The +proxy+ may be the URI of the proxy server, + # Sets the proxy server. The +proxy+ may be the Bundler::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 + # If the proxy Bundler::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 @@ -819,9 +819,9 @@ class Bundler::Persistent::Net::HTTP::Persistent def proxy= proxy @proxy_uri = case proxy when :ENV then proxy_from_env - when URI::HTTP then proxy + when Bundler::URI::HTTP then proxy when nil then # ignore - else raise ArgumentError, 'proxy must be :ENV or a URI::HTTP' + else raise ArgumentError, 'proxy must be :ENV or a Bundler::URI::HTTP' end @no_proxy.clear @@ -846,13 +846,13 @@ class Bundler::Persistent::Net::HTTP::Persistent end ## - # Creates a URI for an HTTP proxy server from ENV variables. + # Creates a Bundler::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 + # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the Bundler::URI is given the # indicated user and password unless HTTP_PROXY contains either of these in - # the URI. + # the Bundler::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 @@ -868,7 +868,7 @@ class Bundler::Persistent::Net::HTTP::Persistent return nil if env_proxy.nil? or env_proxy.empty? - uri = URI normalize_uri env_proxy + uri = Bundler::URI normalize_uri env_proxy env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY'] @@ -951,7 +951,7 @@ class Bundler::Persistent::Net::HTTP::Persistent retried = false bad_response = false - uri = URI uri + uri = Bundler::URI uri req = request_setup req || uri response = nil @@ -1024,13 +1024,13 @@ class Bundler::Persistent::Net::HTTP::Persistent end ## - # Creates a GET request if +req_or_uri+ is a URI and adds headers to the + # Creates a GET request if +req_or_uri+ is a Bundler::URI and adds headers to the # request. # # Returns the request. def request_setup req_or_uri # :nodoc: - req = if URI === req_or_uri then + req = if Bundler::URI === req_or_uri then Net::HTTP::Get.new req_or_uri.request_uri else req_or_uri diff --git a/lib/bundler/vendor/thor/lib/thor.rb b/lib/bundler/vendor/thor/lib/thor.rb index f2a03388cc..01c0b2f83c 100644 --- a/lib/bundler/vendor/thor/lib/thor.rb +++ b/lib/bundler/vendor/thor/lib/thor.rb @@ -344,6 +344,13 @@ class Bundler::Thor command && disable_required_check.include?(command.name.to_sym) end + def deprecation_warning(message) #:nodoc: + unless ENV['THOR_SILENCE_DEPRECATION'] + warn "Deprecation warning: #{message}\n" + + 'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.' + end + end + protected def stop_on_unknown_option #:nodoc: diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb index 39ce67e142..a5368d07f3 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions.rb @@ -1,5 +1,3 @@ -require "uri" -require_relative "core_ext/io_binary_read" require_relative "actions/create_file" require_relative "actions/create_link" require_relative "actions/directory" @@ -258,13 +256,19 @@ class Bundler::Thor return if options[:pretend] - result = config[:capture] ? `#{command}` : system(command.to_s) + env_splat = [config[:env]] if config[:env] - if config[:abort_on_failure] - success = config[:capture] ? $?.success? : result - abort unless success + if config[:capture] + require "open3" + result, status = Open3.capture2e(*env_splat, command.to_s) + success = status.success? + else + result = system(*env_splat, command.to_s) + success = result end + abort if !success && config.fetch(:abort_on_failure, self.class.exit_on_failure?) + result end diff --git a/lib/bundler/vendor/thor/lib/thor/base.rb b/lib/bundler/vendor/thor/lib/thor/base.rb index 6089fd3dc4..bd2ebb6156 100644 --- a/lib/bundler/vendor/thor/lib/thor/base.rb +++ b/lib/bundler/vendor/thor/lib/thor/base.rb @@ -153,17 +153,20 @@ class Bundler::Thor # 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. + # This will be the default; for compatibility a deprecation warning is issued if necessary. def check_default_type! @check_default_type = true end - def check_default_type #:nodoc: - @check_default_type ||= from_superclass(:check_default_type, false) + # If you want to use defaults that don't match the type of an option, + # either specify `check_default_type: false` or call `allow_incompatible_default_type!` + def allow_incompatible_default_type! + @check_default_type = false end - def check_default_type? #:nodoc: - !!check_default_type + def check_default_type #:nodoc: + @check_default_type = from_superclass(:check_default_type, nil) unless defined?(@check_default_type) + @check_default_type end # If true, option parsing is suspended as soon as an unknown option or a @@ -506,6 +509,12 @@ class Bundler::Thor raise InvocationError, msg end + # A flag that makes the process exit with status 1 if any error happens. + def exit_on_failure? + Bundler::Thor.deprecation_warning "Bundler::Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `#{self.name}`" + false + end + protected # Prints the class options per group. If an option does not belong to @@ -563,7 +572,7 @@ class Bundler::Thor # 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?)) + scope[name] = Bundler::Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options)) end # Receives a hash of options, parse them and add to the scope. This is a @@ -643,11 +652,6 @@ class Bundler::Thor 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. # diff --git a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb index a17a3fcf22..d0f43e2d97 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb @@ -82,7 +82,7 @@ class Bundler::Thor end def current_is_value? - peek && peek.to_s !~ /^-/ + peek && peek.to_s !~ /^-{1,2}\S+/ end # Runs through the argument array getting strings that contains ":" and diff --git a/lib/bundler/vendor/thor/lib/thor/parser/option.rb b/lib/bundler/vendor/thor/lib/thor/parser/option.rb index 0ddd472b43..5a5af6f888 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/option.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/option.rb @@ -112,7 +112,7 @@ class Bundler::Thor def validate! raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? - validate_default_type! if @check_default_type + validate_default_type! end def validate_default_type! @@ -130,7 +130,18 @@ class Bundler::Thor end expected_type = (@repeatable && @type != :hash) ? :array : @type - raise ArgumentError, "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == expected_type + + if default_type != expected_type + err = "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" + + if @check_default_type + raise ArgumentError, err + elsif @check_default_type == nil + Bundler::Thor.deprecation_warning "#{err}.\n" + + 'This will be rejected in the future unless you explicitly pass the options `check_default_type: false`' + + ' or call `allow_incompatible_default_type!` in your code' + end + end end def dasherized? diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb index 48d33d7ac3..54c5525093 100644 --- a/lib/bundler/vendor/thor/lib/thor/runner.rb +++ b/lib/bundler/vendor/thor/lib/thor/runner.rb @@ -1,6 +1,5 @@ require_relative "../thor" require_relative "group" -require_relative "core_ext/io_binary_read" require "yaml" require "digest/md5" @@ -67,7 +66,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng raise Error, "Error opening file '#{name}'" end - say "Your Bundler::Thorfile contains:" + say "Your Thorfile contains:" say contents unless options["force"] @@ -206,7 +205,7 @@ private 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 + # Load the 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 @@ -219,11 +218,11 @@ private end end - # Finds Bundler::Thorfiles by traversing from your current directory down to the root + # Finds 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. + # We also ensure that system-wide Thorfiles are loaded first, so local + # Thorfiles can override them. # # ==== Example # @@ -231,7 +230,7 @@ private # # 1. /Users/wycats/dev/thor # 2. /Users/wycats/dev - # 3. /Users/wycats <-- we find a Bundler::Thorfile here, so we stop + # 3. /Users/wycats <-- we find a Thorfile here, so we stop # # Suppose we start at c:\Documents and Settings\james\dev\thor ... # @@ -239,7 +238,7 @@ private # 2. c:\Documents and Settings\james\dev # 3. c:\Documents and Settings\james # 4. c:\Documents and Settings - # 5. c:\ <-- no Bundler::Thorfiles found! + # 5. c:\ <-- no Thorfiles found! # def thorfiles(relevant_to = nil, skip_lookup = false) thorfiles = [] @@ -260,7 +259,7 @@ private end end - # Load Bundler::Thorfiles relevant to the given method. If you provide "foo:bar" it + # Load 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. # diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb index 52648fee8f..be48358cb1 100644 --- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +++ b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb @@ -451,16 +451,25 @@ class Bundler::Thor def ask_filtered(statement, color, options) answer_set = options[:limited_to] + case_insensitive = options.fetch(:case_insensitive, false) 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 + correct_answer = answer_match(answer_set, answer, case_insensitive) say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer end correct_answer end + def answer_match(possibilities, answer, case_insensitive) + if case_insensitive + possibilities.detect{ |possibility| possibility.downcase == answer.downcase } + else + possibilities.detect{ |possibility| possibility == answer } + end + end + def merge(destination, content) #:nodoc: require "tempfile" Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp| diff --git a/lib/bundler/vendor/thor/lib/thor/shell/html.rb b/lib/bundler/vendor/thor/lib/thor/shell/html.rb index 55262f19cc..77a6d13a23 100644 --- a/lib/bundler/vendor/thor/lib/thor/shell/html.rb +++ b/lib/bundler/vendor/thor/lib/thor/shell/html.rb @@ -51,13 +51,13 @@ class Bundler::Thor 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>" + "<span style=\"#{html_colors.join('; ')};\">#{Bundler::Thor::Util.escape_html(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>" + "<span style=\"#{styles.join('; ')};\">#{Bundler::Thor::Util.escape_html(string)}</span>" end end diff --git a/lib/bundler/vendor/thor/lib/thor/util.rb b/lib/bundler/vendor/thor/lib/thor/util.rb index 0fe7d4d859..ddf4d21b90 100644 --- a/lib/bundler/vendor/thor/lib/thor/util.rb +++ b/lib/bundler/vendor/thor/lib/thor/util.rb @@ -211,7 +211,7 @@ class Bundler::Thor # def globs_for(path) path = escape_globs(path) - ["#{path}/Bundler::Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"] + ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"] end # Return the path to the ruby interpreter taking into account multiple @@ -263,6 +263,22 @@ class Bundler::Thor def escape_globs(path) path.to_s.gsub(/[*?{}\[\]]/, '\\\\\\&') end + + # Returns a string that has had any HTML characters escaped. + # + # ==== Examples + # + # Bundler::Thor::Util.escape_html('<div>') # => "<div>" + # + # ==== Parameters + # String + # + # ==== Returns + # String + # + def escape_html(string) + CGI.escapeHTML(string) + end end end end diff --git a/lib/bundler/vendor/uri/lib/uri.rb b/lib/bundler/vendor/uri/lib/uri.rb new file mode 100644 index 0000000000..00c01bd07b --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: false +# Bundler::URI is a module providing classes to handle Uniform Resource Identifiers +# (RFC2396[http://tools.ietf.org/html/rfc2396]). +# +# == Features +# +# * Uniform way of handling URIs. +# * Flexibility to introduce custom Bundler::URI schemes. +# * Flexibility to have an alternate Bundler::URI::Parser (or just different patterns +# and regexp's). +# +# == Basic example +# +# require 'bundler/vendor/uri/lib/uri' +# +# uri = Bundler::URI("http://foo.com/posts?id=30&limit=5#time=1305298413") +# #=> #<Bundler::URI::HTTP http://foo.com/posts?id=30&limit=5#time=1305298413> +# +# uri.scheme #=> "http" +# uri.host #=> "foo.com" +# uri.path #=> "/posts" +# uri.query #=> "id=30&limit=5" +# uri.fragment #=> "time=1305298413" +# +# uri.to_s #=> "http://foo.com/posts?id=30&limit=5#time=1305298413" +# +# == Adding custom URIs +# +# module Bundler::URI +# class RSYNC < Generic +# DEFAULT_PORT = 873 +# end +# @@schemes['RSYNC'] = RSYNC +# end +# #=> Bundler::URI::RSYNC +# +# Bundler::URI.scheme_list +# #=> {"FILE"=>Bundler::URI::File, "FTP"=>Bundler::URI::FTP, "HTTP"=>Bundler::URI::HTTP, +# # "HTTPS"=>Bundler::URI::HTTPS, "LDAP"=>Bundler::URI::LDAP, "LDAPS"=>Bundler::URI::LDAPS, +# # "MAILTO"=>Bundler::URI::MailTo, "RSYNC"=>Bundler::URI::RSYNC} +# +# uri = Bundler::URI("rsync://rsync.foo.com") +# #=> #<Bundler::URI::RSYNC rsync://rsync.foo.com> +# +# == RFC References +# +# A good place to view an RFC spec is http://www.ietf.org/rfc.html. +# +# Here is a list of all related RFC's: +# - RFC822[http://tools.ietf.org/html/rfc822] +# - RFC1738[http://tools.ietf.org/html/rfc1738] +# - RFC2255[http://tools.ietf.org/html/rfc2255] +# - RFC2368[http://tools.ietf.org/html/rfc2368] +# - RFC2373[http://tools.ietf.org/html/rfc2373] +# - RFC2396[http://tools.ietf.org/html/rfc2396] +# - RFC2732[http://tools.ietf.org/html/rfc2732] +# - RFC3986[http://tools.ietf.org/html/rfc3986] +# +# == Class tree +# +# - Bundler::URI::Generic (in uri/generic.rb) +# - Bundler::URI::File - (in uri/file.rb) +# - Bundler::URI::FTP - (in uri/ftp.rb) +# - Bundler::URI::HTTP - (in uri/http.rb) +# - Bundler::URI::HTTPS - (in uri/https.rb) +# - Bundler::URI::LDAP - (in uri/ldap.rb) +# - Bundler::URI::LDAPS - (in uri/ldaps.rb) +# - Bundler::URI::MailTo - (in uri/mailto.rb) +# - Bundler::URI::Parser - (in uri/common.rb) +# - Bundler::URI::REGEXP - (in uri/common.rb) +# - Bundler::URI::REGEXP::PATTERN - (in uri/common.rb) +# - Bundler::URI::Util - (in uri/common.rb) +# - Bundler::URI::Escape - (in uri/common.rb) +# - Bundler::URI::Error - (in uri/common.rb) +# - Bundler::URI::InvalidURIError - (in uri/common.rb) +# - Bundler::URI::InvalidComponentError - (in uri/common.rb) +# - Bundler::URI::BadURIError - (in uri/common.rb) +# +# == Copyright Info +# +# Author:: Akira Yamada <[email protected]> +# Documentation:: +# Akira Yamada <[email protected]> +# Dmitry V. Sabanin <[email protected]> +# Vincent Batts <[email protected]> +# License:: +# Copyright (c) 2001 akira yamada <[email protected]> +# You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id$ +# + +module Bundler::URI +end + +require_relative 'uri/version' +require_relative 'uri/common' +require_relative 'uri/generic' +require_relative 'uri/file' +require_relative 'uri/ftp' +require_relative 'uri/http' +require_relative 'uri/https' +require_relative 'uri/ldap' +require_relative 'uri/ldaps' +require_relative 'uri/mailto' diff --git a/lib/bundler/vendor/uri/lib/uri/common.rb b/lib/bundler/vendor/uri/lib/uri/common.rb new file mode 100644 index 0000000000..cc1ab86c2f --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/common.rb @@ -0,0 +1,744 @@ +# frozen_string_literal: true +#-- +# = uri/common.rb +# +# Author:: Akira Yamada <[email protected]> +# Revision:: $Id$ +# License:: +# You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative "rfc2396_parser" +require_relative "rfc3986_parser" + +module Bundler::URI + REGEXP = RFC2396_REGEXP + Parser = RFC2396_Parser + RFC3986_PARSER = RFC3986_Parser.new + + # Bundler::URI::Parser.new + DEFAULT_PARSER = Parser.new + DEFAULT_PARSER.pattern.each_pair do |sym, str| + unless REGEXP::PATTERN.const_defined?(sym) + REGEXP::PATTERN.const_set(sym, str) + end + end + DEFAULT_PARSER.regexp.each_pair do |sym, str| + const_set(sym, str) + end + + module Util # :nodoc: + def make_components_hash(klass, array_hash) + tmp = {} + if array_hash.kind_of?(Array) && + array_hash.size == klass.component.size - 1 + klass.component[1..-1].each_index do |i| + begin + tmp[klass.component[i + 1]] = array_hash[i].clone + rescue TypeError + tmp[klass.component[i + 1]] = array_hash[i] + end + end + + elsif array_hash.kind_of?(Hash) + array_hash.each do |key, value| + begin + tmp[key] = value.clone + rescue TypeError + tmp[key] = value + end + end + else + raise ArgumentError, + "expected Array of or Hash of components of #{klass} (#{klass.component[1..-1].join(', ')})" + end + tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase + + return tmp + end + module_function :make_components_hash + end + + # Module for escaping unsafe characters with codes. + module Escape + # + # == Synopsis + # + # Bundler::URI.escape(str [, unsafe]) + # + # == Args + # + # +str+:: + # String to replaces in. + # +unsafe+:: + # Regexp that matches all symbols that must be replaced with codes. + # By default uses <tt>UNSAFE</tt>. + # When this argument is a String, it represents a character set. + # + # == Description + # + # Escapes the string, replacing all unsafe characters with codes. + # + # This method is obsolete and should not be used. Instead, use + # CGI.escape, Bundler::URI.encode_www_form or Bundler::URI.encode_www_form_component + # depending on your specific use case. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # enc_uri = Bundler::URI.escape("http://example.com/?a=\11\15") + # # => "http://example.com/?a=%09%0D" + # + # Bundler::URI.unescape(enc_uri) + # # => "http://example.com/?a=\t\r" + # + # Bundler::URI.escape("@?@!", "!?") + # # => "@%3F@%21" + # + def escape(*arg) + warn "Bundler::URI.escape is obsolete", uplevel: 1 + DEFAULT_PARSER.escape(*arg) + end + alias encode escape + # + # == Synopsis + # + # Bundler::URI.unescape(str) + # + # == Args + # + # +str+:: + # String to unescape. + # + # == Description + # + # This method is obsolete and should not be used. Instead, use + # CGI.unescape, Bundler::URI.decode_www_form or Bundler::URI.decode_www_form_component + # depending on your specific use case. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # enc_uri = Bundler::URI.escape("http://example.com/?a=\11\15") + # # => "http://example.com/?a=%09%0D" + # + # Bundler::URI.unescape(enc_uri) + # # => "http://example.com/?a=\t\r" + # + def unescape(*arg) + warn "Bundler::URI.unescape is obsolete", uplevel: 1 + DEFAULT_PARSER.unescape(*arg) + end + alias decode unescape + end # module Escape + + extend Escape + include REGEXP + + @@schemes = {} + # Returns a Hash of the defined schemes. + def self.scheme_list + @@schemes + end + + # + # Base class for all Bundler::URI exceptions. + # + class Error < StandardError; end + # + # Not a Bundler::URI. + # + class InvalidURIError < Error; end + # + # Not a Bundler::URI component. + # + class InvalidComponentError < Error; end + # + # Bundler::URI is valid, bad usage is not. + # + class BadURIError < Error; end + + # + # == Synopsis + # + # Bundler::URI::split(uri) + # + # == Args + # + # +uri+:: + # String with Bundler::URI. + # + # == Description + # + # Splits the string on following parts and returns array with result: + # + # * Scheme + # * Userinfo + # * Host + # * Port + # * Registry + # * Path + # * Opaque + # * Query + # * Fragment + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # Bundler::URI.split("http://www.ruby-lang.org/") + # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil] + # + def self.split(uri) + RFC3986_PARSER.split(uri) + end + + # + # == Synopsis + # + # Bundler::URI::parse(uri_str) + # + # == Args + # + # +uri_str+:: + # String with Bundler::URI. + # + # == Description + # + # Creates one of the Bundler::URI's subclasses instance from the string. + # + # == Raises + # + # Bundler::URI::InvalidURIError:: + # Raised if Bundler::URI given is not a correct one. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://www.ruby-lang.org/") + # # => #<Bundler::URI::HTTP http://www.ruby-lang.org/> + # uri.scheme + # # => "http" + # uri.host + # # => "www.ruby-lang.org" + # + # It's recommended to first ::escape the provided +uri_str+ if there are any + # invalid Bundler::URI characters. + # + def self.parse(uri) + RFC3986_PARSER.parse(uri) + end + + # + # == Synopsis + # + # Bundler::URI::join(str[, str, ...]) + # + # == Args + # + # +str+:: + # String(s) to work with, will be converted to RFC3986 URIs before merging. + # + # == Description + # + # Joins URIs. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # Bundler::URI.join("http://example.com/","main.rbx") + # # => #<Bundler::URI::HTTP http://example.com/main.rbx> + # + # Bundler::URI.join('http://example.com', 'foo') + # # => #<Bundler::URI::HTTP http://example.com/foo> + # + # Bundler::URI.join('http://example.com', '/foo', '/bar') + # # => #<Bundler::URI::HTTP http://example.com/bar> + # + # Bundler::URI.join('http://example.com', '/foo', 'bar') + # # => #<Bundler::URI::HTTP http://example.com/bar> + # + # Bundler::URI.join('http://example.com', '/foo/', 'bar') + # # => #<Bundler::URI::HTTP http://example.com/foo/bar> + # + def self.join(*str) + RFC3986_PARSER.join(*str) + end + + # + # == Synopsis + # + # Bundler::URI::extract(str[, schemes][,&blk]) + # + # == Args + # + # +str+:: + # String to extract URIs from. + # +schemes+:: + # Limit Bundler::URI matching to specific schemes. + # + # == Description + # + # Extracts URIs from a string. If block given, iterates through all matched URIs. + # Returns nil if block given or array with matches. + # + # == Usage + # + # require "bundler/vendor/uri/lib/uri" + # + # Bundler::URI.extract("text here http://foo.example.org/bla and here mailto:[email protected] and here also.") + # # => ["http://foo.example.com/bla", "mailto:[email protected]"] + # + def self.extract(str, schemes = nil, &block) + warn "Bundler::URI.extract is obsolete", uplevel: 1 if $VERBOSE + DEFAULT_PARSER.extract(str, schemes, &block) + end + + # + # == Synopsis + # + # Bundler::URI::regexp([match_schemes]) + # + # == Args + # + # +match_schemes+:: + # Array of schemes. If given, resulting regexp matches to URIs + # whose scheme is one of the match_schemes. + # + # == Description + # + # Returns a Regexp object which matches to Bundler::URI-like strings. + # The Regexp object returned by this method includes arbitrary + # number of capture group (parentheses). Never rely on it's number. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # # extract first Bundler::URI from html_string + # html_string.slice(Bundler::URI.regexp) + # + # # remove ftp URIs + # html_string.sub(Bundler::URI.regexp(['ftp']), '') + # + # # You should not rely on the number of parentheses + # html_string.scan(Bundler::URI.regexp) do |*matches| + # p $& + # end + # + def self.regexp(schemes = nil) + warn "Bundler::URI.regexp is obsolete", uplevel: 1 if $VERBOSE + DEFAULT_PARSER.make_regexp(schemes) + end + + TBLENCWWWCOMP_ = {} # :nodoc: + 256.times do |i| + TBLENCWWWCOMP_[-i.chr] = -('%%%02X' % i) + end + TBLENCWWWCOMP_[' '] = '+' + TBLENCWWWCOMP_.freeze + TBLDECWWWCOMP_ = {} # :nodoc: + 256.times do |i| + h, l = i>>4, i&15 + TBLDECWWWCOMP_[-('%%%X%X' % [h, l])] = -i.chr + TBLDECWWWCOMP_[-('%%%x%X' % [h, l])] = -i.chr + TBLDECWWWCOMP_[-('%%%X%x' % [h, l])] = -i.chr + TBLDECWWWCOMP_[-('%%%x%x' % [h, l])] = -i.chr + end + TBLDECWWWCOMP_['+'] = ' ' + TBLDECWWWCOMP_.freeze + + # Encodes given +str+ to URL-encoded form data. + # + # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP + # (ASCII space) to + and converts others to %XX. + # + # If +enc+ is given, convert +str+ to the encoding before percent encoding. + # + # This is an implementation of + # http://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data. + # + # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form. + def self.encode_www_form_component(str, enc=nil) + str = str.to_s.dup + if str.encoding != Encoding::ASCII_8BIT + if enc && enc != Encoding::ASCII_8BIT + str.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) + str.encode!(enc, fallback: ->(x){"&##{x.ord};"}) + end + str.force_encoding(Encoding::ASCII_8BIT) + end + str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_) + str.force_encoding(Encoding::US_ASCII) + end + + # Decodes given +str+ of URL-encoded form data. + # + # This decodes + to SP. + # + # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form. + def self.decode_www_form_component(str, enc=Encoding::UTF_8) + raise ArgumentError, "invalid %-encoding (#{str})" if /%(?!\h\h)/ =~ str + str.b.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc) + end + + # Generates URL-encoded form data from given +enum+. + # + # This generates application/x-www-form-urlencoded data defined in HTML5 + # from given an Enumerable object. + # + # This internally uses Bundler::URI.encode_www_form_component(str). + # + # This method doesn't convert the encoding of given items, so convert them + # before calling this method if you want to send data as other than original + # encoding or mixed encoding data. (Strings which are encoded in an HTML5 + # ASCII incompatible encoding are converted to UTF-8.) + # + # This method doesn't handle files. When you send a file, use + # multipart/form-data. + # + # This refers http://url.spec.whatwg.org/#concept-urlencoded-serializer + # + # Bundler::URI.encode_www_form([["q", "ruby"], ["lang", "en"]]) + # #=> "q=ruby&lang=en" + # Bundler::URI.encode_www_form("q" => "ruby", "lang" => "en") + # #=> "q=ruby&lang=en" + # Bundler::URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en") + # #=> "q=ruby&q=perl&lang=en" + # Bundler::URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]]) + # #=> "q=ruby&q=perl&lang=en" + # + # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form. + def self.encode_www_form(enum, enc=nil) + enum.map do |k,v| + if v.nil? + encode_www_form_component(k, enc) + elsif v.respond_to?(:to_ary) + v.to_ary.map do |w| + str = encode_www_form_component(k, enc) + unless w.nil? + str << '=' + str << encode_www_form_component(w, enc) + end + end.join('&') + else + str = encode_www_form_component(k, enc) + str << '=' + str << encode_www_form_component(v, enc) + end + end.join('&') + end + + # Decodes URL-encoded form data from given +str+. + # + # This decodes application/x-www-form-urlencoded data + # and returns an array of key-value arrays. + # + # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser, + # so this supports only &-separator, and doesn't support ;-separator. + # + # ary = Bundler::URI.decode_www_form("a=1&a=2&b=3") + # ary #=> [['a', '1'], ['a', '2'], ['b', '3']] + # ary.assoc('a').last #=> '1' + # ary.assoc('b').last #=> '3' + # ary.rassoc('a').last #=> '2' + # Hash[ary] #=> {"a"=>"2", "b"=>"3"} + # + # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form. + def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false) + raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only? + ary = [] + return ary if str.empty? + enc = Encoding.find(enc) + str.b.each_line(separator) do |string| + string.chomp!(separator) + key, sep, val = string.partition('=') + if isindex + if sep.empty? + val = key + key = +'' + end + isindex = false + end + + if use__charset_ and key == '_charset_' and e = get_encoding(val) + enc = e + use__charset_ = false + end + + key.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_) + if val + val.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_) + else + val = +'' + end + + ary << [key, val] + end + ary.each do |k, v| + k.force_encoding(enc) + k.scrub! + v.force_encoding(enc) + v.scrub! + end + ary + end + + private +=begin command for WEB_ENCODINGS_ + curl https://encoding.spec.whatwg.org/encodings.json| + ruby -rjson -e 'H={} + h={ + "shift_jis"=>"Windows-31J", + "euc-jp"=>"cp51932", + "iso-2022-jp"=>"cp50221", + "x-mac-cyrillic"=>"macCyrillic", + } + JSON($<.read).map{|x|x["encodings"]}.flatten.each{|x| + Encoding.find(n=h.fetch(n=x["name"].downcase,n))rescue next + x["labels"].each{|y|H[y]=n} + } + puts "{" + H.each{|k,v|puts %[ #{k.dump}=>#{v.dump},]} + puts "}" +' +=end + WEB_ENCODINGS_ = { + "unicode-1-1-utf-8"=>"utf-8", + "utf-8"=>"utf-8", + "utf8"=>"utf-8", + "866"=>"ibm866", + "cp866"=>"ibm866", + "csibm866"=>"ibm866", + "ibm866"=>"ibm866", + "csisolatin2"=>"iso-8859-2", + "iso-8859-2"=>"iso-8859-2", + "iso-ir-101"=>"iso-8859-2", + "iso8859-2"=>"iso-8859-2", + "iso88592"=>"iso-8859-2", + "iso_8859-2"=>"iso-8859-2", + "iso_8859-2:1987"=>"iso-8859-2", + "l2"=>"iso-8859-2", + "latin2"=>"iso-8859-2", + "csisolatin3"=>"iso-8859-3", + "iso-8859-3"=>"iso-8859-3", + "iso-ir-109"=>"iso-8859-3", + "iso8859-3"=>"iso-8859-3", + "iso88593"=>"iso-8859-3", + "iso_8859-3"=>"iso-8859-3", + "iso_8859-3:1988"=>"iso-8859-3", + "l3"=>"iso-8859-3", + "latin3"=>"iso-8859-3", + "csisolatin4"=>"iso-8859-4", + "iso-8859-4"=>"iso-8859-4", + "iso-ir-110"=>"iso-8859-4", + "iso8859-4"=>"iso-8859-4", + "iso88594"=>"iso-8859-4", + "iso_8859-4"=>"iso-8859-4", + "iso_8859-4:1988"=>"iso-8859-4", + "l4"=>"iso-8859-4", + "latin4"=>"iso-8859-4", + "csisolatincyrillic"=>"iso-8859-5", + "cyrillic"=>"iso-8859-5", + "iso-8859-5"=>"iso-8859-5", + "iso-ir-144"=>"iso-8859-5", + "iso8859-5"=>"iso-8859-5", + "iso88595"=>"iso-8859-5", + "iso_8859-5"=>"iso-8859-5", + "iso_8859-5:1988"=>"iso-8859-5", + "arabic"=>"iso-8859-6", + "asmo-708"=>"iso-8859-6", + "csiso88596e"=>"iso-8859-6", + "csiso88596i"=>"iso-8859-6", + "csisolatinarabic"=>"iso-8859-6", + "ecma-114"=>"iso-8859-6", + "iso-8859-6"=>"iso-8859-6", + "iso-8859-6-e"=>"iso-8859-6", + "iso-8859-6-i"=>"iso-8859-6", + "iso-ir-127"=>"iso-8859-6", + "iso8859-6"=>"iso-8859-6", + "iso88596"=>"iso-8859-6", + "iso_8859-6"=>"iso-8859-6", + "iso_8859-6:1987"=>"iso-8859-6", + "csisolatingreek"=>"iso-8859-7", + "ecma-118"=>"iso-8859-7", + "elot_928"=>"iso-8859-7", + "greek"=>"iso-8859-7", + "greek8"=>"iso-8859-7", + "iso-8859-7"=>"iso-8859-7", + "iso-ir-126"=>"iso-8859-7", + "iso8859-7"=>"iso-8859-7", + "iso88597"=>"iso-8859-7", + "iso_8859-7"=>"iso-8859-7", + "iso_8859-7:1987"=>"iso-8859-7", + "sun_eu_greek"=>"iso-8859-7", + "csiso88598e"=>"iso-8859-8", + "csisolatinhebrew"=>"iso-8859-8", + "hebrew"=>"iso-8859-8", + "iso-8859-8"=>"iso-8859-8", + "iso-8859-8-e"=>"iso-8859-8", + "iso-ir-138"=>"iso-8859-8", + "iso8859-8"=>"iso-8859-8", + "iso88598"=>"iso-8859-8", + "iso_8859-8"=>"iso-8859-8", + "iso_8859-8:1988"=>"iso-8859-8", + "visual"=>"iso-8859-8", + "csisolatin6"=>"iso-8859-10", + "iso-8859-10"=>"iso-8859-10", + "iso-ir-157"=>"iso-8859-10", + "iso8859-10"=>"iso-8859-10", + "iso885910"=>"iso-8859-10", + "l6"=>"iso-8859-10", + "latin6"=>"iso-8859-10", + "iso-8859-13"=>"iso-8859-13", + "iso8859-13"=>"iso-8859-13", + "iso885913"=>"iso-8859-13", + "iso-8859-14"=>"iso-8859-14", + "iso8859-14"=>"iso-8859-14", + "iso885914"=>"iso-8859-14", + "csisolatin9"=>"iso-8859-15", + "iso-8859-15"=>"iso-8859-15", + "iso8859-15"=>"iso-8859-15", + "iso885915"=>"iso-8859-15", + "iso_8859-15"=>"iso-8859-15", + "l9"=>"iso-8859-15", + "iso-8859-16"=>"iso-8859-16", + "cskoi8r"=>"koi8-r", + "koi"=>"koi8-r", + "koi8"=>"koi8-r", + "koi8-r"=>"koi8-r", + "koi8_r"=>"koi8-r", + "koi8-ru"=>"koi8-u", + "koi8-u"=>"koi8-u", + "dos-874"=>"windows-874", + "iso-8859-11"=>"windows-874", + "iso8859-11"=>"windows-874", + "iso885911"=>"windows-874", + "tis-620"=>"windows-874", + "windows-874"=>"windows-874", + "cp1250"=>"windows-1250", + "windows-1250"=>"windows-1250", + "x-cp1250"=>"windows-1250", + "cp1251"=>"windows-1251", + "windows-1251"=>"windows-1251", + "x-cp1251"=>"windows-1251", + "ansi_x3.4-1968"=>"windows-1252", + "ascii"=>"windows-1252", + "cp1252"=>"windows-1252", + "cp819"=>"windows-1252", + "csisolatin1"=>"windows-1252", + "ibm819"=>"windows-1252", + "iso-8859-1"=>"windows-1252", + "iso-ir-100"=>"windows-1252", + "iso8859-1"=>"windows-1252", + "iso88591"=>"windows-1252", + "iso_8859-1"=>"windows-1252", + "iso_8859-1:1987"=>"windows-1252", + "l1"=>"windows-1252", + "latin1"=>"windows-1252", + "us-ascii"=>"windows-1252", + "windows-1252"=>"windows-1252", + "x-cp1252"=>"windows-1252", + "cp1253"=>"windows-1253", + "windows-1253"=>"windows-1253", + "x-cp1253"=>"windows-1253", + "cp1254"=>"windows-1254", + "csisolatin5"=>"windows-1254", + "iso-8859-9"=>"windows-1254", + "iso-ir-148"=>"windows-1254", + "iso8859-9"=>"windows-1254", + "iso88599"=>"windows-1254", + "iso_8859-9"=>"windows-1254", + "iso_8859-9:1989"=>"windows-1254", + "l5"=>"windows-1254", + "latin5"=>"windows-1254", + "windows-1254"=>"windows-1254", + "x-cp1254"=>"windows-1254", + "cp1255"=>"windows-1255", + "windows-1255"=>"windows-1255", + "x-cp1255"=>"windows-1255", + "cp1256"=>"windows-1256", + "windows-1256"=>"windows-1256", + "x-cp1256"=>"windows-1256", + "cp1257"=>"windows-1257", + "windows-1257"=>"windows-1257", + "x-cp1257"=>"windows-1257", + "cp1258"=>"windows-1258", + "windows-1258"=>"windows-1258", + "x-cp1258"=>"windows-1258", + "x-mac-cyrillic"=>"macCyrillic", + "x-mac-ukrainian"=>"macCyrillic", + "chinese"=>"gbk", + "csgb2312"=>"gbk", + "csiso58gb231280"=>"gbk", + "gb2312"=>"gbk", + "gb_2312"=>"gbk", + "gb_2312-80"=>"gbk", + "gbk"=>"gbk", + "iso-ir-58"=>"gbk", + "x-gbk"=>"gbk", + "gb18030"=>"gb18030", + "big5"=>"big5", + "big5-hkscs"=>"big5", + "cn-big5"=>"big5", + "csbig5"=>"big5", + "x-x-big5"=>"big5", + "cseucpkdfmtjapanese"=>"cp51932", + "euc-jp"=>"cp51932", + "x-euc-jp"=>"cp51932", + "csiso2022jp"=>"cp50221", + "iso-2022-jp"=>"cp50221", + "csshiftjis"=>"Windows-31J", + "ms932"=>"Windows-31J", + "ms_kanji"=>"Windows-31J", + "shift-jis"=>"Windows-31J", + "shift_jis"=>"Windows-31J", + "sjis"=>"Windows-31J", + "windows-31j"=>"Windows-31J", + "x-sjis"=>"Windows-31J", + "cseuckr"=>"euc-kr", + "csksc56011987"=>"euc-kr", + "euc-kr"=>"euc-kr", + "iso-ir-149"=>"euc-kr", + "korean"=>"euc-kr", + "ks_c_5601-1987"=>"euc-kr", + "ks_c_5601-1989"=>"euc-kr", + "ksc5601"=>"euc-kr", + "ksc_5601"=>"euc-kr", + "windows-949"=>"euc-kr", + "utf-16be"=>"utf-16be", + "utf-16"=>"utf-16le", + "utf-16le"=>"utf-16le", + } # :nodoc: + + # :nodoc: + # return encoding or nil + # http://encoding.spec.whatwg.org/#concept-encoding-get + def self.get_encoding(label) + Encoding.find(WEB_ENCODINGS_[label.to_str.strip.downcase]) rescue nil + end +end # module Bundler::URI + +module Bundler + + # + # Returns +uri+ converted to an Bundler::URI object. + # + def URI(uri) + if uri.is_a?(Bundler::URI::Generic) + uri + elsif uri = String.try_convert(uri) + Bundler::URI.parse(uri) + else + raise ArgumentError, + "bad argument (expected Bundler::URI object or Bundler::URI string)" + end + end + module_function :URI +end diff --git a/lib/bundler/vendor/uri/lib/uri/file.rb b/lib/bundler/vendor/uri/lib/uri/file.rb new file mode 100644 index 0000000000..df42f8bcdd --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/file.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require_relative 'generic' + +module Bundler::URI + + # + # The "file" Bundler::URI is defined by RFC8089. + # + class File < Generic + # A Default port of nil for Bundler::URI::File. + DEFAULT_PORT = nil + + # + # An Array of the available components for Bundler::URI::File. + # + COMPONENT = [ + :scheme, + :host, + :path + ].freeze + + # + # == Description + # + # Creates a new Bundler::URI::File object from components, with syntax checking. + # + # The components accepted are +host+ and +path+. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order <code>[host, path]</code>. + # + # Examples: + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri1 = Bundler::URI::File.build(['host.example.com', '/path/file.zip']) + # uri1.to_s # => "file://host.example.com/path/file.zip" + # + # uri2 = Bundler::URI::File.build({:host => 'host.example.com', + # :path => '/ruby/src'}) + # uri2.to_s # => "file://host.example.com/ruby/src" + # + def self.build(args) + tmp = Util::make_components_hash(self, args) + super(tmp) + end + + # Protected setter for the host component +v+. + # + # See also Bundler::URI::Generic.host=. + # + def set_host(v) + v = "" if v.nil? || v == "localhost" + @host = v + end + + # do nothing + def set_port(v) + end + + # raise InvalidURIError + def check_userinfo(user) + raise Bundler::URI::InvalidURIError, "can not set userinfo for file Bundler::URI" + end + + # raise InvalidURIError + def check_user(user) + raise Bundler::URI::InvalidURIError, "can not set user for file Bundler::URI" + end + + # raise InvalidURIError + def check_password(user) + raise Bundler::URI::InvalidURIError, "can not set password for file Bundler::URI" + end + + # do nothing + def set_userinfo(v) + end + + # do nothing + def set_user(v) + end + + # do nothing + def set_password(v) + end + end + + @@schemes['FILE'] = File +end diff --git a/lib/bundler/vendor/uri/lib/uri/ftp.rb b/lib/bundler/vendor/uri/lib/uri/ftp.rb new file mode 100644 index 0000000000..ad39f57d7b --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/ftp.rb @@ -0,0 +1,267 @@ +# frozen_string_literal: false +# = uri/ftp.rb +# +# Author:: Akira Yamada <[email protected]> +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id$ +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # FTP Bundler::URI syntax is defined by RFC1738 section 3.2. + # + # This class will be redesigned because of difference of implementations; + # the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it + # is a good summary about the de facto spec. + # http://tools.ietf.org/html/draft-hoffman-ftp-uri-04 + # + class FTP < Generic + # A Default port of 21 for Bundler::URI::FTP. + DEFAULT_PORT = 21 + + # + # An Array of the available components for Bundler::URI::FTP. + # + COMPONENT = [ + :scheme, + :userinfo, :host, :port, + :path, :typecode + ].freeze + + # + # Typecode is "a", "i", or "d". + # + # * "a" indicates a text file (the FTP command was ASCII) + # * "i" indicates a binary file (FTP command IMAGE) + # * "d" indicates the contents of a directory should be displayed + # + TYPECODE = ['a', 'i', 'd'].freeze + + # Typecode prefix ";type=". + TYPECODE_PREFIX = ';type='.freeze + + def self.new2(user, password, host, port, path, + typecode = nil, arg_check = true) # :nodoc: + # Do not use this method! Not tested. [Bug #7301] + # This methods remains just for compatibility, + # Keep it undocumented until the active maintainer is assigned. + typecode = nil if typecode.size == 0 + if typecode && !TYPECODE.include?(typecode) + raise ArgumentError, + "bad typecode is specified: #{typecode}" + end + + # do escape + + self.new('ftp', + [user, password], + host, port, nil, + typecode ? path + TYPECODE_PREFIX + typecode : path, + nil, nil, nil, arg_check) + end + + # + # == Description + # + # Creates a new Bundler::URI::FTP object from components, with syntax checking. + # + # The components accepted are +userinfo+, +host+, +port+, +path+, and + # +typecode+. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order <code>[userinfo, host, port, path, typecode]</code>. + # + # If the path supplied is absolute, it will be escaped in order to + # make it absolute in the Bundler::URI. + # + # Examples: + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri1 = Bundler::URI::FTP.build(['user:password', 'ftp.example.com', nil, + # '/path/file.zip', 'i']) + # uri1.to_s # => "ftp://user:[email protected]/%2Fpath/file.zip;type=i" + # + # uri2 = Bundler::URI::FTP.build({:host => 'ftp.example.com', + # :path => 'ruby/src'}) + # uri2.to_s # => "ftp://ftp.example.com/ruby/src" + # + def self.build(args) + + # Fix the incoming path to be generic URL syntax + # FTP path -> URL path + # foo/bar /foo/bar + # /foo/bar /%2Ffoo/bar + # + if args.kind_of?(Array) + args[3] = '/' + args[3].sub(/^\//, '%2F') + else + args[:path] = '/' + args[:path].sub(/^\//, '%2F') + end + + tmp = Util::make_components_hash(self, args) + + if tmp[:typecode] + if tmp[:typecode].size == 1 + tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode] + end + tmp[:path] << tmp[:typecode] + end + + return super(tmp) + end + + # + # == Description + # + # Creates a new Bundler::URI::FTP object from generic URL components with no + # syntax checking. + # + # Unlike build(), this method does not escape the path component as + # required by RFC1738; instead it is treated as per RFC2396. + # + # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, + # +opaque+, +query+, and +fragment+, in that order. + # + def initialize(scheme, + userinfo, host, port, registry, + path, opaque, + query, + fragment, + parser = nil, + arg_check = false) + raise InvalidURIError unless path + path = path.sub(/^\//,'') + path.sub!(/^%2F/,'/') + super(scheme, userinfo, host, port, registry, path, opaque, + query, fragment, parser, arg_check) + @typecode = nil + if tmp = @path.index(TYPECODE_PREFIX) + typecode = @path[tmp + TYPECODE_PREFIX.size..-1] + @path = @path[0..tmp - 1] + + if arg_check + self.typecode = typecode + else + self.set_typecode(typecode) + end + end + end + + # typecode accessor. + # + # See Bundler::URI::FTP::COMPONENT. + attr_reader :typecode + + # Validates typecode +v+, + # returns +true+ or +false+. + # + def check_typecode(v) + if TYPECODE.include?(v) + return true + else + raise InvalidComponentError, + "bad typecode(expected #{TYPECODE.join(', ')}): #{v}" + end + end + private :check_typecode + + # Private setter for the typecode +v+. + # + # See also Bundler::URI::FTP.typecode=. + # + def set_typecode(v) + @typecode = v + end + protected :set_typecode + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the typecode +v+ + # (with validation). + # + # See also Bundler::URI::FTP.check_typecode. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("ftp://[email protected]/my_file.img") + # #=> #<Bundler::URI::FTP ftp://[email protected]/my_file.img> + # uri.typecode = "i" + # uri + # #=> #<Bundler::URI::FTP ftp://[email protected]/my_file.img;type=i> + # + def typecode=(typecode) + check_typecode(typecode) + set_typecode(typecode) + typecode + end + + def merge(oth) # :nodoc: + tmp = super(oth) + if self != tmp + tmp.set_typecode(oth.typecode) + end + + return tmp + end + + # Returns the path from an FTP Bundler::URI. + # + # RFC 1738 specifically states that the path for an FTP Bundler::URI does not + # include the / which separates the Bundler::URI path from the Bundler::URI host. Example: + # + # <code>ftp://ftp.example.com/pub/ruby</code> + # + # The above Bundler::URI indicates that the client should connect to + # ftp.example.com then cd to pub/ruby from the initial login directory. + # + # If you want to cd to an absolute directory, you must include an + # escaped / (%2F) in the path. Example: + # + # <code>ftp://ftp.example.com/%2Fpub/ruby</code> + # + # This method will then return "/pub/ruby". + # + def path + return @path.sub(/^\//,'').sub(/^%2F/,'/') + end + + # Private setter for the path of the Bundler::URI::FTP. + def set_path(v) + super("/" + v.sub(/^\//, "%2F")) + end + protected :set_path + + # Returns a String representation of the Bundler::URI::FTP. + def to_s + save_path = nil + if @typecode + save_path = @path + @path = @path + TYPECODE_PREFIX + @typecode + end + str = super + if @typecode + @path = save_path + end + + return str + end + end + @@schemes['FTP'] = FTP +end diff --git a/lib/bundler/vendor/uri/lib/uri/generic.rb b/lib/bundler/vendor/uri/lib/uri/generic.rb new file mode 100644 index 0000000000..56b09e1d7f --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/generic.rb @@ -0,0 +1,1568 @@ +# frozen_string_literal: true + +# = uri/generic.rb +# +# Author:: Akira Yamada <[email protected]> +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id$ +# +# See Bundler::URI for general documentation +# + +require_relative 'common' +autoload :IPSocket, 'socket' +autoload :IPAddr, 'ipaddr' + +module Bundler::URI + + # + # Base class for all Bundler::URI classes. + # Implements generic Bundler::URI syntax as per RFC 2396. + # + class Generic + include Bundler::URI + + # + # A Default port of nil for Bundler::URI::Generic. + # + DEFAULT_PORT = nil + + # + # Returns default port. + # + def self.default_port + self::DEFAULT_PORT + end + + # + # Returns default port. + # + def default_port + self.class.default_port + end + + # + # An Array of the available components for Bundler::URI::Generic. + # + COMPONENT = [ + :scheme, + :userinfo, :host, :port, :registry, + :path, :opaque, + :query, + :fragment + ].freeze + + # + # Components of the Bundler::URI in the order. + # + def self.component + self::COMPONENT + end + + USE_REGISTRY = false # :nodoc: + + def self.use_registry # :nodoc: + self::USE_REGISTRY + end + + # + # == Synopsis + # + # See ::new. + # + # == Description + # + # At first, tries to create a new Bundler::URI::Generic instance using + # Bundler::URI::Generic::build. But, if exception Bundler::URI::InvalidComponentError is raised, + # then it does Bundler::URI::Escape.escape all Bundler::URI components and tries again. + # + def self.build2(args) + begin + return self.build(args) + rescue InvalidComponentError + if args.kind_of?(Array) + return self.build(args.collect{|x| + if x.is_a?(String) + DEFAULT_PARSER.escape(x) + else + x + end + }) + elsif args.kind_of?(Hash) + tmp = {} + args.each do |key, value| + tmp[key] = if value + DEFAULT_PARSER.escape(value) + else + value + end + end + return self.build(tmp) + end + end + end + + # + # == Synopsis + # + # See ::new. + # + # == Description + # + # Creates a new Bundler::URI::Generic instance from components of Bundler::URI::Generic + # with check. Components are: scheme, userinfo, host, port, registry, path, + # opaque, query, and fragment. You can provide arguments either by an Array or a Hash. + # See ::new for hash keys to use or for order of array items. + # + def self.build(args) + if args.kind_of?(Array) && + args.size == ::Bundler::URI::Generic::COMPONENT.size + tmp = args.dup + elsif args.kind_of?(Hash) + tmp = ::Bundler::URI::Generic::COMPONENT.collect do |c| + if args.include?(c) + args[c] + else + nil + end + end + else + component = self.class.component rescue ::Bundler::URI::Generic::COMPONENT + raise ArgumentError, + "expected Array of or Hash of components of #{self.class} (#{component.join(', ')})" + end + + tmp << nil + tmp << true + return self.new(*tmp) + end + + # + # == Args + # + # +scheme+:: + # Protocol scheme, i.e. 'http','ftp','mailto' and so on. + # +userinfo+:: + # User name and password, i.e. 'sdmitry:bla'. + # +host+:: + # Server host name. + # +port+:: + # Server port. + # +registry+:: + # Registry of naming authorities. + # +path+:: + # Path on server. + # +opaque+:: + # Opaque part. + # +query+:: + # Query data. + # +fragment+:: + # Part of the Bundler::URI after '#' character. + # +parser+:: + # Parser for internal use [Bundler::URI::DEFAULT_PARSER by default]. + # +arg_check+:: + # Check arguments [false by default]. + # + # == Description + # + # Creates a new Bundler::URI::Generic instance from ``generic'' components without check. + # + def initialize(scheme, + userinfo, host, port, registry, + path, opaque, + query, + fragment, + parser = DEFAULT_PARSER, + arg_check = false) + @scheme = nil + @user = nil + @password = nil + @host = nil + @port = nil + @path = nil + @query = nil + @opaque = nil + @fragment = nil + @parser = parser == DEFAULT_PARSER ? nil : parser + + if arg_check + self.scheme = scheme + self.userinfo = userinfo + self.hostname = host + self.port = port + self.path = path + self.query = query + self.opaque = opaque + self.fragment = fragment + else + self.set_scheme(scheme) + self.set_userinfo(userinfo) + self.set_host(host) + self.set_port(port) + self.set_path(path) + self.query = query + self.set_opaque(opaque) + self.fragment=(fragment) + end + if registry + raise InvalidURIError, + "the scheme #{@scheme} does not accept registry part: #{registry} (or bad hostname?)" + end + + @scheme&.freeze + self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2) + self.set_port(self.default_port) if self.default_port && !@port + end + + # + # Returns the scheme component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").scheme #=> "http" + # + attr_reader :scheme + + # Returns the host component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").host #=> "foo" + # + # It returns nil if no host component exists. + # + # Bundler::URI("mailto:[email protected]").host #=> nil + # + # The component does not contain the port number. + # + # Bundler::URI("http://foo:8080/bar/baz").host #=> "foo" + # + # Since IPv6 addresses are wrapped with brackets in URIs, + # this method returns IPv6 addresses wrapped with brackets. + # This form is not appropriate to pass to socket methods such as TCPSocket.open. + # If unwrapped host names are required, use the #hostname method. + # + # Bundler::URI("http://[::1]/bar/baz").host #=> "[::1]" + # Bundler::URI("http://[::1]/bar/baz").hostname #=> "::1" + # + attr_reader :host + + # Returns the port component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").port #=> 80 + # Bundler::URI("http://foo:8080/bar/baz").port #=> 8080 + # + attr_reader :port + + def registry # :nodoc: + nil + end + + # Returns the path component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz").path #=> "/bar/baz" + # + attr_reader :path + + # Returns the query component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar" + # + attr_reader :query + + # Returns the opaque part of the Bundler::URI. + # + # Bundler::URI("mailto:[email protected]").opaque #=> "[email protected]" + # Bundler::URI("http://foo/bar/baz").opaque #=> nil + # + # The portion of the path that does not make use of the slash '/'. + # The path typically refers to an absolute path or an opaque part. + # (See RFC2396 Section 3 and 5.2.) + # + attr_reader :opaque + + # Returns the fragment component of the Bundler::URI. + # + # Bundler::URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies" + # + attr_reader :fragment + + # Returns the parser to be used. + # + # Unless a Bundler::URI::Parser is defined, DEFAULT_PARSER is used. + # + def parser + if !defined?(@parser) || !@parser + DEFAULT_PARSER + else + @parser || DEFAULT_PARSER + end + end + + # Replaces self by other Bundler::URI object. + # + def replace!(oth) + if self.class != oth.class + raise ArgumentError, "expected #{self.class} object" + end + + component.each do |c| + self.__send__("#{c}=", oth.__send__(c)) + end + end + private :replace! + + # + # Components of the Bundler::URI in the order. + # + def component + self.class.component + end + + # + # Checks the scheme +v+ component against the Bundler::URI::Parser Regexp for :SCHEME. + # + def check_scheme(v) + if v && parser.regexp[:SCHEME] !~ v + raise InvalidComponentError, + "bad component(expected scheme component): #{v}" + end + + return true + end + private :check_scheme + + # Protected setter for the scheme component +v+. + # + # See also Bundler::URI::Generic.scheme=. + # + def set_scheme(v) + @scheme = v&.downcase + end + protected :set_scheme + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the scheme component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_scheme. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.scheme = "https" + # uri.to_s #=> "https://my.example.com" + # + def scheme=(v) + check_scheme(v) + set_scheme(v) + v + end + + # + # Checks the +user+ and +password+. + # + # If +password+ is not provided, then +user+ is + # split, using Bundler::URI::Generic.split_userinfo, to + # pull +user+ and +password. + # + # See also Bundler::URI::Generic.check_user, Bundler::URI::Generic.check_password. + # + def check_userinfo(user, password = nil) + if !password + user, password = split_userinfo(user) + end + check_user(user) + check_password(password, user) + + return true + end + private :check_userinfo + + # + # Checks the user +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :USERINFO. + # + # Can not have a registry or opaque component defined, + # with a user component defined. + # + def check_user(v) + if @opaque + raise InvalidURIError, + "can not set user with opaque" + end + + return v unless v + + if parser.regexp[:USERINFO] !~ v + raise InvalidComponentError, + "bad component(expected userinfo component or user component): #{v}" + end + + return true + end + private :check_user + + # + # Checks the password +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :USERINFO. + # + # Can not have a registry or opaque component defined, + # with a user component defined. + # + def check_password(v, user = @user) + if @opaque + raise InvalidURIError, + "can not set password with opaque" + end + return v unless v + + if !user + raise InvalidURIError, + "password component depends user component" + end + + if parser.regexp[:USERINFO] !~ v + raise InvalidComponentError, + "bad password component" + end + + return true + end + private :check_password + + # + # Sets userinfo, argument is string like 'name:pass'. + # + def userinfo=(userinfo) + if userinfo.nil? + return nil + end + check_userinfo(*userinfo) + set_userinfo(*userinfo) + # returns userinfo + end + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the +user+ component + # (with validation). + # + # See also Bundler::URI::Generic.check_user. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://john:[email protected]") + # uri.user = "sam" + # uri.to_s #=> "http://sam:[email protected]" + # + def user=(user) + check_user(user) + set_user(user) + # returns user + end + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the +password+ component + # (with validation). + # + # See also Bundler::URI::Generic.check_password. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://john:[email protected]") + # uri.password = "V3ry_S3nsit1ve" + # uri.to_s #=> "http://john:[email protected]" + # + def password=(password) + check_password(password) + set_password(password) + # returns password + end + + # Protected setter for the +user+ component, and +password+ if available + # (with validation). + # + # See also Bundler::URI::Generic.userinfo=. + # + def set_userinfo(user, password = nil) + unless password + user, password = split_userinfo(user) + end + @user = user + @password = password if password + + [@user, @password] + end + protected :set_userinfo + + # Protected setter for the user component +v+. + # + # See also Bundler::URI::Generic.user=. + # + def set_user(v) + set_userinfo(v, @password) + v + end + protected :set_user + + # Protected setter for the password component +v+. + # + # See also Bundler::URI::Generic.password=. + # + def set_password(v) + @password = v + # returns v + end + protected :set_password + + # Returns the userinfo +ui+ as <code>[user, password]</code> + # if properly formatted as 'user:password'. + def split_userinfo(ui) + return nil, nil unless ui + user, password = ui.split(':', 2) + + return user, password + end + private :split_userinfo + + # Escapes 'user:password' +v+ based on RFC 1738 section 3.1. + def escape_userpass(v) + parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/ + end + private :escape_userpass + + # Returns the userinfo, either as 'user' or 'user:password'. + def userinfo + if @user.nil? + nil + elsif @password.nil? + @user + else + @user + ':' + @password + end + end + + # Returns the user component. + def user + @user + end + + # Returns the password component. + def password + @password + end + + # + # Checks the host +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :HOST. + # + # Can not have a registry or opaque component defined, + # with a host component defined. + # + def check_host(v) + return v unless v + + if @opaque + raise InvalidURIError, + "can not set host with registry or opaque" + elsif parser.regexp[:HOST] !~ v + raise InvalidComponentError, + "bad component(expected host component): #{v}" + end + + return true + end + private :check_host + + # Protected setter for the host component +v+. + # + # See also Bundler::URI::Generic.host=. + # + def set_host(v) + @host = v + end + protected :set_host + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the host component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_host. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.host = "foo.com" + # uri.to_s #=> "http://foo.com" + # + def host=(v) + check_host(v) + set_host(v) + v + end + + # Extract the host part of the Bundler::URI and unwrap brackets for IPv6 addresses. + # + # This method is the same as Bundler::URI::Generic#host except + # brackets for IPv6 (and future IP) addresses are removed. + # + # uri = Bundler::URI("http://[::1]/bar") + # uri.hostname #=> "::1" + # uri.host #=> "[::1]" + # + def hostname + v = self.host + /\A\[(.*)\]\z/ =~ v ? $1 : v + end + + # Sets the host part of the Bundler::URI as the argument with brackets for IPv6 addresses. + # + # This method is the same as Bundler::URI::Generic#host= except + # the argument can be a bare IPv6 address. + # + # uri = Bundler::URI("http://foo/bar") + # uri.hostname = "::1" + # uri.to_s #=> "http://[::1]/bar" + # + # If the argument seems to be an IPv6 address, + # it is wrapped with brackets. + # + def hostname=(v) + v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v + self.host = v + end + + # + # Checks the port +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp for :PORT. + # + # Can not have a registry or opaque component defined, + # with a port component defined. + # + def check_port(v) + return v unless v + + if @opaque + raise InvalidURIError, + "can not set port with registry or opaque" + elsif !v.kind_of?(Integer) && parser.regexp[:PORT] !~ v + raise InvalidComponentError, + "bad component(expected port component): #{v.inspect}" + end + + return true + end + private :check_port + + # Protected setter for the port component +v+. + # + # See also Bundler::URI::Generic.port=. + # + def set_port(v) + v = v.empty? ? nil : v.to_i unless !v || v.kind_of?(Integer) + @port = v + end + protected :set_port + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the port component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_port. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.port = 8080 + # uri.to_s #=> "http://my.example.com:8080" + # + def port=(v) + check_port(v) + set_port(v) + port + end + + def check_registry(v) # :nodoc: + raise InvalidURIError, "can not set registry" + end + private :check_registry + + def set_registry(v) #:nodoc: + raise InvalidURIError, "can not set registry" + end + protected :set_registry + + def registry=(v) + raise InvalidURIError, "can not set registry" + end + + # + # Checks the path +v+ component for RFC2396 compliance + # and against the Bundler::URI::Parser Regexp + # for :ABS_PATH and :REL_PATH. + # + # Can not have a opaque component defined, + # with a path component defined. + # + def check_path(v) + # raise if both hier and opaque are not nil, because: + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + if v && @opaque + raise InvalidURIError, + "path conflicts with opaque" + end + + # If scheme is ftp, path may be relative. + # See RFC 1738 section 3.2.2, and RFC 2396. + if @scheme && @scheme != "ftp" + if v && v != '' && parser.regexp[:ABS_PATH] !~ v + raise InvalidComponentError, + "bad component(expected absolute path component): #{v}" + end + else + if v && v != '' && parser.regexp[:ABS_PATH] !~ v && + parser.regexp[:REL_PATH] !~ v + raise InvalidComponentError, + "bad component(expected relative path component): #{v}" + end + end + + return true + end + private :check_path + + # Protected setter for the path component +v+. + # + # See also Bundler::URI::Generic.path=. + # + def set_path(v) + @path = v + end + protected :set_path + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the path component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_path. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/pub/files") + # uri.path = "/faq/" + # uri.to_s #=> "http://my.example.com/faq/" + # + def path=(v) + check_path(v) + set_path(v) + v + end + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the query component +v+. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/?id=25") + # uri.query = "id=1" + # uri.to_s #=> "http://my.example.com/?id=1" + # + def query=(v) + return @query = nil unless v + raise InvalidURIError, "query conflicts with opaque" if @opaque + + x = v.to_str + v = x.dup if x.equal? v + v.encode!(Encoding::UTF_8) rescue nil + v.delete!("\t\r\n") + v.force_encoding(Encoding::ASCII_8BIT) + raise InvalidURIError, "invalid percent escape: #{$1}" if /(%\H\H)/n.match(v) + v.gsub!(/(?!%\h\h|[!$-&(-;=?-_a-~])./n.freeze){'%%%02X' % $&.ord} + v.force_encoding(Encoding::US_ASCII) + @query = v + end + + # + # Checks the opaque +v+ component for RFC2396 compliance and + # against the Bundler::URI::Parser Regexp for :OPAQUE. + # + # Can not have a host, port, user, or path component defined, + # with an opaque component defined. + # + def check_opaque(v) + return v unless v + + # raise if both hier and opaque are not nil, because: + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + if @host || @port || @user || @path # userinfo = @user + ':' + @password + raise InvalidURIError, + "can not set opaque with host, port, userinfo or path" + elsif v && parser.regexp[:OPAQUE] !~ v + raise InvalidComponentError, + "bad component(expected opaque component): #{v}" + end + + return true + end + private :check_opaque + + # Protected setter for the opaque component +v+. + # + # See also Bundler::URI::Generic.opaque=. + # + def set_opaque(v) + @opaque = v + end + protected :set_opaque + + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the opaque component +v+ + # (with validation). + # + # See also Bundler::URI::Generic.check_opaque. + # + def opaque=(v) + check_opaque(v) + set_opaque(v) + v + end + + # + # Checks the fragment +v+ component against the Bundler::URI::Parser Regexp for :FRAGMENT. + # + # + # == Args + # + # +v+:: + # String + # + # == Description + # + # Public setter for the fragment component +v+ + # (with validation). + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/?id=25#time=1305212049") + # uri.fragment = "time=1305212086" + # uri.to_s #=> "http://my.example.com/?id=25#time=1305212086" + # + def fragment=(v) + return @fragment = nil unless v + + x = v.to_str + v = x.dup if x.equal? v + v.encode!(Encoding::UTF_8) rescue nil + v.delete!("\t\r\n") + v.force_encoding(Encoding::ASCII_8BIT) + v.gsub!(/(?!%\h\h|[!-~])./n){'%%%02X' % $&.ord} + v.force_encoding(Encoding::US_ASCII) + @fragment = v + end + + # + # Returns true if Bundler::URI is hierarchical. + # + # == Description + # + # Bundler::URI has components listed in order of decreasing significance from left to right, + # see RFC3986 https://tools.ietf.org/html/rfc3986 1.2.3. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com/") + # uri.hierarchical? + # #=> true + # uri = Bundler::URI.parse("mailto:[email protected]") + # uri.hierarchical? + # #=> false + # + def hierarchical? + if @path + true + else + false + end + end + + # + # Returns true if Bundler::URI has a scheme (e.g. http:// or https://) specified. + # + def absolute? + if @scheme + true + else + false + end + end + alias absolute absolute? + + # + # Returns true if Bundler::URI does not have a scheme (e.g. http:// or https://) specified. + # + def relative? + !absolute? + end + + # + # Returns an Array of the path split on '/'. + # + def split_path(path) + path.split("/", -1) + end + private :split_path + + # + # Merges a base path +base+, with relative path +rel+, + # returns a modified base path. + # + def merge_path(base, rel) + + # RFC2396, Section 5.2, 5) + # RFC2396, Section 5.2, 6) + base_path = split_path(base) + rel_path = split_path(rel) + + # RFC2396, Section 5.2, 6), a) + base_path << '' if base_path.last == '..' + while i = base_path.index('..') + base_path.slice!(i - 1, 2) + end + + if (first = rel_path.first) and first.empty? + base_path.clear + rel_path.shift + end + + # RFC2396, Section 5.2, 6), c) + # RFC2396, Section 5.2, 6), d) + rel_path.push('') if rel_path.last == '.' || rel_path.last == '..' + rel_path.delete('.') + + # RFC2396, Section 5.2, 6), e) + tmp = [] + rel_path.each do |x| + if x == '..' && + !(tmp.empty? || tmp.last == '..') + tmp.pop + else + tmp << x + end + end + + add_trailer_slash = !tmp.empty? + if base_path.empty? + base_path = [''] # keep '/' for root directory + elsif add_trailer_slash + base_path.pop + end + while x = tmp.shift + if x == '..' + # RFC2396, Section 4 + # a .. or . in an absolute path has no special meaning + base_path.pop if base_path.size > 1 + else + # if x == '..' + # valid absolute (but abnormal) path "/../..." + # else + # valid absolute path + # end + base_path << x + tmp.each {|t| base_path << t} + add_trailer_slash = false + break + end + end + base_path.push('') if add_trailer_slash + + return base_path.join('/') + end + private :merge_path + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Destructive form of #merge. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.merge!("/main.rbx?page=1") + # uri.to_s # => "http://my.example.com/main.rbx?page=1" + # + def merge!(oth) + t = merge(oth) + if self == t + nil + else + replace!(t) + self + end + end + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Merges two URIs. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.merge("/main.rbx?page=1") + # # => "http://my.example.com/main.rbx?page=1" + # + def merge(oth) + rel = parser.send(:convert_to_uri, oth) + + if rel.absolute? + #raise BadURIError, "both Bundler::URI are absolute" if absolute? + # hmm... should return oth for usability? + return rel + end + + unless self.absolute? + raise BadURIError, "both Bundler::URI are relative" + end + + base = self.dup + + authority = rel.userinfo || rel.host || rel.port + + # RFC2396, Section 5.2, 2) + if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query + base.fragment=(rel.fragment) if rel.fragment + return base + end + + base.query = nil + base.fragment=(nil) + + # RFC2396, Section 5.2, 4) + if !authority + base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path + else + # RFC2396, Section 5.2, 4) + base.set_path(rel.path) if rel.path + end + + # RFC2396, Section 5.2, 7) + base.set_userinfo(rel.userinfo) if rel.userinfo + base.set_host(rel.host) if rel.host + base.set_port(rel.port) if rel.port + base.query = rel.query if rel.query + base.fragment=(rel.fragment) if rel.fragment + + return base + end # merge + alias + merge + + # :stopdoc: + def route_from_path(src, dst) + case dst + when src + # RFC2396, Section 4.2 + return '' + when %r{(?:\A|/)\.\.?(?:/|\z)} + # dst has abnormal absolute path, + # like "/./", "/../", "/x/../", ... + return dst.dup + end + + src_path = src.scan(%r{[^/]*/}) + dst_path = dst.scan(%r{[^/]*/?}) + + # discard same parts + while !dst_path.empty? && dst_path.first == src_path.first + src_path.shift + dst_path.shift + end + + tmp = dst_path.join + + # calculate + if src_path.empty? + if tmp.empty? + return './' + elsif dst_path.first.include?(':') # (see RFC2396 Section 5) + return './' + tmp + else + return tmp + end + end + + return '../' * src_path.size + tmp + end + private :route_from_path + # :startdoc: + + # :stopdoc: + def route_from0(oth) + oth = parser.send(:convert_to_uri, oth) + if self.relative? + raise BadURIError, + "relative Bundler::URI: #{self}" + end + if oth.relative? + raise BadURIError, + "relative Bundler::URI: #{oth}" + end + + if self.scheme != oth.scheme + return self, self.dup + end + rel = Bundler::URI::Generic.new(nil, # it is relative Bundler::URI + self.userinfo, self.host, self.port, + nil, self.path, self.opaque, + self.query, self.fragment, parser) + + if rel.userinfo != oth.userinfo || + rel.host.to_s.downcase != oth.host.to_s.downcase || + rel.port != oth.port + + if self.userinfo.nil? && self.host.nil? + return self, self.dup + end + + rel.set_port(nil) if rel.port == oth.default_port + return rel, rel + end + rel.set_userinfo(nil) + rel.set_host(nil) + rel.set_port(nil) + + if rel.path && rel.path == oth.path + rel.set_path('') + rel.query = nil if rel.query == oth.query + return rel, rel + elsif rel.opaque && rel.opaque == oth.opaque + rel.set_opaque('') + rel.query = nil if rel.query == oth.query + return rel, rel + end + + # you can modify `rel', but can not `oth'. + return oth, rel + end + private :route_from0 + # :startdoc: + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Calculates relative path from oth to self. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse('http://my.example.com/main.rbx?page=1') + # uri.route_from('http://my.example.com') + # #=> #<Bundler::URI::Generic /main.rbx?page=1> + # + def route_from(oth) + # you can modify `rel', but can not `oth'. + begin + oth, rel = route_from0(oth) + rescue + raise $!.class, $!.message + end + if oth == rel + return rel + end + + rel.set_path(route_from_path(oth.path, self.path)) + if rel.path == './' && self.query + # "./?foo" -> "?foo" + rel.set_path('') + end + + return rel + end + + alias - route_from + + # + # == Args + # + # +oth+:: + # Bundler::URI or String + # + # == Description + # + # Calculates relative path to oth from self. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse('http://my.example.com') + # uri.route_to('http://my.example.com/main.rbx?page=1') + # #=> #<Bundler::URI::Generic /main.rbx?page=1> + # + def route_to(oth) + parser.send(:convert_to_uri, oth).route_from(self) + end + + # + # Returns normalized Bundler::URI. + # + # require 'bundler/vendor/uri/lib/uri' + # + # Bundler::URI("HTTP://my.EXAMPLE.com").normalize + # #=> #<Bundler::URI::HTTP http://my.example.com/> + # + # Normalization here means: + # + # * scheme and host are converted to lowercase, + # * an empty path component is set to "/". + # + def normalize + uri = dup + uri.normalize! + uri + end + + # + # Destructive version of #normalize. + # + def normalize! + if path&.empty? + set_path('/') + end + if scheme && scheme != scheme.downcase + set_scheme(self.scheme.downcase) + end + if host && host != host.downcase + set_host(self.host.downcase) + end + end + + # + # Constructs String from Bundler::URI. + # + def to_s + str = ''.dup + if @scheme + str << @scheme + str << ':' + end + + if @opaque + str << @opaque + else + if @host || %w[file postgres].include?(@scheme) + str << '//' + end + if self.userinfo + str << self.userinfo + str << '@' + end + if @host + str << @host + end + if @port && @port != self.default_port + str << ':' + str << @port.to_s + end + str << @path + if @query + str << '?' + str << @query + end + end + if @fragment + str << '#' + str << @fragment + end + str + end + + # + # Compares two URIs. + # + def ==(oth) + if self.class == oth.class + self.normalize.component_ary == oth.normalize.component_ary + else + false + end + end + + def hash + self.component_ary.hash + end + + def eql?(oth) + self.class == oth.class && + parser == oth.parser && + self.component_ary.eql?(oth.component_ary) + end + +=begin + +--- Bundler::URI::Generic#===(oth) + +=end +# def ===(oth) +# raise NotImplementedError +# end + +=begin +=end + + + # Returns an Array of the components defined from the COMPONENT Array. + def component_ary + component.collect do |x| + self.send(x) + end + end + protected :component_ary + + # == Args + # + # +components+:: + # Multiple Symbol arguments defined in Bundler::URI::HTTP. + # + # == Description + # + # Selects specified components from Bundler::URI. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse('http://myuser:[email protected]/test.rbx') + # uri.select(:userinfo, :host, :path) + # # => ["myuser:mypass", "my.example.com", "/test.rbx"] + # + def select(*components) + components.collect do |c| + if component.include?(c) + self.send(c) + else + raise ArgumentError, + "expected of components of #{self.class} (#{self.class.component.join(', ')})" + end + end + end + + def inspect + "#<#{self.class} #{self}>" + end + + # + # == Args + # + # +v+:: + # Bundler::URI or String + # + # == Description + # + # Attempts to parse other Bundler::URI +oth+, + # returns [parsed_oth, self]. + # + # == Usage + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("http://my.example.com") + # uri.coerce("http://foo.com") + # #=> [#<Bundler::URI::HTTP http://foo.com>, #<Bundler::URI::HTTP http://my.example.com>] + # + def coerce(oth) + case oth + when String + oth = parser.parse(oth) + else + super + end + + return oth, self + end + + # Returns a proxy Bundler::URI. + # The proxy Bundler::URI is obtained from environment variables such as http_proxy, + # ftp_proxy, no_proxy, etc. + # If there is no proper proxy, nil is returned. + # + # If the optional parameter +env+ is specified, it is used instead of ENV. + # + # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) + # are examined, too. + # + # But http_proxy and HTTP_PROXY is treated specially under CGI environment. + # It's because HTTP_PROXY may be set by Proxy: header. + # So HTTP_PROXY is not used. + # http_proxy is not used too if the variable is case insensitive. + # CGI_HTTP_PROXY can be used instead. + def find_proxy(env=ENV) + raise BadURIError, "relative Bundler::URI: #{self}" if self.relative? + name = self.scheme.downcase + '_proxy' + proxy_uri = nil + if name == 'http_proxy' && env.include?('REQUEST_METHOD') # CGI? + # HTTP_PROXY conflicts with *_proxy for proxy settings and + # HTTP_* for header information in CGI. + # So it should be careful to use it. + pairs = env.reject {|k, v| /\Ahttp_proxy\z/i !~ k } + case pairs.length + when 0 # no proxy setting anyway. + proxy_uri = nil + when 1 + k, _ = pairs.shift + if k == 'http_proxy' && env[k.upcase] == nil + # http_proxy is safe to use because ENV is case sensitive. + proxy_uri = env[name] + else + proxy_uri = nil + end + else # http_proxy is safe to use because ENV is case sensitive. + proxy_uri = env.to_hash[name] + end + if !proxy_uri + # Use CGI_HTTP_PROXY. cf. libwww-perl. + proxy_uri = env["CGI_#{name.upcase}"] + end + elsif name == 'http_proxy' + unless proxy_uri = env[name] + if proxy_uri = env[name.upcase] + warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.', uplevel: 1 + end + end + else + proxy_uri = env[name] || env[name.upcase] + end + + if proxy_uri.nil? || proxy_uri.empty? + return nil + end + + if self.hostname + begin + addr = IPSocket.getaddress(self.hostname) + return nil if /\A127\.|\A::1\z/ =~ addr + rescue SocketError + end + end + + name = 'no_proxy' + if no_proxy = env[name] || env[name.upcase] + return nil unless Bundler::URI::Generic.use_proxy?(self.hostname, addr, self.port, no_proxy) + end + Bundler::URI.parse(proxy_uri) + end + + def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc: + hostname = hostname.downcase + dothostname = ".#{hostname}" + no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) {|p_host, p_port| + if !p_port || port == p_port.to_i + if p_host.start_with?('.') + return false if hostname.end_with?(p_host.downcase) + else + return false if dothostname.end_with?(".#{p_host.downcase}") + end + if addr + begin + return false if IPAddr.new(p_host).include?(addr) + rescue IPAddr::InvalidAddressError + next + end + end + end + } + true + end + end +end diff --git a/lib/bundler/vendor/uri/lib/uri/http.rb b/lib/bundler/vendor/uri/lib/uri/http.rb new file mode 100644 index 0000000000..b6ca1c51de --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/http.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: false +# = uri/http.rb +# +# Author:: Akira Yamada <[email protected]> +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id$ +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # The syntax of HTTP URIs is defined in RFC1738 section 3.3. + # + # Note that the Ruby Bundler::URI library allows HTTP URLs containing usernames and + # passwords. This is not legal as per the RFC, but used to be + # supported in Internet Explorer 5 and 6, before the MS04-004 security + # update. See <URL:http://support.microsoft.com/kb/834489>. + # + class HTTP < Generic + # A Default port of 80 for Bundler::URI::HTTP. + DEFAULT_PORT = 80 + + # An Array of the available components for Bundler::URI::HTTP. + COMPONENT = %i[ + scheme + userinfo host port + path + query + fragment + ].freeze + + # + # == Description + # + # Creates a new Bundler::URI::HTTP object from components, with syntax checking. + # + # The components accepted are userinfo, host, port, path, query, and + # fragment. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order <code>[userinfo, host, port, path, query, fragment]</code>. + # + # Example: + # + # uri = Bundler::URI::HTTP.build(host: 'www.example.com', path: '/foo/bar') + # + # uri = Bundler::URI::HTTP.build([nil, "www.example.com", nil, "/path", + # "query", 'fragment']) + # + # Currently, if passed userinfo components this method generates + # invalid HTTP URIs as per RFC 1738. + # + def self.build(args) + tmp = Util.make_components_hash(self, args) + super(tmp) + end + + # + # == Description + # + # Returns the full path for an HTTP request, as required by Net::HTTP::Get. + # + # If the Bundler::URI contains a query, the full path is Bundler::URI#path + '?' + Bundler::URI#query. + # Otherwise, the path is simply Bundler::URI#path. + # + # Example: + # + # uri = Bundler::URI::HTTP.build(path: '/foo/bar', query: 'test=true') + # uri.request_uri # => "/foo/bar?test=true" + # + def request_uri + return unless @path + + url = @query ? "#@path?#@query" : @path.dup + url.start_with?(?/.freeze) ? url : ?/ + url + end + end + + @@schemes['HTTP'] = HTTP + +end diff --git a/lib/bundler/vendor/uri/lib/uri/https.rb b/lib/bundler/vendor/uri/lib/uri/https.rb new file mode 100644 index 0000000000..78dc6bf532 --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/https.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: false +# = uri/https.rb +# +# Author:: Akira Yamada <[email protected]> +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id$ +# +# See Bundler::URI for general documentation +# + +require_relative 'http' + +module Bundler::URI + + # The default port for HTTPS URIs is 443, and the scheme is 'https:' rather + # than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs; + # see Bundler::URI::HTTP. + class HTTPS < HTTP + # A Default port of 443 for Bundler::URI::HTTPS + DEFAULT_PORT = 443 + end + @@schemes['HTTPS'] = HTTPS +end diff --git a/lib/bundler/vendor/uri/lib/uri/ldap.rb b/lib/bundler/vendor/uri/lib/uri/ldap.rb new file mode 100644 index 0000000000..b707bedb97 --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/ldap.rb @@ -0,0 +1,261 @@ +# frozen_string_literal: false +# = uri/ldap.rb +# +# Author:: +# Takaaki Tateishi <[email protected]> +# Akira Yamada <[email protected]> +# License:: +# Bundler::URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada. +# You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id$ +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # LDAP Bundler::URI SCHEMA (described in RFC2255). + #-- + # ldap://<host>/<dn>[?<attrs>[?<scope>[?<filter>[?<extensions>]]]] + #++ + class LDAP < Generic + + # A Default port of 389 for Bundler::URI::LDAP. + DEFAULT_PORT = 389 + + # An Array of the available components for Bundler::URI::LDAP. + COMPONENT = [ + :scheme, + :host, :port, + :dn, + :attributes, + :scope, + :filter, + :extensions, + ].freeze + + # Scopes available for the starting point. + # + # * SCOPE_BASE - the Base DN + # * SCOPE_ONE - one level under the Base DN, not including the base DN and + # not including any entries under this + # * SCOPE_SUB - subtrees, all entries at all levels + # + SCOPE = [ + SCOPE_ONE = 'one', + SCOPE_SUB = 'sub', + SCOPE_BASE = 'base', + ].freeze + + # + # == Description + # + # Creates a new Bundler::URI::LDAP object from components, with syntax checking. + # + # The components accepted are host, port, dn, attributes, + # scope, filter, and extensions. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the + # order <code>[host, port, dn, attributes, scope, filter, extensions]</code>. + # + # Example: + # + # uri = Bundler::URI::LDAP.build({:host => 'ldap.example.com', + # :dn => '/dc=example'}) + # + # uri = Bundler::URI::LDAP.build(["ldap.example.com", nil, + # "/dc=example;dc=com", "query", nil, nil, nil]) + # + def self.build(args) + tmp = Util::make_components_hash(self, args) + + if tmp[:dn] + tmp[:path] = tmp[:dn] + end + + query = [] + [:extensions, :filter, :scope, :attributes].collect do |x| + next if !tmp[x] && query.size == 0 + query.unshift(tmp[x]) + end + + tmp[:query] = query.join('?') + + return super(tmp) + end + + # + # == Description + # + # Creates a new Bundler::URI::LDAP object from generic Bundler::URI components as per + # RFC 2396. No LDAP-specific syntax checking is performed. + # + # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, + # +opaque+, +query+, and +fragment+, in that order. + # + # Example: + # + # uri = Bundler::URI::LDAP.new("ldap", nil, "ldap.example.com", nil, nil, + # "/dc=example;dc=com", nil, "query", nil) + # + # See also Bundler::URI::Generic.new. + # + def initialize(*arg) + super(*arg) + + if @fragment + raise InvalidURIError, 'bad LDAP URL' + end + + parse_dn + parse_query + end + + # Private method to cleanup +dn+ from using the +path+ component attribute. + def parse_dn + @dn = @path[1..-1] + end + private :parse_dn + + # Private method to cleanup +attributes+, +scope+, +filter+, and +extensions+ + # from using the +query+ component attribute. + def parse_query + @attributes = nil + @scope = nil + @filter = nil + @extensions = nil + + if @query + attrs, scope, filter, extensions = @query.split('?') + + @attributes = attrs if attrs && attrs.size > 0 + @scope = scope if scope && scope.size > 0 + @filter = filter if filter && filter.size > 0 + @extensions = extensions if extensions && extensions.size > 0 + end + end + private :parse_query + + # Private method to assemble +query+ from +attributes+, +scope+, +filter+, and +extensions+. + def build_path_query + @path = '/' + @dn + + query = [] + [@extensions, @filter, @scope, @attributes].each do |x| + next if !x && query.size == 0 + query.unshift(x) + end + @query = query.join('?') + end + private :build_path_query + + # Returns dn. + def dn + @dn + end + + # Private setter for dn +val+. + def set_dn(val) + @dn = val + build_path_query + @dn + end + protected :set_dn + + # Setter for dn +val+. + def dn=(val) + set_dn(val) + val + end + + # Returns attributes. + def attributes + @attributes + end + + # Private setter for attributes +val+. + def set_attributes(val) + @attributes = val + build_path_query + @attributes + end + protected :set_attributes + + # Setter for attributes +val+. + def attributes=(val) + set_attributes(val) + val + end + + # Returns scope. + def scope + @scope + end + + # Private setter for scope +val+. + def set_scope(val) + @scope = val + build_path_query + @scope + end + protected :set_scope + + # Setter for scope +val+. + def scope=(val) + set_scope(val) + val + end + + # Returns filter. + def filter + @filter + end + + # Private setter for filter +val+. + def set_filter(val) + @filter = val + build_path_query + @filter + end + protected :set_filter + + # Setter for filter +val+. + def filter=(val) + set_filter(val) + val + end + + # Returns extensions. + def extensions + @extensions + end + + # Private setter for extensions +val+. + def set_extensions(val) + @extensions = val + build_path_query + @extensions + end + protected :set_extensions + + # Setter for extensions +val+. + def extensions=(val) + set_extensions(val) + val + end + + # Checks if Bundler::URI has a path. + # For Bundler::URI::LDAP this will return +false+. + def hierarchical? + false + end + end + + @@schemes['LDAP'] = LDAP +end diff --git a/lib/bundler/vendor/uri/lib/uri/ldaps.rb b/lib/bundler/vendor/uri/lib/uri/ldaps.rb new file mode 100644 index 0000000000..0af35bb16b --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/ldaps.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: false +# = uri/ldap.rb +# +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +require_relative 'ldap' + +module Bundler::URI + + # The default port for LDAPS URIs is 636, and the scheme is 'ldaps:' rather + # than 'ldap:'. Other than that, LDAPS URIs are identical to LDAP URIs; + # see Bundler::URI::LDAP. + class LDAPS < LDAP + # A Default port of 636 for Bundler::URI::LDAPS + DEFAULT_PORT = 636 + end + @@schemes['LDAPS'] = LDAPS +end diff --git a/lib/bundler/vendor/uri/lib/uri/mailto.rb b/lib/bundler/vendor/uri/lib/uri/mailto.rb new file mode 100644 index 0000000000..5b2a4765c8 --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/mailto.rb @@ -0,0 +1,294 @@ +# frozen_string_literal: false +# = uri/mailto.rb +# +# Author:: Akira Yamada <[email protected]> +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id$ +# +# See Bundler::URI for general documentation +# + +require_relative 'generic' + +module Bundler::URI + + # + # RFC6068, the mailto URL scheme. + # + class MailTo < Generic + include REGEXP + + # A Default port of nil for Bundler::URI::MailTo. + DEFAULT_PORT = nil + + # An Array of the available components for Bundler::URI::MailTo. + COMPONENT = [ :scheme, :to, :headers ].freeze + + # :stopdoc: + # "hname" and "hvalue" are encodings of an RFC 822 header name and + # value, respectively. As with "to", all URL reserved characters must + # be encoded. + # + # "#mailbox" is as specified in RFC 822 [RFC822]. This means that it + # consists of zero or more comma-separated mail addresses, possibly + # including "phrase" and "comment" components. Note that all URL + # reserved characters in "to" must be encoded: in particular, + # parentheses, commas, and the percent sign ("%"), which commonly occur + # in the "mailbox" syntax. + # + # Within mailto URLs, the characters "?", "=", "&" are reserved. + + # ; RFC 6068 + # hfields = "?" hfield *( "&" hfield ) + # hfield = hfname "=" hfvalue + # hfname = *qchar + # hfvalue = *qchar + # qchar = unreserved / pct-encoded / some-delims + # some-delims = "!" / "$" / "'" / "(" / ")" / "*" + # / "+" / "," / ";" / ":" / "@" + # + # ; RFC3986 + # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + # pct-encoded = "%" HEXDIG HEXDIG + HEADER_REGEXP = /\A(?<hfield>(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g<hfield>)*\z/ + # practical regexp for email address + # https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address + EMAIL_REGEXP = /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/ + # :startdoc: + + # + # == Description + # + # Creates a new Bundler::URI::MailTo object from components, with syntax checking. + # + # Components can be provided as an Array or Hash. If an Array is used, + # the components must be supplied as <code>[to, headers]</code>. + # + # If a Hash is used, the keys are the component names preceded by colons. + # + # The headers can be supplied as a pre-encoded string, such as + # <code>"subject=subscribe&cc=address"</code>, or as an Array of Arrays + # like <code>[['subject', 'subscribe'], ['cc', 'address']]</code>. + # + # Examples: + # + # require 'bundler/vendor/uri/lib/uri' + # + # m1 = Bundler::URI::MailTo.build(['[email protected]', 'subject=Ruby']) + # m1.to_s # => "mailto:[email protected]?subject=Ruby" + # + # m2 = Bundler::URI::MailTo.build(['[email protected]', [['Subject', 'Ruby'], ['Cc', '[email protected]']]]) + # m2.to_s # => "mailto:[email protected]?Subject=Ruby&[email protected]" + # + # m3 = Bundler::URI::MailTo.build({:to => '[email protected]', :headers => [['subject', 'subscribe']]}) + # m3.to_s # => "mailto:[email protected]?subject=subscribe" + # + def self.build(args) + tmp = Util.make_components_hash(self, args) + + case tmp[:to] + when Array + tmp[:opaque] = tmp[:to].join(',') + when String + tmp[:opaque] = tmp[:to].dup + else + tmp[:opaque] = '' + end + + if tmp[:headers] + query = + case tmp[:headers] + when Array + tmp[:headers].collect { |x| + if x.kind_of?(Array) + x[0] + '=' + x[1..-1].join + else + x.to_s + end + }.join('&') + when Hash + tmp[:headers].collect { |h,v| + h + '=' + v + }.join('&') + else + tmp[:headers].to_s + end + unless query.empty? + tmp[:opaque] << '?' << query + end + end + + super(tmp) + end + + # + # == Description + # + # Creates a new Bundler::URI::MailTo object from generic URL components with + # no syntax checking. + # + # This method is usually called from Bundler::URI::parse, which checks + # the validity of each component. + # + def initialize(*arg) + super(*arg) + + @to = nil + @headers = [] + + # The RFC3986 parser does not normally populate opaque + @opaque = "?#{@query}" if @query && !@opaque + + unless @opaque + raise InvalidComponentError, + "missing opaque part for mailto URL" + end + to, header = @opaque.split('?', 2) + # allow semicolon as a addr-spec separator + # http://support.microsoft.com/kb/820868 + unless /\A(?:[^@,;]+@[^@,;]+(?:\z|[,;]))*\z/ =~ to + raise InvalidComponentError, + "unrecognised opaque part for mailtoURL: #{@opaque}" + end + + if arg[10] # arg_check + self.to = to + self.headers = header + else + set_to(to) + set_headers(header) + end + end + + # The primary e-mail address of the URL, as a String. + attr_reader :to + + # E-mail headers set by the URL, as an Array of Arrays. + attr_reader :headers + + # Checks the to +v+ component. + def check_to(v) + return true unless v + return true if v.size == 0 + + v.split(/[,;]/).each do |addr| + # check url safety as path-rootless + if /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*\z/ !~ addr + raise InvalidComponentError, + "an address in 'to' is invalid as Bundler::URI #{addr.dump}" + end + + # check addr-spec + # don't s/\+/ /g + addr.gsub!(/%\h\h/, Bundler::URI::TBLDECWWWCOMP_) + if EMAIL_REGEXP !~ addr + raise InvalidComponentError, + "an address in 'to' is invalid as uri-escaped addr-spec #{addr.dump}" + end + end + + true + end + private :check_to + + # Private setter for to +v+. + def set_to(v) + @to = v + end + protected :set_to + + # Setter for to +v+. + def to=(v) + check_to(v) + set_to(v) + v + end + + # Checks the headers +v+ component against either + # * HEADER_REGEXP + def check_headers(v) + return true unless v + return true if v.size == 0 + if HEADER_REGEXP !~ v + raise InvalidComponentError, + "bad component(expected opaque component): #{v}" + end + + true + end + private :check_headers + + # Private setter for headers +v+. + def set_headers(v) + @headers = [] + if v + v.split('&').each do |x| + @headers << x.split(/=/, 2) + end + end + end + protected :set_headers + + # Setter for headers +v+. + def headers=(v) + check_headers(v) + set_headers(v) + v + end + + # Constructs String from Bundler::URI. + def to_s + @scheme + ':' + + if @to + @to + else + '' + end + + if @headers.size > 0 + '?' + @headers.collect{|x| x.join('=')}.join('&') + else + '' + end + + if @fragment + '#' + @fragment + else + '' + end + end + + # Returns the RFC822 e-mail text equivalent of the URL, as a String. + # + # Example: + # + # require 'bundler/vendor/uri/lib/uri' + # + # uri = Bundler::URI.parse("mailto:[email protected]?Subject=subscribe&cc=myaddr") + # uri.to_mailtext + # # => "To: [email protected]\nSubject: subscribe\nCc: myaddr\n\n\n" + # + def to_mailtext + to = Bundler::URI.decode_www_form_component(@to) + head = '' + body = '' + @headers.each do |x| + case x[0] + when 'body' + body = Bundler::URI.decode_www_form_component(x[1]) + when 'to' + to << ', ' + Bundler::URI.decode_www_form_component(x[1]) + else + head << Bundler::URI.decode_www_form_component(x[0]).capitalize + ': ' + + Bundler::URI.decode_www_form_component(x[1]) + "\n" + end + end + + "To: #{to} +#{head} +#{body} +" + end + alias to_rfc822text to_mailtext + end + + @@schemes['MAILTO'] = MailTo +end diff --git a/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb b/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb new file mode 100644 index 0000000000..a0d62ede64 --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb @@ -0,0 +1,546 @@ +# frozen_string_literal: false +#-- +# = uri/common.rb +# +# Author:: Akira Yamada <[email protected]> +# Revision:: $Id$ +# License:: +# You can redistribute it and/or modify it under the same term as Ruby. +# +# See Bundler::URI for general documentation +# + +module Bundler::URI + # + # Includes Bundler::URI::REGEXP::PATTERN + # + module RFC2396_REGEXP + # + # Patterns used to parse Bundler::URI's + # + module PATTERN + # :stopdoc: + + # RFC 2396 (Bundler::URI Generic Syntax) + # RFC 2732 (IPv6 Literal Addresses in URL's) + # RFC 2373 (IPv6 Addressing Architecture) + + # alpha = lowalpha | upalpha + ALPHA = "a-zA-Z" + # alphanum = alpha | digit + ALNUM = "#{ALPHA}\\d" + + # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + # "a" | "b" | "c" | "d" | "e" | "f" + HEX = "a-fA-F\\d" + # escaped = "%" hex hex + ESCAPED = "%[#{HEX}]{2}" + # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | + # "(" | ")" + # unreserved = alphanum | mark + UNRESERVED = "\\-_.!~*'()#{ALNUM}" + # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + # "$" | "," + # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + # "$" | "," | "[" | "]" (RFC 2732) + RESERVED = ";/?:@&=+$,\\[\\]" + + # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)" + # toplabel = alpha | alpha *( alphanum | "-" ) alphanum + TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)" + # hostname = *( domainlabel "." ) toplabel [ "." ] + HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?" + + # :startdoc: + end # PATTERN + + # :startdoc: + end # REGEXP + + # Class that parses String's into Bundler::URI's. + # + # It contains a Hash set of patterns and Regexp's that match and validate. + # + class RFC2396_Parser + include RFC2396_REGEXP + + # + # == Synopsis + # + # Bundler::URI::Parser.new([opts]) + # + # == Args + # + # The constructor accepts a hash as options for parser. + # Keys of options are pattern names of Bundler::URI components + # and values of options are pattern strings. + # The constructor generates set of regexps for parsing URIs. + # + # You can use the following keys: + # + # * :ESCAPED (Bundler::URI::PATTERN::ESCAPED in default) + # * :UNRESERVED (Bundler::URI::PATTERN::UNRESERVED in default) + # * :DOMLABEL (Bundler::URI::PATTERN::DOMLABEL in default) + # * :TOPLABEL (Bundler::URI::PATTERN::TOPLABEL in default) + # * :HOSTNAME (Bundler::URI::PATTERN::HOSTNAME in default) + # + # == Examples + # + # p = Bundler::URI::Parser.new(:ESCAPED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})") + # u = p.parse("http://example.jp/%uABCD") #=> #<Bundler::URI::HTTP http://example.jp/%uABCD> + # Bundler::URI.parse(u.to_s) #=> raises Bundler::URI::InvalidURIError + # + # s = "http://example.com/ABCD" + # u1 = p.parse(s) #=> #<Bundler::URI::HTTP http://example.com/ABCD> + # u2 = Bundler::URI.parse(s) #=> #<Bundler::URI::HTTP http://example.com/ABCD> + # u1 == u2 #=> true + # u1.eql?(u2) #=> false + # + def initialize(opts = {}) + @pattern = initialize_pattern(opts) + @pattern.each_value(&:freeze) + @pattern.freeze + + @regexp = initialize_regexp(@pattern) + @regexp.each_value(&:freeze) + @regexp.freeze + end + + # The Hash of patterns. + # + # See also Bundler::URI::Parser.initialize_pattern. + attr_reader :pattern + + # The Hash of Regexp. + # + # See also Bundler::URI::Parser.initialize_regexp. + attr_reader :regexp + + # Returns a split Bundler::URI against regexp[:ABS_URI]. + def split(uri) + case uri + when '' + # null uri + + when @regexp[:ABS_URI] + scheme, opaque, userinfo, host, port, + registry, path, query, fragment = $~[1..-1] + + # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + # opaque_part = uric_no_slash *uric + + # abs_path = "/" path_segments + # net_path = "//" authority [ abs_path ] + + # authority = server | reg_name + # server = [ [ userinfo "@" ] hostport ] + + if !scheme + raise InvalidURIError, + "bad Bundler::URI(absolute but no scheme): #{uri}" + end + if !opaque && (!path && (!host && !registry)) + raise InvalidURIError, + "bad Bundler::URI(absolute but no path): #{uri}" + end + + when @regexp[:REL_URI] + scheme = nil + opaque = nil + + userinfo, host, port, registry, + rel_segment, abs_path, query, fragment = $~[1..-1] + if rel_segment && abs_path + path = rel_segment + abs_path + elsif rel_segment + path = rel_segment + elsif abs_path + path = abs_path + end + + # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + + # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + + # net_path = "//" authority [ abs_path ] + # abs_path = "/" path_segments + # rel_path = rel_segment [ abs_path ] + + # authority = server | reg_name + # server = [ [ userinfo "@" ] hostport ] + + else + raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri}" + end + + path = '' if !path && !opaque # (see RFC2396 Section 5.2) + ret = [ + scheme, + userinfo, host, port, # X + registry, # X + path, # Y + opaque, # Y + query, + fragment + ] + return ret + end + + # + # == Args + # + # +uri+:: + # String + # + # == Description + # + # Parses +uri+ and constructs either matching Bundler::URI scheme object + # (File, FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or Bundler::URI::Generic. + # + # == Usage + # + # p = Bundler::URI::Parser.new + # p.parse("ldap://ldap.example.com/dc=example?user=john") + # #=> #<Bundler::URI::LDAP ldap://ldap.example.com/dc=example?user=john> + # + def parse(uri) + scheme, userinfo, host, port, + registry, path, opaque, query, fragment = self.split(uri) + + if scheme && Bundler::URI.scheme_list.include?(scheme.upcase) + Bundler::URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port, + registry, path, opaque, query, + fragment, self) + else + Generic.new(scheme, userinfo, host, port, + registry, path, opaque, query, + fragment, self) + end + end + + + # + # == Args + # + # +uris+:: + # an Array of Strings + # + # == Description + # + # Attempts to parse and merge a set of URIs. + # + def join(*uris) + uris[0] = convert_to_uri(uris[0]) + uris.inject :merge + end + + # + # :call-seq: + # extract( str ) + # extract( str, schemes ) + # extract( str, schemes ) {|item| block } + # + # == Args + # + # +str+:: + # String to search + # +schemes+:: + # Patterns to apply to +str+ + # + # == Description + # + # Attempts to parse and merge a set of URIs. + # If no +block+ given, then returns the result, + # else it calls +block+ for each element in result. + # + # See also Bundler::URI::Parser.make_regexp. + # + def extract(str, schemes = nil) + if block_given? + str.scan(make_regexp(schemes)) { yield $& } + nil + else + result = [] + str.scan(make_regexp(schemes)) { result.push $& } + result + end + end + + # Returns Regexp that is default self.regexp[:ABS_URI_REF], + # unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI]. + def make_regexp(schemes = nil) + unless schemes + @regexp[:ABS_URI_REF] + else + /(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x + end + end + + # + # :call-seq: + # escape( str ) + # escape( str, unsafe ) + # + # == Args + # + # +str+:: + # String to make safe + # +unsafe+:: + # Regexp to apply. Defaults to self.regexp[:UNSAFE] + # + # == Description + # + # Constructs a safe String from +str+, removing unsafe characters, + # replacing them with codes. + # + def escape(str, unsafe = @regexp[:UNSAFE]) + unless unsafe.kind_of?(Regexp) + # perhaps unsafe is String object + unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false) + end + str.gsub(unsafe) do + us = $& + tmp = '' + us.each_byte do |uc| + tmp << sprintf('%%%02X', uc) + end + tmp + end.force_encoding(Encoding::US_ASCII) + end + + # + # :call-seq: + # unescape( str ) + # unescape( str, escaped ) + # + # == Args + # + # +str+:: + # String to remove escapes from + # +escaped+:: + # Regexp to apply. Defaults to self.regexp[:ESCAPED] + # + # == Description + # + # Removes escapes from +str+. + # + def unescape(str, escaped = @regexp[:ESCAPED]) + enc = str.encoding + enc = Encoding::UTF_8 if enc == Encoding::US_ASCII + str.gsub(escaped) { [$&[1, 2]].pack('H2').force_encoding(enc) } + end + + @@to_s = Kernel.instance_method(:to_s) + def inspect + @@to_s.bind_call(self) + end + + private + + # Constructs the default Hash of patterns. + def initialize_pattern(opts = {}) + ret = {} + ret[:ESCAPED] = escaped = (opts.delete(:ESCAPED) || PATTERN::ESCAPED) + ret[:UNRESERVED] = unreserved = opts.delete(:UNRESERVED) || PATTERN::UNRESERVED + ret[:RESERVED] = reserved = opts.delete(:RESERVED) || PATTERN::RESERVED + ret[:DOMLABEL] = opts.delete(:DOMLABEL) || PATTERN::DOMLABEL + ret[:TOPLABEL] = opts.delete(:TOPLABEL) || PATTERN::TOPLABEL + ret[:HOSTNAME] = hostname = opts.delete(:HOSTNAME) + + # RFC 2396 (Bundler::URI Generic Syntax) + # RFC 2732 (IPv6 Literal Addresses in URL's) + # RFC 2373 (IPv6 Addressing Architecture) + + # uric = reserved | unreserved | escaped + ret[:URIC] = uric = "(?:[#{unreserved}#{reserved}]|#{escaped})" + # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | + # "&" | "=" | "+" | "$" | "," + ret[:URIC_NO_SLASH] = uric_no_slash = "(?:[#{unreserved};?:@&=+$,]|#{escaped})" + # query = *uric + ret[:QUERY] = query = "#{uric}*" + # fragment = *uric + ret[:FRAGMENT] = fragment = "#{uric}*" + + # hostname = *( domainlabel "." ) toplabel [ "." ] + # reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986 + unless hostname + ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+" + end + + # RFC 2373, APPENDIX B: + # IPv6address = hexpart [ ":" IPv4address ] + # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT + # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ] + # hexseq = hex4 *( ":" hex4) + # hex4 = 1*4HEXDIG + # + # XXX: This definition has a flaw. "::" + IPv4address must be + # allowed too. Here is a replacement. + # + # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT + ret[:IPV4ADDR] = ipv4addr = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}" + # hex4 = 1*4HEXDIG + hex4 = "[#{PATTERN::HEX}]{1,4}" + # lastpart = hex4 | IPv4address + lastpart = "(?:#{hex4}|#{ipv4addr})" + # hexseq1 = *( hex4 ":" ) hex4 + hexseq1 = "(?:#{hex4}:)*#{hex4}" + # hexseq2 = *( hex4 ":" ) lastpart + hexseq2 = "(?:#{hex4}:)*#{lastpart}" + # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ] + ret[:IPV6ADDR] = ipv6addr = "(?:#{hexseq2}|(?:#{hexseq1})?::(?:#{hexseq2})?)" + + # IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT + # unused + + # ipv6reference = "[" IPv6address "]" (RFC 2732) + ret[:IPV6REF] = ipv6ref = "\\[#{ipv6addr}\\]" + + # host = hostname | IPv4address + # host = hostname | IPv4address | IPv6reference (RFC 2732) + ret[:HOST] = host = "(?:#{hostname}|#{ipv4addr}|#{ipv6ref})" + # port = *digit + ret[:PORT] = port = '\d*' + # hostport = host [ ":" port ] + ret[:HOSTPORT] = hostport = "#{host}(?::#{port})?" + + # userinfo = *( unreserved | escaped | + # ";" | ":" | "&" | "=" | "+" | "$" | "," ) + ret[:USERINFO] = userinfo = "(?:[#{unreserved};:&=+$,]|#{escaped})*" + + # pchar = unreserved | escaped | + # ":" | "@" | "&" | "=" | "+" | "$" | "," + pchar = "(?:[#{unreserved}:@&=+$,]|#{escaped})" + # param = *pchar + param = "#{pchar}*" + # segment = *pchar *( ";" param ) + segment = "#{pchar}*(?:;#{param})*" + # path_segments = segment *( "/" segment ) + ret[:PATH_SEGMENTS] = path_segments = "#{segment}(?:/#{segment})*" + + # server = [ [ userinfo "@" ] hostport ] + server = "(?:#{userinfo}@)?#{hostport}" + # reg_name = 1*( unreserved | escaped | "$" | "," | + # ";" | ":" | "@" | "&" | "=" | "+" ) + ret[:REG_NAME] = reg_name = "(?:[#{unreserved}$,;:@&=+]|#{escaped})+" + # authority = server | reg_name + authority = "(?:#{server}|#{reg_name})" + + # rel_segment = 1*( unreserved | escaped | + # ";" | "@" | "&" | "=" | "+" | "$" | "," ) + ret[:REL_SEGMENT] = rel_segment = "(?:[#{unreserved};@&=+$,]|#{escaped})+" + + # scheme = alpha *( alpha | digit | "+" | "-" | "." ) + ret[:SCHEME] = scheme = "[#{PATTERN::ALPHA}][\\-+.#{PATTERN::ALPHA}\\d]*" + + # abs_path = "/" path_segments + ret[:ABS_PATH] = abs_path = "/#{path_segments}" + # rel_path = rel_segment [ abs_path ] + ret[:REL_PATH] = rel_path = "#{rel_segment}(?:#{abs_path})?" + # net_path = "//" authority [ abs_path ] + ret[:NET_PATH] = net_path = "//#{authority}(?:#{abs_path})?" + + # hier_part = ( net_path | abs_path ) [ "?" query ] + ret[:HIER_PART] = hier_part = "(?:#{net_path}|#{abs_path})(?:\\?(?:#{query}))?" + # opaque_part = uric_no_slash *uric + ret[:OPAQUE_PART] = opaque_part = "#{uric_no_slash}#{uric}*" + + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + ret[:ABS_URI] = abs_uri = "#{scheme}:(?:#{hier_part}|#{opaque_part})" + # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + ret[:REL_URI] = rel_uri = "(?:#{net_path}|#{abs_path}|#{rel_path})(?:\\?#{query})?" + + # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + ret[:URI_REF] = "(?:#{abs_uri}|#{rel_uri})?(?:##{fragment})?" + + ret[:X_ABS_URI] = " + (#{scheme}): (?# 1: scheme) + (?: + (#{opaque_part}) (?# 2: opaque) + | + (?:(?: + //(?: + (?:(?:(#{userinfo})@)? (?# 3: userinfo) + (?:(#{host})(?::(\\d*))?))? (?# 4: host, 5: port) + | + (#{reg_name}) (?# 6: registry) + ) + | + (?!//)) (?# XXX: '//' is the mark for hostport) + (#{abs_path})? (?# 7: path) + )(?:\\?(#{query}))? (?# 8: query) + ) + (?:\\#(#{fragment}))? (?# 9: fragment) + " + + ret[:X_REL_URI] = " + (?: + (?: + // + (?: + (?:(#{userinfo})@)? (?# 1: userinfo) + (#{host})?(?::(\\d*))? (?# 2: host, 3: port) + | + (#{reg_name}) (?# 4: registry) + ) + ) + | + (#{rel_segment}) (?# 5: rel_segment) + )? + (#{abs_path})? (?# 6: abs_path) + (?:\\?(#{query}))? (?# 7: query) + (?:\\#(#{fragment}))? (?# 8: fragment) + " + + ret + end + + # Constructs the default Hash of Regexp's. + def initialize_regexp(pattern) + ret = {} + + # for Bundler::URI::split + ret[:ABS_URI] = Regexp.new('\A\s*' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED) + ret[:REL_URI] = Regexp.new('\A\s*' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED) + + # for Bundler::URI::extract + ret[:URI_REF] = Regexp.new(pattern[:URI_REF]) + ret[:ABS_URI_REF] = Regexp.new(pattern[:X_ABS_URI], Regexp::EXTENDED) + ret[:REL_URI_REF] = Regexp.new(pattern[:X_REL_URI], Regexp::EXTENDED) + + # for Bundler::URI::escape/unescape + ret[:ESCAPED] = Regexp.new(pattern[:ESCAPED]) + ret[:UNSAFE] = Regexp.new("[^#{pattern[:UNRESERVED]}#{pattern[:RESERVED]}]") + + # for Generic#initialize + ret[:SCHEME] = Regexp.new("\\A#{pattern[:SCHEME]}\\z") + ret[:USERINFO] = Regexp.new("\\A#{pattern[:USERINFO]}\\z") + ret[:HOST] = Regexp.new("\\A#{pattern[:HOST]}\\z") + ret[:PORT] = Regexp.new("\\A#{pattern[:PORT]}\\z") + ret[:OPAQUE] = Regexp.new("\\A#{pattern[:OPAQUE_PART]}\\z") + ret[:REGISTRY] = Regexp.new("\\A#{pattern[:REG_NAME]}\\z") + ret[:ABS_PATH] = Regexp.new("\\A#{pattern[:ABS_PATH]}\\z") + ret[:REL_PATH] = Regexp.new("\\A#{pattern[:REL_PATH]}\\z") + ret[:QUERY] = Regexp.new("\\A#{pattern[:QUERY]}\\z") + ret[:FRAGMENT] = Regexp.new("\\A#{pattern[:FRAGMENT]}\\z") + + ret + end + + def convert_to_uri(uri) + if uri.is_a?(Bundler::URI::Generic) + uri + elsif uri = String.try_convert(uri) + parse(uri) + else + raise ArgumentError, + "bad argument (expected Bundler::URI object or Bundler::URI string)" + end + end + + end # class Parser +end # module Bundler::URI diff --git a/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb b/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb new file mode 100644 index 0000000000..07ef4391c0 --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: false +module Bundler::URI + class RFC3986_Parser # :nodoc: + # Bundler::URI defined in RFC3986 + # this regexp is modified not to host is not empty string + RFC3986_URI = /\A(?<Bundler::URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ + RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+)\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])+)(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ + attr_reader :regexp + + def initialize + @regexp = default_regexp.each_value(&:freeze).freeze + end + + def split(uri) #:nodoc: + begin + uri = uri.to_str + rescue NoMethodError + raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri.inspect}" + end + uri.ascii_only? or + raise InvalidURIError, "Bundler::URI must be ascii only #{uri.dump}" + if m = RFC3986_URI.match(uri) + query = m["query".freeze] + scheme = m["scheme".freeze] + opaque = m["path-rootless".freeze] + if opaque + opaque << "?#{query}" if query + [ scheme, + nil, # userinfo + nil, # host + nil, # port + nil, # registry + nil, # path + opaque, + nil, # query + m["fragment".freeze] + ] + else # normal + [ scheme, + m["userinfo".freeze], + m["host".freeze], + m["port".freeze], + nil, # registry + (m["path-abempty".freeze] || + m["path-absolute".freeze] || + m["path-empty".freeze]), + nil, # opaque + query, + m["fragment".freeze] + ] + end + elsif m = RFC3986_relative_ref.match(uri) + [ nil, # scheme + m["userinfo".freeze], + m["host".freeze], + m["port".freeze], + nil, # registry, + (m["path-abempty".freeze] || + m["path-absolute".freeze] || + m["path-noscheme".freeze] || + m["path-empty".freeze]), + nil, # opaque + m["query".freeze], + m["fragment".freeze] + ] + else + raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri.inspect}" + end + end + + def parse(uri) # :nodoc: + scheme, userinfo, host, port, + registry, path, opaque, query, fragment = self.split(uri) + scheme_list = Bundler::URI.scheme_list + if scheme && scheme_list.include?(uc = scheme.upcase) + scheme_list[uc].new(scheme, userinfo, host, port, + registry, path, opaque, query, + fragment, self) + else + Generic.new(scheme, userinfo, host, port, + registry, path, opaque, query, + fragment, self) + end + end + + + def join(*uris) # :nodoc: + uris[0] = convert_to_uri(uris[0]) + uris.inject :merge + end + + @@to_s = Kernel.instance_method(:to_s) + def inspect + @@to_s.bind_call(self) + end + + private + + def default_regexp # :nodoc: + { + SCHEME: /\A[A-Za-z][A-Za-z0-9+\-.]*\z/, + USERINFO: /\A(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*\z/, + HOST: /\A(?:(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{,4}::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*))\z/, + ABS_PATH: /\A\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/, + REL_PATH: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/, + QUERY: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/, + FRAGMENT: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/, + OPAQUE: /\A(?:[^\/].*)?\z/, + PORT: /\A[\x09\x0a\x0c\x0d ]*\d*[\x09\x0a\x0c\x0d ]*\z/, + } + end + + def convert_to_uri(uri) + if uri.is_a?(Bundler::URI::Generic) + uri + elsif uri = String.try_convert(uri) + parse(uri) + else + raise ArgumentError, + "bad argument (expected Bundler::URI object or Bundler::URI string)" + end + end + + end # class Parser +end # module Bundler::URI diff --git a/lib/bundler/vendor/uri/lib/uri/version.rb b/lib/bundler/vendor/uri/lib/uri/version.rb new file mode 100644 index 0000000000..56177ef194 --- /dev/null +++ b/lib/bundler/vendor/uri/lib/uri/version.rb @@ -0,0 +1,6 @@ +module Bundler::URI + # :stopdoc: + VERSION_CODE = '001000'.freeze + VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze + # :startdoc: +end diff --git a/lib/bundler/vendored_uri.rb b/lib/bundler/vendored_uri.rb new file mode 100644 index 0000000000..905e8158e8 --- /dev/null +++ b/lib/bundler/vendored_uri.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module Bundler; end +require_relative "vendor/uri/lib/uri" diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index 4cf11c5fb5..417b21f18a 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.1.0.pre.3".freeze + VERSION = "2.1.0".freeze def self.bundler_major_version @bundler_major_version ||= VERSION.split(".").first.to_i diff --git a/man/bundle-add.1 b/man/bundle-add.1 index ba81726c5f..24bfe50f4f 100644 --- a/man/bundle-add.1 +++ b/man/bundle-add.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-ADD" "1" "November 2019" "" "" +.TH "BUNDLE\-ADD" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install diff --git a/man/bundle-add.1.txt b/man/bundle-add.1.txt index 16a1405c9b..aff9977fb1 100644 --- a/man/bundle-add.1.txt +++ b/man/bundle-add.1.txt @@ -55,4 +55,4 @@ OPTIONS - November 2019 BUNDLE-ADD(1) + December 2019 BUNDLE-ADD(1) diff --git a/man/bundle-binstubs.1 b/man/bundle-binstubs.1 index 559350c7d0..4e69bfb715 100644 --- a/man/bundle-binstubs.1 +++ b/man/bundle-binstubs.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-BINSTUBS" "1" "November 2019" "" "" +.TH "BUNDLE\-BINSTUBS" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems diff --git a/man/bundle-binstubs.1.txt b/man/bundle-binstubs.1.txt index 1e35f6111b..564989bd8a 100644 --- a/man/bundle-binstubs.1.txt +++ b/man/bundle-binstubs.1.txt @@ -45,4 +45,4 @@ BUNDLE INSTALL --BINSTUBS - November 2019 BUNDLE-BINSTUBS(1) + December 2019 BUNDLE-BINSTUBS(1) diff --git a/man/bundle-cache.1 b/man/bundle-cache.1 index 1adb0b152c..23bc757d03 100644 --- a/man/bundle-cache.1 +++ b/man/bundle-cache.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CACHE" "1" "November 2019" "" "" +.TH "BUNDLE\-CACHE" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application diff --git a/man/bundle-cache.1.txt b/man/bundle-cache.1.txt index b5cec05f8a..4dcc7c9cc9 100644 --- a/man/bundle-cache.1.txt +++ b/man/bundle-cache.1.txt @@ -75,4 +75,4 @@ REMOTE FETCHING - November 2019 BUNDLE-CACHE(1) + December 2019 BUNDLE-CACHE(1) diff --git a/man/bundle-check.1 b/man/bundle-check.1 index 56516255c7..ac80f697f5 100644 --- a/man/bundle-check.1 +++ b/man/bundle-check.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CHECK" "1" "November 2019" "" "" +.TH "BUNDLE\-CHECK" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems diff --git a/man/bundle-check.1.txt b/man/bundle-check.1.txt index a1edc4d4a4..05d1c7dc5c 100644 --- a/man/bundle-check.1.txt +++ b/man/bundle-check.1.txt @@ -30,4 +30,4 @@ OPTIONS - November 2019 BUNDLE-CHECK(1) + December 2019 BUNDLE-CHECK(1) diff --git a/man/bundle-clean.1 b/man/bundle-clean.1 index 9d62619bb2..61fcf9d396 100644 --- a/man/bundle-clean.1 +++ b/man/bundle-clean.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CLEAN" "1" "November 2019" "" "" +.TH "BUNDLE\-CLEAN" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory diff --git a/man/bundle-clean.1.txt b/man/bundle-clean.1.txt index 6e24aaf2c4..9438f8adc9 100644 --- a/man/bundle-clean.1.txt +++ b/man/bundle-clean.1.txt @@ -23,4 +23,4 @@ OPTIONS - November 2019 BUNDLE-CLEAN(1) + December 2019 BUNDLE-CLEAN(1) diff --git a/man/bundle-config.1 b/man/bundle-config.1 index e982ec0501..56ef24791d 100644 --- a/man/bundle-config.1 +++ b/man/bundle-config.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CONFIG" "1" "November 2019" "" "" +.TH "BUNDLE\-CONFIG" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-config\fR \- Set bundler configuration options diff --git a/man/bundle-config.1.txt b/man/bundle-config.1.txt index cff5990296..bc3fe39069 100644 --- a/man/bundle-config.1.txt +++ b/man/bundle-config.1.txt @@ -525,4 +525,4 @@ CONFIGURE BUNDLER DIRECTORIES - November 2019 BUNDLE-CONFIG(1) + December 2019 BUNDLE-CONFIG(1) diff --git a/man/bundle-doctor.1 b/man/bundle-doctor.1 index ec7231d4a9..d3e3e73bbe 100644 --- a/man/bundle-doctor.1 +++ b/man/bundle-doctor.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-DOCTOR" "1" "November 2019" "" "" +.TH "BUNDLE\-DOCTOR" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-doctor\fR \- Checks the bundle for common problems diff --git a/man/bundle-doctor.1.txt b/man/bundle-doctor.1.txt index 58fd9ed4a0..6b2fdcbdf4 100644 --- a/man/bundle-doctor.1.txt +++ b/man/bundle-doctor.1.txt @@ -41,4 +41,4 @@ OPTIONS - November 2019 BUNDLE-DOCTOR(1) + December 2019 BUNDLE-DOCTOR(1) diff --git a/man/bundle-exec.1 b/man/bundle-exec.1 index 187251740a..fa0728a5de 100644 --- a/man/bundle-exec.1 +++ b/man/bundle-exec.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-EXEC" "1" "November 2019" "" "" +.TH "BUNDLE\-EXEC" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-exec\fR \- Execute a command in the context of the bundle diff --git a/man/bundle-exec.1.txt b/man/bundle-exec.1.txt index 2b0a17c4fc..efcb130b48 100644 --- a/man/bundle-exec.1.txt +++ b/man/bundle-exec.1.txt @@ -175,4 +175,4 @@ RUBYGEMS PLUGINS - November 2019 BUNDLE-EXEC(1) + December 2019 BUNDLE-EXEC(1) diff --git a/man/bundle-gem.1 b/man/bundle-gem.1 index e814e3f1aa..9971e3528c 100644 --- a/man/bundle-gem.1 +++ b/man/bundle-gem.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-GEM" "1" "November 2019" "" "" +.TH "BUNDLE\-GEM" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem diff --git a/man/bundle-gem.1.txt b/man/bundle-gem.1.txt index 266cc43131..c95c409c65 100644 --- a/man/bundle-gem.1.txt +++ b/man/bundle-gem.1.txt @@ -88,4 +88,4 @@ SEE ALSO - November 2019 BUNDLE-GEM(1) + December 2019 BUNDLE-GEM(1) diff --git a/man/bundle-info.1 b/man/bundle-info.1 index 75b0cfa358..9dbef738fa 100644 --- a/man/bundle-info.1 +++ b/man/bundle-info.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INFO" "1" "November 2019" "" "" +.TH "BUNDLE\-INFO" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-info\fR \- Show information for the given gem in your bundle diff --git a/man/bundle-info.1.txt b/man/bundle-info.1.txt index 4e908c6e4c..102ec48f6e 100644 --- a/man/bundle-info.1.txt +++ b/man/bundle-info.1.txt @@ -18,4 +18,4 @@ OPTIONS - November 2019 BUNDLE-INFO(1) + December 2019 BUNDLE-INFO(1) diff --git a/man/bundle-init.1 b/man/bundle-init.1 index 9e2a23004f..8fe0d02406 100644 --- a/man/bundle-init.1 +++ b/man/bundle-init.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INIT" "1" "November 2019" "" "" +.TH "BUNDLE\-INIT" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-init\fR \- Generates a Gemfile into the current working directory diff --git a/man/bundle-init.1.txt b/man/bundle-init.1.txt index cdebbebf14..187ed4b3c0 100644 --- a/man/bundle-init.1.txt +++ b/man/bundle-init.1.txt @@ -31,4 +31,4 @@ SEE ALSO - November 2019 BUNDLE-INIT(1) + December 2019 BUNDLE-INIT(1) diff --git a/man/bundle-inject.1 b/man/bundle-inject.1 index 6ce2973b5f..afc328771e 100644 --- a/man/bundle-inject.1 +++ b/man/bundle-inject.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INJECT" "1" "November 2019" "" "" +.TH "BUNDLE\-INJECT" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile diff --git a/man/bundle-inject.1.txt b/man/bundle-inject.1.txt index df0a032b97..a73927cef0 100644 --- a/man/bundle-inject.1.txt +++ b/man/bundle-inject.1.txt @@ -29,4 +29,4 @@ DESCRIPTION - November 2019 BUNDLE-INJECT(1) + December 2019 BUNDLE-INJECT(1) diff --git a/man/bundle-install.1 b/man/bundle-install.1 index 4656a0cbe3..200acfca24 100644 --- a/man/bundle-install.1 +++ b/man/bundle-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INSTALL" "1" "November 2019" "" "" +.TH "BUNDLE\-INSTALL" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile diff --git a/man/bundle-install.1.txt b/man/bundle-install.1.txt index cef9494cc3..08a0869d6f 100644 --- a/man/bundle-install.1.txt +++ b/man/bundle-install.1.txt @@ -398,4 +398,4 @@ SEE ALSO - November 2019 BUNDLE-INSTALL(1) + December 2019 BUNDLE-INSTALL(1) diff --git a/man/bundle-list.1 b/man/bundle-list.1 index 0d932dbf28..53427b4504 100644 --- a/man/bundle-list.1 +++ b/man/bundle-list.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-LIST" "1" "November 2019" "" "" +.TH "BUNDLE\-LIST" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-list\fR \- List all the gems in the bundle diff --git a/man/bundle-list.1.txt b/man/bundle-list.1.txt index d2433c5648..f4eab62783 100644 --- a/man/bundle-list.1.txt +++ b/man/bundle-list.1.txt @@ -40,4 +40,4 @@ OPTIONS - November 2019 BUNDLE-LIST(1) + December 2019 BUNDLE-LIST(1) diff --git a/man/bundle-lock.1 b/man/bundle-lock.1 index 6b86531f60..b64a645eb8 100644 --- a/man/bundle-lock.1 +++ b/man/bundle-lock.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-LOCK" "1" "November 2019" "" "" +.TH "BUNDLE\-LOCK" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing diff --git a/man/bundle-lock.1.txt b/man/bundle-lock.1.txt index b8f18c13e0..a50ee25643 100644 --- a/man/bundle-lock.1.txt +++ b/man/bundle-lock.1.txt @@ -90,4 +90,4 @@ PATCH LEVEL OPTIONS - November 2019 BUNDLE-LOCK(1) + December 2019 BUNDLE-LOCK(1) diff --git a/man/bundle-open.1 b/man/bundle-open.1 index 4eb5aebdf3..6213aeca65 100644 --- a/man/bundle-open.1 +++ b/man/bundle-open.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-OPEN" "1" "November 2019" "" "" +.TH "BUNDLE\-OPEN" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle diff --git a/man/bundle-open.1.txt b/man/bundle-open.1.txt index a4ca7eaf61..9ecc89c10a 100644 --- a/man/bundle-open.1.txt +++ b/man/bundle-open.1.txt @@ -26,4 +26,4 @@ DESCRIPTION - November 2019 BUNDLE-OPEN(1) + December 2019 BUNDLE-OPEN(1) diff --git a/man/bundle-outdated.1 b/man/bundle-outdated.1 index d126a14f05..81543bb65b 100644 --- a/man/bundle-outdated.1 +++ b/man/bundle-outdated.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-OUTDATED" "1" "November 2019" "" "" +.TH "BUNDLE\-OUTDATED" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-outdated\fR \- List installed gems with newer versions available diff --git a/man/bundle-outdated.1.txt b/man/bundle-outdated.1.txt index 49534557d9..905a1fd9fc 100644 --- a/man/bundle-outdated.1.txt +++ b/man/bundle-outdated.1.txt @@ -128,4 +128,4 @@ FILTERING OUTPUT - November 2019 BUNDLE-OUTDATED(1) + December 2019 BUNDLE-OUTDATED(1) diff --git a/man/bundle-platform.1 b/man/bundle-platform.1 index 8d0dd9bfda..f7f65045dc 100644 --- a/man/bundle-platform.1 +++ b/man/bundle-platform.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-PLATFORM" "1" "November 2019" "" "" +.TH "BUNDLE\-PLATFORM" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-platform\fR \- Displays platform compatibility information diff --git a/man/bundle-platform.1.txt b/man/bundle-platform.1.txt index e609225e84..d808bed64f 100644 --- a/man/bundle-platform.1.txt +++ b/man/bundle-platform.1.txt @@ -54,4 +54,4 @@ OPTIONS - November 2019 BUNDLE-PLATFORM(1) + December 2019 BUNDLE-PLATFORM(1) diff --git a/man/bundle-pristine.1 b/man/bundle-pristine.1 index 3ba82f0eb1..5b3522dd1a 100644 --- a/man/bundle-pristine.1 +++ b/man/bundle-pristine.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-PRISTINE" "1" "November 2019" "" "" +.TH "BUNDLE\-PRISTINE" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition diff --git a/man/bundle-pristine.1.txt b/man/bundle-pristine.1.txt index 780441595a..a22bd53927 100644 --- a/man/bundle-pristine.1.txt +++ b/man/bundle-pristine.1.txt @@ -41,4 +41,4 @@ DESCRIPTION - November 2019 BUNDLE-PRISTINE(1) + December 2019 BUNDLE-PRISTINE(1) diff --git a/man/bundle-remove.1 b/man/bundle-remove.1 index 35874563a0..4a4ed7ac95 100644 --- a/man/bundle-remove.1 +++ b/man/bundle-remove.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-REMOVE" "1" "November 2019" "" "" +.TH "BUNDLE\-REMOVE" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-remove\fR \- Removes gems from the Gemfile diff --git a/man/bundle-remove.1.txt b/man/bundle-remove.1.txt index 968aeed416..7c8945e2c0 100644 --- a/man/bundle-remove.1.txt +++ b/man/bundle-remove.1.txt @@ -31,4 +31,4 @@ OPTIONS - November 2019 BUNDLE-REMOVE(1) + December 2019 BUNDLE-REMOVE(1) diff --git a/man/bundle-show.1 b/man/bundle-show.1 index 51329ecb2c..575619370b 100644 --- a/man/bundle-show.1 +++ b/man/bundle-show.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-SHOW" "1" "November 2019" "" "" +.TH "BUNDLE\-SHOW" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem diff --git a/man/bundle-show.1.txt b/man/bundle-show.1.txt index cbab9e0bd7..fa80081427 100644 --- a/man/bundle-show.1.txt +++ b/man/bundle-show.1.txt @@ -24,4 +24,4 @@ OPTIONS - November 2019 BUNDLE-SHOW(1) + December 2019 BUNDLE-SHOW(1) diff --git a/man/bundle-update.1 b/man/bundle-update.1 index 726f4f7cb7..6a3fd877e2 100644 --- a/man/bundle-update.1 +++ b/man/bundle-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-UPDATE" "1" "November 2019" "" "" +.TH "BUNDLE\-UPDATE" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-update\fR \- Update your gems to the latest available versions diff --git a/man/bundle-update.1.txt b/man/bundle-update.1.txt index bc84254475..c54ade9713 100644 --- a/man/bundle-update.1.txt +++ b/man/bundle-update.1.txt @@ -387,4 +387,4 @@ RECOMMENDED WORKFLOW - November 2019 BUNDLE-UPDATE(1) + December 2019 BUNDLE-UPDATE(1) diff --git a/man/bundle-viz.1 b/man/bundle-viz.1 index 0ad8a1fa58..f1852e4206 100644 --- a/man/bundle-viz.1 +++ b/man/bundle-viz.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-VIZ" "1" "November 2019" "" "" +.TH "BUNDLE\-VIZ" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile diff --git a/man/bundle-viz.1.txt b/man/bundle-viz.1.txt index c9e3ce2c2b..7956cf18ed 100644 --- a/man/bundle-viz.1.txt +++ b/man/bundle-viz.1.txt @@ -36,4 +36,4 @@ OPTIONS - November 2019 BUNDLE-VIZ(1) + December 2019 BUNDLE-VIZ(1) diff --git a/man/bundle.1 b/man/bundle.1 index c391270cf2..93a43c0c70 100644 --- a/man/bundle.1 +++ b/man/bundle.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE" "1" "November 2019" "" "" +.TH "BUNDLE" "1" "December 2019" "" "" . .SH "NAME" \fBbundle\fR \- Ruby Dependency Management diff --git a/man/bundle.1.txt b/man/bundle.1.txt index e952002870..cd0fabadea 100644 --- a/man/bundle.1.txt +++ b/man/bundle.1.txt @@ -113,4 +113,4 @@ OBSOLETE - November 2019 BUNDLE(1) + December 2019 BUNDLE(1) diff --git a/man/gemfile.5 b/man/gemfile.5 index 8d1ac996a0..536af70a6e 100644 --- a/man/gemfile.5 +++ b/man/gemfile.5 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GEMFILE" "5" "November 2019" "" "" +.TH "GEMFILE" "5" "December 2019" "" "" . .SH "NAME" \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs diff --git a/man/gemfile.5.txt b/man/gemfile.5.txt index e7dd2c0d97..b3da595b17 100644 --- a/man/gemfile.5.txt +++ b/man/gemfile.5.txt @@ -646,4 +646,4 @@ SOURCE PRIORITY - November 2019 GEMFILE(5) + December 2019 GEMFILE(5) diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb index 92f836299d..1f4c1a0807 100644 --- a/spec/bundler/bundler/definition_spec.rb +++ b/spec/bundler/bundler/definition_spec.rb @@ -46,7 +46,7 @@ RSpec.describe Bundler::Definition do s.add_dependency "rack", "1.0" end - bundle :install, :env => { "DEBUG" => 1 } + bundle :install, :env => { "DEBUG" => "1" } expect(out).to match(/re-resolving dependencies/) lockfile_should_be <<-G @@ -84,7 +84,7 @@ RSpec.describe Bundler::Definition do s.add_dependency "rack", "1.0" end - bundle :install, :env => { "DEBUG" => 1 } + bundle :install, :env => { "DEBUG" => "1" } expect(out).to match(/re-resolving dependencies/) lockfile_should_be <<-G @@ -121,7 +121,7 @@ RSpec.describe Bundler::Definition do gem "foo", :path => "#{lib_path("foo")}" G - bundle :check, :env => { "DEBUG" => 1 } + bundle :check, :env => { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) lockfile_should_be <<-G @@ -154,7 +154,7 @@ RSpec.describe Bundler::Definition do G bundle "lock --add-platform java" - bundle :check, :env => { "DEBUG" => 1 } + bundle :check, :env => { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) lockfile_should_be <<-G @@ -181,7 +181,7 @@ RSpec.describe Bundler::Definition do gem "foo" G - bundle :check, :env => { "DEBUG" => 1 } + bundle :check, :env => { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) lockfile_should_be <<-G diff --git a/spec/bundler/bundler/env_spec.rb b/spec/bundler/bundler/env_spec.rb index f0ab5d5f35..7686fe386a 100644 --- a/spec/bundler/bundler/env_spec.rb +++ b/spec/bundler/bundler/env_spec.rb @@ -27,9 +27,9 @@ RSpec.describe Bundler::Env do end it "prints gem path" do - with_clear_paths("GEM_PATH", "/a/b/c:/d/e/f") do + with_clear_paths("GEM_PATH", "/a/b/c#{File::PATH_SEPARATOR}d/e/f") do out = described_class.report - expect(out).to include("Gem Path /a/b/c:/d/e/f") + expect(out).to include("Gem Path /a/b/c#{File::PATH_SEPARATOR}d/e/f") end end diff --git a/spec/bundler/bundler/fetcher/base_spec.rb b/spec/bundler/bundler/fetcher/base_spec.rb index df1245d44d..02506591f3 100644 --- a/spec/bundler/bundler/fetcher/base_spec.rb +++ b/spec/bundler/bundler/fetcher/base_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Bundler::Fetcher::Base do end describe "#fetch_uri" do - let(:remote_uri_obj) { URI("http://rubygems.org") } + let(:remote_uri_obj) { Bundler::URI("http://rubygems.org") } before { allow(subject).to receive(:remote_uri).and_return(remote_uri_obj) } @@ -49,10 +49,10 @@ RSpec.describe Bundler::Fetcher::Base do end context "when the remote uri's host is not rubygems.org" do - let(:remote_uri_obj) { URI("http://otherhost.org") } + let(:remote_uri_obj) { Bundler::URI("http://otherhost.org") } it "should return the remote uri" do - expect(subject.fetch_uri).to eq(URI("http://otherhost.org")) + expect(subject.fetch_uri).to eq(Bundler::URI("http://otherhost.org")) end end diff --git a/spec/bundler/bundler/fetcher/compact_index_spec.rb b/spec/bundler/bundler/fetcher/compact_index_spec.rb index f5ae6f4d77..c9419d3eb1 100644 --- a/spec/bundler/bundler/fetcher/compact_index_spec.rb +++ b/spec/bundler/bundler/fetcher/compact_index_spec.rb @@ -2,7 +2,7 @@ RSpec.describe Bundler::Fetcher::CompactIndex do let(:downloader) { double(:downloader) } - let(:display_uri) { URI("http://sampleuri.com") } + let(:display_uri) { Bundler::URI("http://sampleuri.com") } let(:remote) { double(:remote, :cache_slug => "lsjdf", :uri => display_uri) } let(:compact_index) { described_class.new(downloader, remote, display_uri) } diff --git a/spec/bundler/bundler/fetcher/dependency_spec.rb b/spec/bundler/bundler/fetcher/dependency_spec.rb index 081fdff34d..53249116cd 100644 --- a/spec/bundler/bundler/fetcher/dependency_spec.rb +++ b/spec/bundler/bundler/fetcher/dependency_spec.rb @@ -2,7 +2,7 @@ RSpec.describe Bundler::Fetcher::Dependency do let(:downloader) { double(:downloader) } - let(:remote) { double(:remote, :uri => URI("http://localhost:5000")) } + let(:remote) { double(:remote, :uri => Bundler::URI("http://localhost:5000")) } let(:display_uri) { "http://sample_uri.com" } subject { described_class.new(downloader, remote, display_uri) } @@ -258,7 +258,7 @@ RSpec.describe Bundler::Fetcher::Dependency do end describe "#dependency_api_uri" do - let(:uri) { URI("http://gem-api.com") } + let(:uri) { Bundler::URI("http://gem-api.com") } context "with gem names" do let(:gem_names) { %w[foo bar bundler rubocop] } diff --git a/spec/bundler/bundler/fetcher/downloader_spec.rb b/spec/bundler/bundler/fetcher/downloader_spec.rb index f985b88982..ba8451d9fa 100644 --- a/spec/bundler/bundler/fetcher/downloader_spec.rb +++ b/spec/bundler/bundler/fetcher/downloader_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Bundler::Fetcher::Downloader do let(:connection) { double(:connection) } let(:redirect_limit) { 5 } - let(:uri) { URI("http://www.uri-to-fetch.com/api/v2/endpoint") } + let(:uri) { Bundler::URI("http://www.uri-to-fetch.com/api/v2/endpoint") } let(:options) { double(:options) } subject { described_class.new(connection, redirect_limit) } @@ -41,19 +41,19 @@ RSpec.describe Bundler::Fetcher::Downloader do before { http_response["location"] = "http://www.redirect-uri.com/api/v2/endpoint" } it "should try to fetch the redirect uri and iterate the # requests counter" do - expect(subject).to receive(:fetch).with(URI("http://www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original - expect(subject).to receive(:fetch).with(URI("http://www.redirect-uri.com/api/v2/endpoint"), options, 1) + expect(subject).to receive(:fetch).with(Bundler::URI("http://www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original + expect(subject).to receive(:fetch).with(Bundler::URI("http://www.redirect-uri.com/api/v2/endpoint"), options, 1) subject.fetch(uri, options, counter) end context "when the redirect uri and original uri are the same" do - let(:uri) { URI("ssh://username:[email protected]/api/v2/endpoint") } + let(:uri) { Bundler::URI("ssh://username:[email protected]/api/v2/endpoint") } before { http_response["location"] = "ssh://www.uri-to-fetch.com/api/v1/endpoint" } it "should set the same user and password for the redirect uri" do - expect(subject).to receive(:fetch).with(URI("ssh://username:[email protected]/api/v2/endpoint"), options, 0).and_call_original - expect(subject).to receive(:fetch).with(URI("ssh://username:[email protected]/api/v1/endpoint"), options, 1) + expect(subject).to receive(:fetch).with(Bundler::URI("ssh://username:[email protected]/api/v2/endpoint"), options, 0).and_call_original + expect(subject).to receive(:fetch).with(Bundler::URI("ssh://username:[email protected]/api/v1/endpoint"), options, 1) subject.fetch(uri, options, counter) end end @@ -84,7 +84,7 @@ RSpec.describe Bundler::Fetcher::Downloader do end context "when the there are credentials provided in the request" do - let(:uri) { URI("http://user:[email protected]") } + let(:uri) { Bundler::URI("http://user:[email protected]") } it "should raise a Bundler::Fetcher::BadAuthenticationError that doesn't contain the password" do expect { subject.fetch(uri, options, counter) }. @@ -102,7 +102,7 @@ RSpec.describe Bundler::Fetcher::Downloader do end context "when the there are credentials provided in the request" do - let(:uri) { URI("http://username:[email protected]/api/v2/endpoint") } + let(:uri) { Bundler::URI("http://username:[email protected]/api/v2/endpoint") } it "should raise a Bundler::Fetcher::FallbackError that doesn't contain the password" do expect { subject.fetch(uri, options, counter) }. @@ -137,7 +137,7 @@ RSpec.describe Bundler::Fetcher::Downloader do context "when there is a user provided in the request" do context "and there is also a password provided" do context "that contains cgi escaped characters" do - let(:uri) { URI("http://username:password%[email protected]/api/v2/endpoint") } + let(:uri) { Bundler::URI("http://username:password%[email protected]/api/v2/endpoint") } it "should request basic authentication with the username and password" do expect(net_http_get).to receive(:basic_auth).with("username", "password$") @@ -146,7 +146,7 @@ RSpec.describe Bundler::Fetcher::Downloader do end context "that is all unescaped characters" do - let(:uri) { URI("http://username:[email protected]/api/v2/endpoint") } + let(:uri) { Bundler::URI("http://username:[email protected]/api/v2/endpoint") } it "should request basic authentication with the username and proper cgi compliant password" do expect(net_http_get).to receive(:basic_auth).with("username", "password") subject.request(uri, options) @@ -155,7 +155,7 @@ RSpec.describe Bundler::Fetcher::Downloader do end context "and there is no password provided" do - let(:uri) { URI("http://[email protected]/api/v2/endpoint") } + let(:uri) { Bundler::URI("http://[email protected]/api/v2/endpoint") } it "should request basic authentication with just the user" do expect(net_http_get).to receive(:basic_auth).with("username", nil) @@ -164,7 +164,7 @@ RSpec.describe Bundler::Fetcher::Downloader do end context "that contains cgi escaped characters" do - let(:uri) { URI("http://username%[email protected]/api/v2/endpoint") } + let(:uri) { Bundler::URI("http://username%[email protected]/api/v2/endpoint") } it "should request basic authentication with the proper cgi compliant password user" do expect(net_http_get).to receive(:basic_auth).with("username$", nil) @@ -244,7 +244,7 @@ RSpec.describe Bundler::Fetcher::Downloader do end context "when the there are credentials provided in the request" do - let(:uri) { URI("http://username:[email protected]/api/v2/endpoint") } + let(:uri) { Bundler::URI("http://username:[email protected]/api/v2/endpoint") } before do allow(net_http_get).to receive(:basic_auth).with("username", "password") end diff --git a/spec/bundler/bundler/fetcher/index_spec.rb b/spec/bundler/bundler/fetcher/index_spec.rb index d5ededae3e..5ecd7d9e05 100644 --- a/spec/bundler/bundler/fetcher/index_spec.rb +++ b/spec/bundler/bundler/fetcher/index_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Bundler::Fetcher::Index do context "error handling" do shared_examples_for "the error is properly handled" do - let(:remote_uri) { URI("http://remote-uri.org") } + let(:remote_uri) { Bundler::URI("http://remote-uri.org") } before do allow(subject).to receive(:remote_uri).and_return(remote_uri) end diff --git a/spec/bundler/bundler/fetcher_spec.rb b/spec/bundler/bundler/fetcher_spec.rb index 184b9efa64..539179db43 100644 --- a/spec/bundler/bundler/fetcher_spec.rb +++ b/spec/bundler/bundler/fetcher_spec.rb @@ -3,7 +3,7 @@ require "bundler/fetcher" RSpec.describe Bundler::Fetcher do - let(:uri) { URI("https://example.com") } + let(:uri) { Bundler::URI("https://example.com") } let(:remote) { double("remote", :uri => uri, :original_uri => nil) } subject(:fetcher) { Bundler::Fetcher.new(remote) } @@ -45,7 +45,7 @@ RSpec.describe Bundler::Fetcher do end context "when a rubygems source mirror is set" do - let(:orig_uri) { URI("http://zombo.com") } + let(:orig_uri) { Bundler::URI("http://zombo.com") } let(:remote_with_mirror) do double("remote", :uri => uri, :original_uri => orig_uri, :anonymized_uri => uri) end @@ -144,14 +144,14 @@ RSpec.describe Bundler::Fetcher do describe "include CI information" do it "from one CI" do with_env_vars("JENKINS_URL" => "foo") do - ci_part = fetcher.user_agent.split(" ").find {|x| x.match(%r{\Aci/}) } + ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") } expect(ci_part).to match("jenkins") end end it "from many CI" do with_env_vars("TRAVIS" => "foo", "CI_NAME" => "my_ci") do - ci_part = fetcher.user_agent.split(" ").find {|x| x.match(%r{\Aci/}) } + ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") } expect(ci_part).to match("travis") expect(ci_part).to match("my_ci") end diff --git a/spec/bundler/bundler/friendly_errors_spec.rb b/spec/bundler/bundler/friendly_errors_spec.rb index 47e7a5d3cd..e9189b0514 100644 --- a/spec/bundler/bundler/friendly_errors_spec.rb +++ b/spec/bundler/bundler/friendly_errors_spec.rb @@ -22,7 +22,7 @@ RSpec.describe Bundler, "friendly errors" do gem "rack" G - bundle :install, :env => { "DEBUG" => true } + bundle :install, :env => { "DEBUG" => "true" } expect(err).to include("Failed to load #{home(".gemrc")}") expect(exitstatus).to eq(0) if exitstatus diff --git a/spec/bundler/bundler/mirror_spec.rb b/spec/bundler/bundler/mirror_spec.rb index 76b697c4d2..4a8a0c7c48 100644 --- a/spec/bundler/bundler/mirror_spec.rb +++ b/spec/bundler/bundler/mirror_spec.rb @@ -36,12 +36,12 @@ RSpec.describe Bundler::Settings::Mirror do it "takes a string for the uri but returns an uri object" do mirror.uri = "http://localhost:9292" - expect(mirror.uri).to eq(URI("http://localhost:9292")) + expect(mirror.uri).to eq(Bundler::URI("http://localhost:9292")) end it "takes an uri object for the uri" do - mirror.uri = URI("http://localhost:9293") - expect(mirror.uri).to eq(URI("http://localhost:9293")) + mirror.uri = Bundler::URI("http://localhost:9293") + expect(mirror.uri).to eq(Bundler::URI("http://localhost:9293")) end context "without a uri" do @@ -145,7 +145,7 @@ RSpec.describe Bundler::Settings::Mirror do end RSpec.describe Bundler::Settings::Mirrors do - let(:localhost_uri) { URI("http://localhost:9292") } + let(:localhost_uri) { Bundler::URI("http://localhost:9292") } context "with a just created mirror" do let(:mirrors) do @@ -260,7 +260,7 @@ RSpec.describe Bundler::Settings::Mirrors do before { mirrors.parse("mirror.all.fallback_timeout", "true") } it "returns the source uri, not localhost" do - expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/")) end end end @@ -270,7 +270,7 @@ RSpec.describe Bundler::Settings::Mirrors do context "without a fallback timeout" do it "returns the uri that is not mirrored" do - expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/")) end it "returns localhost for rubygems.org" do @@ -282,11 +282,11 @@ RSpec.describe Bundler::Settings::Mirrors do before { mirrors.parse("mirror.http://rubygems.org/.fallback_timeout", "true") } it "returns the uri that is not mirrored" do - expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/")) end it "returns rubygems.org for rubygems.org" do - expect(mirrors.for("http://rubygems.org/").uri).to eq(URI("http://rubygems.org/")) + expect(mirrors.for("http://rubygems.org/").uri).to eq(Bundler::URI("http://rubygems.org/")) end end end diff --git a/spec/bundler/bundler/rubygems_integration_spec.rb b/spec/bundler/bundler/rubygems_integration_spec.rb index 26cbaa630b..11fa2f4e0d 100644 --- a/spec/bundler/bundler/rubygems_integration_spec.rb +++ b/spec/bundler/bundler/rubygems_integration_spec.rb @@ -44,7 +44,7 @@ RSpec.describe Bundler::RubygemsIntegration do describe "#download_gem" do let(:bundler_retry) { double(Bundler::Retry) } let(:retry) { double("Bundler::Retry") } - let(:uri) { URI.parse("https://foo.bar") } + let(:uri) { Bundler::URI.parse("https://foo.bar") } let(:path) { Gem.path.first } let(:spec) do spec = Bundler::RemoteSpecification.new("Foo", Gem::Version.new("2.5.2"), @@ -67,13 +67,13 @@ RSpec.describe Bundler::RubygemsIntegration do end describe "#fetch_all_remote_specs" do - let(:uri) { URI("https://example.com") } + let(:uri) { "https://example.com" } let(:fetcher) { double("gem_remote_fetcher") } let(:specs_response) { Marshal.dump(["specs"]) } let(:prerelease_specs_response) { Marshal.dump(["prerelease_specs"]) } context "when a rubygems source mirror is set" do - let(:orig_uri) { URI("http://zombo.com") } + let(:orig_uri) { Bundler::URI("http://zombo.com") } let(:remote_with_mirror) { double("remote", :uri => uri, :original_uri => orig_uri) } it "sets the 'X-Gemfile-Source' header containing the original source" do diff --git a/spec/bundler/bundler/settings_spec.rb b/spec/bundler/bundler/settings_spec.rb index 2a285fdcf3..b83d768477 100644 --- a/spec/bundler/bundler/settings_spec.rb +++ b/spec/bundler/bundler/settings_spec.rb @@ -180,7 +180,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow end describe "#mirror_for" do - let(:uri) { URI("https://rubygems.org/") } + let(:uri) { Bundler::URI("https://rubygems.org/") } context "with no configured mirror" do it "returns the original URI" do @@ -193,7 +193,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow end context "with a configured mirror" do - let(:mirror_uri) { URI("https://rubygems-mirror.org/") } + let(:mirror_uri) { Bundler::URI("https://rubygems-mirror.org/") } before { settings.set_local "mirror.https://rubygems.org/", mirror_uri.to_s } @@ -214,7 +214,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow end context "with a file URI" do - let(:mirror_uri) { URI("file:/foo/BAR/baz/qUx/") } + let(:mirror_uri) { Bundler::URI("file:/foo/BAR/baz/qUx/") } it "returns the mirror URI" do expect(settings.mirror_for(uri)).to eq(mirror_uri) @@ -232,7 +232,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow end describe "#credentials_for" do - let(:uri) { URI("https://gemserver.example.org/") } + let(:uri) { Bundler::URI("https://gemserver.example.org/") } let(:credentials) { "username:password" } context "with no configured credentials" do @@ -292,7 +292,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow it "reads older keys without trailing slashes" do settings.set_local "mirror.https://rubygems.org", "http://rubygems-mirror.org" expect(settings.mirror_for("https://rubygems.org/")).to eq( - URI("http://rubygems-mirror.org/") + Bundler::URI("http://rubygems-mirror.org/") ) end diff --git a/spec/bundler/bundler/source/rubygems/remote_spec.rb b/spec/bundler/bundler/source/rubygems/remote_spec.rb index 52fb4e7f1c..07ce4f968e 100644 --- a/spec/bundler/bundler/source/rubygems/remote_spec.rb +++ b/spec/bundler/bundler/source/rubygems/remote_spec.rb @@ -11,8 +11,8 @@ RSpec.describe Bundler::Source::Rubygems::Remote do allow(Digest(:MD5)).to receive(:hexdigest).with(duck_type(:to_s)) {|string| "MD5HEX(#{string})" } end - let(:uri_no_auth) { URI("https://gems.example.com") } - let(:uri_with_auth) { URI("https://#{credentials}@gems.example.com") } + let(:uri_no_auth) { Bundler::URI("https://gems.example.com") } + let(:uri_with_auth) { Bundler::URI("https://#{credentials}@gems.example.com") } let(:credentials) { "username:password" } context "when the original URI has no credentials" do @@ -89,11 +89,11 @@ RSpec.describe Bundler::Source::Rubygems::Remote do end context "when the original URI has only a username" do - let(:uri) { URI("https://[email protected]/me/") } + let(:uri) { Bundler::URI("https://[email protected]/me/") } describe "#anonymized_uri" do it "returns the URI without username and password" do - expect(remote(uri).anonymized_uri).to eq(URI("https://gem.fury.io/me/")) + expect(remote(uri).anonymized_uri).to eq(Bundler::URI("https://gem.fury.io/me/")) end end @@ -105,9 +105,9 @@ RSpec.describe Bundler::Source::Rubygems::Remote do end context "when a mirror with inline credentials is configured for the URI" do - let(:uri) { URI("https://rubygems.org/") } - let(:mirror_uri_with_auth) { URI("https://username:[email protected]/") } - let(:mirror_uri_no_auth) { URI("https://rubygems-mirror.org/") } + let(:uri) { Bundler::URI("https://rubygems.org/") } + let(:mirror_uri_with_auth) { Bundler::URI("https://username:[email protected]/") } + let(:mirror_uri_no_auth) { Bundler::URI("https://rubygems-mirror.org/") } before { Bundler.settings.temporary("mirror.https://rubygems.org/" => mirror_uri_with_auth.to_s) } @@ -131,9 +131,9 @@ RSpec.describe Bundler::Source::Rubygems::Remote do end context "when a mirror with configured credentials is configured for the URI" do - let(:uri) { URI("https://rubygems.org/") } - let(:mirror_uri_with_auth) { URI("https://#{credentials}@rubygems-mirror.org/") } - let(:mirror_uri_no_auth) { URI("https://rubygems-mirror.org/") } + let(:uri) { Bundler::URI("https://rubygems.org/") } + let(:mirror_uri_with_auth) { Bundler::URI("https://#{credentials}@rubygems-mirror.org/") } + let(:mirror_uri_no_auth) { Bundler::URI("https://rubygems-mirror.org/") } before do Bundler.settings.temporary("mirror.https://rubygems.org/" => mirror_uri_no_auth.to_s) diff --git a/spec/bundler/bundler/source_list_spec.rb b/spec/bundler/bundler/source_list_spec.rb index a78b80ec3b..93159998c6 100644 --- a/spec/bundler/bundler/source_list_spec.rb +++ b/spec/bundler/bundler/source_list_spec.rb @@ -125,8 +125,8 @@ RSpec.describe Bundler::SourceList do it "adds the provided remote to the beginning of the aggregate source" do source_list.add_rubygems_remote("https://othersource.org") expect(returned_source.remotes).to eq [ - URI("https://othersource.org/"), - URI("https://rubygems.org/"), + Bundler::URI("https://othersource.org/"), + Bundler::URI("https://rubygems.org/"), ] end end diff --git a/spec/bundler/bundler/uri_credentials_filter_spec.rb b/spec/bundler/bundler/uri_credentials_filter_spec.rb index fe52d16306..466c1b8594 100644 --- a/spec/bundler/bundler/uri_credentials_filter_spec.rb +++ b/spec/bundler/bundler/uri_credentials_filter_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Bundler::URICredentialsFilter do let(:credentials) { "oauth_token:x-oauth-basic@" } it "returns the uri without the oauth token" do - expect(subject.credential_filtered_uri(uri).to_s).to eq(URI("https://[email protected]/company/private-repo").to_s) + expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://[email protected]/company/private-repo").to_s) end it_behaves_like "original type of uri is maintained" @@ -26,7 +26,7 @@ RSpec.describe Bundler::URICredentialsFilter do let(:credentials) { "oauth_token:x@" } it "returns the uri without the oauth token" do - expect(subject.credential_filtered_uri(uri).to_s).to eq(URI("https://[email protected]/company/private-repo").to_s) + expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://[email protected]/company/private-repo").to_s) end it_behaves_like "original type of uri is maintained" @@ -37,7 +37,7 @@ RSpec.describe Bundler::URICredentialsFilter do let(:credentials) { "username1:hunter3@" } it "returns the uri without the password" do - expect(subject.credential_filtered_uri(uri).to_s).to eq(URI("https://[email protected]/company/private-repo").to_s) + expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://[email protected]/company/private-repo").to_s) end it_behaves_like "original type of uri is maintained" @@ -55,7 +55,7 @@ RSpec.describe Bundler::URICredentialsFilter do end context "uri is a uri object" do - let(:uri) { URI("https://#{credentials}github.com/company/private-repo") } + let(:uri) { Bundler::URI("https://#{credentials}github.com/company/private-repo") } it_behaves_like "sensitive credentials in uri are filtered out" end @@ -90,7 +90,7 @@ RSpec.describe Bundler::URICredentialsFilter do describe "#credential_filtered_string" do let(:str_to_filter) { "This is a git message containing a uri #{uri}!" } let(:credentials) { "" } - let(:uri) { URI("https://#{credentials}github.com/company/private-repo") } + let(:uri) { Bundler::URI("https://#{credentials}github.com/company/private-repo") } context "with a uri that contains credentials" do let(:credentials) { "oauth_token:x-oauth-basic@" } diff --git a/spec/bundler/bundler/vendored_persistent_spec.rb b/spec/bundler/bundler/vendored_persistent_spec.rb index b4d68c2ea0..3ed899dbcf 100644 --- a/spec/bundler/bundler/vendored_persistent_spec.rb +++ b/spec/bundler/bundler/vendored_persistent_spec.rb @@ -23,14 +23,14 @@ RSpec.describe Bundler::PersistentHTTP do shared_examples_for "does not warn" do it "does not warn" do allow(Bundler.ui).to receive(:warn).never - subject.warn_old_tls_version_rubygems_connection(URI(uri), connection) + subject.warn_old_tls_version_rubygems_connection(Bundler::URI(uri), connection) end end shared_examples_for "does warn" do |*expected| it "warns" do expect(Bundler.ui).to receive(:warn).with(*expected) - subject.warn_old_tls_version_rubygems_connection(URI(uri), connection) + subject.warn_old_tls_version_rubygems_connection(Bundler::URI(uri), connection) end end diff --git a/spec/bundler/commands/binstubs_spec.rb b/spec/bundler/commands/binstubs_spec.rb index df10bd3498..7c04e8ddbd 100644 --- a/spec/bundler/commands/binstubs_spec.rb +++ b/spec/bundler/commands/binstubs_spec.rb @@ -458,7 +458,7 @@ RSpec.describe "bundle binstubs <gem>" do G bundle "config set auto_install 1" - bundle "binstubs rack", :env => { "BUNDLE_INSTALL" => 1 } + bundle "binstubs rack", :env => { "BUNDLE_INSTALL" => "1" } expect(out).not_to include("Installing rack 1.0.0") end end diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb index 7f9f84c104..5cc97de912 100644 --- a/spec/bundler/commands/clean_spec.rb +++ b/spec/bundler/commands/clean_spec.rb @@ -782,7 +782,7 @@ RSpec.describe "bundle clean" do expect(vendored_gems("bundler/gems/very_simple_git_binary-1.0-#{revision[0..11]}")).to exist bundle! :clean - expect(out).to eq("") + expect(out).to be_empty expect(vendored_gems("bundler/gems/extensions")).to exist expect(vendored_gems("bundler/gems/very_simple_git_binary-1.0-#{revision[0..11]}")).to exist diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb index 7ae504d360..a5d67c6d68 100644 --- a/spec/bundler/commands/exec_spec.rb +++ b/spec/bundler/commands/exec_spec.rb @@ -55,6 +55,12 @@ RSpec.describe "bundle exec" do expect(out).to eq("hi") end + it "works when exec'ing to rubygems" do + install_gemfile 'gem "rack"' + bundle "exec gem --version" + expect(out).to eq(Gem::VERSION) + end + it "respects custom process title when loading through ruby" do script_that_changes_its_own_title_and_checks_if_picked_up_by_ps_unix_utility = <<~'RUBY' Process.setproctitle("1-2-3-4-5-6-7-8-9-10-11-12-13-14-15") @@ -98,7 +104,7 @@ RSpec.describe "bundle exec" do install_gemfile "" sys_exec "#{Gem.ruby} #{command.path}" - expect(out).to eq("") + expect(out).to be_empty expect(err).to be_empty end diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 8e161a4aae..b57d81b10a 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -45,7 +45,7 @@ RSpec.describe "bundle install with gem sources" do gem "rack" G - bundle! :install, :env => { "BUNDLE_PATH__SYSTEM" => true } # can't use install_gemfile since it sets retry + bundle! :install, :env => { "BUNDLE_PATH__SYSTEM" => "true" } # can't use install_gemfile since it sets retry expect(bundled_app(".bundle")).not_to exist end diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb index ab54925756..6e82d34b05 100644 --- a/spec/bundler/commands/outdated_spec.rb +++ b/spec/bundler/commands/outdated_spec.rb @@ -228,7 +228,7 @@ RSpec.describe "bundle outdated" do context "and no gems are outdated" do it "has empty output" do subject - expect(out).to eq("") + expect(out).to be_empty end end end diff --git a/spec/bundler/commands/version_spec.rb b/spec/bundler/commands/version_spec.rb index f85ac82a40..8eecd9c53e 100644 --- a/spec/bundler/commands/version_spec.rb +++ b/spec/bundler/commands/version_spec.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -require_relative '../support/path' +require_relative "../support/path" RSpec.describe "bundle version" do if Spec::Path.ruby_core? - COMMIT_HASH = /unknown|[a-fA-F0-9]{7,}/ + COMMIT_HASH = /unknown|[a-fA-F0-9]{7,}/.freeze else - COMMIT_HASH = /[a-fA-F0-9]{7,}/ + COMMIT_HASH = /[a-fA-F0-9]{7,}/.freeze end context "with -v" do diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb index d607f8bb46..89da3fc801 100644 --- a/spec/bundler/install/deploy_spec.rb +++ b/spec/bundler/install/deploy_spec.rb @@ -146,7 +146,7 @@ RSpec.describe "install with --deployment or --frozen" do expect(the_bundle).to include_gems "path_gem 1.0" FileUtils.rm_r lib_path("path_gem-1.0") - bundle! :install, forgotten_command_line_options(:path => ".bundle", :without => "development", :deployment => true).merge(:env => { :DEBUG => "1" }) + bundle! :install, forgotten_command_line_options(:path => ".bundle", :without => "development", :deployment => true).merge(:env => { "DEBUG" => "1" }) run! "puts :WIN" expect(out).to eq("WIN") end diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb index 786b767354..e53636da09 100644 --- a/spec/bundler/install/gemfile/path_spec.rb +++ b/spec/bundler/install/gemfile/path_spec.rb @@ -439,7 +439,7 @@ RSpec.describe "bundle install with explicit source paths" do gem 'net-ssh', '1.0' G - bundle :check, :env => { "DEBUG" => 1 } + bundle :check, :env => { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0" end @@ -459,7 +459,7 @@ RSpec.describe "bundle install with explicit source paths" do gem 'net-ssh', :path => "#{lib_path("omg")}" G - bundle :check, :env => { "DEBUG" => 1 } + bundle :check, :env => { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0" end @@ -654,7 +654,7 @@ RSpec.describe "bundle install with explicit source paths" do File.open(lib_path("private_lib/Gemfile"), "w") {|f| f.puts gemfile } Dir.chdir(lib_path("private_lib")) do - bundle :install, :env => { "DEBUG" => 1 }, :artifice => "endpoint" + bundle :install, :env => { "DEBUG" => "1" }, :artifice => "endpoint" expect(out).to match(%r{^HTTP GET http://localgemserver\.test/api/v1/dependencies\?gems=rack$}) expect(out).not_to match(/^HTTP GET.*private_lib/) expect(the_bundle).to include_gems "private_lib 2.2" diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb index 2c145ce643..a294b83d1c 100644 --- a/spec/bundler/install/gems/compact_index_spec.rb +++ b/spec/bundler/install/gems/compact_index_spec.rb @@ -51,7 +51,7 @@ RSpec.describe "compact index api" do build_gem "Rack", "0.1" end - install_gemfile! <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4 } + install_gemfile! <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" gem "rack", "1.0" gem "Rack", "0.1" diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index 26ff40f7aa..52511ff67f 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -22,7 +22,7 @@ RSpec.describe "bundle install with install-time dependencies" do build_repo2 path = "#{gem_repo2}/#{Gem::MARSHAL_SPEC_DIR}/actionpack-2.3.2.gemspec.rz" - spec = Marshal.load(Bundler.rubygems.inflate(File.read(path))) + spec = Marshal.load(Bundler.rubygems.inflate(File.binread(path))) spec.dependencies.each do |d| d.instance_variable_set(:@type, :fail) end @@ -108,7 +108,7 @@ RSpec.describe "bundle install with install-time dependencies" do end end - install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2 } + install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } ruby "#{RUBY_VERSION}" source "http://localgemserver.test/" gem 'rack' @@ -127,7 +127,7 @@ RSpec.describe "bundle install with install-time dependencies" do build_gem "foo1", "1.0" end - install_gemfile <<-G, :artifice => "compact_index_rate_limited", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4 } + install_gemfile <<-G, :artifice => "compact_index_rate_limited", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } ruby "#{RUBY_VERSION}" source "http://localgemserver.test/" gem 'rack' @@ -153,7 +153,7 @@ RSpec.describe "bundle install with install-time dependencies" do shared_examples_for "ruby version conflicts" do it "raises an error during resolution" do - install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2 } + install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } source "http://localgemserver.test/" ruby #{ruby_requirement} gem 'require_ruby' diff --git a/spec/bundler/install/gems/sudo_spec.rb b/spec/bundler/install/gems/sudo_spec.rb index fcafe4a907..170ffaca03 100644 --- a/spec/bundler/install/gems/sudo_spec.rb +++ b/spec/bundler/install/gems/sudo_spec.rb @@ -172,7 +172,7 @@ RSpec.describe "when using sudo", :sudo => true do context "when ENV['BUNDLE_SILENCE_ROOT_WARNING'] is set" do it "skips the warning" do - bundle :install, :sudo => :preserve_env, :env => { "BUNDLE_SILENCE_ROOT_WARNING" => true } + bundle :install, :sudo => :preserve_env, :env => { "BUNDLE_SILENCE_ROOT_WARNING" => "true" } expect(err).to_not include(warning) end end diff --git a/spec/bundler/install/git_spec.rb b/spec/bundler/install/git_spec.rb index c16285241f..cc8bf70b03 100644 --- a/spec/bundler/install/git_spec.rb +++ b/spec/bundler/install/git_spec.rb @@ -61,5 +61,25 @@ RSpec.describe "bundle install" do expect(out).to include("Bundle complete!") end + + it "allows multiple gems from the same git source" do + build_repo2 do + build_lib "foo", "1.0", :path => lib_path("gems/foo") + build_lib "zebra", "2.0", :path => lib_path("gems/zebra") + build_git "gems", :path => lib_path("gems"), :gemspec => false + end + + install_gemfile <<-G + source "#{file_uri_for(gem_repo2)}" + gem "foo", :git => "#{lib_path("gems")}", :glob => "foo/*.gemspec" + gem "zebra", :git => "#{lib_path("gems")}", :glob => "zebra/*.gemspec" + G + + bundle "info foo" + expect(out).to include("* foo (1.0 #{revision_for(lib_path("gems"))[0..6]})") + + bundle "info zebra" + expect(out).to include("* zebra (2.0 #{revision_for(lib_path("gems"))[0..6]})") + end end end diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb index f743bccb92..df2fdd263a 100644 --- a/spec/bundler/other/major_deprecation_spec.rb +++ b/spec/bundler/other/major_deprecation_spec.rb @@ -127,7 +127,7 @@ RSpec.describe "major deprecations" do bundle! "config" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config list` instead.") end @@ -139,7 +139,7 @@ RSpec.describe "major deprecations" do bundle! "config waka" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config get waka` instead.") end @@ -151,7 +151,7 @@ RSpec.describe "major deprecations" do bundle! "config waka wakapun" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set waka wakapun` instead.") end @@ -163,7 +163,7 @@ RSpec.describe "major deprecations" do bundle! "config --local waka wakapun" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set --local waka wakapun` instead.") end @@ -175,7 +175,7 @@ RSpec.describe "major deprecations" do bundle! "config --global waka wakapun" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set --global waka wakapun` instead.") end @@ -187,7 +187,7 @@ RSpec.describe "major deprecations" do bundle! "config --delete waka" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset waka` instead.") end @@ -199,7 +199,7 @@ RSpec.describe "major deprecations" do bundle! "config --delete --local waka" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset --local waka` instead.") end @@ -211,7 +211,7 @@ RSpec.describe "major deprecations" do bundle! "config --delete --global waka" end - it "warns", :bundler => "2" do + it "warns", :bundler => "3" do expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset --global waka` instead.") end @@ -227,7 +227,7 @@ RSpec.describe "major deprecations" do G end - it "warns when no options are given", :bundler => "2" do + it "warns when no options are given", :bundler => "3" do bundle! "update" expect(deprecations).to include("Pass --all to `bundle update` to update everything") end diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index 53d9f9a026..a91e6a359e 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -8,7 +8,7 @@ RSpec.describe "real world edgecases", :realworld => true, :sometimes => true do require "#{lib_dir}/bundler/source/rubygems/remote" require "#{lib_dir}/bundler/fetcher" rubygem = Bundler.ui.silence do - source = Bundler::Source::Rubygems::Remote.new(URI("https://rubygems.org")) + source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org")) fetcher = Bundler::Fetcher.new(source) index = fetcher.specs([#{name.dump}], nil) index.search(Gem::Dependency.new(#{name.dump}, #{requirement.dump})).last diff --git a/spec/bundler/rubygems/rubygems.rb b/spec/bundler/rubygems/rubygems.rb deleted file mode 100644 index 6fa63013bf..0000000000 --- a/spec/bundler/rubygems/rubygems.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -require_relative "../support/rubygems_version_manager" - -RubygemsVersionManager.new(ENV["RGV"]).switch - -$:.delete("#{Spec::Path.spec_dir}/rubygems") - -require "rubygems" diff --git a/spec/bundler/runtime/gem_tasks_spec.rb b/spec/bundler/runtime/gem_tasks_spec.rb index 4760b6a749..4b92de76bb 100644 --- a/spec/bundler/runtime/gem_tasks_spec.rb +++ b/spec/bundler/runtime/gem_tasks_spec.rb @@ -6,15 +6,25 @@ RSpec.describe "require 'bundler/gem_tasks'" do f.write <<-GEMSPEC Gem::Specification.new do |s| s.name = "foo" + s.version = "1.0" + s.summary = "dummy" + s.author = "Perry Mason" end GEMSPEC end + bundled_app("Rakefile").open("w") do |f| f.write <<-RAKEFILE $:.unshift("#{lib_dir}") require "bundler/gem_tasks" RAKEFILE end + + install_gemfile! <<-G + source "#{file_uri_for(gem_repo1)}" + + gem "rake" + G end it "includes the relevant tasks" do @@ -22,7 +32,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do sys_exec "#{rake} -T", "RUBYOPT" => "-I#{lib_dir}" end - expect(err).to eq("") + expect(err).to be_empty expected_tasks = [ "rake build", "rake clean", @@ -35,6 +45,18 @@ RSpec.describe "require 'bundler/gem_tasks'" do expect(exitstatus).to eq(0) if exitstatus end + it "defines a working `rake install` task" do + with_gem_path_as(Spec::Path.base_system_gems.to_s) do + sys_exec "#{rake} install", "RUBYOPT" => "-I#{lib_dir}" + end + + expect(err).to be_empty + + bundle! "exec rake install" + + expect(err).to be_empty + end + it "adds 'pkg' to rake/clean's CLOBBER" do with_gem_path_as(Spec::Path.base_system_gems.to_s) do sys_exec! %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect') diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb index 06be2ef83d..94d8b086a2 100644 --- a/spec/bundler/runtime/inline_spec.rb +++ b/spec/bundler/runtime/inline_spec.rb @@ -5,7 +5,7 @@ RSpec.describe "bundler/inline#gemfile" do requires = ["#{lib_dir}/bundler/inline"] requires.unshift "#{spec_dir}/support/artifice/" + options.delete(:artifice) if options.key?(:artifice) requires = requires.map {|r| "require '#{r}'" }.join("\n") - @out = ruby("#{requires}\n\n" + code, options) + ruby("#{requires}\n\n" + code, options) end before :each do @@ -88,9 +88,8 @@ RSpec.describe "bundler/inline#gemfile" do RUBY expect(out).to include("Installing activesupport") - err.gsub! %r{(.*lib/sinatra/base\.rb:\d+: warning: constant ::Fixnum is deprecated$)}, "" err_lines = err.split("\n") - err_lines.reject!{|line| line =~ /\.rb:\d+: warning: / } + err_lines.reject!{|line| line =~ /\.rb:\d+: warning: / } unless RUBY_VERSION < "2.7" expect(err_lines).to be_empty expect(exitstatus).to be_zero if exitstatus end @@ -317,4 +316,21 @@ RSpec.describe "bundler/inline#gemfile" do expect(err).to be_empty end + + it "preserves previous BUNDLE_GEMFILE value" do + ENV["BUNDLE_GEMFILE"] = "" + script <<-RUBY + gemfile do + source "#{file_uri_for(gem_repo1)}" + gem "rack" + end + + puts "BUNDLE_GEMFILE is empty" if ENV["BUNDLE_GEMFILE"].empty? + system("#{Gem.ruby} -w -e '42'") # this should see original value of BUNDLE_GEMFILE + exit $?.exitstatus + RUBY + + expect(last_command).to be_success + expect(out).to include("BUNDLE_GEMFILE is empty") + end end diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index 4a754945b7..53300af618 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -130,7 +130,7 @@ RSpec.describe "Bundler.setup" do load_path = out.split("\n") rack_load_order = load_path.index {|path| path.include?("rack") } - expect(err).to eq("") + expect(err).to be_empty expect(load_path).to include(a_string_ending_with("dash_i_dir"), "rubylib_dir") expect(rack_load_order).to be > 0 end @@ -845,6 +845,12 @@ end end describe "when a vendored gem specification uses the :path option" do + let(:filesystem_root) do + current = Pathname.new(Dir.pwd) + current = current.parent until current == current.parent + current + end + it "should resolve paths relative to the Gemfile" do path = bundled_app(File.join("vendor", "foo")) build_lib "foo", :path => path @@ -858,7 +864,7 @@ end G Dir.chdir(bundled_app.parent) do - run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app("Gemfile") } + run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app("Gemfile").to_s } require 'foo' R end @@ -866,7 +872,7 @@ end end it "should make sure the Bundler.root is really included in the path relative to the Gemfile" do - relative_path = File.join("vendor", Dir.pwd[1..-1], "foo") + relative_path = File.join("vendor", Dir.pwd.gsub(/^#{filesystem_root}/, "")) absolute_path = bundled_app(relative_path) FileUtils.mkdir_p(absolute_path) build_lib "foo", :path => absolute_path @@ -882,7 +888,7 @@ end bundle :install Dir.chdir(bundled_app.parent) do - run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app("Gemfile") } + run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app("Gemfile").to_s } require 'foo' R end @@ -1027,6 +1033,8 @@ end ruby <<-RUBY require '#{lib_dir}/bundler' + bundler_module = class << Bundler; self; end + bundler_module.send(:remove_method, :require) def Bundler.require(path) raise "LOSE" end @@ -1034,7 +1042,7 @@ end RUBY expect(err).to be_empty - expect(out).to eq("") + expect(out).to be_empty end end @@ -1090,8 +1098,8 @@ end it "does not change the lock or warn" do lockfile lock_with(Bundler::VERSION.succ) ruby "require '#{lib_dir}/bundler/setup'" - expect(out).to eq("") - expect(err).to eq("") + expect(out).to be_empty + expect(err).to be_empty lockfile_should_be lock_with(Bundler::VERSION.succ) end end @@ -1154,8 +1162,8 @@ end let(:ruby_version) { "5.5.5" } it "does not change the lock or warn" do expect { ruby! "require '#{lib_dir}/bundler/setup'" }.not_to change { lockfile } - expect(out).to eq("") - expect(err).to eq("") + expect(out).to be_empty + expect(err).to be_empty end end @@ -1195,7 +1203,7 @@ end describe "default gem activation" do let(:exemptions) do if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("2.7") - [] + %w[delegate did_you_mean] else %w[io-console openssl] end << "bundler" @@ -1204,17 +1212,15 @@ end let(:activation_warning_hack) { strip_whitespace(<<-RUBY) } require #{spec_dir.join("support/hax").to_s.dump} - if Gem::Specification.instance_methods.map(&:to_sym).include?(:activate) - Gem::Specification.send(:alias_method, :bundler_spec_activate, :activate) - Gem::Specification.send(:define_method, :activate) do - unless #{exemptions.inspect}.include?(name) - warn '-' * 80 - warn "activating \#{full_name}" - warn *caller - warn '*' * 80 - end - bundler_spec_activate + Gem::Specification.send(:alias_method, :bundler_spec_activate, :activate) + Gem::Specification.send(:define_method, :activate) do + unless #{exemptions.inspect}.include?(name) + warn '-' * 80 + warn "activating \#{full_name}" + warn(*caller) + warn '*' * 80 end + bundler_spec_activate end RUBY @@ -1238,14 +1244,14 @@ end it "activates no gems with -rbundler/setup" do install_gemfile! "" - ruby! code, :env => { :RUBYOPT => activation_warning_hack_rubyopt + " -r#{lib_dir}/bundler/setup" } + ruby! code, :env => { "RUBYOPT" => activation_warning_hack_rubyopt + " -r#{lib_dir}/bundler/setup" } expect(out).to eq("{}") end it "activates no gems with bundle exec" do install_gemfile! "" create_file("script.rb", code) - bundle! "exec ruby ./script.rb", :env => { :RUBYOPT => activation_warning_hack_rubyopt } + bundle! "exec ruby ./script.rb", :env => { "RUBYOPT" => activation_warning_hack_rubyopt } expect(out).to eq("{}") end @@ -1253,54 +1259,40 @@ end install_gemfile! "" create_file("script.rb", "#!/usr/bin/env ruby\n\n#{code}") FileUtils.chmod(0o777, bundled_app("script.rb")) - bundle! "exec ./script.rb", :artifice => nil, :env => { :RUBYOPT => activation_warning_hack_rubyopt } + bundle! "exec ./script.rb", :artifice => nil, :env => { "RUBYOPT" => activation_warning_hack_rubyopt } expect(out).to eq("{}") end - let(:default_gems) do - ruby!(<<-RUBY).split("\n") - if Gem::Specification.is_a?(Enumerable) - puts Gem::Specification.select(&:default_gem?).map(&:name) - end - RUBY - end + Gem::Specification.select(&:default_gem?).map(&:name).each do |g| + it "activates newer versions of #{g}" do + skip if exemptions.include?(g) - it "activates newer versions of default gems" do - build_repo4 do - default_gems.each do |g| + build_repo4 do build_gem g, "999999" end - end - default_gems.reject! {|g| exemptions.include?(g) } + install_gemfile! <<-G + source "#{file_uri_for(gem_repo4)}" + gem "#{g}", "999999" + G - install_gemfile! <<-G - source "#{file_uri_for(gem_repo4)}" - #{default_gems}.each do |g| - gem g, "999999" - end - G + expect(the_bundle).to include_gem("#{g} 999999", :env => { "RUBYOPT" => activation_warning_hack_rubyopt }) + end - expect(the_bundle).to include_gems(*default_gems.map {|g| "#{g} 999999" }) - end + it "activates older versions of #{g}" do + skip if exemptions.include?(g) - it "activates older versions of default gems" do - build_repo4 do - default_gems.each do |g| + build_repo4 do build_gem g, "0.0.0.a" end - end - default_gems.reject! {|g| exemptions.include?(g) } + install_gemfile! <<-G + source "#{file_uri_for(gem_repo4)}" + gem "#{g}", "0.0.0.a" + G - install_gemfile! <<-G - source "#{file_uri_for(gem_repo4)}" - #{default_gems}.each do |g| - gem g, "0.0.0.a" - end - G - - expect(the_bundle).to include_gems(*default_gems.map {|g| "#{g} 0.0.0.a" }) + expect(the_bundle).to include_gem("#{g} 0.0.0.a", :env => { "RUBYOPT" => activation_warning_hack_rubyopt }) + end end end end diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb index 9702ab71f5..0a49b46aaa 100644 --- a/spec/bundler/spec_helper.rb +++ b/spec/bundler/spec_helper.rb @@ -7,7 +7,7 @@ $:.unshift Spec::Path.lib_dir.to_s require "bundler/psyched_yaml" require "bundler/vendored_fileutils" -require "uri" +require "bundler/vendored_uri" require "digest" if File.expand_path(__FILE__) =~ %r{([^\w/\.:\-])} @@ -82,7 +82,7 @@ RSpec.configure do |config| config.before :suite do require_relative "support/rubygems_ext" Spec::Rubygems.setup - ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -I#{Spec::Path.spec_dir}/rubygems -r#{Spec::Path.spec_dir}/support/hax.rb" + ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -r#{Spec::Path.spec_dir}/support/hax.rb" ENV["BUNDLE_SPEC_RUN"] = "true" ENV["BUNDLE_USER_CONFIG"] = ENV["BUNDLE_USER_CACHE"] = ENV["BUNDLE_USER_PLUGIN"] = nil ENV["GEMRC"] = nil diff --git a/spec/bundler/support/artifice/compact_index.rb b/spec/bundler/support/artifice/compact_index.rb index 89362c4dbc..72abf26224 100644 --- a/spec/bundler/support/artifice/compact_index.rb +++ b/spec/bundler/support/artifice/compact_index.rb @@ -10,7 +10,7 @@ class CompactIndexAPI < Endpoint def load_spec(name, version, platform, gem_repo) full_name = "#{name}-#{version}" full_name += "-#{platform}" if platform != "ruby" - Marshal.load(Bundler.rubygems.inflate(File.open(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read)) + Marshal.load(Bundler.rubygems.inflate(File.binread(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")))) end def etag_response diff --git a/spec/bundler/support/artifice/compact_index_api_missing.rb b/spec/bundler/support/artifice/compact_index_api_missing.rb index fdd342bc08..6514fde01e 100644 --- a/spec/bundler/support/artifice/compact_index_api_missing.rb +++ b/spec/bundler/support/artifice/compact_index_api_missing.rb @@ -10,7 +10,7 @@ class CompactIndexApiMissing < CompactIndexAPI if params[:id] == "rack-1.0.gemspec.rz" halt 404 else - File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") + File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") end end end diff --git a/spec/bundler/support/artifice/compact_index_extra_api_missing.rb b/spec/bundler/support/artifice/compact_index_extra_api_missing.rb index 6bd24ddbb4..b9d757c266 100644 --- a/spec/bundler/support/artifice/compact_index_extra_api_missing.rb +++ b/spec/bundler/support/artifice/compact_index_extra_api_missing.rb @@ -9,7 +9,7 @@ class CompactIndexExtraAPIMissing < CompactIndexExtraApi if params[:id] == "missing-1.0.gemspec.rz" halt 404 else - File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") + File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") end end end diff --git a/spec/bundler/support/artifice/compact_index_extra_missing.rb b/spec/bundler/support/artifice/compact_index_extra_missing.rb index 4758b785ac..ff1e47a1bb 100644 --- a/spec/bundler/support/artifice/compact_index_extra_missing.rb +++ b/spec/bundler/support/artifice/compact_index_extra_missing.rb @@ -9,7 +9,7 @@ class CompactIndexExtraMissing < CompactIndexExtra if params[:id] == "missing-1.0.gemspec.rz" halt 404 else - File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") + File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") end end end diff --git a/spec/bundler/support/artifice/endpoint.rb b/spec/bundler/support/artifice/endpoint.rb index bf26c56503..7bca681e70 100644 --- a/spec/bundler/support/artifice/endpoint.rb +++ b/spec/bundler/support/artifice/endpoint.rb @@ -68,7 +68,7 @@ class Endpoint < Sinatra::Base def load_spec(name, version, platform, gem_repo) full_name = "#{name}-#{version}" full_name += "-#{platform}" if platform != "ruby" - Marshal.load(Bundler.rubygems.inflate(File.open(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read)) + Marshal.load(Bundler.rubygems.inflate(File.binread(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")))) end end diff --git a/spec/bundler/support/artifice/endpoint_api_missing.rb b/spec/bundler/support/artifice/endpoint_api_missing.rb index 8dafde7362..755c42e836 100644 --- a/spec/bundler/support/artifice/endpoint_api_missing.rb +++ b/spec/bundler/support/artifice/endpoint_api_missing.rb @@ -10,7 +10,7 @@ class EndpointApiMissing < Endpoint if params[:id] == "rack-1.0.gemspec.rz" halt 404 else - File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") + File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") end end end diff --git a/spec/bundler/support/artifice/endpoint_extra_missing.rb b/spec/bundler/support/artifice/endpoint_extra_missing.rb index ee129025ff..5fd9238207 100644 --- a/spec/bundler/support/artifice/endpoint_extra_missing.rb +++ b/spec/bundler/support/artifice/endpoint_extra_missing.rb @@ -9,7 +9,7 @@ class EndpointExtraMissing < EndpointExtra if params[:id] == "missing-1.0.gemspec.rz" halt 404 else - File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") + File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") end end end diff --git a/spec/bundler/support/artifice/windows.rb b/spec/bundler/support/artifice/windows.rb index ce7455b86c..21170c81d9 100644 --- a/spec/bundler/support/artifice/windows.rb +++ b/spec/bundler/support/artifice/windows.rb @@ -27,7 +27,7 @@ class Windows < Sinatra::Base files.each do |file| get "/#{file}" do - File.read gem_repo.join(file) + File.binread gem_repo.join(file) end end diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb index 911f734d8b..7d1bd65185 100644 --- a/spec/bundler/support/helpers.rb +++ b/spec/bundler/support/helpers.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "open3" - require_relative "command_execution" require_relative "the_bundle" @@ -25,9 +23,7 @@ module Spec define_method("#{method}!") do |*args, &blk| send(method, *args, &blk).tap do unless last_command.success? - raise RuntimeError, - "Invoking #{method}!(#{args.map(&:inspect).join(", ")}) failed:\n#{last_command.stdboth}", - caller.drop_while {|bt| bt.start_with?(__FILE__) } + raise "Invoking #{method}!(#{args.map(&:inspect).join(", ")}) failed:\n#{last_command.stdboth}" end end end @@ -174,7 +170,7 @@ module Spec env = options.delete(:env) || {} ruby = ruby.gsub(/["`\$]/) {|m| "\\#{m}" } lib_option = options[:no_lib] ? "" : " -I#{lib_dir}" - sys_exec(%(#{Gem.ruby}#{lib_option} -e "#{ruby}"), env) + sys_exec(%(#{Gem.ruby}#{lib_option} -w -e "#{ruby}"), env) end bang :ruby @@ -209,8 +205,7 @@ module Spec def sys_exec(cmd, env = {}) command_execution = CommandExecution.new(cmd.to_s, Dir.pwd) - env = env.map {|k, v| [k.to_s, v.to_s] }.to_h # convert env keys and values to string - + require "open3" Open3.popen3(env, cmd.to_s) do |stdin, stdout, stderr, wait_thr| yield stdin, stdout, wait_thr if block_given? stdin.close diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb index 6f78490fe8..eea3161b15 100644 --- a/spec/bundler/support/path.rb +++ b/spec/bundler/support/path.rb @@ -22,7 +22,7 @@ module Spec end def gem_bin - @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "#{Gem.ruby} -I#{spec_dir}/rubygems -S gem --backtrace" + @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "#{Gem.ruby} -S gem --backtrace" end def spec_dir @@ -30,23 +30,20 @@ module Spec end def tracked_files - if root != `git rev-parse --show-toplevel` - skip 'not in git working directory' - end + skip "not in git working directory" unless git_root_dir? + @tracked_files ||= ruby_core? ? `git ls-files -z -- lib/bundler lib/bundler.rb spec/bundler man/bundler*` : `git ls-files -z` end def shipped_files - if root != `git rev-parse --show-toplevel` - skip 'not in git working directory' - end + skip "not in git working directory" unless git_root_dir? + @shipped_files ||= ruby_core? ? `git ls-files -z -- lib/bundler lib/bundler.rb man/bundler* libexec/bundle*` : `git ls-files -z -- lib man exe CHANGELOG.md LICENSE.md README.md bundler.gemspec` end def lib_tracked_files - if root != `git rev-parse --show-toplevel` - skip 'not in git working directory' - end + skip "not in git working directory" unless git_root_dir? + @lib_tracked_files ||= ruby_core? ? `git ls-files -z -- lib/bundler lib/bundler.rb` : `git ls-files -z -- lib` end @@ -103,8 +100,6 @@ module Spec protocol = "file://" root = Gem.win_platform? ? "/" : "" - return protocol + "localhost" + root + path.to_s if RUBY_VERSION < "2.5" - protocol + root + path.to_s end @@ -182,5 +177,11 @@ module Spec end extend self + + private + + def git_root_dir? + root.to_s == `git rev-parse --show-toplevel`.chomp + end end end diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb index d237897b67..7e9e8328c5 100644 --- a/spec/bundler/support/rubygems_ext.rb +++ b/spec/bundler/support/rubygems_ext.rb @@ -5,13 +5,13 @@ require_relative "path" module Spec module Rubygems DEV_DEPS = { - "automatiek" => "~> 0.2.0", + "automatiek" => "~> 0.3.0", "parallel_tests" => "~> 2.29", "rake" => "~> 12.0", "ronn" => "~> 0.7.3", "rspec" => "~> 3.8", - "rubocop" => "= 0.74.0", - "rubocop-performance" => "= 1.4.0", + "rubocop" => "= 0.77.0", + "rubocop-performance" => "= 1.5.1", }.freeze DEPS = { @@ -39,7 +39,9 @@ module Spec end def gem_load(gem_name, bin_container) - require_relative "../rubygems/rubygems" + require_relative "rubygems_version_manager" + RubygemsVersionManager.new(ENV["RGV"]).switch + gem_load_and_activate(gem_name, bin_container) end @@ -65,7 +67,7 @@ module Spec FileUtils.mkdir_p(Path.base_system_gems) puts "installing gems for the tests to use..." install_gems(DEPS) - manifest_path.open("w") {|f| f << manifest.join } + manifest_path.open("wb") {|f| f << manifest.join } end FileUtils.mkdir_p(Path.home) diff --git a/spec/bundler/support/rubygems_version_manager.rb b/spec/bundler/support/rubygems_version_manager.rb index 356d391c08..854bce890d 100644 --- a/spec/bundler/support/rubygems_version_manager.rb +++ b/spec/bundler/support/rubygems_version_manager.rb @@ -8,27 +8,25 @@ class RubygemsVersionManager include Spec::Helpers include Spec::Path - def initialize(env_version) - @env_version = env_version + def initialize(source) + @source = source end def switch return if use_system? - unrequire_rubygems_if_needed - switch_local_copy_if_needed - prepare_environment + reexec_if_needed end private def use_system? - @env_version.nil? + @source.nil? end - def unrequire_rubygems_if_needed + def reexec_if_needed return unless rubygems_unrequire_needed? require "rbconfig" @@ -37,7 +35,8 @@ private ruby << RbConfig::CONFIG["EXEEXT"] cmd = [ruby, $0, *ARGV].compact - cmd[1, 0] = "--disable-gems" + + ENV["RUBYOPT"] = "-I#{local_copy_path.join("lib")} #{ENV["RUBYOPT"]}" exec(ENV, *cmd) end @@ -47,35 +46,28 @@ private Dir.chdir(local_copy_path) do sys_exec!("git remote update") - sys_exec!("git checkout #{target_tag_version} --quiet") + sys_exec!("git checkout #{target_tag} --quiet") end - end - def prepare_environment - $:.unshift File.expand_path("lib", local_copy_path) + ENV["RGV"] = local_copy_path.to_s end def rubygems_unrequire_needed? - defined?(Gem::VERSION) && Gem::VERSION != target_gem_version + !$LOADED_FEATURES.include?(local_copy_path.join("lib/rubygems.rb").to_s) end def local_copy_switch_needed? - !env_version_is_path? && target_gem_version != local_copy_version - end - - def target_gem_version - @target_gem_version ||= resolve_target_gem_version + !source_is_path? && target_tag != local_copy_tag end - def target_tag_version - @target_tag_version ||= resolve_target_tag_version + def target_tag + @target_tag ||= resolve_target_tag end - def local_copy_version - gemspec_contents = File.read(local_copy_path.join("lib/rubygems.rb")) - version_regexp = /VERSION = ["'](.*)["']/ - - version_regexp.match(gemspec_contents)[1] + def local_copy_tag + Dir.chdir(local_copy_path) do + sys_exec!("git rev-parse --abbrev-ref HEAD") + end end def local_copy_path @@ -83,7 +75,7 @@ private end def resolve_local_copy_path - return expanded_env_version if env_version_is_path? + return expanded_source if source_is_path? rubygems_path = root.join("tmp/rubygems") @@ -95,33 +87,17 @@ private rubygems_path end - def env_version_is_path? - expanded_env_version.directory? + def source_is_path? + expanded_source.directory? end - def expanded_env_version - @expanded_env_version ||= Pathname.new(@env_version).expand_path(root) + def expanded_source + @expanded_source ||= Pathname.new(@source).expand_path(root) end - def resolve_target_tag_version - return "v#{@env_version}" if @env_version.match(/^\d/) - - return "master" if @env_version == master_gem_version - - @env_version - end - - def resolve_target_gem_version - return local_copy_version if env_version_is_path? - - return @env_version[1..-1] if @env_version.match(/^v/) - - return master_gem_version if @env_version == "master" - - @env_version - end + def resolve_target_tag + return "v#{@source}" if @source.match(/^\d/) - def master_gem_version - "3.1.0.pre1" + @source end end |