bundler 1.7.15 → 1.8.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 (191) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -14
  3. data/.rspec +1 -0
  4. data/.travis.yml +22 -15
  5. data/CHANGELOG.md +43 -13
  6. data/CODE_OF_CONDUCT.md +40 -0
  7. data/CONTRIBUTING.md +14 -12
  8. data/DEVELOPMENT.md +4 -2
  9. data/ISSUES.md +1 -1
  10. data/README.md +10 -14
  11. data/Rakefile +10 -10
  12. data/bin/bundle +1 -1
  13. data/bundler.gemspec +5 -4
  14. data/lib/bundler.rb +22 -3
  15. data/lib/bundler/anonymizable_uri.rb +24 -8
  16. data/lib/bundler/cli.rb +103 -66
  17. data/lib/bundler/cli/cache.rb +1 -0
  18. data/lib/bundler/cli/clean.rb +11 -4
  19. data/lib/bundler/cli/common.rb +2 -0
  20. data/lib/bundler/cli/console.rb +22 -26
  21. data/lib/bundler/cli/exec.rb +29 -22
  22. data/lib/bundler/cli/gem.rb +125 -37
  23. data/lib/bundler/cli/install.rb +22 -9
  24. data/lib/bundler/cli/outdated.rb +1 -1
  25. data/lib/bundler/cli/package.rb +8 -1
  26. data/lib/bundler/cli/show.rb +29 -3
  27. data/lib/bundler/cli/update.rb +2 -2
  28. data/lib/bundler/cli/viz.rb +1 -1
  29. data/lib/bundler/definition.rb +14 -22
  30. data/lib/bundler/dependency.rb +8 -1
  31. data/lib/bundler/dsl.rb +17 -4
  32. data/lib/bundler/endpoint_specification.rb +1 -1
  33. data/lib/bundler/env.rb +44 -25
  34. data/lib/bundler/fetcher.rb +33 -25
  35. data/lib/bundler/friendly_errors.rb +38 -5
  36. data/lib/bundler/gem_helper.rb +16 -10
  37. data/lib/bundler/gem_helpers.rb +1 -0
  38. data/lib/bundler/graph.rb +4 -1
  39. data/lib/bundler/index.rb +15 -25
  40. data/lib/bundler/installer.rb +6 -6
  41. data/lib/bundler/lockfile_parser.rb +7 -7
  42. data/lib/bundler/resolver.rb +2 -1
  43. data/lib/bundler/ruby_version.rb +1 -1
  44. data/lib/bundler/rubygems_ext.rb +1 -0
  45. data/lib/bundler/rubygems_integration.rb +1 -1
  46. data/lib/bundler/runtime.rb +22 -40
  47. data/lib/bundler/settings.rb +14 -5
  48. data/lib/bundler/setup.rb +2 -1
  49. data/lib/bundler/shared_helpers.rb +56 -4
  50. data/lib/bundler/source.rb +8 -9
  51. data/lib/bundler/source/git.rb +5 -1
  52. data/lib/bundler/source/git/git_proxy.rb +4 -0
  53. data/lib/bundler/source/path.rb +8 -11
  54. data/lib/bundler/source/path/installer.rb +0 -2
  55. data/lib/bundler/source/rubygems.rb +58 -72
  56. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +13 -0
  57. data/lib/bundler/templates/newgem/LICENSE.txt.tt +17 -18
  58. data/lib/bundler/templates/newgem/README.md.tt +9 -1
  59. data/lib/bundler/templates/newgem/Rakefile.tt +2 -0
  60. data/lib/bundler/templates/newgem/bin/console.tt +14 -0
  61. data/lib/bundler/templates/newgem/bin/setup.tt +7 -0
  62. data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  63. data/lib/bundler/templates/newgem/gitignore.tt +2 -0
  64. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +1 -1
  65. data/lib/bundler/templates/newgem/newgem.gemspec.tt +17 -13
  66. data/lib/bundler/templates/newgem/test/test_newgem.rb.tt +1 -1
  67. data/lib/bundler/ui/shell.rb +1 -1
  68. data/lib/bundler/version.rb +1 -1
  69. data/lib/bundler/worker.rb +73 -0
  70. data/man/bundle-config.ronn +17 -15
  71. data/man/bundle-install.ronn +102 -93
  72. data/man/bundle-update.ronn +39 -30
  73. data/man/bundle.ronn +6 -0
  74. data/man/gemfile.5.ronn +74 -13
  75. metadata +10 -231
  76. data/lib/bundler/parallel_workers.rb +0 -18
  77. data/lib/bundler/parallel_workers/thread_worker.rb +0 -30
  78. data/lib/bundler/parallel_workers/unix_worker.rb +0 -101
  79. data/lib/bundler/parallel_workers/worker.rb +0 -69
  80. data/lib/bundler/templates/newgem/bin/newgem.tt +0 -3
  81. data/spec/bundler/anonymizable_uri_spec.rb +0 -32
  82. data/spec/bundler/bundler_spec.rb +0 -72
  83. data/spec/bundler/cli_spec.rb +0 -16
  84. data/spec/bundler/definition_spec.rb +0 -22
  85. data/spec/bundler/dsl_spec.rb +0 -82
  86. data/spec/bundler/friendly_errors_spec.rb +0 -13
  87. data/spec/bundler/gem_helper_spec.rb +0 -226
  88. data/spec/bundler/psyched_yaml_spec.rb +0 -8
  89. data/spec/bundler/retry_spec.rb +0 -59
  90. data/spec/bundler/settings_spec.rb +0 -13
  91. data/spec/bundler/source/rubygems_spec.rb +0 -25
  92. data/spec/bundler/source_list_spec.rb +0 -361
  93. data/spec/cache/gems_spec.rb +0 -284
  94. data/spec/cache/git_spec.rb +0 -188
  95. data/spec/cache/path_spec.rb +0 -121
  96. data/spec/cache/platform_spec.rb +0 -57
  97. data/spec/commands/binstubs_spec.rb +0 -219
  98. data/spec/commands/check_spec.rb +0 -278
  99. data/spec/commands/clean_spec.rb +0 -592
  100. data/spec/commands/config_spec.rb +0 -263
  101. data/spec/commands/console_spec.rb +0 -76
  102. data/spec/commands/exec_spec.rb +0 -309
  103. data/spec/commands/help_spec.rb +0 -39
  104. data/spec/commands/init_spec.rb +0 -39
  105. data/spec/commands/inject_spec.rb +0 -78
  106. data/spec/commands/licenses_spec.rb +0 -18
  107. data/spec/commands/newgem_spec.rb +0 -428
  108. data/spec/commands/open_spec.rb +0 -68
  109. data/spec/commands/outdated_spec.rb +0 -156
  110. data/spec/commands/package_spec.rb +0 -114
  111. data/spec/commands/show_spec.rb +0 -125
  112. data/spec/install/binstubs_spec.rb +0 -24
  113. data/spec/install/bundler_spec.rb +0 -146
  114. data/spec/install/deploy_spec.rb +0 -250
  115. data/spec/install/gemfile/gemspec_spec.rb +0 -170
  116. data/spec/install/gemfile/git_spec.rb +0 -967
  117. data/spec/install/gemfile/path_spec.rb +0 -500
  118. data/spec/install/gemfile_spec.rb +0 -44
  119. data/spec/install/gems/c_ext_spec.rb +0 -48
  120. data/spec/install/gems/dependency_api_spec.rb +0 -652
  121. data/spec/install/gems/env_spec.rb +0 -107
  122. data/spec/install/gems/flex_spec.rb +0 -314
  123. data/spec/install/gems/groups_spec.rb +0 -308
  124. data/spec/install/gems/mirror_spec.rb +0 -39
  125. data/spec/install/gems/platform_spec.rb +0 -195
  126. data/spec/install/gems/post_install_spec.rb +0 -121
  127. data/spec/install/gems/resolving_spec.rb +0 -124
  128. data/spec/install/gems/simple_case_spec.rb +0 -377
  129. data/spec/install/gems/sources_spec.rb +0 -386
  130. data/spec/install/gems/standalone_spec.rb +0 -260
  131. data/spec/install/gems/sudo_spec.rb +0 -136
  132. data/spec/install/gems/win32_spec.rb +0 -26
  133. data/spec/install/gemspecs_spec.rb +0 -50
  134. data/spec/install/path_spec.rb +0 -150
  135. data/spec/install/post_bundle_message_spec.rb +0 -142
  136. data/spec/install/prereleases_spec.rb +0 -43
  137. data/spec/install/security_policy_spec.rb +0 -77
  138. data/spec/install/upgrade_spec.rb +0 -26
  139. data/spec/lock/git_spec.rb +0 -34
  140. data/spec/lock/lockfile_spec.rb +0 -924
  141. data/spec/other/bundle_ruby_spec.rb +0 -142
  142. data/spec/other/cli_dispatch_spec.rb +0 -21
  143. data/spec/other/ext_spec.rb +0 -60
  144. data/spec/other/platform_spec.rb +0 -1285
  145. data/spec/other/ssl_cert_spec.rb +0 -23
  146. data/spec/quality_spec.rb +0 -88
  147. data/spec/realworld/dependency_api_spec.rb +0 -60
  148. data/spec/realworld/edgecases_spec.rb +0 -212
  149. data/spec/realworld/parallel_spec.rb +0 -71
  150. data/spec/resolver/basic_spec.rb +0 -66
  151. data/spec/resolver/platform_spec.rb +0 -88
  152. data/spec/runtime/executable_spec.rb +0 -149
  153. data/spec/runtime/load_spec.rb +0 -107
  154. data/spec/runtime/platform_spec.rb +0 -90
  155. data/spec/runtime/require_spec.rb +0 -332
  156. data/spec/runtime/setup_spec.rb +0 -853
  157. data/spec/runtime/with_clean_env_spec.rb +0 -91
  158. data/spec/spec_helper.rb +0 -123
  159. data/spec/support/artifice/endopint_marshal_fail_basic_authentication.rb +0 -13
  160. data/spec/support/artifice/endpoint.rb +0 -71
  161. data/spec/support/artifice/endpoint_500.rb +0 -37
  162. data/spec/support/artifice/endpoint_api_forbidden.rb +0 -11
  163. data/spec/support/artifice/endpoint_api_missing.rb +0 -16
  164. data/spec/support/artifice/endpoint_basic_authentication.rb +0 -13
  165. data/spec/support/artifice/endpoint_creds_diff_host.rb +0 -38
  166. data/spec/support/artifice/endpoint_extra.rb +0 -31
  167. data/spec/support/artifice/endpoint_extra_api.rb +0 -32
  168. data/spec/support/artifice/endpoint_extra_missing.rb +0 -15
  169. data/spec/support/artifice/endpoint_fallback.rb +0 -17
  170. data/spec/support/artifice/endpoint_host_redirect.rb +0 -15
  171. data/spec/support/artifice/endpoint_marshal_fail.rb +0 -11
  172. data/spec/support/artifice/endpoint_redirect.rb +0 -15
  173. data/spec/support/artifice/endpoint_strict_basic_authentication.rb +0 -18
  174. data/spec/support/artifice/endpoint_timeout.rb +0 -13
  175. data/spec/support/builders.rb +0 -693
  176. data/spec/support/fakeweb/rack-1.0.0.marshal +0 -2
  177. data/spec/support/fakeweb/windows.rb +0 -23
  178. data/spec/support/hax.rb +0 -22
  179. data/spec/support/helpers.rb +0 -361
  180. data/spec/support/indexes.rb +0 -280
  181. data/spec/support/matchers.rb +0 -77
  182. data/spec/support/path.rb +0 -85
  183. data/spec/support/permissions.rb +0 -10
  184. data/spec/support/platforms.rb +0 -94
  185. data/spec/support/ruby_ext.rb +0 -20
  186. data/spec/support/rubygems_ext.rb +0 -39
  187. data/spec/support/streams.rb +0 -13
  188. data/spec/support/sudo.rb +0 -16
  189. data/spec/update/gems_spec.rb +0 -201
  190. data/spec/update/git_spec.rb +0 -283
  191. data/spec/update/path_spec.rb +0 -18
