bundler 1.2.5 → 1.3.0.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (124) hide show
  1. data/.gitignore +10 -7
  2. data/.travis.yml +12 -3
  3. data/CHANGELOG.md +26 -19
  4. data/CONTRIBUTE.md +97 -0
  5. data/README.md +4 -2
  6. data/Rakefile +17 -59
  7. data/bundler.gemspec +2 -1
  8. data/lib/bundler.rb +23 -20
  9. data/lib/bundler/cli.rb +68 -22
  10. data/lib/bundler/definition.rb +3 -2
  11. data/lib/bundler/deprecate.rb +15 -0
  12. data/lib/bundler/dsl.rb +14 -16
  13. data/lib/bundler/environment.rb +0 -5
  14. data/lib/bundler/fetcher.rb +23 -78
  15. data/lib/bundler/friendly_errors.rb +4 -5
  16. data/lib/bundler/gem_helper.rb +14 -16
  17. data/lib/bundler/injector.rb +64 -0
  18. data/lib/bundler/installer.rb +1 -7
  19. data/lib/bundler/lazy_specification.rb +6 -3
  20. data/lib/bundler/lockfile_parser.rb +25 -13
  21. data/lib/bundler/resolver.rb +0 -1
  22. data/lib/bundler/rubygems_integration.rb +83 -17
  23. data/lib/bundler/settings.rb +4 -2
  24. data/lib/bundler/similarity_detector.rb +63 -0
  25. data/lib/bundler/source.rb +3 -886
  26. data/lib/bundler/source/git.rb +267 -0
  27. data/lib/bundler/source/git/git_proxy.rb +142 -0
  28. data/lib/bundler/source/path.rb +209 -0
  29. data/lib/bundler/source/path/installer.rb +33 -0
  30. data/lib/bundler/source/rubygems.rb +261 -0
  31. data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -0
  32. data/lib/bundler/templates/newgem/rspec.tt +2 -0
  33. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
  34. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -0
  35. data/lib/bundler/templates/newgem/test/minitest_helper.rb.tt +4 -0
  36. data/lib/bundler/templates/newgem/test/test_newgem.rb.tt +11 -0
  37. data/lib/bundler/ui.rb +20 -5
  38. data/lib/bundler/vendor/.document +0 -0
  39. data/lib/bundler/vendor/thor.rb +74 -5
  40. data/lib/bundler/vendor/thor/actions.rb +5 -5
  41. data/lib/bundler/vendor/thor/actions/directory.rb +1 -0
  42. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +7 -1
  43. data/lib/bundler/vendor/thor/base.rb +44 -11
  44. data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +5 -0
  45. data/lib/bundler/vendor/thor/parser/argument.rb +14 -7
  46. data/lib/bundler/vendor/thor/parser/arguments.rb +7 -1
  47. data/lib/bundler/vendor/thor/parser/option.rb +8 -8
  48. data/lib/bundler/vendor/thor/parser/options.rb +62 -24
  49. data/lib/bundler/vendor/thor/runner.rb +1 -1
  50. data/lib/bundler/vendor/thor/shell/basic.rb +2 -2
  51. data/lib/bundler/vendor/thor/task.rb +2 -2
  52. data/lib/bundler/vendor/thor/version.rb +1 -1
  53. data/lib/bundler/vendored_persistent.rb +3 -15
  54. data/lib/bundler/version.rb +1 -1
  55. data/man/bundle-exec.ronn +1 -1
  56. data/man/bundle-update.ronn +1 -1
  57. data/man/bundle.ronn +4 -1
  58. data/spec/bundler/bundler_spec.rb +2 -28
  59. data/spec/bundler/cli_rspec.rb +9 -0
  60. data/spec/bundler/definition_spec.rb +1 -1
  61. data/spec/bundler/dsl_spec.rb +15 -8
  62. data/spec/bundler/gem_helper_spec.rb +38 -21
  63. data/spec/bundler/psyched_yaml_spec.rb +1 -0
  64. data/spec/bundler/source_spec.rb +3 -3
  65. data/spec/cache/gems_spec.rb +24 -24
  66. data/spec/cache/git_spec.rb +21 -23
  67. data/spec/cache/path_spec.rb +11 -11
  68. data/spec/cache/platform_spec.rb +6 -6
  69. data/spec/install/deploy_spec.rb +38 -38
  70. data/spec/install/gems/c_ext_spec.rb +2 -2
  71. data/spec/install/gems/dependency_api_spec.rb +23 -116
  72. data/spec/install/gems/env_spec.rb +1 -1
  73. data/spec/install/gems/flex_spec.rb +7 -8
  74. data/spec/install/gems/groups_spec.rb +10 -10
  75. data/spec/install/gems/packed_spec.rb +4 -4
  76. data/spec/install/gems/platform_spec.rb +3 -3
  77. data/spec/install/gems/post_install_spec.rb +9 -9
  78. data/spec/install/gems/resolving_spec.rb +2 -2
  79. data/spec/install/gems/simple_case_spec.rb +50 -53
  80. data/spec/install/gems/standalone_spec.rb +19 -19
  81. data/spec/install/gems/sudo_spec.rb +31 -16
  82. data/spec/install/gems/win32_spec.rb +1 -1
  83. data/spec/install/gemspec_spec.rb +6 -6
  84. data/spec/install/git_spec.rb +34 -34
  85. data/spec/install/invalid_spec.rb +3 -3
  86. data/spec/install/path_spec.rb +71 -8
  87. data/spec/install/upgrade_spec.rb +2 -2
  88. data/spec/integration/inject.rb +78 -0
  89. data/spec/lock/git_spec.rb +2 -2
  90. data/spec/lock/lockfile_spec.rb +14 -14
  91. data/spec/other/check_spec.rb +29 -29
  92. data/spec/other/clean_spec.rb +47 -48
  93. data/spec/other/config_spec.rb +20 -20
  94. data/spec/other/console_spec.rb +5 -5
  95. data/spec/other/exec_spec.rb +48 -28
  96. data/spec/other/ext_spec.rb +3 -3
  97. data/spec/other/help_spec.rb +6 -6
  98. data/spec/other/init_spec.rb +8 -8
  99. data/spec/other/newgem_spec.rb +95 -15
  100. data/spec/other/open_spec.rb +10 -5
  101. data/spec/other/outdated_spec.rb +8 -8
  102. data/spec/other/platform_spec.rb +45 -45
  103. data/spec/other/show_spec.rb +10 -10
  104. data/spec/quality_spec.rb +2 -2
  105. data/spec/realworld/dependency_api_spec.rb +61 -0
  106. data/spec/realworld/edgecases_spec.rb +8 -8
  107. data/spec/runtime/executable_spec.rb +13 -13
  108. data/spec/runtime/load_spec.rb +12 -12
  109. data/spec/runtime/platform_spec.rb +1 -1
  110. data/spec/runtime/require_spec.rb +24 -24
  111. data/spec/runtime/setup_spec.rb +113 -56
  112. data/spec/runtime/with_clean_env_spec.rb +11 -13
  113. data/spec/spec_helper.rb +6 -0
  114. data/spec/support/artifice/endpoint.rb +28 -13
  115. data/spec/support/artifice/endpoint_extra.rb +4 -0
  116. data/spec/support/builders.rb +1 -1
  117. data/spec/support/helpers.rb +2 -7
  118. data/spec/support/indexes.rb +3 -3
  119. data/spec/support/matchers.rb +6 -6
  120. data/spec/update/gems_spec.rb +19 -8
  121. data/spec/update/git_spec.rb +10 -10
  122. data/spec/update/source_spec.rb +1 -1
  123. metadata +86 -55
  124. data/.rspec +0 -2
