bundler 1.12.6 → 1.13.0.pre.1

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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +15 -13
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +40 -3
  5. data/CONTRIBUTING.md +9 -5
  6. data/DEVELOPMENT.md +30 -18
  7. data/ISSUES.md +26 -22
  8. data/Rakefile +15 -4
  9. data/bin/rubocop +1 -1
  10. data/bundler.gemspec +2 -2
  11. data/exe/bundle +7 -0
  12. data/lib/bundler.rb +6 -3
  13. data/lib/bundler/capistrano.rb +1 -1
  14. data/lib/bundler/cli.rb +27 -10
  15. data/lib/bundler/cli/binstubs.rb +2 -0
  16. data/lib/bundler/cli/exec.rb +1 -1
  17. data/lib/bundler/cli/install.rb +87 -56
  18. data/lib/bundler/cli/lock.rb +5 -0
  19. data/lib/bundler/cli/open.rb +3 -1
  20. data/lib/bundler/cli/outdated.rb +8 -8
  21. data/lib/bundler/cli/plugin.rb +23 -0
  22. data/lib/bundler/cli/update.rb +2 -2
  23. data/lib/bundler/cli/viz.rb +3 -0
  24. data/lib/bundler/definition.rb +72 -16
  25. data/lib/bundler/dsl.rb +19 -7
  26. data/lib/bundler/endpoint_specification.rb +2 -2
  27. data/lib/bundler/env.rb +2 -2
  28. data/lib/bundler/errors.rb +15 -1
  29. data/lib/bundler/fetcher.rb +5 -2
  30. data/lib/bundler/fetcher/compact_index.rb +2 -2
  31. data/lib/bundler/fetcher/dependency.rb +8 -4
  32. data/lib/bundler/fetcher/downloader.rb +1 -1
  33. data/lib/bundler/friendly_errors.rb +1 -1
  34. data/lib/bundler/index.rb +29 -36
  35. data/lib/bundler/inline.rb +14 -4
  36. data/lib/bundler/installer.rb +22 -3
  37. data/lib/bundler/installer/gem_installer.rb +1 -1
  38. data/lib/bundler/installer/standalone.rb +1 -1
  39. data/lib/bundler/mirror.rb +4 -4
  40. data/lib/bundler/plugin.rb +156 -0
  41. data/lib/bundler/plugin/api.rb +56 -0
  42. data/lib/bundler/plugin/dsl.rb +29 -0
  43. data/lib/bundler/plugin/index.rb +88 -0
  44. data/lib/bundler/plugin/installer.rb +99 -0
  45. data/lib/bundler/plugin/installer/git.rb +38 -0
  46. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  47. data/lib/bundler/plugin/source_list.rb +24 -0
  48. data/lib/bundler/postit_trampoline.rb +54 -0
  49. data/lib/bundler/psyched_yaml.rb +1 -1
  50. data/lib/bundler/remote_specification.rb +5 -5
  51. data/lib/bundler/resolver.rb +27 -29
  52. data/lib/bundler/ruby_version.rb +29 -3
  53. data/lib/bundler/rubygems_ext.rb +3 -1
  54. data/lib/bundler/rubygems_integration.rb +10 -4
  55. data/lib/bundler/runtime.rb +1 -16
  56. data/lib/bundler/settings.rb +19 -15
  57. data/lib/bundler/setup.rb +1 -0
  58. data/lib/bundler/shared_helpers.rb +3 -0
  59. data/lib/bundler/source.rb +4 -3
  60. data/lib/bundler/source/gemspec.rb +13 -0
  61. data/lib/bundler/source/git.rb +4 -3
  62. data/lib/bundler/source/git/git_proxy.rb +9 -5
  63. data/lib/bundler/source/path.rb +11 -2
  64. data/lib/bundler/source/rubygems.rb +28 -15
  65. data/lib/bundler/source_list.rb +5 -1
  66. data/lib/bundler/spec_set.rb +3 -3
  67. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  68. data/lib/bundler/ssl_certs/rubygems.org/{AddTrustExternalCARoot-2048.pem → AddTrustExternalCARoot.pem} +0 -0
  69. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +54 -29
  70. data/lib/bundler/templates/newgem/newgem.gemspec.tt +5 -2
  71. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +3 -3
  72. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -2
  73. data/lib/bundler/ui/shell.rb +4 -0
  74. data/lib/bundler/ui/silent.rb +3 -0
  75. data/lib/bundler/uri_credentials_filter.rb +36 -0
  76. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +1 -1
  77. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +50 -0
  78. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +80 -0
  79. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +56 -144
  80. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +35 -0
  81. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +58 -0
  82. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +61 -0
  83. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +53 -0
  84. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +114 -0
  85. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +45 -0
  86. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +35 -0
  87. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +123 -0
  88. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  89. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +46 -51
  90. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +4 -2
  91. data/lib/bundler/vendor/postit/lib/postit.rb +15 -0
  92. data/lib/bundler/vendor/postit/lib/postit/environment.rb +44 -0
  93. data/lib/bundler/vendor/postit/lib/postit/installer.rb +28 -0
  94. data/lib/bundler/vendor/postit/lib/postit/parser.rb +21 -0
  95. data/lib/bundler/vendor/postit/lib/postit/setup.rb +12 -0
  96. data/lib/bundler/vendor/postit/lib/postit/version.rb +3 -0
  97. data/lib/bundler/version.rb +1 -1
  98. data/lib/bundler/vlad.rb +1 -1
  99. data/lib/bundler/yaml_serializer.rb +67 -0
  100. data/man/bundle-install.ronn +10 -5
  101. data/man/bundle-package.ronn +7 -6
  102. data/man/bundle-platform.ronn +1 -1
  103. data/man/bundle-update.ronn +5 -2
  104. data/man/bundle.ronn +5 -5
  105. data/man/gemfile.5.ronn +32 -28
  106. metadata +37 -12
  107. data/lib/bundler/ssl_certs/Fastly.pem +0 -82
  108. data/lib/bundler/ssl_certs/GlobalSignOrganizationValidationCA.pem +0 -26
  109. data/lib/bundler/ssl_certs/GlobalSignRoot.pem +0 -18
  110. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRoot.pem +0 -18
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ require "bundler/vendored_thor"
3
+ module Bundler
4
+ class CLI::Plugin < Thor
5
+ desc "install PLUGINS", "Install the plugin from the source"
6
+ long_desc <<-D
7
+ Install plugins either from the rubygems source provided (with --source option) or from a git source provided with (--git option). If no sources are provided, it uses Gem.sources
8
+ D
9
+ method_option "source", :type => :string, :default => nil, :banner =>
10
+ "URL of the RubyGems source to fetch the plugin from"
11
+ method_option "version", :type => :string, :default => nil, :banner =>
12
+ "The version of the plugin to fetch"
13
+ method_option "git", :type => :string, :default => nil, :banner =>
14
+ "URL of the git repo to fetch from"
15
+ method_option "branch", :type => :string, :default => nil, :banner =>
16
+ "The git branch to checkout"
17
+ method_option "ref", :type => :string, :default => nil, :banner =>
18
+ "The git revision to check out"
19
+ def install(*plugins)
20
+ Bundler::Plugin.install(plugins, options)
21
+ end
22
+ end
23
+ end
@@ -13,7 +13,7 @@ module Bundler
13
13
  sources = Array(options[:source])