@@ -9,6 +9,8 @@ module Bundler
9
9
  def run
10
10
  Bundler.ui.level = "error" if options[:quiet]
11
11
  Bundler.settings[:path] = File.expand_path(options[:path]) if options[:path]
12
+ Bundler.settings[:cache_all_platforms] = options["all-platforms"] if options.key?("all-platforms")
13
+ Bundler.settings[:cache_path] = options["cache-path"] if options.key?("cache-path")
12
14
 
13
15
  setup_cache_all
14
16
  install
@@ -22,7 +24,12 @@ module Bundler
22
24
 
23
25
  def install
24
26
  require 'bundler/cli/install'
25
- Bundler::CLI::Install.new(options.dup).run
27
+ options = self.options.dup
28
+ if Bundler.settings[:cache_all_platforms]
29
+ options["local"] = false
30
+ options["update"] = true
31
+ end
32
+ Bundler::CLI::Install.new(options).run
26
33
  end
27
34
 
28
35
  def setup_cache_all
@@ -2,10 +2,12 @@ require 'bundler/cli/common'
2
2
 
3
3
  module Bundler
4
4
  class CLI::Show
5
- attr_reader :options, :gem_name
5
+ attr_reader :options, :gem_name, :latest_specs
6
6
  def initialize(options, gem_name)
