bundler 2.1.1 → 2.2.0.rc.2

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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1543 -1418
  3. data/README.md +6 -8
  4. data/bundler.gemspec +3 -3
  5. data/exe/bundle +3 -0
  6. data/lib/bundler.rb +21 -7
  7. data/lib/bundler/build_metadata.rb +3 -11
  8. data/lib/bundler/cli.rb +54 -20
  9. data/lib/bundler/cli/add.rb +1 -1
  10. data/lib/bundler/cli/cache.rb +1 -7
  11. data/lib/bundler/cli/clean.rb +1 -1
  12. data/lib/bundler/cli/common.rb +14 -0
  13. data/lib/bundler/cli/console.rb +1 -1
  14. data/lib/bundler/cli/doctor.rb +1 -1
  15. data/lib/bundler/cli/exec.rb +1 -1
  16. data/lib/bundler/cli/fund.rb +36 -0
  17. data/lib/bundler/cli/gem.rb +84 -11
  18. data/lib/bundler/cli/info.rb +15 -4
  19. data/lib/bundler/cli/init.rb +2 -2
  20. data/lib/bundler/cli/inject.rb +1 -1
  21. data/lib/bundler/cli/install.rb +12 -18
  22. data/lib/bundler/cli/issue.rb +2 -2
  23. data/lib/bundler/cli/list.rb +12 -10
  24. data/lib/bundler/cli/outdated.rb +89 -66
  25. data/lib/bundler/cli/plugin.rb +10 -0
  26. data/lib/bundler/cli/pristine.rb +5 -0
  27. data/lib/bundler/cli/show.rb +1 -1
  28. data/lib/bundler/cli/update.rb +2 -0
  29. data/lib/bundler/compact_index_client.rb +1 -1
  30. data/lib/bundler/compact_index_client/cache.rb +1 -1
  31. data/lib/bundler/definition.rb +51 -60
  32. data/lib/bundler/dep_proxy.rb +1 -1
  33. data/lib/bundler/dependency.rb +0 -9
  34. data/lib/bundler/dsl.rb +5 -9
  35. data/lib/bundler/endpoint_specification.rb +1 -1
  36. data/lib/bundler/environment_preserver.rb +26 -2
  37. data/lib/bundler/errors.rb +1 -0
  38. data/lib/bundler/feature_flag.rb +0 -2
  39. data/lib/bundler/fetcher.rb +4 -3
  40. data/lib/bundler/fetcher/base.rb +1 -1
  41. data/lib/bundler/fetcher/compact_index.rb +1 -1
  42. data/lib/bundler/fetcher/downloader.rb +1 -1
  43. data/lib/bundler/fetcher/index.rb +1 -1
  44. data/lib/bundler/friendly_errors.rb +7 -13
  45. data/lib/bundler/gem_helper.rb +33 -19
  46. data/lib/bundler/gem_helpers.rb +6 -1
  47. data/lib/bundler/gem_version_promoter.rb +2 -2
  48. data/lib/bundler/graph.rb +1 -1
  49. data/lib/bundler/index.rb +1 -1
  50. data/lib/bundler/injector.rb +15 -4
  51. data/lib/bundler/inline.rb +2 -2
  52. data/lib/bundler/installer.rb +30 -29
  53. data/lib/bundler/installer/gem_installer.rb +3 -3
  54. data/lib/bundler/installer/parallel_installer.rb +10 -10
  55. data/lib/bundler/installer/standalone.rb +2 -2
  56. data/lib/bundler/lazy_specification.rb +19 -6
  57. data/lib/bundler/lockfile_generator.rb +1 -1
  58. data/lib/bundler/lockfile_parser.rb +1 -1
  59. data/lib/bundler/mirror.rb +2 -2
  60. data/lib/bundler/plugin.rb +30 -5
  61. data/lib/bundler/plugin/index.rb +10 -1
  62. data/lib/bundler/plugin/installer.rb +1 -1
  63. data/lib/bundler/plugin/installer/rubygems.rb +1 -1
  64. data/lib/bundler/plugin/source_list.rb +1 -1
  65. data/lib/bundler/psyched_yaml.rb +0 -15
  66. data/lib/bundler/remote_specification.rb +5 -2
  67. data/lib/bundler/resolver.rb +32 -9
  68. data/lib/bundler/resolver/spec_group.rb +27 -6
  69. data/lib/bundler/retry.rb +1 -1
  70. data/lib/bundler/ruby_version.rb +1 -1
  71. data/lib/bundler/rubygems_ext.rb +53 -9
  72. data/lib/bundler/rubygems_gem_installer.rb +3 -9
  73. data/lib/bundler/rubygems_integration.rb +23 -54
  74. data/lib/bundler/runtime.rb +4 -14
  75. data/lib/bundler/settings.rb +49 -45
  76. data/lib/bundler/shared_helpers.rb +2 -2
  77. data/lib/bundler/similarity_detector.rb +1 -1
  78. data/lib/bundler/source.rb +1 -1
  79. data/lib/bundler/source/git.rb +5 -5
  80. data/lib/bundler/source/git/git_proxy.rb +56 -59
  81. data/lib/bundler/source/path.rb +7 -3
  82. data/lib/bundler/source/path/installer.rb +8 -10
  83. data/lib/bundler/source/rubygems.rb +13 -16
  84. data/lib/bundler/source/rubygems/remote.rb +1 -1
  85. data/lib/bundler/source_list.rb +2 -2
  86. data/lib/bundler/spec_set.rb +1 -1
  87. data/lib/bundler/stub_specification.rb +17 -5
  88. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  89. data/lib/bundler/templates/newgem/Gemfile.tt +9 -1
  90. data/lib/bundler/templates/newgem/README.md.tt +1 -1
  91. data/lib/bundler/templates/newgem/Rakefile.tt +19 -5
  92. data/lib/bundler/templates/newgem/bin/console.tt +1 -0
  93. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  94. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  95. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +18 -0
  96. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  97. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +2 -0
  98. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  99. data/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -6
  100. data/lib/bundler/templates/newgem/rubocop.yml.tt +10 -0
  101. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  102. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -1
  103. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +2 -0
  104. data/lib/bundler/templates/newgem/test/{test_helper.rb.tt → minitest/test_helper.rb.tt} +2 -0
  105. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  106. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  107. data/lib/bundler/ui/shell.rb +5 -5
  108. data/lib/bundler/uri_credentials_filter.rb +1 -1
  109. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +79 -212
  110. data/lib/bundler/vendor/thor/lib/thor.rb +0 -7
  111. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  112. data/lib/bundler/vendor/thor/lib/thor/base.rb +9 -0
  113. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  114. data/lib/bundler/vendored_persistent.rb +0 -7
  115. data/lib/bundler/version.rb +1 -1
  116. data/lib/bundler/worker.rb +1 -1
  117. data/lib/bundler/yaml_serializer.rb +1 -1
  118. data/man/bundle-add.1 +1 -1
  119. data/man/{bundle-add.ronn → bundle-add.1.ronn} +0 -0
  120. data/man/bundle-binstubs.1 +5 -3
  121. data/man/{bundle-binstubs.ronn → bundle-binstubs.1.ronn} +2 -4
  122. data/man/bundle-cache.1 +1 -1
  123. data/man/{bundle-cache.ronn → bundle-cache.1.ronn} +0 -0
  124. data/man/bundle-check.1 +1 -1
  125. data/man/{bundle-check.ronn → bundle-check.1.ronn} +0 -0
  126. data/man/bundle-clean.1 +1 -1
  127. data/man/{bundle-clean.ronn → bundle-clean.1.ronn} +0 -0
  128. data/man/bundle-config.1 +16 -22
  129. data/man/{bundle-config.ronn → bundle-config.1.ronn} +19 -22
  130. data/man/bundle-doctor.1 +1 -1
  131. data/man/{bundle-doctor.ronn → bundle-doctor.1.ronn} +0 -0
  132. data/man/bundle-exec.1 +1 -1
  133. data/man/{bundle-exec.ronn → bundle-exec.1.ronn} +0 -0
  134. data/man/bundle-gem.1 +25 -3
  135. data/man/{bundle-gem.ronn → bundle-gem.1.ronn} +30 -7
  136. data/man/bundle-info.1 +1 -1
  137. data/man/{bundle-info.ronn → bundle-info.1.ronn} +0 -0
  138. data/man/bundle-init.1 +1 -1
  139. data/man/{bundle-init.ronn → bundle-init.1.ronn} +0 -0
  140. data/man/bundle-inject.1 +1 -1
  141. data/man/{bundle-inject.ronn → bundle-inject.1.ronn} +0 -0
  142. data/man/bundle-install.1 +29 -2
  143. data/man/{bundle-install.ronn → bundle-install.1.ronn} +24 -2
  144. data/man/bundle-list.1 +7 -7
  145. data/man/{bundle-list.ronn → bundle-list.1.ronn} +6 -6
  146. data/man/bundle-lock.1 +1 -1
  147. data/man/{bundle-lock.ronn → bundle-lock.1.ronn} +0 -0
  148. data/man/bundle-open.1 +1 -1
  149. data/man/{bundle-open.ronn → bundle-open.1.ronn} +0 -0
  150. data/man/bundle-outdated.1 +1 -1
  151. data/man/{bundle-outdated.ronn → bundle-outdated.1.ronn} +0 -0
  152. data/man/bundle-platform.1 +1 -1
  153. data/man/{bundle-platform.ronn → bundle-platform.1.ronn} +0 -0
  154. data/man/bundle-pristine.1 +1 -1
  155. data/man/{bundle-pristine.ronn → bundle-pristine.1.ronn} +0 -0
  156. data/man/bundle-remove.1 +1 -1
  157. data/man/{bundle-remove.ronn → bundle-remove.1.ronn} +0 -0
  158. data/man/bundle-show.1 +1 -1
  159. data/man/{bundle-show.ronn → bundle-show.1.ronn} +0 -0
  160. data/man/bundle-update.1 +1 -1
  161. data/man/{bundle-update.ronn → bundle-update.1.ronn} +0 -0
  162. data/man/bundle-viz.1 +1 -1
  163. data/man/{bundle-viz.ronn → bundle-viz.1.ronn} +0 -0
  164. data/man/bundle.1 +1 -1
  165. data/man/{bundle.ronn → bundle.1.ronn} +0 -0
  166. data/man/gemfile.5 +4 -4
  167. data/man/gemfile.5.ronn +4 -4
  168. metadata +39 -58
  169. data/man/bundle-add.1.txt +0 -58
  170. data/man/bundle-binstubs.1.txt +0 -48
  171. data/man/bundle-cache.1.txt +0 -78
  172. data/man/bundle-check.1.txt +0 -33
  173. data/man/bundle-clean.1.txt +0 -26
  174. data/man/bundle-config.1.txt +0 -528
  175. data/man/bundle-doctor.1.txt +0 -44
  176. data/man/bundle-exec.1.txt +0 -178
  177. data/man/bundle-gem.1.txt +0 -91
  178. data/man/bundle-info.1.txt +0 -21
  179. data/man/bundle-init.1.txt +0 -34
  180. data/man/bundle-inject.1.txt +0 -32
  181. data/man/bundle-install.1.txt +0 -401
  182. data/man/bundle-list.1.txt +0 -43
  183. data/man/bundle-lock.1.txt +0 -93
  184. data/man/bundle-open.1.txt +0 -29
  185. data/man/bundle-outdated.1.txt +0 -131
  186. data/man/bundle-platform.1.txt +0 -57
  187. data/man/bundle-pristine.1.txt +0 -44
  188. data/man/bundle-remove.1.txt +0 -34
  189. data/man/bundle-show.1.txt +0 -27
  190. data/man/bundle-update.1.txt +0 -390
  191. data/man/bundle-viz.1.txt +0 -39
  192. data/man/bundle.1.txt +0 -116
  193. data/man/gemfile.5.txt +0 -649
  194. data/man/index.txt +0 -25
