bundler 1.9.10 → 1.10.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +21 -13
  4. data/Rakefile +2 -2
  5. data/bin/bundle_ruby +2 -0
  6. data/bin/bundler +1 -1
  7. data/lib/bundler.rb +6 -10
  8. data/lib/bundler/cli.rb +23 -1
  9. data/lib/bundler/cli/gem.rb +5 -2
  10. data/lib/bundler/cli/install.rb +37 -5
  11. data/lib/bundler/cli/lock.rb +36 -0
  12. data/lib/bundler/cli/outdated.rb +9 -2
  13. data/lib/bundler/definition.rb +22 -7
  14. data/lib/bundler/dependency.rb +7 -6
  15. data/lib/bundler/deployment.rb +3 -0
  16. data/lib/bundler/dsl.rb +172 -39
  17. data/lib/bundler/endpoint_specification.rb +1 -1
  18. data/lib/bundler/fetcher.rb +90 -252
  19. data/lib/bundler/fetcher/base.rb +27 -0
  20. data/lib/bundler/fetcher/dependency.rb +88 -0
  21. data/lib/bundler/fetcher/downloader.rb +61 -0
  22. data/lib/bundler/fetcher/index.rb +31 -0
  23. data/lib/bundler/friendly_errors.rb +3 -0
  24. data/lib/bundler/inline.rb +50 -0
  25. data/lib/bundler/installer.rb +15 -60
  26. data/lib/bundler/installer/parallel_installer.rb +117 -0
  27. data/lib/bundler/lazy_specification.rb +1 -1
  28. data/lib/bundler/lockfile_parser.rb +26 -10
  29. data/lib/bundler/remote_specification.rb +21 -1
  30. data/lib/bundler/resolver.rb +2 -1
  31. data/lib/bundler/retry.rb +11 -10
  32. data/lib/bundler/rubygems_ext.rb +1 -1
  33. data/lib/bundler/rubygems_integration.rb +33 -6
  34. data/lib/bundler/settings.rb +58 -14
  35. data/lib/bundler/shared_helpers.rb +6 -3
  36. data/lib/bundler/source.rb +0 -10
  37. data/lib/bundler/source/git.rb +2 -2
  38. data/lib/bundler/source/path.rb +1 -1
  39. data/lib/bundler/source/path/installer.rb +8 -11
  40. data/lib/bundler/source/rubygems.rb +46 -16
  41. data/lib/bundler/source/rubygems/remote.rb +39 -0
  42. data/lib/bundler/templates/newgem/.travis.yml.tt +1 -0
  43. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +2 -2
  44. data/lib/bundler/templates/newgem/Rakefile.tt +2 -0
  45. data/lib/bundler/templates/newgem/test/{test_newgem.rb.tt → newgem_test.rb.tt} +2 -2
  46. data/lib/bundler/templates/newgem/test/{minitest_helper.rb.tt → test_helper.rb.tt} +0 -0
  47. data/lib/bundler/version.rb +1 -1
  48. data/man/bundle-config.ronn +7 -0
  49. data/man/bundle-install.ronn +9 -0
  50. data/man/bundle.ronn +3 -3
  51. data/man/gemfile.5.ronn +9 -5
  52. metadata +13 -8
  53. data/UPGRADING.md +0 -103
  54. data/lib/bundler/anonymizable_uri.rb +0 -32
@@ -7,7 +7,7 @@ module Bundler
7
7
  include MatchPlatform
8
8
 
9
9
  attr_reader :name, :version, :dependencies, :platform
10
- attr_accessor :source, :source_uri
10
+ attr_accessor :source, :remote
11
11
 
12
12
  def initialize(name, version, platform, source = nil)
13
13
  @name = name
@@ -12,8 +12,9 @@ require "strscan"
12
12
 
13
13
  module Bundler
14
14
  class LockfileParser
15
- attr_reader :sources, :dependencies, :specs, :platforms
15
+ attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version
16
16
 
17
+ BUNDLED = "BUNDLED WITH"
17
18
  DEPENDENCIES = "DEPENDENCIES"
18
19
  PLATFORMS = "PLATFORMS"
19
20
  GIT = "GIT"