7
7
  @options = options
8
8
  @gem_name = gem_name
9
+ @verbose = options[:verbose] || options[:outdated]
10
+ @latest_specs = fetch_latest_specs if @verbose
9
11
  end
10
12
 
11
13
  def run
@@ -36,13 +38,37 @@ module Bundler
36
38
  Bundler.ui.info "Gems included by the bundle:"
37
39
  Bundler.load.specs.sort_by { |s| s.name }.each do |s|
38
40
  desc = " * #{s.name} (#{s.version}#{s.git_version})"
39
- if @options[:verbose]
40
- Bundler.ui.info "#{desc} - #{s.summary || 'No description available.'}"
41
+ if @verbose
42
+ latest = latest_specs.find { |l| l.name == s.name }
43
+ Bundler.ui.info <<-END.gsub(/^ +/, '')
44
+ #{desc}
45
+ \tSummary: #{s.summary || 'No description available.'}
46
+ \tHomepage: #{s.homepage || 'No website available.'}
47
+ \tStatus: #{outdated?(s, latest) ? "Outdated - #{s.version} < #{latest.version}" : "Up to date"}
48
+ END
41
49
  else
42
50
  Bundler.ui.info desc
43
51
  end
44
52
  end
45
53
  end
46
54
  end
55
+
56
+ private
57
+
58
+ def fetch_latest_specs
59
+ definition = Bundler.definition(true)
60
+ if options[:outdated]
61
+ Bundler.ui.info "Fetching remote specs for outdated check...\n\n"
62
+ Bundler.ui.silence { definition.resolve_remotely! }
63
+ else
64
+ definition.resolve_with_cache!
65
+ end
66
+ definition.specs
67
+ end
68
+
69
+ def outdated?(current, latest)
70
+ return false unless latest
71
+ Gem::Version.new(current.version) < Gem::Version.new(latest.version)
72
+ end
47
73
  end
