bundler 1.13.0.rc.1 → 1.13.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -0
  3. data/.rubocop.yml +8 -0
  4. data/.rubocop_todo.yml +21 -21
  5. data/.travis.yml +5 -1
  6. data/CHANGELOG.md +33 -1
  7. data/DEVELOPMENT.md +1 -1
  8. data/Rakefile +21 -12
  9. data/bin/rake +1 -1
  10. data/bin/rspec +1 -1
  11. data/bin/rubocop +2 -2
  12. data/bundler.gemspec +2 -2
  13. data/exe/bundler +1 -19
  14. data/lib/bundler.rb +43 -34
  15. data/lib/bundler/cli.rb +54 -5
  16. data/lib/bundler/cli/binstubs.rb +3 -2
  17. data/lib/bundler/cli/console.rb +3 -0
  18. data/lib/bundler/cli/doctor.rb +95 -0
  19. data/lib/bundler/cli/exec.rb +18 -2
  20. data/lib/bundler/cli/gem.rb +1 -1
  21. data/lib/bundler/cli/inject.rb +25 -7
  22. data/lib/bundler/cli/install.rb +23 -2
  23. data/lib/bundler/cli/lock.rb +14 -2
  24. data/lib/bundler/cli/update.rb +9 -0
  25. data/lib/bundler/definition.rb +86 -17
  26. data/lib/bundler/deployment.rb +6 -0
  27. data/lib/bundler/dsl.rb +67 -22
  28. data/lib/bundler/env.rb +1 -1
  29. data/lib/bundler/environment_preserver.rb +1 -1
  30. data/lib/bundler/errors.rb +11 -1
  31. data/lib/bundler/fetcher.rb +3 -2
  32. data/lib/bundler/fetcher/base.rb +10 -0
  33. data/lib/bundler/fetcher/compact_index.rb +27 -9
  34. data/lib/bundler/fetcher/dependency.rb +1 -12
  35. data/lib/bundler/fetcher/downloader.rb +1 -1
  36. data/lib/bundler/friendly_errors.rb +4 -2
  37. data/lib/bundler/gem_helper.rb +2 -2
  38. data/lib/bundler/gem_version_promoter.rb +175 -0
  39. data/lib/bundler/graph.rb +4 -25
  40. data/lib/bundler/index.rb +9 -1
  41. data/lib/bundler/injector.rb +12 -5
  42. data/lib/bundler/inline.rb +2 -2
  43. data/lib/bundler/installer.rb +23 -8
  44. data/lib/bundler/installer/gem_installer.rb +13 -15
  45. data/lib/bundler/installer/parallel_installer.rb +121 -99
  46. data/lib/bundler/lazy_specification.rb +8 -2
  47. data/lib/bundler/lockfile_parser.rb +20 -12
  48. data/lib/bundler/mirror.rb +2 -2
  49. data/lib/bundler/plugin.rb +153 -31
  50. data/lib/bundler/plugin/api.rb +29 -5
  51. data/lib/bundler/plugin/api/source.rb +293 -0
  52. data/lib/bundler/plugin/dsl.rb +25 -1
  53. data/lib/bundler/plugin/index.rb +80 -13
  54. data/lib/bundler/plugin/installer.rb +6 -10
  55. data/lib/bundler/plugin/source_list.rb +4 -0
  56. data/lib/bundler/postit_trampoline.rb +57 -40
  57. data/lib/bundler/resolver.rb +24 -12
  58. data/lib/bundler/retry.rb +2 -1
  59. data/lib/bundler/ruby_version.rb +4 -2
  60. data/lib/bundler/rubygems_ext.rb +10 -3
  61. data/lib/bundler/rubygems_gem_installer.rb +6 -0
  62. data/lib/bundler/rubygems_integration.rb +101 -66
  63. data/lib/bundler/runtime.rb +25 -2
  64. data/lib/bundler/settings.rb +30 -11
  65. data/lib/bundler/setup.rb +6 -3
  66. data/lib/bundler/shared_helpers.rb +11 -5
  67. data/lib/bundler/source/gemspec.rb +4 -0
  68. data/lib/bundler/source/git.rb +9 -6
  69. data/lib/bundler/source/git/git_proxy.rb +27 -3
  70. data/lib/bundler/source/path.rb +4 -26
  71. data/lib/bundler/source/path/installer.rb +39 -11
  72. data/lib/bundler/source/rubygems.rb +1 -1
  73. data/lib/bundler/source_list.rb +28 -8
  74. data/lib/bundler/spec_set.rb +1 -1
  75. data/lib/bundler/templates/Executable.standalone +4 -2
  76. data/lib/bundler/templates/Gemfile +0 -1
  77. data/lib/bundler/ui/shell.rb +11 -3
  78. data/lib/bundler/ui/silent.rb +1 -3
  79. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +1 -2
  80. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/cache.rb +16 -2
  81. data/lib/bundler/version.rb +1 -1
  82. data/lib/bundler/yaml_serializer.rb +34 -11
  83. data/man/bundle-binstubs.ronn +29 -0
  84. data/man/bundle-config.ronn +32 -0
  85. data/man/bundle-install.ronn +6 -41
  86. data/man/bundle-package.ronn +1 -1
  87. data/man/bundle.ronn +4 -3
  88. data/man/gemfile.5.ronn +1 -1
  89. metadata +13 -9
  90. data/lib/bundler/environment.rb +0 -42
