rubygems-update 2.4.1 → 2.4.2

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

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.txt +38 -0
  5. data/README.rdoc +1 -1
  6. data/Rakefile +3 -3
  7. data/lib/rubygems.rb +1 -1
  8. data/lib/rubygems/command_manager.rb +1 -1
  9. data/lib/rubygems/commands/owner_command.rb +3 -1
  10. data/lib/rubygems/commands/update_command.rb +6 -5
  11. data/lib/rubygems/config_file.rb +1 -1
  12. data/lib/rubygems/dependency.rb +4 -2
  13. data/lib/rubygems/dependency_installer.rb +2 -0
  14. data/lib/rubygems/exceptions.rb +2 -2
  15. data/lib/rubygems/installer.rb +13 -4
  16. data/lib/rubygems/local_remote_options.rb +1 -1
  17. data/lib/rubygems/package/tar_reader/entry.rb +2 -0
  18. data/lib/rubygems/rdoc.rb +0 -1
  19. data/lib/rubygems/request/connection_pools.rb +5 -3
  20. data/lib/rubygems/request_set.rb +57 -1
  21. data/lib/rubygems/request_set/gem_dependency_api.rb +58 -10
  22. data/lib/rubygems/request_set/lockfile.rb +13 -5
  23. data/lib/rubygems/resolver.rb +2 -1
  24. data/lib/rubygems/resolver/composed_set.rb +12 -0
  25. data/lib/rubygems/resolver/conflict.rb +2 -2
  26. data/lib/rubygems/resolver/dependency_request.rb +2 -2
  27. data/lib/rubygems/resolver/index_set.rb +1 -1
  28. data/lib/rubygems/resolver/installer_set.rb +6 -0
  29. data/lib/rubygems/resolver/lock_specification.rb +4 -0
  30. data/lib/rubygems/resolver/set.rb +8 -2
  31. data/lib/rubygems/resolver/vendor_set.rb +2 -0
  32. data/lib/rubygems/source.rb +2 -0
  33. data/lib/rubygems/source/git.rb +10 -2
  34. data/lib/rubygems/specification.rb +9 -3
  35. data/lib/rubygems/stub_specification.rb +5 -0
  36. data/lib/rubygems/test_case.rb +1 -1
  37. data/lib/rubygems/test_utilities.rb +2 -0
  38. data/lib/rubygems/user_interaction.rb +10 -0
  39. data/lib/rubygems/util.rb +14 -1
  40. data/test/rubygems/test_gem_commands_setup_command.rb +6 -8
  41. data/test/rubygems/test_gem_commands_uninstall_command.rb +1 -1
  42. data/test/rubygems/test_gem_commands_update_command.rb +28 -0
  43. data/test/rubygems/test_gem_dependency.rb +27 -0
  44. data/test/rubygems/test_gem_dependency_installer.rb +21 -0
  45. data/test/rubygems/test_gem_ext_builder.rb +1 -1
  46. data/test/rubygems/test_gem_impossible_dependencies_error.rb +6 -6
  47. data/test/rubygems/test_gem_installer.rb +27 -3
  48. data/test/rubygems/test_gem_remote_fetcher.rb +4 -0
  49. data/test/rubygems/test_gem_request_connection_pools.rb +37 -0
  50. data/test/rubygems/test_gem_request_set.rb +20 -1
  51. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +95 -9
  52. data/test/rubygems/test_gem_request_set_lockfile.rb +54 -0
  53. data/test/rubygems/test_gem_resolver_composed_set.rb +13 -0
  54. data/test/rubygems/test_gem_resolver_conflict.rb +2 -2
  55. data/test/rubygems/test_gem_resolver_dependency_request.rb +9 -0
  56. data/test/rubygems/test_gem_resolver_installer_set.rb +12 -0
  57. data/test/rubygems/test_gem_resolver_lock_specification.rb +11 -0
  58. data/test/rubygems/test_gem_resolver_vendor_set.rb +3 -1
  59. data/test/rubygems/test_gem_silent_ui.rb +5 -0
  60. data/test/rubygems/test_gem_source.rb +13 -0
  61. data/test/rubygems/test_gem_source_git.rb +15 -0
  62. data/test/rubygems/test_gem_specification.rb +46 -10
  63. data/test/rubygems/test_gem_stub_specification.rb +10 -0
  64. metadata +3 -3
  65. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cfb3f2be16ac3c109c54b92dab14a6e2aff80f78