14
14
  groups = Array(options[:group]).map(&:to_sym)
15
15
 
16
- if gems.empty? && sources.empty? && groups.empty? && !options[:ruby]
16
+ if gems.empty? && sources.empty? && groups.empty? && !options[:ruby] && !options[:bundler]
17
17
  # We're doing a full update
18
18
  Bundler.definition(true)
19
19
  else
@@ -21,7 +21,7 @@ module Bundler
21
21
  raise GemfileLockNotFound, "This Bundle hasn't been installed yet. " \
22
22
  "Run `bundle install` to update and install the bundled gems."
23
23
  end
24
- # cycle through the requested gems, just to make sure they exist
24
+ # cycle through the requested gems, to make sure they exist
25
25
  names = Bundler.locked_gems.specs.map(&:name)
26
26
  gems.each do |g|
27
27
  next if names.include?(g)
@@ -8,7 +8,10 @@ module Bundler
8
8
 
9
9
  def run
10
10
  require "graphviz"
11
+
12
+ options[:without] = options[:without].join(":").tr(" ", ":").split(":")
11
13
  output_file = File.expand_path(options[:file])
14
+
12
15
  graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format], options[:without])
13
16
  graph.viz
14
17
  rescue LoadError => e
@@ -85,10 +85,17 @@ module Bundler
85
85
 