@@ -21,13 +22,12 @@ module Bundler
21
22
  PATH = "PATH"
22
23
  SPECS = " specs:"
23
24
  OPTIONS = /^ ([a-z]+): (.*)$/i
24
- SOURCE = [GIT, GEM, PATH]
25
25
 
26
26
  def initialize(lockfile)
27
27
  @platforms = []
28
28
  @sources = []
29
29
  @dependencies = []
30
- @state = nil
30
+ @state = :source
31
31
  @specs = {}
32
32
 
33
33
  @rubygems_aggregate = Source::Rubygems.new
@@ -38,27 +38,36 @@ module Bundler
38
38
  end
39
39
 
40
40
  lockfile.split(/(?:\r?\n)+/).each do |line|
41
- if SOURCE.include?(line)
42
- @state = :source
43
- parse_source(line)
44
- elsif line == DEPENDENCIES
41
+ if line == DEPENDENCIES
45
42
  @state = :dependency
46
43
  elsif line == PLATFORMS
47
44
  @state = :platform
48
- elsif line =~ /^[^\s]/
49
- @state = nil
50
- elsif @state
45
+ elsif line == BUNDLED
46
+ @state = :bundled_with
47
+ else
51
48
  send("parse_#{@state}", line)
52
49
  end
53
50
  end
54
51
  @sources << @rubygems_aggregate
55
52
  @specs = @specs.values
53
+ warn_for_outdated_bundler_version
56
54
  rescue ArgumentError => e
57
55
  Bundler.ui.debug(e)
58
56
  raise LockfileError, "Your lockfile is unreadable. Run `rm Gemfile.lock` " \
59
57
  "and then `bundle install` to generate a new lockfile."
60
58
  end
61
59
 
60
+ def warn_for_outdated_bundler_version
61
+ return unless bundler_version
62
+ prerelease_text = bundler_version.prerelease? ? " --pre" : ""
63
+ if Gem::Version.new(Bundler::VERSION) < Gem::Version.new(bundler_version)
64
+ Bundler.ui.warn "Warning: the running version of Bundler is older " \
65
+ "than the version that created the lockfile. We suggest you " \
66
+ "upgrade to the latest version of Bundler by running `gem " \
67
+ "install bundler#{prerelease_text}`.\n"
68
+ end
69
+ end
70
+
62
71
  private
63
72
 