@@ -19,15 +19,15 @@ module Bundler
19
19
  Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
20
20
  generate_executable_stubs
21
21
  return true, post_install_message
22
- rescue Bundler::InstallHookError, Bundler::SecurityError, APIResponseMismatchError
22
+ rescue Bundler::InstallHookError, Bundler::SecurityError, Bundler::APIResponseMismatchError
23
23
  raise
24
24
  rescue Errno::ENOSPC
25
25
  return false, out_of_space_message
26
- rescue StandardError => e
26
+ rescue Bundler::BundlerError, Gem::InstallError, Bundler::APIResponseInvalidDependenciesError => e
27
27
  return false, specific_failure_message(e)
28
28
  end
29
29
 
30
- private
30
+ private
31
31
 
32
32
  def specific_failure_message(e)
33
33
  message = "#{e.class}: #{e.message}\n"
@@ -99,7 +99,7 @@ module Bundler
99
99
  install_serially
100
100
  end
101
101
 
102
- handle_error if @specs.any?(&:failed?)
102
+ handle_error if failed_specs.any?
103
103
  @specs
104
104
  ensure
105
105
  worker_pool && worker_pool.stop
@@ -130,7 +130,11 @@ module Bundler
130
130
  Bundler.ui.warn(warning.join("\n"))