@@ -42,7 +42,7 @@ module Bundler
42
42
  PATTERN = /
43
43
  ruby\s
44
44
  ([\d.]+) # ruby version
45
- (?:p(\d+))? # optional patchlevel
45
+ (?:p(-?\d+))? # optional patchlevel
46
46
  (?:\s\((\S+)\s(.+)\))? # optional engine info
47
47
  /xo
48
48
 
@@ -115,7 +115,9 @@ module Bundler
115
115
  else
116
116
  raise BundlerError, "RUBY_ENGINE value #{RUBY_ENGINE} is not recognized"
117
117
  end
118
- @ruby_version ||= RubyVersion.new(ruby_version, RUBY_PATCHLEVEL.to_s, ruby_engine, ruby_engine_version)
118
+ patchlevel = RUBY_PATCHLEVEL.to_s
119
+
120
+ @ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version)
119
121
  end
120
122
 
121
123
  def to_gem_version_with_patchlevel
@@ -16,8 +16,15 @@ module Gem
16
16
  class Specification
17
17
  attr_accessor :remote, :location, :relative_loaded_from
18
18
 
19
- remove_method :source if instance_methods(false).include?(:source)
20
- attr_accessor :source
19
+ if instance_methods(false).map(&:to_sym).include?(:source)
20
+ remove_method :source
21
+ attr_writer :source
22
+ def source
23
+ (defined?(@source) && @source) || Gem::Source::Installed.new
24
+ end
25
+ else
26
+ attr_accessor :source
27
+ end
21
28
 
22
29
  alias_method :rg_full_gem_path, :full_gem_path
23
30
  alias_method :rg_loaded_from, :loaded_from
@@ -25,7 +32,7 @@ module Gem
25
32
  attr_writer :full_gem_path unless instance_methods.include?(:full_gem_path=)
26
33
 
27
34
  def full_gem_path
28
- if source.respond_to?(:path)
35
+ if source.respond_to?(:path) || source.is_a?(Bundler::Plugin::API::Source)
29
36
  Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.untaint
30
37
  else
31
38
  rg_full_gem_path
@@ -3,6 +3,12 @@ require "rubygems/installer"
3
3
 
4
4
  module Bundler
5
5
  class RubyGemsGemInstaller < Gem::Installer
6
+ unless respond_to?(:at)
7
+ def self.at(*args)
8
+ new(*args)
9
+ end
10
+ end
11
+
6
12
  def check_executable_overwrite(filename)