86
86
  @unlock[:gems] ||= []
87
87
  @unlock[:sources] ||= []
88
+ @unlock[:ruby] ||= if @ruby_version && @locked_ruby_version
89
+ unless locked_ruby_version_object = RubyVersion.from_string(@locked_ruby_version)
90
+ raise LockfileError, "Failed to create a `RubyVersion` object from " \
91
+ "`#{@locked_ruby_version}` found in #{lockfile} -- try running `bundle update --ruby`."
92
+ end
93
+ @ruby_version.diff(locked_ruby_version_object)
94
+ end
95
+ @unlocking ||= @unlock[:ruby] || (!@locked_ruby_version ^ !@ruby_version)
88
96
 
89
97
  current_platform = Bundler.rubygems.platforms.map {|p| generic(p) }.compact.last
90
- @new_platform = !@platforms.include?(current_platform)
91
- @platforms |= [current_platform]
98
+ add_platform(current_platform)
92
99
 
93
100
  @path_changes = converge_paths
94
101
  eager_unlock = expand_dependencies(@unlock[:gems])
@@ -137,8 +144,17 @@ module Bundler
137
144
  # @return [Bundler::SpecSet]
138
145
  def specs
139
146
  @specs ||= begin
140
- specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)
141
-
147
+ begin
148
+ specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)
149
+ rescue GemNotFound => e # Handle yanked gem
150
+ gem_name, gem_version = extract_gem_info(e)
151
+ locked_gem = @locked_specs[gem_name].last
152
+ raise if locked_gem.nil? || locked_gem.version.to_s != gem_version
153
+ raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
154
+ "be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
155
+ "that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
156
+ "to a different version of #{locked_gem} that hasn't been removed in order to install."
157
+ end
142
158
  unless specs["bundler"].any?
143
159
  local = Bundler.settings[:frozen] ? rubygems_index : index
144
160
  bundler = local.search(Gem::Dependency.new("bundler", VERSION)).last
@@ -167,6 +183,12 @@ module Bundler
167
183
  missing
168
184
  end
169
185
 
186
+ def missing_dependencies
187
+ missing = []
188
+ resolve.materialize(current_dependencies, missing)
189
+ missing
190
+ end
191
+
170
192
  def requested_specs
171
193
  @requested_specs ||= begin
172
194
  groups = requested_groups
@@ -194,9 +216,11 @@ module Bundler
194
216
  @resolve ||= begin
195
217
  last_resolve = converge_locked_specs
196
218
  if Bundler.settings[:frozen] || (!@unlocking && nothing_changed?)
219
+ Bundler.ui.debug("Found no changes, using resolution from the lockfile")
197
220
  last_resolve
198
221
  else
199
222
  # Run a resolve against the locally available gems
223
+ Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies")
200
224
  last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, ruby_version)
201
225
  end
202
226
  end
@@ -210,7 +234,7 @@ module Bundler
210
234
  source.dependency_names = dependency_names.dup
211
235
  idx.add_source source.specs