131
131
  end
132
132
 
133
- private
133
+ private
134
+
135
+ def failed_specs
136
+ @specs.select(&:failed?)
137
+ end
134
138
 
135
139
  def install_with_worker
136
140
  enqueue_specs
@@ -156,17 +160,13 @@ module Bundler
156
160
  gem_installer = Bundler::GemInstaller.new(
157
161
  spec_install.spec, @installer, @standalone, worker_num, @force
158
162
  )
159
- success, message = begin
160
- gem_installer.install_from_spec
161
- rescue RuntimeError => e
162
- raise e, "#{e}\n\n#{require_tree_for_spec(spec_install.spec)}"
163
- end
163
+ success, message = gem_installer.install_from_spec
164
164
  if success
165
165
  spec_install.state = :installed
166
166
  spec_install.post_install_message = message unless message.nil?
167
167
  else
168
- spec_install.state = :failed
169
168
  spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
169
+ spec_install.state = :failed
170
170
  end
171
171
  Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL, spec_install)
172
172
  spec_install
@@ -190,11 +190,11 @@ module Bundler
190
190
  end
191
191
 
192
192
  def handle_error
193
- errors = @specs.select(&:failed?).map(&:error)
193
+ errors = failed_specs.map(&:error)
194
194
  if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
195
195
  raise exception