48
74
  end
@@ -49,14 +49,14 @@ module Bundler
49
49
 
50
50
  Bundler.definition.validate_ruby!
51
51
  Installer.install Bundler.root, Bundler.definition, opts
52
- Bundler.load.cache if Bundler.root.join("vendor/cache").exist?
52
+ Bundler.load.cache if Bundler.app_cache.exist?
53
53
 
54
54
  if Bundler.settings[:clean] && Bundler.settings[:path]
55
55
  require "bundler/cli/clean"
56
56
  Bundler::CLI::Clean.new(options).run
57
57
  end
58
58
 
59
- Bundler.ui.confirm "Your bundle is updated!"
59
+ Bundler.ui.confirm "Bundle updated!"
60
60
  without_groups_messages
61
61
  end
62
62
 
@@ -8,7 +8,7 @@ module Bundler
8
8
  def run
9
9
  require 'graphviz'
10
10
  output_file = File.expand_path(options[:file])
11
- graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format])
11
+ graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format], options[:without])
12
12
  graph.viz
13
13
  rescue LoadError => e
14
14
  Bundler.ui.error e.inspect
@@ -129,7 +129,7 @@ module Bundler
129
129
  # @return [Bundler::SpecSet]
130
130
  def specs
131
131
  @specs ||= begin
132
- specs = resolve.materialize(requested_dependencies)
132
+ specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)
133
133
 
134
134
  unless specs["bundler"].any?
135
135
  local = Bundler.settings[:frozen] ? rubygems_index : index
@@ -184,10 +184,11 @@ module Bundler
184
184
  # @return [SpecSet] resolved dependencies
