bundler 1.8.0.pre → 1.8.0

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 479faa1691c86039ec5e869bad6dcce4d5ccf4fc
4
- data.tar.gz: 5292b6135750e581aeb3007b8a8675f7530b3e2a
3
+ metadata.gz: ef2d9111a116f5375fcbbc9fcf791173f17f8191
4
+ data.tar.gz: 4aa9735c3b3e22247ea7586c0afb4461d98c1f53
5
5
  SHA512:
6
- metadata.gz: cb0d50e7108d2175c806dc8e3057243ba7f69ca53d17d7c7acb23da574339eaba836811a7287060c83f4143edeeee461b27fa5bc868b8c623391a88dc0a91d48
7
- data.tar.gz: d90bbeeca48a52828aa24304b71a3f68e4ced97001a13ea404262b4ae2c28ca99af70f3c2bfa62330090fd562b40a98d9da673768d5f37360ebc3824972b1426
6
+ metadata.gz: 68568a8e2ac0307a22e2ca03813f85c4669e0387fdb404810a82db19bb547f907e5cb180db076e481a24367e8428285503a6f14e00629ae1a09e86d1b864fb30
7
+ data.tar.gz: 74c1ab0165a4cf9281eec6745019eb7ec5ab0f2544e44148deb3ac722709b078ebbe408820c37e2b9596c0d496566ccd6214823f7be5df3b9eac65e567769569
@@ -1,3 +1,29 @@
1
+ ## 1.8.0 (2015-02-10)
2
+
3
+ Bugfixes:
4
+
5
+ - Gemfile `github` blocks now work (#3379, @indirect)
6
+
7
+ Bugfixes from v1.7.13:
8
+
9
+ - Look up installed gems in remote sources (#3300, #3368, #3377, #3380, #3381, @indirect)
10
+ - Look up gems across all sources to satisfy dependencies (#3365, @keiths-osc)
11
+ - Request dependencies for no more than 100 gems at a time (#3367, @segiddins)
12
+
13
+ ## 1.8.0.rc (2015-01-26)
14
+
15
+ Features:
16
+
17
+ - add `config disable_multisource` option to ensure sources can't compete (@indirect)
18
+
19
+ Bugfixes:
20
+
21
+ - don't add extra quotes around long, quoted config values (@aroben, #3338)
22
+
23
+ Security:
24
+
25
+ - warn when more than one top-level source is present (@indirect)
26
+
1
27
  ## 1.8.0.pre (2015-01-26)
2
28
 
3
29
  Features:
@@ -32,6 +58,14 @@ Documentation:
32
58
 
33
59
  - add missing Gemfile global `path` explanation (@agenteo)
34
60
 
61
+ ## 1.7.13 (2015-02-07)
62
+
63
+ Bugfixes:
64
+
65
+ - Look up installed gems in remote sources (#3300, #3368, #3377, #3380, #3381, @indirect)
66
+ - Look up gems across all sources to satisfy dependencies (#3365, @keiths-osc)
67
+ - Request dependencies for no more than 100 gems at a time (#3367, @segiddins)
68
+
35
69
  ## 1.7.12 (2015-01-08)
36
70
 
37
71
  Bugfixes:
@@ -20,7 +20,7 @@ module Bundler
20
20
 
21
21
  underscored_name = name.tr('-', '_')
22
22
  namespaced_path = name.tr('-', '/')
23
- constant_name = name.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join
23
+ constant_name = name.split('_').map{|p| p[0..0].upcase + p[1..-1] unless p.empty?}.join
24
24
  constant_name = constant_name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/
25
25
  constant_array = constant_name.split('::')
26
26
  git_user_name = `git config user.name`.chomp
@@ -199,11 +199,11 @@ module Bundler
199
199
  @index ||= Index.build do |idx|
200
200
  dependency_names = @dependencies.map { |d| d.name }
201
201
 
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!
202
+ sources.all_sources.each do |source|
203
+ source.dependency_names = dependency_names.dup
204
+ idx.add_source source.specs
205
+ dependency_names -= pinned_spec_names(source.specs)
206
+ dependency_names.push(*source.unmet_deps).uniq!
207
207
  end
208
208
  end
209
209
  end
@@ -599,5 +599,19 @@ module Bundler
599
599
  source_requirements
600
600
  end
601
601
 
602
+ def pinned_spec_names(specs)
603
+ names = []
604
+ specs.each do |s|
605
+ # TODO when two sources without blocks is an error, we can change
606
+ # this check to !s.source.is_a?(Source::LocalRubygems). For now,
607
+ # we need to ask every Rubygems for every gem name.
608
+ if s.source.is_a?(Source::Git) || s.source.is_a?(Source::Path)
609
+ names << s.name
610
+ end
611
+ end
612
+ names.uniq!
613
+ names
614
+ end
615
+
602
616
  end
603
617
  end
@@ -112,6 +112,7 @@ module Bundler
112
112
  if block_given?
113
113
  with_source(@sources.add_rubygems_source("remotes" => source), &blk)
114
114
  else
115
+ check_primary_source_safety(@sources)
115
116
  @sources.add_rubygems_remote(source)
116
117
  end
117
118
  end
@@ -148,8 +149,12 @@ module Bundler
148
149
  with_source(@sources.add_git_source(normalize_hash(options).merge("uri" => uri)), &blk)
149
150
  end
150
151
 
151
- def github(repo, options = {}, &blk)
152
- with_source(@sources.add_git_source(normalize_hash(options).merge("github" => repo)), &blk)
152
+ def github(repo, options = {})
153
+ raise ArgumentError, "Github sources require a block" unless block_given?
154
+ github_uri = @git_sources["github"].call(repo)
155
+ git_options = normalize_hash(options).merge("uri" => github_uri)
156
+ git_source = @sources.add_git_source(git_options)
157
+ with_source(git_source) { yield }
153
158
  end
154
159
 
155
160
  def to_definition(lockfile, unlock)
@@ -303,5 +308,24 @@ module Bundler
303
308
  raise GemfileError, "Unknown source '#{source}'"
304
309
  end
305
310
  end
311
+
312
+ def check_primary_source_safety(source)
313
+ return unless source.rubygems_primary_remotes.any?
314
+
315
+ if Bundler.settings[:disable_multisource]
316
+ raise GemspecError, "Warning: this Gemfile contains multiple primary sources. " \
317
+ "Each source after the first must include a block to indicate which gems " \
318
+ "should come from that source. To downgrade this error to a warning, run " \
319
+ "`bundle config --delete disable_multisource`."
320
+ else
321
+ Bundler.ui.warn "Warning: this Gemfile contains multiple primary sources. " \
322
+ "Using `source` more than once without a block is a security risk, and " \
323
+ "may result in installing unexpected gems. To resolve this warning, use " \
324
+ "a block to indicate which gems should come from the secondary source. " \
325
+ "To upgrade this warning to an error, run `bundle config " \
326
+ "disable_multisource true`."
327
+ end
328
+ end
329
+
306
330
  end
307
331
  end
@@ -320,10 +320,14 @@ module Bundler
320
320
  # fetch from Gemcutter Dependency Endpoint API
321
321
  def fetch_dependency_remote_specs(gem_names)
322
322
  Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(',')}"
323
- marshalled_deps = fetch dependency_api_uri(gem_names)
324
- gem_list = Bundler.load_marshal(marshalled_deps)
323
+ gem_list = []
325
324
  deps_list = []
326
325
 
326
+ gem_names.each_slice(Source::Rubygems::API_REQUEST_LIMIT) do |names|
327
+ marshalled_deps = fetch dependency_api_uri(names)
328
+ gem_list += Bundler.load_marshal(marshalled_deps)
329
+ end
330
+
327
331
  spec_list = gem_list.map do |s|
328
332
  dependencies = s[:dependencies].map do |name, requirement|
329
333
  dep = well_formed_dependency(name, requirement.split(", "))
@@ -101,13 +101,17 @@ module Bundler
101
101
 
102
102
  # returns a list of the dependencies
103
103
  def unmet_dependency_names
104
- names = []
105
- each{|s| names.push(*s.dependencies.map{|d| d.name }) }
106
- names.uniq!
104
+ names = dependency_names
107
105
  names.delete_if{|n| n == "bundler" }
108
106
  names.select{|n| search(n).empty? }
109
107
  end
110
108
 
109
+ def dependency_names
110
+ names = []
111
+ each{|s| names.push(*s.dependencies.map{|d| d.name }) }
112
+ names.uniq
113
+ end
114
+
111
115
  def use(other, override_dupes = false)
112
116
  return unless other
113
117
  other.each do |s|
@@ -29,7 +29,7 @@ module Bundler
29
29
  @state = :source
30
30
  @specs = {}
31
31
 
32
- @rubygems_aggregate = Source::Rubygems.new
32
+ @rubygems_aggregate = Source::LocalRubygems.new
33
33
 
34
34
  if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
35
35
  raise LockfileError, "Your Gemfile.lock contains merge conflicts.\n" \
@@ -165,9 +165,10 @@ module Bundler
165
165
  def load_config(config_file)
166
166
  valid_file = config_file && config_file.exist? && !config_file.size.zero?
167
167
  if !ignore_config? && valid_file
168
- config_regex = /^(BUNDLE_.+): (?:['"](.*)['"]|(.+(?:\n(?!BUNDLE).+))|(.+))$/
168
+ config_regex = /^(BUNDLE_.+): (['"]?)(.*(?:\n(?!BUNDLE).+)?)\2$/
169
169
  config_pairs = config_file.read.scan(config_regex).map do |m|
170
- m.compact.map { |n| n.gsub(/\s+/, " ").tr('"', "'") }
170
+ key, _, value = m
171
+ [key, value.gsub(/\s+/, " ").tr('"', "'")]
171
172
  end
172
173
  Hash[config_pairs]
173
174
  else
@@ -1,8 +1,9 @@
1
1
  module Bundler
2
2
  class Source
3
- autoload :Rubygems, 'bundler/source/rubygems'
4
- autoload :Path, 'bundler/source/path'
5
- autoload :Git, 'bundler/source/git'
3
+ autoload :Rubygems, 'bundler/source/rubygems'
4
+ autoload :LocalRubygems, 'bundler/source/local_rubygems'
5
+ autoload :Path, 'bundler/source/path'
6
+ autoload :Git, 'bundler/source/git'
6
7
 
7
8
  def self.mirror_for(uri)
8
9
  uri = URI(uri.to_s) unless uri.is_a?(URI)
@@ -0,0 +1,16 @@
1
+ module Bundler
2
+ class Source
3
+ class LocalRubygems < Rubygems
4
+
5
+ def specs
6
+ @specs ||= begin
7
+ idx = super
8
+ idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
9
+ idx.use(installed_specs, :override_dupes)
10
+ idx
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -5,7 +5,8 @@ require 'rubygems/spec_fetcher'
5
5
  module Bundler
6
6
  class Source
7
7
  class Rubygems < Source
8
- API_REQUEST_LIMIT = 100 # threshold for switching back to the modern index instead of fetching every spec
8
+ # threshold for switching back to the modern index instead of fetching every spec
9
+ API_REQUEST_LIMIT = 100
9
10
 
10
11
  attr_reader :remotes, :caches
11
12
 
@@ -65,15 +66,10 @@ module Bundler
65
66
  alias_method :name, :to_s
66
67
 
67
68
  def specs
68
- @specs ||= begin
69
- # remote_specs usually generates a way larger Index than the other
70
- # sources, and large_idx.use small_idx is way faster than
71
- # small_idx.use large_idx.
72
- idx = @allow_remote ? remote_specs.dup : Index.new
73
- idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
74
- idx.use(installed_specs, :override_dupes)
75
- idx
76
- end
69
+ # remote_specs usually generates a way larger Index than the other
70
+ # sources, and large_idx.use small_idx is way faster than
71
+ # small_idx.use large_idx.
72
+ @specs ||= @allow_remote ? remote_specs.dup : Index.new
77
73
  end
78
74
 
79
75
  def install(spec)
@@ -309,6 +305,20 @@ module Bundler
309
305
  Bundler.ui.info "" if !Bundler.ui.debug? # new line now that the dots are over
310
306
  end
311
307
 
308
+ # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
309
+ # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
310
+ # but will not have found any versions of Bar from source B, which is a problem if the requested version
311
+ # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
312
+ # each spec we found, we add all possible versions from all sources to the index.
313
+ begin
314
+ idxcount = idx.size
315
+ api_fetchers.each do |f|
316
+ Bundler.ui.info "Fetching version metadata from #{f.uri}", Bundler.ui.debug?
317
+ idx.use f.specs(idx.dependency_names, self), true
318
+ Bundler.ui.info "" if !Bundler.ui.debug? # new line now that the dots are over
319
+ end
320
+ end until idxcount == idx.size
321
+
312
322
  if api_fetchers.any? && api_fetchers.all?{|f| f.use_api }
313
323
  # it's possible that gems from one source depend on gems from some
314
324
  # other source, so now we download gemspecs and iterate over those
@@ -317,7 +327,7 @@ module Bundler
317
327
 
318
328
  # if there are any cross-site gems we missed, get them now
319
329
  api_fetchers.each do |f|
320
- Bundler.ui.info "Fetching additional metadata from #{f.uri}", Bundler.ui.debug?
330
+ Bundler.ui.info "Fetching dependency metadata from #{f.uri}", Bundler.ui.debug?
321
331
  idx.use f.specs(unmet, self)
322
332
  Bundler.ui.info "" if !Bundler.ui.debug? # new line now that the dots are over
323
333
  end if unmet.any?
@@ -6,7 +6,7 @@ module Bundler
6
6
  def initialize
7
7
  @path_sources = []
8
8
  @git_sources = []
9
- @rubygems_aggregate = Source::Rubygems.new
9
+ @rubygems_aggregate = Source::LocalRubygems.new
10
10
  @rubygems_sources = []
11
11
  end
12
12
 
@@ -57,8 +57,7 @@ module Bundler
57
57
  end
58
58
  end
59
59
 
60
- replacement_rubygems =
61
- replacement_sources.detect { |s| s.is_a?(Source::Rubygems) }
60
+ replacement_rubygems = replacement_sources.detect { |s| s.is_a?(Source::LocalRubygems) }
62
61
  @rubygems_aggregate = replacement_rubygems if replacement_rubygems
63
62
 
64
63
  # Return true if there were changes
@@ -74,6 +73,10 @@ module Bundler
74
73
  all_sources.each(&:remote!)
75
74
  end
76
75
 
76
+ def rubygems_primary_remotes
77
+ @rubygems_aggregate.remotes
78
+ end
79
+
77
80
  private
78
81
 
79
82
  def add_source_to_list(source, list)
@@ -2,5 +2,5 @@ module Bundler
2
2
  # We're doing this because we might write tests that deal
3
3
  # with other versions of bundler and we are unsure how to
4
4
  # handle this better.
5
- VERSION = "1.8.0.pre" unless defined?(::Bundler::VERSION)
5
+ VERSION = "1.8.0" unless defined?(::Bundler::VERSION)
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0.pre
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-01-26 00:00:00.000000000 Z
14
+ date: 2015-02-10 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: mustache
@@ -175,6 +175,7 @@ files:
175
175
  - lib/bundler/source.rb
176
176
  - lib/bundler/source/git.rb
177
177
  - lib/bundler/source/git/git_proxy.rb
178
+ - lib/bundler/source/local_rubygems.rb
178
179
  - lib/bundler/source/path.rb
179
180
  - lib/bundler/source/path/installer.rb
180
181
  - lib/bundler/source/rubygems.rb