196
196
  end
197
- raise Bundler::InstallError, errors.map(&:to_s).join("\n\n")
197
+ raise Bundler::InstallError, errors.join("\n\n")
198
198
  end
199
199
 
200
200
  def require_tree_for_spec(spec)
@@ -16,12 +16,12 @@ module Bundler
16
16
  file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
17
17
  file.puts "path = File.expand_path('..', __FILE__)"
18
18
  paths.each do |path|
19
- file.puts %($:.unshift "\#{path}/#{path}")
19
+ file.puts %($:.unshift File.expand_path("\#{path}/#{path}"))
20
20
  end
21
21
  end
22
22
  end
23
23
 
24
- private
24
+ private
25
25
 
26
26
  def paths
27
27
  @specs.map do |spec|
@@ -12,7 +12,7 @@ module Bundler
12
12
  [name, version, platform_string] <=> [other.name, other.version, other.platform_string]
13
13
  end
14
14
 
15
- protected
15
+ protected
16
16
 
17
17
  def platform_string
18
18
  platform_string = platform.to_s
@@ -46,6 +46,14 @@ module Bundler
46
46
  identifier == other.identifier
47
47
  end
48
48
 
49
+ def eql?(other)
50
+ identifier.eql?(other.identifier)
51
+ end
52
+
53
+ def hash
54
+ identifier.hash
55
+ end
56
+
49
57
  def satisfies?(dependency)
50
58
  @name == dependency.name && dependency.requirement.satisfied_by?(Gem::Version.new(@version))
51
59
  end
@@ -68,15 +76,20 @@ module Bundler
68
76
  end
69
77
 
70
78
  def __materialize__
71
- search_object = Bundler.feature_flag.specific_platform? || Bundler.settings[:force_ruby_platform] ? self : Dependency.new(name, version)
72
79
  @specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name
73
80
  source.gemspec.tap {|s| s.source = source }
74
81
  else
75
- search = source.specs.search(search_object).last
76
- if search && Gem::Platform.new(search.platform) != Gem::Platform.new(platform) && !search.runtime_dependencies.-(dependencies.reject {|d| d.type == :development }).empty?
82
+ search_object = Bundler.feature_flag.specific_platform? || Bundler.settings[:force_ruby_platform] ? self : Dependency.new(name, version)
83
+ platform_object = Gem::Platform.new(platform)
84
+ candidates = source.specs.search(search_object)
85
+ same_platform_candidates = candidates.select do |spec|
86
+ MatchPlatform.platforms_match?(spec.platform, platform_object)
87
+ end
88
+ search = same_platform_candidates.last || candidates.last
89
+ if search && Gem::Platform.new(search.platform) != platform_object && !search.runtime_dependencies.-(dependencies.reject {|d| d.type == :development }).empty?
77
90
  Bundler.ui.warn "Unable to use the platform-specific (#{search.platform}) version of #{name} (#{version}) " \