185
185
  def resolve
186
186
  @resolve ||= begin
187
- last_resolve = converge_locked_specs
188
187
  if Bundler.settings[:frozen] || (!@unlocking && nothing_changed?)
189
- last_resolve
188
+ @locked_specs
190
189
  else
190
+ last_resolve = converge_locked_specs
191
+
191
192
  # Run a resolve against the locally available gems
192
193
  last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve)
193
194
  end
@@ -198,15 +199,11 @@ module Bundler
198
199
  @index ||= Index.build do |idx|
199
200
  dependency_names = @dependencies.map { |d| d.name }
200
201
 
201
- sources.all_sources.each do |source|
202
- source.dependency_names = dependency_names.dup
203
- idx.add_source source.specs
204
-
205
- if source.is_a?(Source::Git) || source.is_a?(Source::Path)
206
- dependency_names -= source.specs.map{|s| s.name }.uniq
207
- end
208
-
209
- dependency_names.push(*source.unmet_deps).uniq!
202
+ sources.all_sources.each do |s|
203
+ s.dependency_names = dependency_names.dup
204
+ idx.add_source s.specs
205
+ s.specs.each { |spec| dependency_names.delete(spec.name) }
206
+ dependency_names.push(*s.unmet_deps).uniq!
210
207
  end
211
208
  end
212
209
  end
@@ -275,7 +272,7 @@ module Bundler
275
272
  each do |spec|
276
273
  next if spec.name == 'bundler'
277
274
  out << spec.to_lock
278
- end
275
+ end
279
276
  out << "\n"
280
277
  end
281
278
 
@@ -517,9 +514,7 @@ module Bundler
517
514
 
518
515
  converged = []
519
516
  @locked_specs.each do |s|
520
- # Replace the locked dependency's source with the equivalent source from the Gemfile
521
- dep = @dependencies.find { |dep| s.satisfies?(dep) }
522
- s.source = (dep && dep.source) || sources.get(s.source)
517
+ s.source = sources.get(s.source)
523
518
 
524
519
  # Don't add a spec to the list if its source is expired. For example,
525
520
  # if you change a Git gem to Rubygems.
@@ -559,15 +554,12 @@ module Bundler
559
554
  resolve
560
555
  end
561
556
 
562
- def in_locked_deps?(dep, locked_dep)
563
- # Because the lockfile can't link a dep to a specific remote, we need to
564
- # treat sources as equivalent anytime the locked dep has all the remotes
565
- # that the Gemfile dep does.
566
- locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
557
+ def in_locked_deps?(dep, d)
558
+ d && dep.source == d.source
567
559
  end
568
560
 
569
561
  def satisfies_locked_spec?(dep)
570
- @locked_specs.any? { |s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
562
+ @locked_specs.any? { |s| s.satisfies?(dep) && (!dep.source || s.source == dep.source) }
571
563
  end
572
564
 
573
565
  def expanded_dependencies
@@ -26,6 +26,14 @@ module Bundler
26
26
  :jruby_18 => Gem::Platform::JAVA,
27
27
  :jruby_19 => Gem::Platform::JAVA,
28
28
  :mswin => Gem::Platform::MSWIN,
29
+ :mswin_18 => Gem::Platform::MSWIN,
30
+ :mswin_19 => Gem::Platform::MSWIN,
31
+ :mswin_20 => Gem::Platform::MSWIN,
32
+ :mswin_21 => Gem::Platform::MSWIN,
33
+ :mswin64 => Gem::Platform::MSWIN64,
34
+ :mswin64_19 => Gem::Platform::MSWIN64,
35
+ :mswin64_20 => Gem::Platform::MSWIN64,
36
+ :mswin64_21 => Gem::Platform::MSWIN64,
29
37
  :mingw => Gem::Platform::MINGW,
30
38
  :mingw_18 => Gem::Platform::MINGW,
31
39
  :mingw_19 => Gem::Platform::MINGW,
@@ -93,7 +101,6 @@ module Bundler
93
101
  out << "\n"
94
102
  end
95
103
 
96
-
97
104
  def specific?
98
105
  super
99
106
  rescue NoMethodError
@@ -24,14 +24,14 @@ module Bundler
24
24
  @platforms = []
25
25
  @env = nil
26
26
  @ruby_version = nil
27
- add_github_sources
27
+ add_git_sources
28
28
  end
29
29
 
30
30
  def eval_gemfile(gemfile, contents = nil)
31
31
  contents ||= Bundler.read_file(gemfile.to_s)
32
32
  instance_eval(contents, gemfile.to_s, 1)
33
33
  rescue SyntaxError => e
34
- syntax_msg = e.message.gsub("#{gemfile.to_s}:", 'on line ')
34
+ syntax_msg = e.message.gsub("#{gemfile}:", 'on line ')
35
35
  raise GemfileError, "Gemfile syntax error #{syntax_msg}"
36
36
  rescue ScriptError, RegexpError, NameError, ArgumentError => e
37
37
  e.backtrace[0] = "#{e.backtrace[0]}: #{e.message} (#{e.class})"
@@ -148,6 +148,10 @@ module Bundler
148
148
  with_source(@sources.add_git_source(normalize_hash(options).merge("uri" => uri)), &blk)
149
149
  end
150
150
 
151
+ def github(repo, options = {}, &blk)
152
+ with_source(@sources.add_git_source(normalize_hash(options).merge("github" => repo)), &blk)
153
+ end
154
+
151
155
  def to_definition(lockfile, unlock)
152
156
  Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version)