212
236
  dependency_names -= pinned_spec_names(source.specs)
213
- dependency_names.push(*source.unmet_deps).uniq!
237
+ dependency_names.concat(source.unmet_deps).uniq!
214
238
  end
215
239
  end
216
240
  end
@@ -352,10 +376,20 @@ module Bundler
352
376
  changed = []
353
377
 
354
378
  gemfile_sources = sources.lock_sources
355
- if @locked_sources != gemfile_sources
356
- new_sources = gemfile_sources - @locked_sources
357
- deleted_sources = @locked_sources - gemfile_sources
358
379
 
380
+ new_sources = gemfile_sources - @locked_sources
381
+ deleted_sources = @locked_sources - gemfile_sources
382
+
383
+ new_deps = @dependencies - @locked_deps
384
+ deleted_deps = @locked_deps - @dependencies
385
+
386
+ # Check if it is possible that the source is only changed thing
387
+ if (new_deps.empty? && deleted_deps.empty?) && (!new_sources.empty? && !deleted_sources.empty?)
388
+ new_sources.reject! {|source| source.is_a_path? && source.path.exist? }
389
+ deleted_sources.reject! {|source| source.is_a_path? && source.path.exist? }
390
+ end
391
+
392
+ if @locked_sources != gemfile_sources
359
393
  if new_sources.any?
360
394
  added.concat new_sources.map {|source| "* source: #{source}" }
361
395
  end
@@ -365,11 +399,7 @@ module Bundler
365
399
  end
366
400
  end
367
401
 
368
- new_deps = @dependencies - @locked_deps
369
- deleted_deps = @locked_deps - @dependencies
370
-
371
402
  added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
372
-
373
403
  if deleted_deps.any?
374
404
  deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
375
405
  end
@@ -418,6 +448,11 @@ module Bundler
418
448
  end
419
449
  end
420
450
 
451
+ def add_platform(platform)
452
+ @new_platform ||= !@platforms.include?(platform)
453
+ @platforms |= [platform]
454
+ end
455
+
421
456
  attr_reader :sources
422
457
  private :sources
423
458
 
@@ -447,14 +482,21 @@ module Bundler
447
482
  end
448
483
  end
449
484
 
450
- !locked || unlocking || dependencies_for_source_changed?(locked) || source.specs != locked.specs
485
+ !locked || unlocking || dependencies_for_source_changed?(source) || specs_for_source_changed?(source)
451
486
  end
452
487
 
453
488
  def dependencies_for_source_changed?(source)
454
489
  deps_for_source = @dependencies.select {|s| s.source == source }
455
490
  locked_deps_for_source = @locked_deps.select {|s| s.source == source }
456
491
 
457
- deps_for_source != locked_deps_for_source
492
+ Set.new(deps_for_source) != Set.new(locked_deps_for_source)
493
+ end
494
+
495
+ def specs_for_source_changed?(source)
496
+ locked_index = Index.new
497
+ locked_index.use(@locked_specs.select {|s| source.can_lock?(s) })
498
+
499
+ source.specs != locked_index
458
500
  end
459
501
 
460
502
  # Get all locals and override their matching sources.
@@ -523,7 +565,15 @@ module Bundler
523
565
 
524
566
  def converge_dependencies
525
567
  (@dependencies + @locked_deps).each do |dep|
526
- dep.source = sources.get(dep.source) if dep.source
568
+ locked_source = @locked_deps.select {|d| d.name == dep.name }.last
569
+ # This is to make sure that if bundler is installing in deployment mode and
570
+ # after locked_source and sources don't match, we still use locked_source.
571
+ if Bundler.settings[:frozen] && !locked_source.nil? &&
572
+ locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
573
+ dep.source = locked_source.source
574
+ elsif dep.source
575
+ dep.source = sources.get(dep.source)
576
+ end
527
577
  end
528
578
  Set.new(@dependencies) != Set.new(@locked_deps)