78
91
  "because it has different dependencies from the #{platform} version. " \
79
- "To use the platform-specific version of the gem, run `bundle config set specific_platform true` and install again."
92
+ "To use the platform-specific version of the gem, run `bundle config set --local specific_platform true` and install again."
80
93
  search = source.specs.search(self).last
81
94
  end
82
95
  search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
@@ -105,7 +118,7 @@ module Bundler
105
118
  " #{source.revision[0..6]}"
106
119
  end
107
120
 
108
- private
121
+ private
109
122
 
110
123
  def to_ary
111
124
  nil
@@ -25,7 +25,7 @@ module Bundler
25
25
  out
26
26
  end
27
27
 
28
- private
28
+ private
29
29
 
30
30
  def add_sources
31
31
  definition.send(:sources).lock_sources.each_with_index do |source, idx|
@@ -109,7 +109,7 @@ module Bundler
109
109
  "bundler:#{bundler_version}#{prerelease_text}`.\n"
110
110
  end
111
111
 
112
- private
112
+ private
113
113
 
114
114
  TYPES = {
115
115
  GIT => Bundler::Source::Git,
@@ -43,7 +43,7 @@ module Bundler
43
43
  config.update_mirror(mirror)
44
44
  end
45
45
 
46
- private
46
+ private
47
47
 
48
48
  def fetch_valid_mirror_for(uri)
49
49
  downcased = uri.to_s.downcase
@@ -158,7 +158,7 @@ module Bundler
158
158
  end
159
159
  end
160
160
 
161
- private
161
+ private
162
162
 
163
163
  def wait_for_writtable_socket(socket, address, timeout)
164
164
  if IO.select(nil, [socket], nil, timeout)
@@ -16,7 +16,7 @@ module Bundler
16
16
 
17
17
  PLUGIN_FILE_NAME = "plugins.rb".freeze
18
18
 
19
- module_function
19
+ module_function
20
20
 
21
21
  def reset!
22
22
  instance_variables.each {|i| remove_instance_variable(i) }
@@ -39,12 +39,37 @@ module Bundler
39
39
 
40
40
  save_plugins names, specs
41
41
  rescue PluginError => e
42
- if specs
43
- specs_to_delete = Hash[specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }]
44
- specs_to_delete.values.each {|spec| Bundler.rm_rf(spec.full_gem_path) }
42
+ specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }
43
+ specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) }
44
+
45
+ names_list = names.map {|name| "`#{name}`" }.join(", ")
46
+ Bundler.ui.error "Failed to install the following plugins: #{names_list}. The underlying error was: #{e.message}.\n #{e.backtrace.join("\n ")}"
47
+ end
48
+
49
+ # Uninstalls plugins by the given names
50
+ #
51
+ # @param [Array<String>] names the names of plugins to be uninstalled
52
+ def uninstall(names, options)
53
+ if names.empty? && !options[:all]
54
+ Bundler.ui.error "No plugins to uninstall. Specify at least 1 plugin to uninstall.\n"\
55
+ "Use --all option to uninstall all the installed plugins."
56
+ return
45
57
  end
46
58
 
47
- Bundler.ui.error "Failed to install plugin #{name}: #{e.message}\n #{e.backtrace.join("\n ")}"
59
+ names = index.installed_plugins if options[:all]
60
+ if names.any?
61
+ names.each do |name|
62
+ if index.installed?(name)
63
+ Bundler.rm_rf(index.plugin_path(name))
64
+ index.unregister_plugin(name)
65
+ Bundler.ui.info "Uninstalled plugin #{name}"
66
+ else
67
+ Bundler.ui.error "Plugin #{name} is not installed \n"
68
+ end
69
+ end
70
+ else
71
+ Bundler.ui.info "No plugins installed"
72
+ end
48
73
  end
49
74
 
50
75
  # List installed plugins and commands
@@ -71,6 +71,15 @@ module Bundler
71
71
  raise
72
72
  end
73
73
 
74
+ def unregister_plugin(name)
75
+ @commands.delete_if {|_, v| v == name }
76
+ @sources.delete_if {|_, v| v == name }
77
+ @hooks.each {|_, plugin_names| plugin_names.delete(name) }
78
+ @plugin_paths.delete(name)
79
+ @load_paths.delete(name)
80
+ save_index
81
+ end
82
+
74
83
  # Path of default index file
75
84
  def index_file
