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
@@ -4,11 +4,11 @@ module Bundler
4
4
  yield
5
5
  rescue Bundler::BundlerError => e
6
6
  Bundler.ui.error e.message
7
- Bundler.ui.debug e.backtrace.join("\n")
7
+ Bundler.ui.trace e
8
8
  exit e.status_code
9
9
  rescue Interrupt => e
10
10
  Bundler.ui.error "\nQuitting..."
11
- Bundler.ui.debug e.backtrace.join("\n")
11
+ Bundler.ui.trace e
12
12
  exit 1
13
13
  rescue SystemExit => e
14
14
  exit e.status
@@ -19,8 +19,7 @@ module Bundler
19
19
  Bundler.ui.warn "You must recompile Ruby with OpenSSL support or change the sources in your" \
20
20
  "\nGemfile from 'https' to 'http'. Instructions for compiling with OpenSSL" \
21
21
  "\nusing RVM are available at rvm.io/packages/openssl."
22
- Bundler.ui.debug "#{e.class}: #{e.message}"
23
- Bundler.ui.debug e.backtrace.join("\n")
22
+ Bundler.ui.trace e
24
23
  exit 1
25
24
  else
26
25
  raise e
@@ -28,7 +27,7 @@ module Bundler
28
27
  rescue Exception => e
29
28
  Bundler.ui.error(
30
29
  "Unfortunately, a fatal error has occurred. Please see the Bundler \n" \
31
- "troubleshooting documentation at http://bit.ly/bundler-issues. Thanks! \n")
30
+ "troubleshooting documentation at http://bit.ly/bundler-issues. Thanks!\n")
32
31
  raise e
33
32
  end
34
33
  end
@@ -24,7 +24,7 @@ module Bundler
24
24
  attr_reader :spec_path, :base, :gemspec
25
25
 
26
26
  def initialize(base = nil, name = nil)
27
- Bundler.ui = UI::Shell.new(Thor::Base.shell.new)
27
+ Bundler.ui = UI::Shell.new
28
28
  @base = (base ||= Dir.pwd)
29
29
  gemspecs = name ? [File.join(base, "#{name}.gemspec")] : Dir[File.join(base, "{,*}.gemspec")]
30
30
  raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1
@@ -33,12 +33,12 @@ module Bundler
33
33
  end
34
34
 
35
35
  def install
36
- desc "Build #{name}-#{version}.gem into the pkg directory"
36
+ desc "Build #{name}-#{version}.gem into the pkg directory."
37
37
  task 'build' do
38
38
  build_gem
39
39
  end
40
40
 
41
- desc "Build and install #{name}-#{version}.gem into system gems"
41
+ desc "Build and install #{name}-#{version}.gem into system gems."
42
42
  task 'install' do
43
43
  install_gem
44
44
  end
@@ -57,7 +57,7 @@ module Bundler
57
57
  file_name = File.basename(built_gem_path)
58
58
  FileUtils.mkdir_p(File.join(base, 'pkg'))
59
59
  FileUtils.mv(built_gem_path, 'pkg')
60
- Bundler.ui.confirm "#{name} #{version} built to pkg/#{file_name}"
60
+ Bundler.ui.confirm "#{name} #{version} built to pkg/#{file_name}."
61
61
  }
62
62
  File.join(base, 'pkg', file_name)
63
63
  end
@@ -66,24 +66,21 @@ module Bundler
66
66
  built_gem_path = build_gem
67
67
  out, _ = sh_with_code("gem install '#{built_gem_path}'")
68
68
  raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
69
- Bundler.ui.confirm "#{name} (#{version}) installed"
69
+ Bundler.ui.confirm "#{name} (#{version}) installed."
70
70
  end
71
71
 
72
72
  def release_gem
73
73
  guard_clean
74
- guard_already_tagged
75
74
  built_gem_path = build_gem
76
- tag_version {
77
- git_push
78
- rubygem_push(built_gem_path)
79
- }
75
+ tag_version { git_push } unless already_tagged?
76
+ rubygem_push(built_gem_path)
80
77
  end
81
78
 