7
13
  # Bundler needs to install gems regardless of binstub overwriting
8
14
  end
@@ -19,6 +19,10 @@ module Bundler
19
19
  Gem::Requirement.new(req_str).satisfied_by?(version)
20
20
  end
21
21
 
22
+ def initialize
23
+ @replaced_methods = {}
24
+ end
25
+
22
26
  def version
23
27
  self.class.version
24
28
  end
@@ -132,6 +136,14 @@ module Bundler
132
136
  Gem.path
133
137
  end
134
138
 
139
+ def reset
140
+ Gem::Specification.reset
141
+ end
142
+
143
+ def post_reset_hooks
144
+ Gem.post_reset_hooks
145
+ end
146
+
135
147
  def gem_cache
136
148
  gem_path.map {|p| File.expand_path("cache", p) }
137
149
  end
@@ -265,7 +277,9 @@ module Bundler
265
277
  def download_gem(spec, uri, path)
266
278
  uri = Bundler.settings.mirror_for(uri)
267
279
  fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
268
- fetcher.download(spec, uri, path)
280
+ Bundler::Retry.new("download gem #{uri}", Gem::RemoteFetcher::FetchError).attempts do
281
+ fetcher.download(spec, uri, path)
282
+ end
269
283
  end
270
284
 
271
285
  def security_policy_keys
@@ -283,13 +297,11 @@ module Bundler
283
297
 
284
298
  def reverse_rubygems_kernel_mixin
285
299
  # Disable rubygems' gem activation system
286
- ::Kernel.class_eval do
287
- if private_method_defined?(:gem_original_require)
288
- alias_method :rubygems_require, :require
289
- alias_method :require, :gem_original_require
300
+ kernel = (class << ::Kernel; self; end)
301
+ [kernel, ::Kernel].each do |k|
302
+ if k.private_method_defined?(:gem_original_require)
303
+ redefine_method(k, :require, k.instance_method(:gem_original_require))
290
304
  end
291
-
292
- undef gem
293
305
  end
294
306
  end
295
307
 
@@ -298,41 +310,44 @@ module Bundler
298
310
 
299
311
  executables = specs.map(&:executables).flatten
300
312
 
301
- ::Kernel.send(:define_method, :gem) do |dep, *reqs|
302
- if executables.include? File.basename(caller.first.split(":").first)
303
- break
304
- end
305
- reqs.pop if reqs.last.is_a?(Hash)
306
-
307
- unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
308
- dep = Gem::Dependency.new(dep, reqs)
309
- end
310
-
311
- spec = specs.find {|s| s.name == dep.name }
312
-
313
- if spec.nil?
313
+ kernel = (class << ::Kernel; self; end)
314
+ [kernel, ::Kernel].each do |kernel_class|
315
+ redefine_method(kernel_class, :gem) do |dep, *reqs|
316
+ if executables.include? File.basename(caller.first.split(":").first)
317
+ break
318
+ end
319
+ reqs.pop if reqs.last.is_a?(Hash)
314
320
 
315
- e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
316
- e.name = dep.name
317
- if e.respond_to?(:requirement=)
318
- e.requirement = dep.requirement
319
- else
320
- e.version_requirement = dep.requirement
321
+ unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
322
+ dep = Gem::Dependency.new(dep, reqs)
321
323
  end
322
- raise e
323
- elsif dep !~ spec
324
- e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
325
- "Make sure all dependencies are added to Gemfile."
326
- e.name = dep.name
327
- if e.respond_to?(:requirement=)
328
- e.requirement = dep.requirement
329
- else
330
- e.version_requirement = dep.requirement
324
+
325
+ spec = specs.find {|s| s.name == dep.name }
326
+
327
+ if spec.nil?
328
+
329
+ e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
330
+ e.name = dep.name
331
+ if e.respond_to?(:requirement=)
332
+ e.requirement = dep.requirement
333
+ else
334
+ e.version_requirement = dep.requirement
335
+ end
336
+ raise e
337
+ elsif dep !~ spec
338
+ e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
339
+ "Make sure all dependencies are added to Gemfile."
340
+ e.name = dep.name
341
+ if e.respond_to?(:requirement=)
342
+ e.requirement = dep.requirement
343
+ else
344
+ e.version_requirement = dep.requirement
345
+ end
346
+ raise e
331
347
  end