76
85
  Plugin.root.join("index")
@@ -124,7 +133,7 @@ module Bundler
124
133
  @hooks[event] || []
125
134
  end
126
135
 
127
- private
136
+ private
128
137
 
129
138
  # Reads the index file from the directory and initializes the instance
130
139
  # variables.
@@ -41,7 +41,7 @@ module Bundler
41
41
  install_from_specs specs
42
42
  end
43
43
 
44
- private
44
+ private
45
45
 
46
46
  def check_sources_consistency!(options)
47
47
  if options.key?(:git) && options.key?(:local_git)
@@ -8,7 +8,7 @@ module Bundler
8
8
  "#{spec.name} #{spec.version}"
9
9
  end
10
10
 
11
- private
11
+ private
12
12
 
13
13
  def requires_sudo?
14
14
  false # Will change on implementation of project level plugins
@@ -17,7 +17,7 @@ module Bundler
17
17
  path_sources + git_sources + rubygems_sources + [metadata_source]
18
18
  end
19
19
 
20
- private
20
+ private
21
21
 
22
22
  def rubygems_aggregate_class
23
23
  Plugin::Installer::Rubygems
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Psych could be a gem, so try to ask for it
4
- begin
5
- gem "psych"
6
- rescue LoadError
7
- end if defined?(gem)
8
-
9
3
  # Psych could be in the stdlib
10
4
  # but it's too late if Syck is already loaded
11
5
  begin
@@ -26,12 +20,3 @@ module Bundler
26
20
  YamlLibrarySyntaxError = ::ArgumentError
27
21
  end
28
22
  end
29
-
30
- require_relative "deprecate"
31
- begin
32
- Bundler::Deprecate.skip_during do
33
- require "rubygems/safe_yaml"
34
- end
35
- rescue LoadError
36
- # it's OK if the file isn't there
37
- end
@@ -50,6 +50,8 @@ module Bundler
50
50
  # once the remote gem is downloaded, the backend specification will
51
51
  # be swapped out.
52
52
  def __swap__(spec)
53
+ raise APIResponseInvalidDependenciesError unless spec.dependencies.all? {|d| d.is_a?(Gem::Dependency) }
54
+
53
55
  SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
54
56
  @_remote_specification = spec
55
57
  end
@@ -76,7 +78,8 @@ module Bundler
76
78
  deps = method_missing(:dependencies)
77
79
 
78
80
  # allow us to handle when the specs dependencies are an array of array of string
79
- # see https://github.com/bundler/bundler/issues/5797
81
+ # in order to delay the crash to `#__swap__` where it results in a friendlier error
82
+ # see https://github.com/rubygems/bundler/issues/5797
80
83
  deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) }
81
84
 
82
85
  deps
@@ -88,7 +91,7 @@ module Bundler
88
91
  " #{source.revision[0..6]}"
89
92
  end
90
93
 
91
- private
94
+ private
92
95
 
93
96
  def to_ary
94
97
  nil
@@ -75,12 +75,17 @@ module Bundler
75
75
  return unless debug?
76
76
  debug_info = yield
77
77
  debug_info = debug_info.inspect unless debug_info.is_a?(String)
78
- warn debug_info.split("\n").map {|s| " " * depth + s }
78
+ warn debug_info.split("\n").map {|s| "BUNDLER: " + " " * depth + s }
79
79
  end
80
80
 
81
81
  def debug?
82
82
  return @debug_mode if defined?(@debug_mode)
83
- @debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
83
+ @debug_mode =
84
+ ENV["BUNDLER_DEBUG_RESOLVER"] ||
85
+ ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
86
+ ENV["DEBUG_RESOLVER"] ||
87
+ ENV["DEBUG_RESOLVER_TREE"] ||
88
+ false
84
89
  end
85
90
 
86
91
  def before_resolution
@@ -146,7 +151,26 @@ module Bundler
146
151
  @gem_version_promoter.sort_versions(dependency, spec_groups)
147
152
  end
148
153
  end