82
79
  protected
83
80
  def rubygem_push(path)
84
81
  if Pathname.new("~/.gem/credentials").expand_path.exist?
85
82
  sh("gem push '#{path}'")
86
- Bundler.ui.confirm "Pushed #{name} #{version} to rubygems.org"
83
+ Bundler.ui.confirm "Pushed #{name} #{version} to rubygems.org."
87
84
  else
88
85
  raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
89
86
  end
@@ -96,7 +93,7 @@ module Bundler
96
93
  def git_push
97
94
  perform_git_push
98
95
  perform_git_push ' --tags'
99
- Bundler.ui.confirm "Pushed git commits and tags"
96
+ Bundler.ui.confirm "Pushed git commits and tags."
100
97
  end
101
98
 
102
99
  def perform_git_push(options = '')
@@ -105,9 +102,10 @@ module Bundler
105
102
  raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
106
103
  end
107
104
 
108
- def guard_already_tagged
105
+ def already_tagged?
109
106
  if sh('git tag').split(/\n/).include?(version_tag)
110
- raise("This tag has already been committed to the repo.")
107
+ Bundler.ui.confirm "Tag #{version_tag} has already been created."
108
+ true
111
109
  end
112
110
  end
113
111
 
@@ -121,10 +119,10 @@ module Bundler
121
119
 
122
120
  def tag_version
123
121
  sh "git tag -a -m \"Version #{version}\" #{version_tag}"
124
- Bundler.ui.confirm "Tagged #{version_tag}"
122
+ Bundler.ui.confirm "Tagged #{version_tag}."
125
123
  yield if block_given?
126
124
  rescue
127
- Bundler.ui.error "Untagged #{version_tag} due to error"
125
+ Bundler.ui.error "Untagging #{version_tag} due to error."
128
126
  sh_with_code "git tag -d #{version_tag}"
129
127
  raise
130
128
  end
@@ -0,0 +1,64 @@
1
+ module Bundler
2
+ class Injector
3
+ def self.inject(new_deps)
4
+ injector = new(new_deps)
5
+ injector.inject(Bundler.default_gemfile, Bundler.default_lockfile)
6
+ end
7
+
8
+ def initialize(new_deps)
9
+ @new_deps = new_deps
10
+ end
11
+
12
+ def inject(gemfile_path, lockfile_path)
13
+ if Bundler.settings[:frozen]
14
+ # ensure the lock and Gemfile are synced
15
+ Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true)
16
+ # temporarily remove frozen while we inject
17
+ frozen = Bundler.settings.delete(:frozen)
18
+ end
19
+
20
+ # evaluate the Gemfile we have now
21
+ builder = Dsl.new
22
+ builder.eval_gemfile(gemfile_path)
23
+
24
+ # don't inject any gems that are already in the Gemfile
25
+ @new_deps -= builder.dependencies
26
+
27
+ # add new deps to the end of the in-memory Gemfile
28
+ builder.eval_gemfile("injected gems", new_gem_lines) if @new_deps.any?
29
+
30
+ # resolve to see if the new deps broke anything
31
+ definition = builder.to_definition(lockfile_path, {})
32
+ definition.resolve_remotely!
33
+
34
+ # since nothing broke, we can add those gems to the gemfile
35
+ append_to(gemfile_path) if @new_deps.any?
36
+
37
+ # since we resolved successfully, write out the lockfile
38
+ definition.lock(Bundler.default_lockfile)
39
+
40
+ # return an array of the deps that we added
41
+ return @new_deps
42
+ ensure
43
+ Bundler.settings[:frozen] = '1' if frozen
44
+ end
45
+
46
+ private
47
+
48
+ def new_gem_lines
49
+ @new_deps.map do |d|
50
+ %|gem '#{d.name}', '#{d.requirement}'|
51
+ end.join("\n")
52
+ end
53
+
54
+ def append_to(gemfile_path)
55
+ gemfile_path.open("a") do |f|
56
+ f.puts
57
+ f.puts "# Added at #{Time.now} by #{`whoami`.chomp}:"
58
+ f.puts new_gem_lines
59
+ end
60
+ end
61
+
62
+
63
+ end
64
+ end
@@ -66,13 +66,11 @@ module Bundler
66
66
  end