332
- raise e
333
- end
334
348
 
335
- true
349
+ true
350
+ end
336
351
  end
337
352
  end
338
353
 
@@ -463,9 +478,19 @@ module Bundler
463
478
  end
464
479
  end
465
480
 
466
- def redefine_method(klass, method, &block)
481
+ def undo_replacements
482
+ @replaced_methods.each do |(sym, klass), method|
483
+ redefine_method(klass, sym, method)
484
+ end
485
+ post_reset_hooks.reject! do |proc|
486
+ proc.binding.eval("__FILE__") == __FILE__
487
+ end
488
+ @replaced_methods.clear
489
+ end
490
+
491
+ def redefine_method(klass, method, unbound_method = nil, &block)
467
492
  begin
468
- if klass.instance_method(method) && method != :initialize
493
+ if (instance_method = klass.instance_method(method)) && method != :initialize
469
494
  # doing this to ensure we also get private methods
470
495
  klass.send(:remove_method, method)
471
496
  end
@@ -473,7 +498,12 @@ module Bundler
473
498
  # method isn't defined
474
499
  nil
475
500
  end
476
- klass.send(:define_method, method, &block)
501
+ @replaced_methods[[method, klass]] = instance_method
502
+ if unbound_method
503
+ klass.send(:define_method, method, unbound_method)
504
+ elsif block
505
+ klass.send(:define_method, method, &block)
506
+ end
477
507
  end
478
508
 
479
509
  # Rubygems 1.4 through 1.6
@@ -489,11 +519,11 @@ module Bundler
489
519
  def stub_rubygems(specs)
490
520
  # Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
491
521
  source_index_class = (class << Gem::SourceIndex; self; end)
492
- source_index_class.send(:define_method, :from_gems_in) do |*args|
493
- source_index = Gem::SourceIndex.new
494
- source_index.spec_dirs = *args
495
- source_index.add_specs(*specs)
496
- source_index
522
+ redefine_method(source_index_class, :from_gems_in) do |*args|
523
+ Gem::SourceIndex.new.tap do |source_index|
524
+ source_index.spec_dirs = *args
525
+ source_index.add_specs(*specs)
526
+ end
497
527
  end
498
528
  end
499
529
 
@@ -510,6 +540,13 @@ module Bundler
510
540
  # which is too strict for the kinds of checks we care about. As a
511
541
  # result, validation is disabled on versions of RubyGems below 1.7.
512
542
  end
543
+
544
+ def post_reset_hooks
545
+ []
546
+ end
547
+
548
+ def reset
549
+ end
513
550
  end
514
551
 
515
552
  # Rubygems versions 1.3.6 and 1.3.7
@@ -688,25 +725,23 @@ module Bundler
688
725
  end
689
726
  end
690
727
 