153
157
  end
@@ -182,13 +186,19 @@ module Bundler
182
186
 
183
187
  private
184
188
 
185
- def add_github_sources
189
+ def add_git_sources
186
190
  git_source(:github) do |repo_name|
187
191
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
188
192
  "git://github.com/#{repo_name}.git"
189
193
  end
190
194
 
191
195
  git_source(:gist){ |repo_name| "https://gist.github.com/#{repo_name}.git" }
196
+
197
+ git_source(:bitbucket) do |repo_name|
198
+ user_name, repo_name = repo_name.split '/'
199
+ repo_name ||= user_name
200
+ "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
201
+ end
192
202
  end
193
203
 
194
204
  def with_source(source)
@@ -214,7 +224,10 @@ module Bundler
214
224
 
215
225
  def normalize_options(name, version, opts)
216
226
  if name.is_a?(Symbol)
217
- raise GemfileError, %{You need to specify gem names as Strings. Use 'gem "#{name.to_s}"' instead.}
227
+ raise GemfileError, %{You need to specify gem names as Strings. Use 'gem "#{name}"' instead.}
228
+ end
229
+ if name =~ /\s/
230
+ raise GemfileError, %{'#{name}' is not a valid gem name because it contains whitespace.}
218
231
  end
219
232
 
220
233
  normalize_hash(opts)
@@ -18,7 +18,7 @@ module Bundler
18
18
  end
19
19
 
20
20
  # needed for standalone, load required_paths from local gemspec
21
- # after the gem in installed
21
+ # after the gem is installed
22
22
  def require_paths
23
23
  if @remote_specification
24
24
  @remote_specification.require_paths
@@ -1,43 +1,44 @@
1
+ require 'bundler/rubygems_integration'
2
+ require 'bundler/source/git/git_proxy'
3
+
1
4
  module Bundler
2
5
  class Env
3
6
 
4
7
  def write(io)
5
- io.write(report)
8
+ io.write report(:print_gemfile => true)
6
9
  end
7
10
 
8
- def report
9
- out = "Bundler #{Bundler::VERSION}\n"
10
-
11
- out << "Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
12
- out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
13
- out << ") [#{RUBY_PLATFORM}]\n"
14
-
15
- out << "Rubygems #{Gem::VERSION}\n"
16
-
17
- out << "rvm #{ENV['rvm_version']}\n" if ENV['rvm_version']
18
-
19
- out << "GEM_HOME #{ENV['GEM_HOME']}\n"
20
-
21
- out << "GEM_PATH #{ENV['GEM_PATH']}\n" unless ENV['GEM_PATH'] == ENV['GEM_HOME']
11
+ def report(options = {})
12
+ print_gemfile = options.delete(:print_gemfile)
22
13
 