64
73
  TYPES = {
@@ -163,5 +172,12 @@ module Bundler
163
172
  end
164
173
  end
165
174
 
175
+ def parse_bundled_with(line)
176
+ line = line.strip
177
+ if Gem::Version.correct?(line)
178
+ @bundler_version = Gem::Version.create(line)
179
+ end
180
+ end
181
+
166
182
  end
167
183
  end
@@ -10,7 +10,7 @@ module Bundler
10
10
  include MatchPlatform
11
11
 
12
12
  attr_reader :name, :version, :platform
13
- attr_accessor :source, :source_uri
13
+ attr_accessor :source, :remote
14
14
 
15
15
  def initialize(name, version, platform, spec_fetcher)
16
16
  @name = name
@@ -54,4 +54,24 @@ module Bundler
54
54
  end
55
55
  end
56
56
  end
57
+
58
+ class StubSpecification < RemoteSpecification
59
+ def self.from_stub(stub)
60
+ spec = new(stub.name, stub.version, stub.platform, nil)
61
+ spec.stub = stub
62
+ spec
63
+ end
64
+
65
+ attr_accessor :stub
66
+
67
+ def to_yaml
68
+ _remote_specification.to_yaml
69
+ end
70
+
71
+ private
72
+
73
+ def _remote_specification
74
+ stub.to_spec
75
+ end
76
+ end
57
77
  end
@@ -323,7 +323,8 @@ module Bundler
323
323
  message << "Source does not contain any versions of '#{requirement}'"
324
324
  end
325
325
  else
326
- message = "Could not find gem '#{requirement}' in any of the gem sources listed in your Gemfile or installed on this machine."
326
+ message = "Could not find gem '#{requirement}' in any of the gem sources " \
327
+ "listed in your Gemfile or available on this machine."
327
328
  end
328
329
  raise GemNotFound, message
329
330
  end
@@ -1,23 +1,24 @@
1
1
  module Bundler
2
2
  # General purpose class for retrying code that may fail
3
3
  class Retry
4
- DEFAULT_ATTEMPTS = 2
5
4
  attr_accessor :name, :total_runs, :current_run
6
5
 
7
6
  class << self
8
- attr_accessor :attempts
7
+ def default_attempts
8
+ default_retries + 1
9
+ end
10
+ alias_method :attempts, :default_attempts
11
+
12
+ def default_retries
13
+ Bundler.settings[:retry]
14
+ end
9
15
  end
10
16
 
11
- def initialize(name, exceptions = nil, attempts = nil)
17
+ def initialize(name, exceptions = nil, retries = self.class.default_retries)
12
18
  @name = name
13
- attempts ||= default_attempts
19
+ @retries = retries
14
20
  @exceptions = Array(exceptions) || []
15
- @total_runs = attempts.next # will run once, then upto attempts.times
16
- end
17
-
18
- def default_attempts
19
- return Integer(self.class.attempts) if self.class.attempts
20
- DEFAULT_ATTEMPTS
21
+ @total_runs = @retries + 1 # will run once, then upto attempts.times
21
22
  end
22
23
 
23
24
  def attempt(&block)
@@ -13,7 +13,7 @@ module Gem
13
13
  @loaded_stacks = Hash.new { |h,k| h[k] = [] }
14
14
 
15
15
  class Specification
16
- attr_accessor :source_uri, :location, :relative_loaded_from
16
+ attr_accessor :remote, :location, :relative_loaded_from
17
17
 
18
18
  remove_method :source if instance_methods(false).include?(:source)
19
19
  attr_accessor :source
@@ -131,6 +131,19 @@ module Bundler
131
131
  yield
132
132
  end
133
133
 
134
+ def loaded_gem_paths
135
+ # RubyGems 2.2+ can put binary extension into dedicated folders,
136
+ # therefore use RubyGems facilities to obtain their load paths.
137
+ if Gem::Specification.method_defined? :full_require_paths
138
+ loaded_gem_paths = Gem.loaded_specs.map {|n, s| s.full_require_paths}
139
+ loaded_gem_paths.flatten
140
+ else
141
+ $LOAD_PATH.select do |p|
142
+ Bundler.rubygems.gem_path.any?{|gp| p =~ /^#{Regexp.escape(gp)}/ }
143
+ end
144
+ end
145
+ end
146
+
134
147
  def ui=(obj)
135
148
  Gem::DefaultUserInteraction.ui = obj
136
149
  end
@@ -204,7 +217,7 @@ module Bundler
204
217
  end
205
218
 
206
219
  def download_gem(spec, uri, path)
207
- uri = Bundler::Source.mirror_for(uri)
220
+ uri = Bundler.settings.mirror_for(uri)
208
221
  fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
209
222
  fetcher.download(spec, uri, path)
210
223
  end
@@ -538,7 +551,7 @@ module Bundler
538
551
 
539
552
  def download_gem(spec, uri, path)
540
553
  require 'resolv'
541
- uri = Bundler::Source.mirror_for(uri)
554
+ uri = Bundler.settings.mirror_for(uri)
542
555
  proxy, dns = configuration[:http_proxy], Resolv::DNS.new
543
556
  fetcher = Gem::RemoteFetcher.new(proxy, dns)
544
557
  fetcher.download(spec, uri, path)
@@ -561,12 +574,20 @@ module Bundler
561
574
  end
562
575
  end
563
576
 
577
+ # RubyGems 2.1.0
564
578
  class MoreFuture < Future
565
579
  def initialize
566
580
  super
567
581
  backport_ext_builder_monitor
568
582
  end
569
583
 
584
+ def all_specs
585
+ require 'bundler/remote_specification'
586
+ Gem::Specification.stubs.map do |stub|
587
+ StubSpecification.from_stub(stub)
588
+ end
589
+ end
590
+
570
591
  def backport_ext_builder_monitor
571
592
  require 'rubygems/ext'
572
593
 
@@ -586,10 +607,16 @@ module Bundler
586
607
  Gem::Ext::Builder::CHDIR_MONITOR
587
608
  end
588
609
 
589
- def find_name(name)
590
- Gem::Specification.stubs.find_all do |spec|
591
- spec.name == name
592
- end.map(&:to_spec)
610
+ if Gem::Specification.respond_to?(:stubs_for)
611
+ def find_name(name)
612
+ Gem::Specification.stubs_for(name).map(&:to_spec)
613
+ end
614
+ else
615
+ def find_name(name)
616
+ Gem::Specification.stubs.find_all do |spec|
617
+ spec.name == name
618
+ end.map(&:to_spec)
619
+ end
593
620
  end
594
621
  end
595
622
 
@@ -2,7 +2,9 @@ require 'uri'
2
2
 
3
3
  module Bundler
4
4
  class Settings
5
- BOOL_KEYS = %w(frozen cache_all no_prune disable_local_branch_check gem.mit gem.coc).freeze
5
+ BOOL_KEYS = %w(frozen cache_all no_prune disable_local_branch_check ignore_messages gem.mit gem.coc).freeze
6
+ NUMBER_KEYS = %w(retry timeout redirect).freeze
7
+ DEFAULT_CONFIG = {:retry => 3, :timeout => 10, :redirect => 5}
6
8
 
7
9
  def initialize(root = nil)
8
10
  @root = root
@@ -12,10 +14,13 @@ module Bundler
12
14
 
13
15
  def [](name)
14
16
  key = key_for(name)
15
- value = (@local_config[key] || ENV[key] || @global_config[key])
17
+ value = (@local_config[key] || ENV[key] || @global_config[key] || DEFAULT_CONFIG[name])
16
18
 
17
- if !value.nil? && is_bool(name)
19
+ case
20
+ when !value.nil? && is_bool(name)
18
21
  to_bool(value)
22
+ when !value.nil? && is_num(name)
23
+ value.to_i
19
24
  else
20
25
  value
21
26
  end
@@ -56,6 +61,18 @@ module Bundler
56
61
  repos
57
62
  end
58
63
 
64
+ def mirror_for(uri)
65
+ uri = URI(uri.to_s) unless uri.is_a?(URI)
66
+
67
+ # Settings keys are all downcased
68
+ normalized_key = normalize_uri(uri.to_s.downcase)
69
+ gem_mirrors[normalized_key] || uri
70
+ end
71
+
72
+ def credentials_for(uri)
73
+ self[uri.to_s] || self[uri.host]
74
+ end
75
+
59
76
  def gem_mirrors
60
77
  all.inject({}) do |h, k|
61
78
  if k =~ /^mirror\./
@@ -72,6 +89,7 @@ module Bundler
72
89
  locations[:local] = @local_config[key] if @local_config.key?(key)
73
90
  locations[:env] = ENV[key] if ENV[key]
74
91
  locations[:global] = @global_config[key] if @global_config.key?(key)
92
+ locations[:default] = DEFAULT_CONFIG[key] if DEFAULT_CONFIG.key?(key)
75
93
  locations
76
94
  end
77
95
 
@@ -96,11 +114,19 @@ module Bundler
96
114
  end
97
115
 
98
116
  def without=(array)
99
- self[:without] = (array.empty? ? nil : array.join(":")) if array
117
+ set_array(:without, array)
118
+ end
119
+
120
+ def with=(array)
121
+ set_array(:with, array)
100
122
  end
101
123
 
102
124
  def without
103
- self[:without] ? self[:without].split(":").map { |w| w.to_sym } : []
125
+ get_array(:without)
126
+ end
127
+
128
+ def with
129
+ get_array(:with)
104
130
  end
105
131
 
106
132
  # @local_config["BUNDLE_PATH"] should be prioritized over ENV["BUNDLE_PATH"]
@@ -141,14 +167,38 @@ module Bundler
141
167
  "BUNDLE_#{key}"
142
168
  end
143
169
 
144
- def is_bool(key)
145
- BOOL_KEYS.include?(key.to_s)
170
+ def parent_setting_for(name)
171
+ split_specfic_setting_for(name)[0]
172
+ end
173
+
174
+ def specfic_gem_for(name)
175
+ split_specfic_setting_for(name)[1]
176
+ end
177
+
178
+ def split_specfic_setting_for(name)
179
+ name.split(".")
180
+ end
181
+
182
+ def is_bool(name)
183
+ BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s))
146
184
  end