@@ -1,6 +1,7 @@
1
1
  require 'bundler/vendored_thor'
2
2
  require 'rubygems/user_interaction'
3
3
  require 'rubygems/config_file'
4
+ require 'bundler/similarity_detector'
4
5
 
5
6
  module Bundler
6
7
  class CLI < Thor
@@ -8,15 +9,18 @@ module Bundler
8
9
 
9
10
  def initialize(*)
10
11
  super
11
- the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell)
12
- Bundler.ui = UI::Shell.new(the_shell)
13
- Bundler.ui.debug! if options["verbose"]
14
12
  Bundler.rubygems.ui = UI::RGProxy.new(Bundler.ui)
15
- warn_on_incompatible_ruby_or_rubygems
13
+ rescue UnknownArgumentError => e
14
+ raise InvalidOption, e.message
15
+ ensure
16
+ Bundler.ui = UI::Shell.new(options)
17
+ Bundler.ui.debug! if options["verbose"]
16
18
  end
17
19
 
18
20
  check_unknown_options!(:except => [:config, :exec])
19
21
 
22
+ stop_on_unknown_option! :exec
23
+
20
24
  default_task :install
21
25
  class_option "no-color", :type => :boolean, :banner => "Disable colorization in output"
22
26
  class_option "verbose", :type => :boolean, :banner => "Enable verbose output mode", :aliases => "-V"