529
579
  end
@@ -572,7 +622,7 @@ module Bundler
572
622
  next if s.source.nil? || @unlock[:sources].include?(s.name)
573
623
 
574
624
  # If the spec is from a path source and it doesn't exist anymore
575
- # then we just unlock it.
625
+ # then we unlock it.
576
626
 
577
627
  # Path sources have special logic
578
628
  if s.source.instance_of?(Source::Path)
@@ -684,5 +734,11 @@ module Bundler
684
734
  end
685
735
  current == proposed
686
736
  end
737
+
738
+ def extract_gem_info(error)
739
+ # This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
740
+ # to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
741
+ error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
742
+ end
687
743
  end
688
744
  end
@@ -34,7 +34,9 @@ module Bundler
34
34
  end
35
35
 
36
36
  def eval_gemfile(gemfile, contents = nil)
37
- @gemfile = Pathname.new(gemfile)
37
+ expanded_gemfile_path = Pathname.new(gemfile).expand_path
38
+ original_gemfile = @gemfile
39
+ @gemfile = expanded_gemfile_path
38
40
  contents ||= Bundler.read_file(gemfile.to_s)
39
41
  instance_eval(contents, gemfile.to_s, 1)
40
42
  rescue Exception => e
@@ -43,6 +45,8 @@ module Bundler
43
45
  "`#{File.basename gemfile.to_s}`: #{e.message}"
44
46
 
45
47
  raise DSLError.new(message, gemfile, e.backtrace, contents)
48
+ ensure
49
+ @gemfile = original_gemfile
46
50
  end
47
51
 
48
52
  def gemspec(opts = nil)
@@ -63,16 +67,16 @@ module Bundler
63
67
  "#{file}. Make sure you can build the gem, then try again"
64
68
  end
65
69
 
70
+ @gemspecs << spec
71
+
66
72
  gem_platforms = Bundler::Dependency::REVERSE_PLATFORM_MAP[Bundler::GemHelpers.generic_local_platform]
67
- gem spec.name, :path => path, :glob => glob, :platforms => gem_platforms
73
+ gem spec.name, :name => spec.name, :path => path, :glob => glob, :platforms => gem_platforms
68
74
 
69
75
  group(development_group) do
70
76
  spec.development_dependencies.each do |dep|
71
- gem dep.name, *(dep.requirement.as_list + [:type => :development])
77
+ gem dep.name, *(dep.requirement.as_list + [:type => :development, :platforms => gem_platforms])
72
78
  end
73
79
  end
74
-
75
- @gemspecs << gemspecs.first
76
80
  when 0
77
81
  raise InvalidOption, "There are no gemspecs at #{expanded_path}"
78
82
  else
@@ -103,7 +107,7 @@ module Bundler
103
107
  else
104
108
  Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
105
109
  "You should probably keep only one of them.\n" \
106
- "While it's not a problem now, it could cause errors if you change the version of just one of them later."
110
+ "While it's not a problem now, it could cause errors if you change the version of one of them later."
107
111
  end
108
112
 
109
113
  if current.source != dep.source
@@ -145,7 +149,11 @@ module Bundler
145
149
  end
146
150
 
147
151
  def path(path, options = {}, &blk)
148
- source_options = normalize_hash(options).merge("path" => Pathname.new(path), "root_path" => gemfile_root)
152
+ source_options = normalize_hash(options).merge(
153
+ "path" => Pathname.new(path),
154
+ "root_path" => gemfile_root,
155
+ "gemspec" => gemspecs.find {|g| g.name == options["name"] }
156
+ )
149
157
  source = @sources.add_path_source(source_options)
150
158
  with_source(source, &blk)
151
159
  end
@@ -216,6 +224,10 @@ module Bundler
216
224
  @env = old
217
225
  end
218
226
 
227
+ def plugin(*args)
228
+ # Pass on
229
+ end
230
+
219
231
  def method_missing(name, *args)