14
+ out = "Environment\n\n"
15
+ out << " Bundler #{Bundler::VERSION}\n"
16
+ out << " Rubygems #{Gem::VERSION}\n"
17
+ out << " Ruby #{ruby_version}"
18
+ out << " GEM_HOME #{ENV['GEM_HOME']}\n" unless ENV['GEM_HOME'].nil? || ENV['GEM_HOME'].empty?
19
+ out << " GEM_PATH #{ENV['GEM_PATH']}\n" unless ENV['GEM_PATH'] == ENV['GEM_HOME']
20
+ out << " RVM #{ENV['rvm_version']}\n" if ENV['rvm_version']
21
+ out << " Git #{git_version}\n"
23
22
  %w(rubygems-bundler open_gem).each do |name|
24
- specs = Gem::Specification.find_all{|s| s.name == name }
25
- out << "#{name} (#{specs.map(&:version).join(',')})\n" unless specs.empty?
23
+ specs = Bundler.rubygems.find_name(name)
24
+ out << " #{name} (#{specs.map(&:version).join(',')})\n" unless specs.empty?
26
25
  end
27
26
 
28
- out << "\nBundler settings\n" unless Bundler.settings.all.empty?
27
+ out << "\nBundler settings\n\n" unless Bundler.settings.all.empty?
29
28
  Bundler.settings.all.each do |setting|
30
- out << " #{setting}\n"
29
+ out << " " << setting << "\n"
31
30
  Bundler.settings.pretty_values_for(setting).each do |line|
32
- out << " " << line << "\n"
31
+ out << " " << line << "\n"
33
32
  end
34
33
  end
35
34
 
36
- out << "\n\n" << "Gemfile\n"
37
- out << read_file("Gemfile") << "\n"
35
+ if print_gemfile
36
+ out << "\nGemfile\n\n"
37
+ out << " " << read_file(Bundler.default_gemfile).gsub(/\n/, "\n ") << "\n"
38
38
 
39
- out << "\n\n" << "Gemfile.lock\n"
40
- out << read_file("Gemfile.lock") << "\n"
39
+ out << "\n" << "Gemfile.lock\n\n"
40
+ out << " " << read_file(Bundler.default_lockfile).gsub(/\n/, "\n ") << "\n"
41
+ end
41
42
 
42
43
  out
43
44
  end
@@ -45,12 +46,30 @@ module Bundler
45
46
  private
46
47
 
47
48
  def read_file(filename)
48
- File.read(filename).strip
49
+ File.read(filename.to_s).strip
49
50
  rescue Errno::ENOENT
50
51
  "<No #{filename} found>"
51
52
  rescue => e
52
53
  "#{e.class}: #{e.message}"
53
54
  end
54
55
 
56
+ def ruby_version
57
+ str = "#{RUBY_VERSION}"
58
+ if RUBY_VERSION < '1.9'
59
+ str << " (#{RUBY_RELEASE_DATE}"
60
+ str << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
61
+ str << ") [#{RUBY_PLATFORM}]\n"
62
+ else
63
+ str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
64
+ str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]\n"
65
+ end
66
+ end
67
+
68
+ def git_version
69
+ Bundler::Source::Git::GitProxy.new(nil, nil, nil).version
70
+ rescue Bundler::Source::Git::GitNotInstalledError
71
+ "not installed"
72
+ end
73
+
55
74
  end
56
75
  end
@@ -6,6 +6,8 @@ module Bundler
6
6
 
7
7
  # Handles all the fetching with the rubygems server
8
8
  class Fetcher
9
+ # This error is raised when it looks like the network is down
10
+ class NetworkDownError < HTTPError; end
9
11
  # This error is raised if the API returns a 413 (only printed in verbose)
10
12
  class FallbackError < HTTPError; end
11
13
  # This is the error raised if OpenSSL fails the cert verification
@@ -73,18 +75,27 @@ module Bundler
73
75
  ruby = Bundler.ruby_version
74
76
 
75
77
  agent = "bundler/#{Bundler::VERSION}"
76
- agent += " rubygems/#{Gem::VERSION}"
77
- agent += " ruby/#{ruby.version}"
78
- agent += " (#{ruby.host})"
79
- agent += " command/#{ARGV.first}"
78
+ agent << " rubygems/#{Gem::VERSION}"
79
+ agent << " ruby/#{ruby.version}"
80
+ agent << " (#{ruby.host})"
81
+ agent << " command/#{ARGV.first}"
80
82
 
81
83
  if ruby.engine != "ruby"
82
84
  # engine_version raises on unknown engines