@@ -219,7 +223,7 @@ module Bundler
219
223
  Bundler.settings[:no_prune] = true if opts["no-prune"]
220
224
  Bundler.settings[:disable_shared_gems] = Bundler.settings[:path] ? '1' : nil
221
225
  Bundler.settings.without = opts[:without]
222
- Bundler.ui.quiet = opts[:quiet]
226
+ Bundler.ui.be_quiet! if opts[:quiet]
223
227
  Bundler.settings[:clean] = opts[:clean] if opts[:clean]
224
228
 
225
229
  Bundler::Fetcher.disable_endpoint = opts["full-index"]
@@ -273,12 +277,14 @@ module Bundler
273
277
  "Use the rubygems modern index instead of the API endpoint"
274
278
  def update(*gems)
275
279
  sources = Array(options[:source])
276
- Bundler.ui.quiet = options[:quiet]
280
+ Bundler.ui.be_quiet! if options[:quiet]
277
281
 
278
282
  if gems.empty? && sources.empty?
279
283
  # We're doing a full update
280
284
  Bundler.definition(true)
281
285
  else
286
+ # cycle through the requested gems, just to make sure they exist
287
+ gems.each{ |n| gem_dependency_with_name(n) }
282
288
  Bundler.definition(:gems => gems, :sources => sources)
283
289
  end
284
290
 
@@ -346,11 +352,6 @@ module Bundler
346
352
  options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely!
347
353
 
348
354
  Bundler.ui.info ""
349
- if options["pre"]
350
- Bundler.ui.info "Outdated gems included in the bundle (including pre-releases):"
351
- else
352
- Bundler.ui.info "Outdated gems included in the bundle:"
353
- end
354
355
 
355
356
  out_count = 0
356
357
  # Loop through the current specs
@@ -369,6 +370,14 @@ module Bundler
369
370
  gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
370
371
  git_outdated = current_spec.git_version != active_spec.git_version
371
372
  if gem_outdated || git_outdated
373
+ if out_count == 0
374
+ if options["pre"]
375
+ Bundler.ui.info "Outdated gems included in the bundle (including pre-releases):"
376
+ else
377
+ Bundler.ui.info "Outdated gems included in the bundle:"
378
+ end
379
+ end
380
+
372
381
  spec_version = "#{active_spec.version}#{active_spec.git_version}"
373
382
  current_version = "#{current_spec.version}#{current_spec.git_version}"
374
383
  Bundler.ui.info " * #{active_spec.name} (#{spec_version} > #{current_version})"
@@ -377,7 +386,7 @@ module Bundler
377
386
  Bundler.ui.debug "from #{active_spec.loaded_from}"
378
387
  end
379
388
 
380
- Bundler.ui.info " Your bundle is up to date!" if out_count < 1
389
+ Bundler.ui.info "Your bundle is up to date!" if out_count < 1
381
390
  Bundler.ui.info ""
382
391
  end
383
392
 
@@ -581,6 +590,7 @@ module Bundler
581
590
 
582
591
  desc "gem GEM", "Creates a skeleton for creating a rubygem"
583
592
  method_option :bin, :type => :boolean, :default => false, :aliases => '-b', :banner => "Generate a binary for your library."
593
+ method_option :test, :type => :string, :default => 'rspec', :aliases => '-t', :banner => "Generate a test directory for your library: 'rspec' is the default, but 'minitest' is also supported."
584
594
  def gem(name)
585
595
  name = name.chomp("/") # remove trailing slash if present
586
596
  target = File.join(Dir.pwd, name)
@@ -608,6 +618,15 @@ module Bundler
608
618
  if options[:bin]
609
619
  template(File.join("newgem/bin/newgem.tt"), File.join(target, 'bin', name), opts)
610
620
  end