4
- data.tar.gz: 723dbd0b9f74a8859078e4669a8b99e0f6cf6090
3
+ metadata.gz: 88e0d3f158fcc7b8b91f1bc7931978ef4ebe1013
4
+ data.tar.gz: 9ee4968c6949df2953caa20c11dd16963b4bf1c8
5
5
  SHA512:
6
- metadata.gz: ef957d7732b7d0b8188c0bd6c7614c59f0092df36725464475eee3fcfd77ff059d0c835c1c461d66827a021da6659421aef071a0ffe01341736c16cee2cea58d
7
- data.tar.gz: e5269c767f58470e66fcfe30eee0cd68ff2d1edf8de55e2d761c51828da542e7be48f211a9bc004f4e7b6f5a27db7380e8e3caecec05870af800502a45ce49b2
6
+ metadata.gz: bbfb3e275c5326017d610784402092a211ea2afe2babd669f63d58a0dfffda0de3845c746b6b48cbfe06630ad2dc91b8c825b17902ab4dab1021cc1aff7f85f3
7
+ data.tar.gz: 65e0a8835e1494de14f03a43f31f51f419006dd54ff2a42c9169a9ce3c0b5c4fec323e09772fcecebf31486fcbbb23c9078e15fb22418fcc81461d1789b9f472
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,5 +1,43 @@
1
1
  # coding: UTF-8
2
2
 
3
+ === 2.4.2 / 2014-10-01
4
+
5
+ This release was sponsored by Ruby Central.
6
+
7
+ Bug fixes:
8
+
9
+ * RubyGems now correctly matches wildcard no_proxy hosts. Issue #997 by
10
+ voelzemo.
11
+ * Added support for missing git_source method in the gem dependencies API.
12
+ * Fixed handling of git gems with an alternate install directory.
13
+ * Lockfiles will no longer be truncated upon resolution errors.
14
+ * Fixed messaging for `gem owner -a`. Issue #1004 by Aaron Patterson, Ryan
15
+ Davis.
16
+ * Removed meaningless ensure. Pull request #1003 by gogotanaka.
17
+ * Improved wording of --source option help. Pull request #989 by Jason Clark.
18
+ * Empty build_info files are now ignored. Issue #903 by Adan Alvarado.
19
+ * Gem::Installer ignores dependency checks when installing development
20
+ dependencies. Issue #994 by Jens Willie.
21
+ * `gem update` now continues after dependency errors. Issue #993 by aaronchi.
22
+ * RubyGems no longer warns about semantic version dependencies for the 0.x
23
+ range. Issue #987 by Jeff Felchner, pull request #1006 by Hsing-Hui Hsu.
24
+ * Added minimal lock to allow multithread installation of gems. Issue #982
25
+ and pull request #1005 by Yorick Peterse
26
+ * RubyGems now considers prerelease dependencies as it did in earlier versions
27
+ when --prerelease is given. Issue #990 by Jeremy Tryba.
28
+ * Updated capitalization in README. Issue #1010 by Ben Bodenmiller.
29
+ * Fixed activating gems from a Gemfile for default gems. Issue #991 by khoan.
30
+ * Fixed windows stub script generation for Cygwin. Issue #1000 by Brett
31
+ DiFrischia.
32
+ * Allow gem bindir and ruby.exe to live in separate diretories. Pull request
33
+ #942 by Ian Flynn.
34
+ * Fixed handling of gemspec in gem dependencies files to match Bundler
35
+ behavior. Issue #1020 by Michal Papis.
36
+ * Fixed `gem update` when updating to prereleases. Issue #1028 by Santiago
37
+ Pastorino.
38
+ * RubyGems now fails immediately when a git reference cannot be found instead
39
+ of spewing git errors. Issue #1031 by Michal Papis
40
+
3
41
  === 2.4.1 / 2014-07-17