147
185
 
148
186
  def to_bool(value)
149
187
  !(value.nil? || value == '' || value =~ /^(false|f|no|n|0)$/i || value == false)
150
188
  end
151
189
 
190
+ def is_num(value)
191
+ NUMBER_KEYS.include?(value.to_s)
192
+ end
193
+
194
+ def get_array(key)
195
+ self[key] ? self[key].split(":").map { |w| w.to_sym } : []
196
+ end
197
+
198
+ def set_array(key, array)
199
+ self[key] = (array.empty? ? nil : array.join(":")) if array
200
+ end
201
+
152
202
  def set_key(key, value, hash, file)
153
203
  key = key_for(key)
154
204
 
@@ -178,7 +228,7 @@ module Bundler
178
228
  config_regex = /^(BUNDLE_.+): (['"]?)(.*(?:\n(?!BUNDLE).+)?)\2$/
179
229
  config_pairs = config_file.read.scan(config_regex).map do |m|
180
230
  key, _, value = m
181
- [convert_to_backward_compatible_key(key), value.gsub(/\s+/, " ").tr('"', "'")]
231
+ [key, value.gsub(/\s+/, " ").tr('"', "'")]
182
232
  end
183
233
  Hash[config_pairs]
184
234
  else
@@ -186,12 +236,6 @@ module Bundler
186
236
  end
187
237
  end
188
238
 
189
- def convert_to_backward_compatible_key(key)
190
- key = "#{key}/" if key =~ /https?:/i && key !~ %r[/\Z]
191
- key = key.gsub(".", "__") if key.include?(".")
192
- key
193
- end
194
-
195
239
  # TODO: duplicates Rubygems#normalize_uri
196
240
  # TODO: is this the correct place to validate mirror URIs?
197
241
  def normalize_uri(uri)
@@ -135,10 +135,13 @@ module Bundler
135
135
  # handle 1.9 where system gems are always on the load path
136
136
  if defined?(::Gem)
137
137
  me = File.expand_path("../../", __FILE__)
138
+ me = /^#{Regexp.escape(me)}/
139
+
140
+ loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
141
+
138
142
  $LOAD_PATH.reject! do |p|
139
- next if File.expand_path(p) =~ /^#{Regexp.escape(me)}/
140
- p != File.dirname(__FILE__) &&
141
- Bundler.rubygems.gem_path.any?{|gp| p =~ /^#{Regexp.escape(gp)}/ }
143
+ next if File.expand_path(p) =~ me
144
+ loaded_gem_paths.delete(p)
142
145
  end
143
146
  $LOAD_PATH.uniq!
144
147
  end
@@ -4,16 +4,6 @@ module Bundler
4
4
  autoload :Path, 'bundler/source/path'
5
5
  autoload :Git, 'bundler/source/git'
6
6
 
7
- def self.mirror_for(uri)
8
- uri = URI(uri.to_s) unless uri.is_a?(URI)
9
-
10
- # Settings keys are all downcased
11
- mirrors = Bundler.settings.gem_mirrors
12
- normalized_key = URI(uri.to_s.downcase)
13
-
14
- mirrors[normalized_key] || uri
15
- end
16
-
17
7
  attr_accessor :dependency_names
18
8
 
19
9
  def unmet_deps
@@ -159,9 +159,9 @@ module Bundler
159
159
  local_specs
160
160
  end
161
161
 
162
- def install(spec)
162
+ def install(spec, force = false)
163
163
  debug = nil
164
- if requires_checkout? && !@copied
164
+ if requires_checkout? && !@copied && !force
165
165
  debug = " * Checking out revision: #{ref}"
166
166
  git_proxy.copy_to(install_path, submodules)
167
167
  serialize_gemspecs_in(install_path)
@@ -69,7 +69,7 @@ module Bundler
69
69
  File.basename(expanded_path.to_s)
70
70
  end
71
71
 
72
- def install(spec)
72
+ def install(spec, force = false)
73
73
  generate_bin(spec, :disable_extensions)
74
74
  ["Using #{version_message(spec)} from #{to_s}", nil]
75
75
  end