621
+ case options[:test]
622
+ when 'rspec'
623
+ template(File.join("newgem/rspec.tt"), File.join(target, ".rspec"), opts)
624
+ template(File.join("newgem/spec/spec_helper.rb.tt"), File.join(target, "spec/spec_helper.rb"), opts)
625
+ template(File.join("newgem/spec/newgem_spec.rb.tt"), File.join(target, "spec/#{name}_spec.rb"), opts)
626
+ when 'minitest'
627
+ template(File.join("newgem/test/minitest_helper.rb.tt"), File.join(target, "test/minitest_helper.rb"), opts)
628
+ template(File.join("newgem/test/test_newgem.rb.tt"), File.join(target, "test/test_#{name}.rb"), opts)
629
+ end
611
630
  Bundler.ui.info "Initializating git repo in #{target}"
612
631
  Dir.chdir(target) { `git init`; `git add .` }
613
632
  end
@@ -663,6 +682,28 @@ module Bundler
663
682
  Bundler.ui.info output.join("\n\n")
664
683
  end
665
684
 
685
+ desc "add GEM VERSION ...", "Add the named gem(s), with version requirements, to the resolved Gemfile"
686
+ def inject(name, version, *gems)
687
+ # The required arguments allow Thor to give useful feedback when the arguments
688
+ # are incorrect. This adds those first two arguments onto the list as a whole.
689
+ gems.unshift(version).unshift(name)
690
+
691
+ # Build an array of Dependency objects out of the arguments
692
+ deps = []
693
+ gems.each_slice(2) do |name, version|
694
+ deps << Bundler::Dependency.new(name, version)
695
+ end
696
+
697
+ added = Injector.inject(deps)
698
+
699
+ if added.any?
700
+ Bundler.ui.confirm "Added to Gemfile:"
701
+ Bundler.ui.confirm added.map{ |g| " #{g}" }.join("\n")
702
+ else
703
+ Bundler.ui.confirm "All injected gems were already present in the Gemfile"
704
+ end
705
+ end
706
+
666
707
  private
667
708
 
668
709
  def setup_cache_all
@@ -681,23 +722,28 @@ module Bundler
681
722
 
682
723
  def locate_gem(name)
683
724
  spec = Bundler.load.specs.find{|s| s.name == name }
684
- raise GemNotFound, "Could not find gem '#{name}' in the current bundle." unless spec
725
+ raise GemNotFound, not_found_message(name, Bundler.load.specs) unless spec
685
726
  if spec.name == 'bundler'
686
727
  return File.expand_path('../../../', __FILE__)
687
728
  end
688
729
  spec.full_gem_path
689
730
  end
690
731
 
691
- def warn_on_incompatible_ruby_or_rubygems
692
- ruby2 = "Ruby 2.0" if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.pre')
693
- rg2 = "Rubygems 2.0" if Gem::Version.new(Gem::VERSION.dup) >= Gem::Version.new('2.0.pre')
694
- upgrade = [ruby2, rg2].compact
732
+ def gem_dependency_with_name(name)
733
+ dep = Bundler.load.dependencies.find{|d| d.name == name }
734
+ raise GemNotFound, not_found_message(name, Bundler.load.dependencies) unless dep
735
+ dep
736
+ end
695
737
 
696
- if upgrade.any?
697
- Bundler.ui.warn "Bundler is not compatible with #{upgrade.join(' or ')}."
698
- Bundler.ui.error "Please upgrade to Bundler 1.3 or higher."
699
- exit 1
700
- end
738
+ def not_found_message(missing_gem_name, alternatives)
739
+ message = "Could not find gem '#{missing_gem_name}'."
740
+
741
+ # This is called as the result of a GemNotFound, let's see if
742
+ # there's any similarly named ones we can propose instead
743
+ alternate_names = alternatives.map{|a| a.name}
744
+ suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name)
745
+ message += "\nDid you mean #{suggestions}?" if suggestions
746
+ message
701
747
  end
702
748
 
703
749
  end
@@ -5,7 +5,8 @@ module Bundler
5
5
  class Definition
6
6
  include GemHelpers
7
7
 
8
- attr_reader :dependencies, :platforms, :sources, :ruby_version
8
+ attr_reader :dependencies, :platforms, :sources, :ruby_version,
9
+ :locked_deps
9
10
 
10
11
  def self.build(gemfile, lockfile, unlock)