83
85
  engine_version = ruby.engine_version rescue "???"
84
- agent += " #{ruby.engine}/#{engine_version}"
86
+ agent << " #{ruby.engine}/#{engine_version}"
85
87
  end
88
+
89
+ agent << " options/#{Bundler.settings.all.join(",")}"
90
+
86
91
  # add a random ID so we can consolidate runs server-side
87
92
  agent << " " << SecureRandom.hex(8)
93
+
94
+ # add any user agent strings set in the config
95
+ extra_ua = Bundler.settings[:user_agent]
96
+ agent << " " << extra_ua if extra_ua
97
+
98
+ agent
88
99
  end
89
100
  end
90
101
 
@@ -95,7 +106,7 @@ module Bundler
95
106
  @api_timeout = 10 # How long to wait for each API call
96
107
  @max_retries = 3 # How many retries for the API call
97
108
 
98
- @anonymizable_uri = resolve_remote_uri(remote_uri)
109
+ @anonymizable_uri = configured_uri_for(remote_uri)
99
110
 
100
111
  Socket.do_not_reverse_lookup = true
101
112
  connection # create persistent connection
@@ -231,6 +242,8 @@ module Bundler
231
242
  elsif fetch(dependency_api_uri)
232
243
  @use_api = true
233
244
  end
245
+ rescue NetworkDownError => e
246
+ raise HTTPError, e.message
234
247
  rescue AuthenticationRequiredError
235
248
  # We got a 401 from the server. Don't fall back to the full index, just fail.
236
249
  raise
@@ -270,7 +283,7 @@ module Bundler
270
283
  when Net::HTTPRequestEntityTooLarge
271
284
  raise FallbackError, response.body
272
285
  when Net::HTTPUnauthorized
273
- raise AuthenticationRequiredError, remote_uri
286
+ raise AuthenticationRequiredError, remote_uri.host
274
287
  else
275
288
  raise HTTPError, "#{response.class}: #{response.body}"
276
289
  end
@@ -289,7 +302,13 @@ module Bundler
289
302
  raise CertificateFailureError.new(uri)
290
303
  rescue *HTTP_ERRORS => e
291
304
  Bundler.ui.trace e
292
- raise HTTPError, "Network error while fetching #{uri}"
305
+ case e.message
306
+ when /host down:/, /getaddrinfo: nodename nor servname provided/
307
+ raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \
308
+ "connection and try again."
309
+ else
310
+ raise HTTPError, "Network error while fetching #{uri}"
311
+ end
293
312
  end
294
313
 
295
314
  def dependency_api_uri(gem_names = [])
@@ -301,14 +320,10 @@ module Bundler
301
320
  # fetch from Gemcutter Dependency Endpoint API
302
321
  def fetch_dependency_remote_specs(gem_names)
303
322
  Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(',')}"
304
- gem_list = []
323
+ marshalled_deps = fetch dependency_api_uri(gem_names)
324
+ gem_list = Bundler.load_marshal(marshalled_deps)
305
325
  deps_list = []
306
326
 
307
- gem_names.each_slice(Source::Rubygems::API_REQUEST_LIMIT) do |names|
308
- marshalled_deps = fetch dependency_api_uri(names)
309
- gem_list += Bundler.load_marshal(marshalled_deps)
310
- end
311
-
312
327
  spec_list = gem_list.map do |s|
313
328
  dependencies = s[:dependencies].map do |name, requirement|
314
329
  dep = well_formed_dependency(name, requirement.split(", "))
@@ -377,17 +392,10 @@ module Bundler
377
392
 
378
393
  private
379
394
 
380
- def resolve_remote_uri(uri)
381
- add_configured_credentials(Bundler::Source.mirror_for(uri))
382
- end
383
-
384
- def add_configured_credentials(uri)
385
- auth = Bundler.settings[uri.to_s]
386
- if auth
387
- uri = uri.dup
388
- uri.user, uri.password = *auth.split(":", 2)
389
- end
390
- AnonymizableURI.new(uri)
395
+ def configured_uri_for(uri)
396
+ uri = Bundler::Source.mirror_for(uri)
397
+ config_auth = Bundler.settings[uri.to_s] || Bundler.settings[uri.host]
398
+ AnonymizableURI.new(uri, config_auth)
391
399
  end
392
400
 
393
401
  def fetch_uri