220
232
  raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
221
233
  end
@@ -115,8 +115,8 @@ module Bundler
115
115
  end
116
116
  end
117
117
 
118
- def build_dependency(name, *requirements)
119
- Gem::Dependency.new(name, *requirements)
118
+ def build_dependency(name, requirements)
119
+ Gem::Dependency.new(name, requirements)
120
120
  rescue ArgumentError => e
121
121
  raise unless e.message.include?(ILLFORMED_MESSAGE)
122
122
  puts # we shouldn't print the error message on the "fetching info" status line
@@ -44,8 +44,8 @@ module Bundler
44
44
  if print_gemspecs
45
45
  dsl = Dsl.new.tap {|d| d.eval_gemfile(Bundler.default_gemfile) }
46
46
  dsl.gemspecs.each do |gs|
47
- out << "\n#{Pathname.new(gs).basename}"
48
- out << "\n\n " << read_file(gs).gsub(/\n/, "\n ") << "\n"
47
+ out << "\n#{File.basename(gs.loaded_from)}"
48
+ out << "\n\n " << read_file(gs.loaded_from).gsub(/\n/, "\n ") << "\n"
49
49
  end
50
50
  end
51
51
 
@@ -30,12 +30,18 @@ module Bundler
30
30
  class GemspecError < BundlerError; status_code(14); end
31
31
  class InvalidOption < BundlerError; status_code(15); end
32
32
  class ProductionError < BundlerError; status_code(16); end
33
- class HTTPError < BundlerError; status_code(17); end
33
+ class HTTPError < BundlerError
34
+ status_code(17)
35
+ def filter_uri(uri)
36
+ URICredentialsFilter.credential_filtered_uri(uri)
37
+ end
38
+ end
34
39
  class RubyVersionMismatch < BundlerError; status_code(18); end
35
40
  class SecurityError < BundlerError; status_code(19); end
36
41
  class LockfileError < BundlerError; status_code(20); end
37
42
  class CyclicDependencyError < BundlerError; status_code(21); end
38
43
  class GemfileLockNotFound < BundlerError; status_code(22); end
44
+ class PluginError < BundlerError; status_code(23); end
39
45
  class GemfileEvalError < GemfileError; end
40
46
  class MarshalError < StandardError; end
41
47
 
@@ -107,4 +113,12 @@ module Bundler
107
113
 
108
114
  status_code(27)
109
115
  end
116
+
117
+ class OperationNotSupportedError < PermissionError
118
+ def message
119
+ "Attempting to #{action} `#{@path}` is unsupported by your OS."
120
+ end
121
+
122
+ status_code(28)
123
+ end
110
124
  end
@@ -19,6 +19,7 @@ module Bundler
19
19
  # This is the error raised if OpenSSL fails the cert verification
20
20
  class CertificateFailureError < HTTPError
21
21
  def initialize(remote_uri)
22
+ remote_uri = filter_uri(remote_uri)
22
23
  super "Could not verify the SSL certificate for #{remote_uri}.\nThere" \
23
24
  " is a chance you are experiencing a man-in-the-middle attack, but" \
24
25
  " most likely your system doesn't have the CA certificates needed" \
@@ -39,6 +40,7 @@ module Bundler
39
40
  # This error is raised if HTTP authentication is required, but not provided.
40
41
  class AuthenticationRequiredError < HTTPError
41
42
  def initialize(remote_uri)
43
+ remote_uri = filter_uri(remote_uri)
42
44
  super "Authentication is required for #{remote_uri}.\n" \
43
45
  "Please supply credentials for this source. You can do this by running:\n" \
44
46
  " bundle config #{remote_uri} username:password"
@@ -47,6 +49,7 @@ module Bundler
47
49
  # This error is raised if HTTP authentication is provided, but incorrect.
48
50
  class BadAuthenticationError < HTTPError
49
51
  def initialize(remote_uri)