11
12
  unlock ||= {}
@@ -225,7 +226,7 @@ module Bundler
225
226
  return if @lockfile_contents == contents
226
227
 
227
228
  if Bundler.settings[:frozen]
228
- # TODO: Warn here if we got here.
229
+ Bundler.ui.error "Cannot write a changed lockfile while frozen."
229
230
  return
230
231
  end
231
232
 
@@ -0,0 +1,15 @@
1
+ module Bundler
2
+
3
+ if defined? ::Deprecate
4
+ Deprecate = ::Deprecate
5
+ elsif defined? Gem::Deprecate
6
+ Deprecate = Gem::Deprecate
7
+ else
8
+ class Deprecate; end
9
+ end
10
+
11
+ unless Deprecate.respond_to?(:skip_during)
12
+ def Deprecate.skip_during; yield; end
13
+ end
14
+
15
+ end
@@ -6,11 +6,6 @@ module Bundler
6
6
  builder = new
7
7
  builder.eval_gemfile(gemfile)
8
8
  builder.to_definition(lockfile, unlock)
9
- rescue ScriptError, RegexpError, NameError, ArgumentError => e
10
- e.backtrace[0] = "#{e.backtrace[0]}: #{e.message} (#{e.class})"
11
- Bundler.ui.info e.backtrace.join("\n ")
12
- raise GemfileError, "There was an error in your Gemfile," \
13
- " and Bundler cannot continue."
14
9
  end
15
10
 
16
11
  VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze
@@ -28,11 +23,17 @@ module Bundler
28
23
  @ruby_version = nil
29
24
  end
30
25
 
31
- def eval_gemfile(gemfile)
32
- instance_eval(Bundler.read_file(gemfile.to_s), gemfile.to_s, 1)
26
+ def eval_gemfile(gemfile, contents = nil)
27
+ contents ||= Bundler.read_file(gemfile.to_s)
28
+ instance_eval(contents, gemfile.to_s, 1)
33
29
  rescue SyntaxError => e
34
30
  bt = e.message.split("\n")[1..-1]
35
31
  raise GemfileError, ["Gemfile syntax error:", *bt].join("\n")
32
+ rescue ScriptError, RegexpError, NameError, ArgumentError => e
33
+ e.backtrace[0] = "#{e.backtrace[0]}: #{e.message} (#{e.class})"
34
+ Bundler.ui.warn e.backtrace.join("\n ")
35
+ raise GemfileError, "There was an error in your Gemfile," \
36
+ " and Bundler cannot continue."
36
37
  end
37
38
 
38
39
  def gemspec(opts = nil)
@@ -79,9 +80,9 @@ module Bundler
79
80
  elsif dep.type == :development
80
81
  return
81
82
  else
82
- raise DslError, "You cannot specify the same gem twice with different version requirements. " \
83
+ raise DslError, "You cannot specify the same gem twice with different version requirements. \n" \
83
84
  "You specified: #{current.name} (#{current.requirement}) and " \
84
- "#{dep.name} (#{dep.requirement})"
85
+ "#{dep.name} (#{dep.requirement})\n"
85
86
  end
86
87
  end
87
88
 
@@ -91,9 +92,9 @@ module Bundler
91
92
  elsif dep.type == :development
92
93
  return
93
94
  else
94
- raise DslError, "You cannot specify the same gem twice coming from different sources. You " \
95
- "specified that #{dep.name} (#{dep.requirement}) should come from " \
96
- "#{current.source || 'an unspecified source'} and #{dep.source}"
95
+ raise DslError, "You cannot specify the same gem twice coming from different sources.\n" \
96
+ "You specified that #{dep.name} (#{dep.requirement}) should come from " \
97
+ "#{current.source || 'an unspecified source'} and #{dep.source}\n"
97
98
  end
98
99
  end
99
100
  end
@@ -104,9 +105,6 @@ module Bundler
104
105
  def source(source, options = {})
105
106
  case source
106
107
  when :gemcutter, :rubygems, :rubyforge then
107
- Bundler.ui.warn "The source :#{source} is deprecated because HTTP " \
108
- "requests are insecure.\nPlease change your source to 'https://" \
109
- "rubygems.org' if possible, or 'http://rubygems.org' if not."
110
108
  @rubygems_source.add_remote "http://rubygems.org"
111
109
  return