4
42
 
5
43
  Bug fixes:
@@ -47,7 +47,7 @@ support request at {help.rubygems.org}[http://help.rubygems.org].
47
47
  Got a bug and you're not sure? You're sure you have a bug, but don't know
48
48
  what to do next? In any case, let us know about it! The best place
49
49
  for letting the RubyGems team know about bugs or problems you're having is
50
- {on the rubygems issues page at github}[http://github.com/rubygems/rubygems/issues].
50
+ {on the RubyGems issues page at GitHub}[http://github.com/rubygems/rubygems/issues].
51
51
 
52
52
  === Bundler Compatibility
53
53
 
data/Rakefile CHANGED
@@ -34,7 +34,7 @@ hoe = Hoe.spec 'rubygems-update' do
34
34
  spec_extras[:executables] = ['update_rubygems']
35
35
 
36
36
  rdoc_locations <<
37
- 'rubyforge.org:/var/www/gforge-projects/rubygems/rubygems-update/'
37
+ 'docs.seattlerb.org:/data/www/docs.seattlerb.org/rubygems/'
38
38
 
39
39
  clean_globs.push('**/debug.log',
40
40
  '*.out',
@@ -152,7 +152,7 @@ task :upload_to_gemcutter do
152
152
  sh "s3cmd put -P pkg/rubygems-update-#{v}.gem pkg/rubygems-#{v}.zip pkg/rubygems-#{v}.tgz s3://production.s3.rubygems.org/rubygems/"
153
153
  end
154
154
 
155
- desc "Upload release to rubyforge and gemcutter"
155
+ desc "Upload release to rubygems.org"
156
156
  task :upload => %w[upload_to_gemcutter]
157
157
 
158
158
  on_master = `git branch --list master`.strip == '* master'
@@ -324,7 +324,7 @@ SHA256 Checksums:
324
324
  #{checksums}
325
325
 
326
326
  [download]: http://rubygems.org/pages/download
327
- [upgrading]: http://rubygems.rubyforge.org/rubygems-update/UPGRADING_rdoc.html
327
+ [upgrading]: http://docs.seattlerb.org/rubygems/UPGRADING_rdoc.html
328
328
 
329
329
  ANNOUNCEMENT
330
330
 
@@ -9,7 +9,7 @@ require 'rbconfig'
9
9
  require 'thread'
10
10
 
11
11
  module Gem
12
- VERSION = '2.4.1'
12
+ VERSION = '2.4.2'
13
13
  end
14
14
 
15
15
  # Must be first since it unloads the prelude from 1.9.2
@@ -137,7 +137,7 @@ class Gem::CommandManager
137
137
  def run(args, build_args=nil)
138
138
  process_args(args, build_args)
139
139
  rescue StandardError, Timeout::Error => ex
140
- alert_error "While executing gem ... (#{ex.class})\n #{ex.to_s}"
140
+ alert_error "While executing gem ... (#{ex.class})\n #{ex}"
141
141
  ui.backtrace ex
142
142
 
143
143
  terminate_interaction(1)
@@ -86,7 +86,9 @@ permission to.
86
86
  request.add_field "Authorization", api_key
87
87
  end
88
88
 
89
- with_response response, "Removing #{owner}"
89
+ action = method == :delete ? "Removing" : "Adding"
90
+
91
+ with_response response, "#{action} #{owner}"
90
92
  rescue
91
93
  # ignore
92
94
  end
@@ -16,6 +16,8 @@ class Gem::Commands::UpdateCommand < Gem::Command
16
16
 
17
17
  attr_reader :installer # :nodoc:
18
18
 
19
+ attr_reader :updated # :nodoc:
20
+
19
21
  def initialize
20
22
  super 'update', 'Update installed gems to the latest version',
21
23
  :document => %w[rdoc ri],
@@ -201,17 +203,16 @@ command to remove old versions.
201
203
  def update_gem name, version = Gem::Requirement.default
202
204
  return if @updated.any? { |spec| spec.name == name }
203
205
 
204
- @installer ||= Gem::DependencyInstaller.new options
206
+ update_options = options.dup
207
+ update_options[:prerelease] = version.prerelease?
205
208
 
206
- success = false
209
+ @installer = Gem::DependencyInstaller.new update_options
207
210
 
208
211
  say "Updating #{name}"
209
212
  begin
210
213
  @installer.install name, Gem::Requirement.new(version)
211
- success = true
212
- rescue Gem::InstallError => e
214
+ rescue Gem::InstallError, Gem::DependencyError => e
213
215
  alert_error "Error installing #{name}:\n\t#{e.message}"
214
- success = false
215
216
  end
216
217
 
217
218
  @installer.installed_gems.each do |spec|
@@ -337,7 +337,7 @@ if you believe they were disclosed to a third party.
337
337
  end
338
338
  return content
339
339
  rescue *YAMLErrors => e
340
- warn "Failed to load #{filename}, #{e.to_s}"
340
+ warn "Failed to load #{filename}, #{e}"
341
341
  rescue Errno::EACCES
342
342
  warn "Failed to load #{filename} due to permissions problem."
343
343
  end
@@ -216,7 +216,7 @@ class Gem::Dependency
216
216
  # NOTE: Unlike #matches_spec? this method does not return true when the
217
217
  # version is a prerelease version unless this is a prerelease dependency.
218
218
 
219
- def match? obj, version=nil
219
+ def match? obj, version=nil, allow_prerelease=false
220
220
  if !version
221
221
  name = obj.name
222
222
  version = obj.version
@@ -229,7 +229,9 @@ class Gem::Dependency
229
229
  version = Gem::Version.new version
230
230
 
231
231
  return true if requirement.none? and not version.prerelease?
232
- return false if version.prerelease? and not prerelease?
232
+ return false if version.prerelease? and
233
+ not allow_prerelease and
234
+ not prerelease?
233
235
 
234
236
  requirement.satisfied_by? version
235
237
  end
@@ -382,6 +382,7 @@ class Gem::DependencyInstaller
382
382
  :force => @force,
383
383
  :format_executable => @format_executable,
384
384
  :ignore_dependencies => @ignore_dependencies,
385
+ :prerelease => @prerelease,
385
386
  :security_policy => @security_policy,
386
387
  :user_install => @user_install,
387
388
  :wrappers => @wrappers,
@@ -423,6 +424,7 @@ class Gem::DependencyInstaller
423
424
  request_set.development = @development
424
425
  request_set.development_shallow = @dev_shallow
425
426
  request_set.soft_missing = @force
427
+ request_set.prerelease = @prerelease
426
428
  request_set.remote = false unless consider_remote?
427
429
 
428
430
  installer_set = Gem::Resolver::InstallerSet.new @domain
@@ -27,7 +27,7 @@ class Gem::DependencyRemovalException < Gem::Exception; end
27
27
  # toplevel. Indicates which dependencies were incompatible through #conflict
28
28
  # and #conflicting_dependencies
29
29
 
30
- class Gem::DependencyResolutionError < Gem::Exception
30
+ class Gem::DependencyResolutionError < Gem::DependencyError
31
31
 
32
32
  attr_reader :conflict
33
33
 
@@ -214,7 +214,7 @@ end
214
214
  # Raised by Resolver when a dependency requests a gem for which
215
215
  # there is no spec.
216
216
 
217
- class Gem::UnsatisfiableDependencyError < Gem::Exception
217
+ class Gem::UnsatisfiableDependencyError < Gem::DependencyError
218
218
 
219
219
  ##
220
220
  # The unsatisfiable dependency. This is a
@@ -68,6 +68,8 @@ class Gem::Installer
68
68
 
69
69
  @path_warning = false
70
70
 
71
+ @install_lock = Mutex.new
72
+
71
73
  class << self
72
74
 
73
75
  ##
@@ -75,6 +77,12 @@ class Gem::Installer
75
77
 
76
78
  attr_accessor :path_warning
77
79
 
80
+ ##
81
+ # Certain aspects of the install process are not thread-safe. This lock is
82
+ # used to allow multiple threads to install Gems at the same time.
83
+
84
+ attr_reader :install_lock
85
+
78
86
  ##
79
87
  # Overrides the executable format.
80
88
  #
@@ -250,7 +258,7 @@ class Gem::Installer
250
258
 
251
259
  say spec.post_install_message unless spec.post_install_message.nil?
252
260
 
253
- Gem::Specification.add_spec spec unless Gem::Specification.include? spec
261
+ Gem::Installer.install_lock.synchronize { Gem::Specification.add_spec spec }
254
262
 
255
263
  run_post_install_hooks
256
264
 
@@ -328,6 +336,7 @@ class Gem::Installer
328
336
  # True if the gems in the system satisfy +dependency+.
329
337
 
330
338
  def installation_satisfies_dependency?(dependency)
339
+ return true if @options[:development] and dependency.type == :development
331
340
  return true if installed_specs.detect { |s| dependency.matches_spec? s }
332
341
  return false if @only_install_dir
333
342
  not dependency.matching_specs.empty?
@@ -672,14 +681,14 @@ TEXT
672
681
  # return the stub script text used to launch the true Ruby script
673
682
 
674
683
  def windows_stub_script(bindir, bin_file_name)
675
- ruby = File.basename(Gem.ruby).chomp('"')
684
+ ruby = Gem.ruby.chomp('"').tr(File::SEPARATOR, "\\")
676
685
  return <<-TEXT
677
686
  @ECHO OFF
678
687
  IF NOT "%~f0" == "~f0" GOTO :WinNT
679
- @"#{bindir.tr(File::SEPARATOR, File::ALT_SEPARATOR)}\\#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
688
+ @"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
680
689
  GOTO :EOF
681
690
  :WinNT
682
- @"%~dp0#{ruby}" "%~dpn0" %*
691
+ @"#{ruby}" "%~dpn0" %*
683
692
  TEXT
684
693
  end
685
694
 
@@ -101,7 +101,7 @@ module Gem::LocalRemoteOptions
101
101
  accept_uri_http
102
102
 
103
103
  add_option(:"Local/Remote", '-s', '--source URL', URI::HTTP,
104
- 'Add URL as a remote source for gems') do |source, options|
104
+ 'Append URL to list of remote gem sources') do |source, options|
105
105
 
106
106
  source << '/' if source !~ /\/\z/
107
107
 
@@ -129,6 +129,8 @@ class Gem::Package::TarReader::Entry
129
129
  ret
130
130
  end
131
131
 
132
+ alias readpartial read # :nodoc:
133
+
132
134
  ##
133
135
  # Rewinds to the beginning of the tar file entry
134
136
 
@@ -279,7 +279,6 @@ class Gem::RDoc # :nodoc: all
279
279
  ui.errs.puts "... RDOC args: #{args.join(' ')}"
280
280
  ui.backtrace ex
281
281
  ui.errs.puts "(continuing with the rest of the installation)"
282
- ensure
283
282
  end
284
283
  end
285
284
  end
@@ -47,11 +47,13 @@ class Gem::Request::ConnectionPools # :nodoc:
47
47
 
48
48
  def no_proxy? host, env_no_proxy
49
49
  host = host.downcase
50
- env_no_proxy.each do |pattern|
50
+
51
+ env_no_proxy.any? do |pattern|
51
52
  pattern = pattern.downcase
52
- return true if host[-pattern.length, pattern.length ] == pattern
53
+
54
+ host[-pattern.length, pattern.length] == pattern or
55
+ (pattern.start_with? '.' and pattern[1..-1] == host)
53
56
  end
54
- return false
55
57
  end
56
58
 
57
59
  def net_http_args uri, proxy_uri
@@ -47,6 +47,13 @@ class Gem::RequestSet
47
47
 
48
48
  attr_accessor :ignore_dependencies
49
49
 
50
+ attr_reader :install_dir # :nodoc:
51
+
52
+ ##
53
+ # If true, allow dependencies to match prerelease gems.
54
+
55
+ attr_accessor :prerelease
56
+
50
57
  ##
51
58
  # When false no remote sets are used for resolving gems.
52
59
 
@@ -90,6 +97,7 @@ class Gem::RequestSet
90
97
  @git_set = nil
91
98
  @ignore_dependencies = false
92
99
  @install_dir = Gem.dir
100
+ @prerelease = false
93
101
  @remote = true
94
102
  @requests = []
95
103
  @sets = []
@@ -135,6 +143,7 @@ class Gem::RequestSet
135
143
  end
136
144
 
137
145
  cache_dir = options[:cache_dir] || Gem.dir
146
+ @prerelease = options[:prerelease]
138
147
 
139
148
  requests = []
140
149
 
@@ -191,6 +200,7 @@ class Gem::RequestSet
191
200
  gemdeps = options[:gemdeps]
192
201
 
193
202
  @install_dir = options[:install_dir] || Gem.dir
203
+ @prerelease = options[:prerelease]
194
204
  @remote = options[:domain] != :local
195
205
  @conservative = true if options[:conservative]
196
206
 
@@ -234,6 +244,7 @@ class Gem::RequestSet
234
244
  options[:development] = false
235
245
  options[:install_dir] = dir
236
246
  options[:only_install_dir] = true
247
+ @prerelease = options[:prerelease]
237
248
 
238
249
  sorted_requests.each do |request|
239
250
  spec = request.spec
@@ -273,6 +284,48 @@ class Gem::RequestSet
273
284
  gf.load
274
285
  end
275
286
 
287
+ def pretty_print q # :nodoc:
288
+ q.group 2, '[RequestSet:', ']' do
289
+ q.breakable
290
+
291
+ if @remote then
292
+ q.text 'remote'
293
+ q.breakable
294
+ end
295
+
296
+ if @prerelease then
297
+ q.text 'prerelease'
298
+ q.breakable
299
+ end
300
+
301
+ if @development_shallow then
302
+ q.text 'shallow development'
303
+ q.breakable
304
+ elsif @development then
305
+ q.text 'development'
306
+ q.breakable
307
+ end
308
+
309
+ if @soft_missing then
310
+ q.text 'soft missing'
311
+ end
312
+
313
+ q.group 2, '[dependencies:', ']' do
314
+ q.breakable
315
+ @dependencies.map do |dep|
316
+ q.text dep.to_s
317
+ q.breakable
318
+ end
319
+ end
320
+
321
+ q.breakable
322
+ q.text 'sets:'
323
+
324
+ q.breakable
325
+ q.pp @sets.map { |set| set.class }
326
+ end
327
+ end
328
+
276
329
  ##
277
330
  # Resolve the requested dependencies and return an Array of Specification
278
331
  # objects to be activated.
@@ -284,6 +337,7 @@ class Gem::RequestSet
284
337
 
285
338
  set = Gem::Resolver.compose_sets(*@sets)
286
339
  set.remote = @remote
340
+ set.prerelease = @prerelease
287
341
 
288
342
  resolver = Gem::Resolver.new @dependencies, set
289
343
  resolver.development = @development
@@ -338,7 +392,9 @@ class Gem::RequestSet
338
392
  node.spec.dependencies.each do |dep|
339
393
  next if dep.type == :development and not @development
340
394
 
341
- match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
395
+ match = @requests.find { |r|
396
+ dep.match? r.spec.name, r.spec.version, @prerelease
397
+ }
342
398
 
343
399
  unless match then
344
400
  next if dep.type == :development and @development_shallow
@@ -200,11 +200,26 @@ class Gem::RequestSet::GemDependencyAPI
200
200
  @dependencies = {}
201
201
  @default_sources = true
202
202
  @git_set = @set.git_set
203
+ @git_sources = {}
203
204
  @installing = false
204
205
  @requires = Hash.new { |h, name| h[name] = [] }
205
206
  @vendor_set = @set.vendor_set
206
207
  @gem_sources = {}
207
208
  @without_groups = []
209
+
210
+ git_source :github do |repo_name|
211
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"
212
+
213
+ "git://github.com/#{repo_name}.git"
214
+ end
215
+
216
+ git_source :bitbucket do |repo_name|
217
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"
218
+
219
+ user, = repo_name.split "/", 2
220
+
221
+ "https://#{user}@bitbucket.org/#{repo_name}.git"
222
+ end
208
223
  end
209
224
 
210
225
  ##
@@ -344,9 +359,11 @@ class Gem::RequestSet::GemDependencyAPI
344
359
 
345
360
  source_set = false
346
361
 
347
- source_set ||= gem_path name, options
348
- source_set ||= gem_git name, options
349
- source_set ||= gem_github name, options
362
+ source_set ||= gem_path name, options
363
+ source_set ||= gem_git name, options
364
+ source_set ||= gem_git_source name, options
365
+
366
+ duplicate = @dependencies.include? name
350
367
 
351
368
  @dependencies[name] =
352
369
  if requirements.empty? and not source_set then
@@ -367,6 +384,12 @@ class Gem::RequestSet::GemDependencyAPI
367
384
 
368
385
  gem_requires name, options
369
386
 
387
+ if duplicate then
388
+ warn <<-WARNING
389
+ Gem dependencies file #{@path} requires #{name} more than once.
390
+ WARNING
391
+ end
392
+
370
393
  @set.gem name, *requirements
371
394
  end
372
395
 
@@ -400,21 +423,27 @@ class Gem::RequestSet::GemDependencyAPI
400
423
  private :gem_git
401
424
 
402
425
  ##
403
- # Handles the github: option from +options+ for gem +name+.
426
+ # Handles a git gem option from +options+ for gem +name+ for a git source
427
+ # registered through git_source.
404
428
  #
405
- # Returns +true+ if the path option was handled.
429
+ # Returns +true+ if the custom source option was handled.
406
430
 
407
- def gem_github name, options # :nodoc:
408
- return unless path = options.delete(:github)
431
+ def gem_git_source name, options # :nodoc:
432
+ return unless git_source = (@git_sources.keys & options.keys).last
409
433
 
410
- options[:git] = "git://github.com/#{path}.git"
434
+ source_callback = @git_sources[git_source]
435
+ source_param = options.delete git_source
436
+
437
+ git_url = source_callback.call source_param
438
+
439
+ options[:git] = git_url
411
440
 
412
441
  gem_git name, options
413
442
 
414
443
  true
415
444
  end
416
445
 
417
- private :gem_github
446
+ private :gem_git_source
418
447
 
419
448
  ##
420
449
  # Handles the :group and :groups +options+ for the gem with the given
@@ -456,7 +485,8 @@ class Gem::RequestSet::GemDependencyAPI
456
485
  # platform matches the current platform.
457
486
 
458
487
  def gem_platforms options # :nodoc:
459
- platform_names = Array(options.delete :platforms)
488
+ platform_names = Array(options.delete :platform)
489
+ platform_names.concat Array(options.delete :platforms)
460
490
  platform_names.concat @current_platforms if @current_platforms
461
491
 
462
492
  return true if platform_names.empty?
@@ -519,6 +549,15 @@ class Gem::RequestSet::GemDependencyAPI
519
549
  @current_repository = nil
520
550
  end
521
551
 
552
+ ##
553
+ # Defines a custom git source that uses +name+ to expand git repositories
554
+ # for use in gems built from git repositories. You must provide a block
555
+ # that accepts a git repository name for expansion.
556
+
557
+ def git_source name, &callback
558
+ @git_sources[name] = callback
559
+ end
560
+
522
561
  ##
523
562
  # Returns the basename of the file the dependencies were loaded from
524
563
 
@@ -557,8 +596,17 @@ class Gem::RequestSet::GemDependencyAPI
557
596
 
558
597
  groups = gem_group spec.name, {}
559
598
 
599
+ self_dep = Gem::Dependency.new spec.name, spec.version
600
+
601
+ add_dependencies groups, [self_dep]
560
602
  add_dependencies groups, spec.runtime_dependencies
561
603
 
604
+ @dependencies[spec.name] = '!'
605
+
606
+ spec.dependencies.each do |dep|
607
+ @dependencies[dep.name] = dep.requirement
608
+ end
609
+
562
610
  groups << development_group
563
611
 
564
612
  add_dependencies groups, spec.development_dependencies