52
+ remote_uri = filter_uri(remote_uri)
50
53
  super "Bad username or password for #{remote_uri}.\n" \
51
54
  "Please double-check your credentials and correct them."
52
55
  end
@@ -63,7 +66,7 @@ module Bundler
63
66
  FAIL_ERRORS = begin
64
67
  fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError]
65
68
  fail_errors << Gem::Requirement::BadRequirementError if defined?(Gem::Requirement::BadRequirementError)
66
- fail_errors.push(*NET_ERRORS.map {|e| SharedHelpers.const_get_safely(e, Net) }.compact)
69
+ fail_errors.concat(NET_ERRORS.map {|e| SharedHelpers.const_get_safely(e, Net) }.compact)
67
70
  end.freeze
68
71
 
69
72
  class << self
@@ -269,7 +272,7 @@ module Bundler
269
272
  Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
270
273
  Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
271
274
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
272
- Net::HTTP::Persistent::Error, Zlib::BufError
275
+ Net::HTTP::Persistent::Error, Zlib::BufError, Errno::EHOSTUNREACH
273
276
  ].freeze
274
277
 
275
278
  def bundler_cert_store
@@ -16,7 +16,7 @@ module Bundler
16
16
  rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
17
17
  raise HTTPError, e.message
18
18
  rescue AuthenticationRequiredError
19
- # We got a 401 from the server. Just fail.
19
+ # Fail since we got a 401 from the server.
20
20
  raise
21
21
  rescue HTTPError => e
22
22
  Bundler.ui.trace(e)
@@ -41,7 +41,7 @@ module Bundler
41
41
  deps = compact_index_client.dependencies(remaining_gems)
42
42
  next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
43
43
  deps.each {|dep| gem_info << dep }
44
- complete_gems.push(*deps.map(&:first)).uniq!
44
+ complete_gems.concat(deps.map(&:first)).uniq!
45
45
  remaining_gems = next_gems - complete_gems
46
46
  end
47
47
 
@@ -10,7 +10,7 @@ module Bundler
10
10
  rescue NetworkDownError => e
11
11
  raise HTTPError, e.message
12
12
  rescue AuthenticationRequiredError
13
- # We got a 401 from the server. Just fail.
13
+ # Fail since we got a 401 from the server.
14
14
  raise
15
15
  rescue HTTPError
16
16
  false
@@ -33,10 +33,14 @@ module Bundler
33
33
 
34
34
  returned_gems = spec_list.map(&:first).uniq
35
35
  specs(deps_list, full_dependency_list + returned_gems, spec_list + last_spec_list)
36
- rescue HTTPError, MarshalError, GemspecError
36
+ rescue MarshalError
37
37
  Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
38
38
  Bundler.ui.debug "could not fetch from the dependency API, trying the full index"
39
39
  nil
40
+ rescue HTTPError, GemspecError
41
+ Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
42
+ Bundler.ui.debug "could not fetch from the dependency API\nit's suggested to retry using the full index via `bundle install --full-index`"
43
+ nil
40
44
  end
41
45
 
42
46
  def dependency_specs(gem_names)
@@ -50,7 +54,7 @@ module Bundler
50
54
  gem_list = []
51
55
  gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names|
52
56
  marshalled_deps = downloader.fetch(dependency_api_uri(names)).body
53
- gem_list.push(*Bundler.load_marshal(marshalled_deps))
57
+ gem_list.concat(Bundler.load_marshal(marshalled_deps))
54
58
  end
55
59
  gem_list
56
60
  end
@@ -60,7 +64,7 @@ module Bundler
60
64
  spec_list = []
61
65
 
62
66
  gem_list.each do |s|
63
- deps_list.push(*s[:dependencies].map(&:first))
67
+ deps_list.concat(s[:dependencies].map(&:first))
64
68
  deps = s[:dependencies].map {|n, d| [n, d.split(", ")] }
65
69
  spec_list.push([s[:name], s[:number], s[:platform], deps])
66
70
  end