691
- if RubygemsIntegration.provides?(">= 2.1.0")
692
- @rubygems = RubygemsIntegration::MoreFuture.new
693
- elsif RubygemsIntegration.provides?(">= 1.99.99")
694
- @rubygems = RubygemsIntegration::Future.new
695
- elsif RubygemsIntegration.provides?(">= 1.8.20")
696
- @rubygems = RubygemsIntegration::MoreModern.new
697
- elsif RubygemsIntegration.provides?(">= 1.8.5")
698
- @rubygems = RubygemsIntegration::Modern.new
699
- elsif RubygemsIntegration.provides?(">= 1.8.0")
700
- @rubygems = RubygemsIntegration::AlmostModern.new
701
- elsif RubygemsIntegration.provides?(">= 1.7.0")
702
- @rubygems = RubygemsIntegration::Transitional.new
703
- elsif RubygemsIntegration.provides?(">= 1.4.0")
704
- @rubygems = RubygemsIntegration::Legacy.new
705
- else # Rubygems 1.3.6 and 1.3.7
706
- @rubygems = RubygemsIntegration::Ancient.new
707
- end
708
-
709
- class << self
710
- attr_reader :rubygems
728
+ def self.rubygems
729
+ @rubygems ||= if RubygemsIntegration.provides?(">= 2.1.0")
730
+ RubygemsIntegration::MoreFuture.new
731
+ elsif RubygemsIntegration.provides?(">= 1.99.99")
732
+ RubygemsIntegration::Future.new
733
+ elsif RubygemsIntegration.provides?(">= 1.8.20")
734
+ RubygemsIntegration::MoreModern.new
735
+ elsif RubygemsIntegration.provides?(">= 1.8.5")
736
+ RubygemsIntegration::Modern.new
737
+ elsif RubygemsIntegration.provides?(">= 1.8.0")
738
+ RubygemsIntegration::AlmostModern.new
739
+ elsif RubygemsIntegration.provides?(">= 1.7.0")
740
+ RubygemsIntegration::Transitional.new
741
+ elsif RubygemsIntegration.provides?(">= 1.4.0")
742
+ RubygemsIntegration::Legacy.new
743
+ else # Rubygems 1.3.6 and 1.3.7
744
+ RubygemsIntegration::Ancient.new
745
+ end
711
746
  end
712
747
  end
@@ -2,9 +2,14 @@
2
2
  require "digest/sha1"
3
3
 
4
4
  module Bundler
5
- class Runtime < Environment
5
+ class Runtime
6
6
  include SharedHelpers
7
7
 
8
+ def initialize(root, definition)
9
+ @root = root
10
+ @definition = definition
11
+ end
12
+
8
13
  def setup(*groups)
9
14
  groups.map!(&:to_sym)
10
15
 
@@ -107,6 +112,24 @@ module Bundler
107
112
  end
108
113
  end
109
114
 
115
+ def self.definition_method(meth)
116
+ define_method(meth) do
117
+ raise ArgumentError, "no definition when calling Runtime##{meth}" unless @definition
118
+ @definition.send(meth)
119
+ end
120
+ end
121
+ private_class_method :definition_method
122
+
123
+ definition_method :requested_specs
124
+ definition_method :specs
125
+ definition_method :dependencies
126
+ definition_method :current_dependencies
127
+ definition_method :requires
128
+
129
+ def lock(opts = {})
130
+ @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
131
+ end
132
+
110
133
  alias_method :gems, :specs
111
134
 
112
135
  def cache(custom_path = nil)
@@ -247,7 +270,7 @@ module Bundler
247
270
 
248
271
  def setup_manpath
249
272
  # Store original MANPATH for restoration later in with_clean_env()
250
- ENV["BUNDLE_ORIG_MANPATH"] = ENV["MANPATH"]
273
+ ENV["BUNDLER_ORIG_MANPATH"] = ENV["MANPATH"]
251
274
 
252
275
  # Add man/ subdirectories from activated bundles to MANPATH for man(1)
253
276
  manuals = $LOAD_PATH.map do |path|
@@ -4,7 +4,9 @@ require "uri"
4
4
  module Bundler
5
5
  class Settings
6
6
  BOOL_KEYS = %w(
7
+ allow_offline_install
7
8
  cache_all
9
+ disable_exec_load
8
10
  disable_local_branch_check
9
11
  disable_shared_gems
10
12
  frozen
@@ -14,6 +16,7 @@ module Bundler
14
16
  major_deprecations
15
17
  no_install
16
18
  no_prune
19
+ only_update_to_newer_versions
17
20
  plugins
18
21
  silence_root_warning
19
22
  ).freeze