112
110
  when String
@@ -233,7 +231,7 @@ module Bundler
233
231
  end
234
232
 
235
233
  if github = opts.delete("github")
236
- github = "#{github}/#{github}" unless github.include?("/")
234
+ github = "#{github}/#{name}" unless github.include?("/")
237
235
  opts["git"] = "git://github.com/#{github}.git"
238
236
  end
239
237
 
@@ -14,11 +14,6 @@ module Bundler
14
14
  @definition.to_lock.inspect
15
15
  end
16
16
 
17
- # TODO: Remove this method. It's used in cli.rb still
18
- def index
19
- @definition.index
20
- end
21
-
22
17
  def requested_specs
23
18
  @definition.requested_specs
24
19
  end
@@ -1,27 +1,13 @@
1
1
  require 'uri'
2
2
  require 'bundler/vendored_persistent'
3
+ require 'openssl' if defined?(JRUBY_VERSION)
3
4
 
4
5
  module Bundler
5
6
  # Handles all the fetching with the rubygems server
6
7
  class Fetcher
7
- # How many redirects to allew in one request
8
8
  REDIRECT_LIMIT = 5
9
9
  # how long to wait for each gemcutter API call
10
- API_TIMEOUT = 10
11
-
12
- # This error is raised if the API returns a 413 (only printed in verbose)
13
- class FallbackError < HTTPError; end
14
- # This is the error raised if OpenSSL fails the cert verification
15
- class CertificateFailureError < HTTPError
16
- def initialize(remote_uri)
17
- super "Could not verify the SSL certificate for #{remote_uri}.\nThere" \
18
- " is a chance you are experiencing a man-in-the-middle attack, but" \
19
- " most likely your system doesn't have the CA certificates needed" \
20
- " for verification. For information about OpenSSL certificates, see" \
21
- " bit.ly/ssl-certs. To connect without using SSL, edit your Gemfile" \
22
- " sources and change 'https' to 'http'."
23
- end
24
- end
10
+ API_TIMEOUT = 10
25
11
 
26
12
  attr_reader :has_api
27
13
 
@@ -60,21 +46,8 @@ module Bundler
60
46
  def initialize(remote_uri)
61
47
  @remote_uri = remote_uri
62
48
  @has_api = true # will be set to false if the rubygems index is ever fetched
63
-
64
- if USE_PERSISTENT
65
- @connection ||= Net::HTTP::Persistent.new 'bundler', :ENV
66
- else
67
- if @remote_uri.scheme == "https"
68
- raise Bundler::HTTPError, "Could not load OpenSSL.\n" \
69
- "You must recompile Ruby with OpenSSL support or change the sources in your " \
70
- "Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL " \
71
- "using RVM are available at rvm.io/packages/openssl."
72
- end
73
- @connection ||= Net::HTTP.new(@remote_uri.host, @remote_uri.port)
74
- end
75
- @connection.read_timeout = API_TIMEOUT
76
-
77
- Socket.do_not_reverse_lookup = true
49
+ @@connection ||= Net::HTTP::Persistent.new nil, :ENV
50
+ @@connection.read_timeout = API_TIMEOUT
78
51
  end
79
52
 
80
53
  # fetch a gem specification
@@ -91,9 +64,10 @@ module Bundler
91
64
  # return the specs in the bundler format as an index
92
65
  def specs(gem_names, source)
93
66
  index = Index.new
94
- use_full_source_index = !gem_names || @remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
95
67
 
96
- if use_full_source_index
68
+ specs = nil
69
+
70
+ if !gem_names || @remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
97
71
  Bundler.ui.info "Fetching source index from #{strip_user_pass_from_uri(@remote_uri)}"
98
72
  specs = fetch_all_remote_specs
99
73
  else
@@ -108,11 +82,11 @@ module Bundler
108
82
  # new line now that the dots are over
109
83
  Bundler.ui.info "" unless Bundler.ui.debug?
110
84
 
111
- if FallbackError === e
112
- Bundler.ui.debug "API refused request: #{e.message}"
113
- else
114
- Bundler.ui.debug "Error during API request. #{e.class}: #{e.message}"
85
+ if @remote_uri.to_s.include?("rubygems.org")
86
+ Bundler.ui.info "Error #{e.class} during request to dependency API"
115
87
  end