67
67
 
68
68
  if Bundler.default_lockfile.exist? && !options["update"]
69
- real_ui, Bundler.ui = Bundler.ui, Bundler::UI.new
70
69
  begin
71
70
  tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
72
71
  local = true unless tmpdef.new_platform? || tmpdef.missing_specs.any?
73
72
  rescue BundlerError
74
73
  end
75
- Bundler.ui = real_ui
76
74
  end
77
75
 
78
76
  # Since we are installing, we can resolve the definition
@@ -177,16 +175,12 @@ module Bundler
177
175
 
178
176
  spec.require_paths.each do |path|
179
177
  full_path = File.join(spec.full_gem_path, path)
180
- gem_path = Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path))
181
- paths << gem_path.to_s.sub("#{SystemRubyVersion.new.engine}/#{RbConfig::CONFIG['ruby_version']}", '#{ruby_engine}/#{ruby_version}')
178
+ paths << Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path))
182
179
  end
183
180
  end
184
181
 
185
182
 
186
183
  File.open File.join(bundler_path, "setup.rb"), "w" do |file|
187
- file.puts "# ruby 1.8.7 doesn't define RUBY_ENGINE"
188
- file.puts "ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'"
189
- file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
190
184
  file.puts "path = File.expand_path('..', __FILE__)"
191
185
  paths.each do |path|
192
186
  file.puts %{$:.unshift File.expand_path("\#{path}/#{path}")}
@@ -26,8 +26,7 @@ module Bundler
26
26
  end
27
27
 
28
28
  def ==(other)
29
- [name, version, dependencies, platform, source] ==
30
- [other.name, other.version, other.dependencies, other.platform, other.source]
29
+ identifier == other.identifier
31
30
  end
32
31
 
33
32
  def satisfies?(dependency)
@@ -58,7 +57,11 @@ module Bundler
58
57
  end
59
58
 
60
59
  def to_s
61
- "#{name} (#{version})"
60
+ @__to_s ||= "#{name} (#{version})"
61
+ end
62
+
63
+ def identifier
64
+ @__identifier ||= [name, version, source, platform, dependencies].hash
62
65
  end
63
66
 
64
67
  private
@@ -14,22 +14,31 @@ module Bundler
14
14
  class LockfileParser
15
15
  attr_reader :sources, :dependencies, :specs, :platforms
16
16
 
17
+ DEPENDENCIES = "DEPENDENCIES"
18
+ PLATFORMS = "PLATFORMS"
19
+ GIT = "GIT"
20
+ GEM = "GEM"
21
+ PATH = "PATH"
22
+ SPECS = " specs:"
23
+ OPTIONS = /^ ([a-z]+): (.*)$/i
24
+
17
25
  def initialize(lockfile)
18
26
  @platforms = []
19
27
  @sources = []
20
28
  @dependencies = []
21
- @specs = []
22
29
  @state = :source
30
+ @specs = {}
23
31
 
24
- lockfile.split(/(\r?\n)+/).each do |line|
25
- if line == "DEPENDENCIES"
32
+ lockfile.split(/(?:\r?\n)+/).each do |line|
33
+ if line == DEPENDENCIES
26
34
  @state = :dependency
27
- elsif line == "PLATFORMS"
35
+ elsif line == PLATFORMS
28
36
  @state = :platform
29
37
  else
30
38
  send("parse_#{@state}", line)
31
39
  end
32
40
  end
41
+ @specs = @specs.values
33
42
  end
34
43
 
35
44
  private
@@ -42,10 +51,10 @@ module Bundler
42
51
 
43
52
  def parse_source(line)
44
53
  case line
45
- when "GIT", "GEM", "PATH"
54
+ when GIT, GEM, PATH
46
55
  @current_source = nil
47
56
  @opts, @type = {}, line
48
- when " specs:"
57
+ when SPECS
49
58
  @current_source = TYPES[@type].from_lock(@opts)
50
59
 