@@ -31,22 +34,24 @@ module Bundler
31
34
  :timeout => 10,
32
35
  }.freeze
33
36
 
37
+ attr_accessor :cli_flags_given
38
+
34
39
  def initialize(root = nil)
35
- @root = root
36
- @local_config = load_config(local_config_file)
37
- @global_config = load_config(global_config_file)
40
+ @root = root
41
+ @local_config = load_config(local_config_file)
42
+ @global_config = load_config(global_config_file)
43
+ @cli_flags_given = false
38
44
  end
39
45
 
40
46
  def [](name)
41
47
  key = key_for(name)
42
48
  value = (@local_config[key] || ENV[key] || @global_config[key] || DEFAULT_CONFIG[name])
43
49
 
44
- case
45
- when value.nil?
50
+ if value.nil?
46
51
  nil
47
- when is_bool(name) || value == "false"
52
+ elsif is_bool(name) || value == "false"
48
53
  to_bool(value)
49
- when is_num(name)
54
+ elsif is_num(name)
50
55
  value.to_i
51
56
  else
52
57
  value
@@ -54,6 +59,19 @@ module Bundler
54
59
  end
55
60
 
56
61
  def []=(key, value)
62
+ if cli_flags_given
63
+ command = if value.nil?
64
+ "bundle config --delete #{key}"
65
+ else
66
+ "bundle config #{key} #{Array(value).join(":")}"
67
+ end
68
+
69
+ Bundler::SharedHelpers.major_deprecation \
70
+ "flags passed to commands " \
71
+ "will no longer be automatically remembered. Instead please set flags " \
72
+ "you want remembered between commands using `bundle config " \
73
+ "<setting name> <setting value>`, i.e. `#{command}`"
74
+ end
57
75
  local_config_file || raise(GemfileNotFound, "Could not locate Gemfile")
58
76
  set_key(key, value, @local_config, local_config_file)
59
77
  end
@@ -260,11 +278,12 @@ module Bundler
260
278
  }xo
261
279
 
262
280
  def load_config(config_file)
263
- SharedHelpers.filesystem_access(config_file, :read) do
264
- valid_file = config_file && config_file.exist? && !config_file.size.zero?
281
+ return unless config_file
282
+ SharedHelpers.filesystem_access(config_file, :read) do |file|
283
+ valid_file = file.exist? && !file.size.zero?
265
284
  return {} if ignore_config? || !valid_file
266
285
  require "bundler/yaml_serializer"
267
- YAMLSerializer.load config_file.read
286
+ YAMLSerializer.load file.read
268
287
  end
269
288
  end
270
289
 
@@ -275,7 +294,7 @@ module Bundler
275
294
  uri = "#{uri}/" unless uri =~ %r{/\Z}
276
295
  uri = URI(uri)
277
296
  unless uri.absolute?
278
- raise ArgumentError, "Gem sources must be absolute. You provided '#{uri}'."
297
+ raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri)
279
298
  end
280
299
  uri
281
300
  end
@@ -20,9 +20,12 @@ if Bundler::SharedHelpers.in_bundle?
20
20
  Bundler.setup
21
21
  end
22
22
 
23
- # Add bundler to the load path after disabling system gems
24
- bundler_lib = File.expand_path("../..", __FILE__)
25
- $LOAD_PATH.unshift(bundler_lib) unless $LOAD_PATH.include?(bundler_lib)
23
+ unless ENV["BUNDLE_POSTIT_TRAMPOLINING_VERSION"]
24
+ # Add bundler to the load path after disabling system gems
25
+ # This is guarenteed to be done already if we've trampolined
26
+ bundler_lib = File.expand_path("../..", __FILE__)
27
+ $LOAD_PATH.unshift(bundler_lib) unless $LOAD_PATH.include?(bundler_lib)
28
+ end
26
29
 
27
30
  Bundler.ui = nil
28
31
  end