88
+ Bundler.ui.debug e.message
89
+ Bundler.ui.debug e.backtrace
116
90
 
117
91
  Bundler.ui.info "Fetching full source index from #{strip_user_pass_from_uri(@remote_uri)}"
118
92
  specs = fetch_all_remote_specs
@@ -136,9 +110,6 @@ module Bundler
136
110
  end
137
111
 
138
112
  index
139
- rescue OpenSSL::SSL::SSLError
140
- Bundler.ui.info "" if !use_full_source_index # newline after dots
141
- raise CertificateFailureError.new(strip_user_pass_from_uri(@remote_uri))
142
113
  end
143
114
 
144
115
  # fetch index
@@ -162,25 +133,15 @@ module Bundler
162
133
 
163
134
  private
164
135
 
165
- HTTP_ERRORS = [
166
- Timeout::Error, EOFError, SocketError,
167
- Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
168
- Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
169
- ]
170
- HTTP_ERRORS << Net::HTTP::Persistent::Error if defined?(Net::HTTP::Persistent)
171
-
172
136
  def fetch(uri, counter = 0)
173
137
  raise HTTPError, "Too many redirects" if counter >= REDIRECT_LIMIT
174
138
 
175
139
  begin
176
140
  Bundler.ui.debug "Fetching from: #{uri}"
177
- if USE_PERSISTENT
178
- response = @connection.request(uri)
179
- else
180
- req = Net::HTTP::Get.new uri.request_uri
181
- response = @connection.request(req)
182
- end
183
- rescue *HTTP_ERRORS
141
+ response = @@connection.request(uri)
142
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT,
143
+ EOFError, SocketError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
144
+ Errno::EAGAIN, Net::HTTP::Persistent::Error, Net::ProtocolError => e
184
145
  raise HTTPError, "Network error while fetching #{uri}"
185
146
  end
186
147
 
@@ -188,18 +149,15 @@ module Bundler
188
149
  when Net::HTTPRedirection
189
150
  Bundler.ui.debug("HTTP Redirection")
190
151
  new_uri = URI.parse(response["location"])
191
- if new_uri.host == uri.host
192
- new_uri.user = uri.user
193
- new_uri.password = uri.password
194
- end
152
+ new_uri.user = uri.user
153
+ new_uri.password = uri.password
195
154
  fetch(new_uri, counter + 1)
196
155
  when Net::HTTPSuccess
197
156
  Bundler.ui.debug("HTTP Success")
198
157
  response.body
199
- when Net::HTTPRequestEntityTooLarge
200
- raise FallbackError, response.body
201
158
  else
202
- raise HTTPError, "#{response.class}: #{response.body}"
159
+ Bundler.ui.debug("HTTP Error")
160
+ raise HTTPError, "Don't know how to process #{response.class}"
203
161
  end
204
162
  end
205
163
 
@@ -244,25 +202,12 @@ module Bundler
244
202
  def fetch_all_remote_specs
245
203
  @has_api = false
246
204
  Gem.sources = ["#{@remote_uri}"]
247
- spec_list = Hash.new { |h,k| h[k] = [] }
205
+
248
206
  begin
249
- # Fetch all specs, minus prerelease specs
250
- spec_list = Gem::SpecFetcher.new.list(true, false)
251
- # Then fetch the prerelease specs
252
- begin
253
- Gem::SpecFetcher.new.list(false, true).each {|k, v| spec_list[k] += v }
254
- rescue Gem::RemoteFetcher::FetchError
255
- Bundler.ui.debug "Could not fetch prerelease specs from #{strip_user_pass_from_uri(@remote_uri)}"
256
- end
257
- rescue Gem::RemoteFetcher::FetchError => e
258
- if e.message.match("certificate verify failed")
259
- raise CertificateFailureError.new(strip_user_pass_from_uri(@remote_uri))
260
- else
261
- raise HTTPError, "Could not fetch specs from #{strip_user_pass_from_uri(@remote_uri)}"
262
- end
207
+ Bundler.rubygems.fetch_all_remote_specs
208
+ rescue Gem::RemoteFetcher::FetchError
209
+ raise HTTPError, "Could not reach #{strip_user_pass_from_uri(@remote_uri)}"
263
210
  end
264
-
265
- return spec_list
266
211
  end
267
212
 
268
213
  def strip_user_pass_from_uri(uri)