51
60
  # Strip out duplicate GIT sections
@@ -54,7 +63,7 @@ module Bundler
54
63
  end
55
64
 
56
65
  @sources << @current_source
57
- when /^ ([a-z]+): (.*)$/i
66
+ when OPTIONS
58
67
  value = $2
59
68
  value = true if value == "true"
60
69
  value = false if value == "false"
@@ -73,17 +82,20 @@ module Bundler
73
82
  end
74
83
 
75
84
  NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'
85
+ NAME_VERSION_2 = %r{^ {2}#{NAME_VERSION}(!)?$}
86
+ NAME_VERSION_4 = %r{^ {4}#{NAME_VERSION}$}
87
+ NAME_VERSION_6 = %r{^ {6}#{NAME_VERSION}$}
76
88
 
77
89
  def parse_dependency(line)
78
- if line =~ %r{^ {2}#{NAME_VERSION}(!)?$}
90
+ if line =~ NAME_VERSION_2
79
91
  name, version, pinned = $1, $2, $4
80
92
  version = version.split(",").map { |d| d.strip } if version
81
93
 
82
94
  dep = Bundler::Dependency.new(name, version)
83
95
 
84
96
  if pinned && dep.name != 'bundler'
85
- spec = @specs.find { |s| s.name == dep.name }
86
- dep.source = spec.source if spec
97
+ spec = @specs.find {|k, v| v.name == dep.name }
98
+ dep.source = spec.last.source if spec
87
99
 
88
100
  # Path sources need to know what the default name / version
89
101
  # to use in the case that there are no gemspecs present. A fake
@@ -100,7 +112,7 @@ module Bundler
100
112
  end
101
113
 
102
114
  def parse_spec(line)
103
- if line =~ %r{^ {4}#{NAME_VERSION}$}
115
+ if line =~ NAME_VERSION_4
104
116
  name, version = $1, Gem::Version.new($2)
105
117
  platform = $3 ? Gem::Platform.new($3) : Gem::Platform::RUBY
106
118
  @current_spec = LazySpecification.new(name, version, platform)
@@ -108,8 +120,8 @@ module Bundler
108
120
 
109
121
  # Avoid introducing multiple copies of the same spec (caused by
110
122
  # duplicate GIT sections)
111
- @specs << @current_spec unless @specs.include?(@current_spec)
112
- elsif line =~ %r{^ {6}#{NAME_VERSION}$}
123
+ @specs[@current_spec.identifier] ||= @current_spec
124
+ elsif line =~ NAME_VERSION_6
113
125
  name, version = $1, $2
114
126
  version = version.split(',').map { |d| d.strip } if version
115
127
  dep = Gem::Dependency.new(name, version)
@@ -122,7 +122,6 @@ module Bundler
122
122
  # <GemBundle>,nil:: If the list of dependencies can be resolved, a
123
123
  # collection of gemspecs is returned. Otherwise, nil is returned.
124
124
  def self.resolve(requirements, index, source_requirements = {}, base = [])
125
- Bundler.ui.info "Resolving dependencies..."
126
125
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
127
126
  resolver = new(index, source_requirements, base)
128
127
  result = catch(:success) do
@@ -1,10 +1,7 @@
1
+ require 'rubygems'
2
+
1
3
  module Bundler
2
4
  class RubygemsIntegration
3
- def initialize
4
- # Work around a RubyGems bug
5
- configuration
6
- end
7
-
8
5
  def loaded_specs(name)
9
6
  Gem.loaded_specs[name]
10
7
  end
@@ -90,6 +87,22 @@ module Bundler
90
87
  Gem::SpecFetcher.new.list(all, pre).each(&blk)
91
88
  end
92
89
 
90
+ def fetch_all_remote_specs
91
+ spec_list = Hash.new { |h,k| h[k] = [] }
92
+ begin
93
+ # Fetch all specs, minus prerelease specs
94
+ spec_list = Gem::SpecFetcher.new.list(true, false)
95
+ # Then fetch the prerelease specs
96
+ begin
97
+ Gem::SpecFetcher.new.list(false, true).each {|k, v| spec_list[k] += v }
98
+ rescue Gem::RemoteFetcher::FetchError => e
99
+ # ignore if we can't fetch the prerelease specs
100
+ end
101
+ end
102
+
103
+ return spec_list
104
+ end
105
+
93
106
  def with_build_args(args)
94
107
  old_args = Gem::Command.build_args
95
108
  begin
@@ -101,7 +114,19 @@ module Bundler
101
114
  end
102
115
 
103
116
  def spec_from_gem(path)
117
+ require 'rubygems/format'
104
118
  Gem::Format.from_file_by_path(path).spec
119
+ rescue Gem::Package::FormatError
120
+ raise Bundler::GemspecError, "Could not read gem at #{path}. It may be corrupted."
121
+ end
122
+
123
+ def build(spec)
124
+ require 'rubygems/builder'
125
+ Gem::Builder.new(spec).build
126
+ end
127
+
128
+ def build_gem(gem_dir, spec)
129
+ Dir.chdir(gem_dir) { build(spec) }
105
130
  end
106
131
 
107
132
  def download_gem(spec, uri, path)
@@ -161,16 +186,6 @@ module Bundler
161
186
  end
162
187
  end
163
188
 
164
- if defined? ::Deprecate
165
- Deprecate = ::Deprecate
166
- elsif defined? Gem::Deprecate
167
- Deprecate = Gem::Deprecate
168
- else
169
- class Deprecate
170
- def skip_during; yield; end
171
- end
172
- end
173
-
174
189
  def stub_source_index137(specs)
175
190
  # Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
176
191
  source_index_class = (class << Gem::SourceIndex ; self ; end)
@@ -341,7 +356,7 @@ module Bundler
341
356
  end
342
357
  end
343
358
 
344
- # Rubygems 1.8.5
359
+ # Rubygems ~> 1.8.5
345
360
  class Modern < RubygemsIntegration
346
361
  def stub_rubygems(specs)
347
362
  Gem::Specification.all = specs
@@ -374,9 +389,60 @@ module Bundler
374
389
  end
375
390
  end
376
391
 
392
+ # Rubygems 2.0
393
+ class Future < RubygemsIntegration
394
+ require 'rubygems/package'
395
+
396
+ def stub_rubygems(specs)
397
+ Gem::Specification.all = specs
398
+
399
+ Gem.post_reset {
400
+ Gem::Specification.all = specs
401
+ }
402
+ end
403
+
404
+ def all_specs
405
+ Gem::Specification.to_a
406
+ end
407
+
408
+ def find_name(name)
409
+ Gem::Specification.find_all_by_name name
410
+ end
411
+
412
+ def fetch_all_remote_specs
413
+ tuples, errors = Gem::SpecFetcher.new.available_specs(:complete)
414
+ # only raise if we don't get any specs back.
415
+ # this means we still work if prerelease_specs.4.8.gz
416
+ # don't exist but specs.4.8.gz do
417
+ if tuples.empty? && error = errors.detect {|e| e.is_a?(Gem::SourceFetchProblem) }
418
+ raise Gem::RemoteFetcher::FetchError.new(error.error, error.source)
419
+ end
420
+
421
+ hash = {}
422
+ tuples.each do |source,tuples|
423
+ hash[source.uri] = tuples.map { |tuple| tuple.to_a }
424
+ end
425
+
426
+ hash
427
+ end
428
+
429
+ def spec_from_gem(path)
430
+ Gem::Package.new(path).spec
431
+ rescue Gem::Package::FormatError
432
+ raise Bundler::GemspecError, "Could not read gem at #{path}. It may be corrupted."
433
+ end
434
+
435
+ def build(spec)
436
+ Gem::Package.build(spec)
437
+ end
438
+
439
+ end
440
+
377
441
  end
378
442
 
379
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.5')
443
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.99.99')
444
+ @rubygems = RubygemsIntegration::Future.new
445
+ elsif Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.5')
380
446
  @rubygems = RubygemsIntegration::Modern.new
381
447
  elsif Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.0')
382
448
  @rubygems = RubygemsIntegration::AlmostModern.new