149
- search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
154
+ selected_sgs = []
155
+ search.each do |sg|
156
+ next unless sg.for?(platform)
157
+ # Add a spec group for "non platform specific spec" as the fallback
158
+ # spec group.
159
+ sg_ruby = sg.copy_for(Gem::Platform::RUBY)
160
+ selected_sgs << sg_ruby if sg_ruby
161
+ all_platforms = @platforms + [platform]
162
+ next if all_platforms.to_a == [Gem::Platform::RUBY]
163
+ sg_all_platforms = nil
164
+ self.class.sort_platforms(all_platforms).reverse_each do |other_platform|
165
+ if sg_all_platforms.nil?
166
+ sg_all_platforms = sg.copy_for(other_platform)
167
+ else
168
+ sg_all_platforms.activate_platform!(other_platform)
169
+ end
170
+ end
171
+ selected_sgs << sg_all_platforms
172
+ end
173
+ selected_sgs
150
174
  end
151
175
 
152
176
  def index_for(dependency)
@@ -183,9 +207,7 @@ module Bundler
183
207
  end
184
208
 
185
209
  def requirement_satisfied_by?(requirement, activated, spec)
186
- return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
187
- spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
188
- true
210
+ requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
189
211
  end
190
212
 
191
213
  def relevant_sources_for_vertex(vertex)
@@ -223,11 +245,12 @@ module Bundler
223
245
  end
224
246
 
225
247
  def self.platform_sort_key(platform)
226
- return ["", "", ""] if Gem::Platform::RUBY == platform
227
- platform.to_a.map {|part| part || "" }
248
+ # Prefer specific platform to not specific platform
249
+ return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
250
+ ["00", *platform.to_a.map {|part| part || "" }]
228
251
  end
229
252
 
230
- private
253
+ private
231
254
 
232
255
  # returns an integer \in (-\infty, 0]
233
256
  # a number closer to 0 means the dependency is less constraining
@@ -9,6 +9,7 @@ module Bundler
9
9
  attr_accessor :ignores_bundler_dependencies
10
10
 
11
11
  def initialize(all_specs)
12
+ @all_specs = all_specs
12
13
  raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
13
14
  @name = exemplary_spec.name
14
15
  @version = exemplary_spec.version
@@ -28,7 +29,7 @@ module Bundler
28
29
  lazy_spec = LazySpecification.new(name, version, s.platform, source)
29
30
  lazy_spec.dependencies.replace s.dependencies
30
31
  lazy_spec
31
- end.compact
32
+ end.compact.uniq
32
33
  end
33
34
 
34
35
  def activate_platform!(platform)
@@ -37,13 +38,25 @@ module Bundler
37
38
  @activated_platforms << platform
38
39
  end
39
40
 
41
+ def copy_for(platform)
42
+ copied_sg = self.class.new(@all_specs)
43
+ copied_sg.ignores_bundler_dependencies = @ignores_bundler_dependencies
44
+ return nil unless copied_sg.for?(platform)
45
+ copied_sg.activate_platform!(platform)
46
+ copied_sg
47
+ end
48
+
49
+ def spec_for(platform)
50
+ @specs[platform]
51
+ end
52
+
40
53
  def for?(platform)
41
- spec = @specs[platform]
42
- !spec.nil?
54
+ !spec_for(platform).nil?
43
55
  end
44
56
 
45
57
  def to_s
46
- @to_s ||= "#{name} (#{version})"
58
+ activated_platforms_string = sorted_activated_platforms.join(", ")
59
+ "#{name} (#{version}) (#{activated_platforms_string})"
47
60
  end
48
61
 
49
62
  def dependencies_for_activated_platforms
@@ -58,6 +71,7 @@ module Bundler
58
71
  return unless other.is_a?(SpecGroup)
59
72
  name == other.name &&
60
73
  version == other.version &&
74
+ sorted_activated_platforms == other.sorted_activated_platforms &&
61
75
  source == other.source
62
76
  end
63
77
 
@@ -65,14 +79,21 @@ module Bundler
65
79
  return unless other.is_a?(SpecGroup)
66
80
  name.eql?(other.name) &&
67
81
  version.eql?(other.version) &&
82
+ sorted_activated_platforms.eql?(other.sorted_activated_platforms) &&
68
83
  source.eql?(other.source)
69
84
  end
70
85
 
71
86
  def hash
72
- to_s.hash ^ source.hash
87
+ name.hash ^ version.hash ^ sorted_activated_platforms.hash ^ source.hash
88
+ end
89
+
90
+ protected
91
+
92
+ def sorted_activated_platforms
93
+ @activated_platforms.sort_by(&:to_s)
73
94
  end
74
95
 
75
- private
96
+ private
76
97
 
77
98
  def __dependencies
78
99
  @dependencies = Hash.new do |dependencies, platform|