bundler 1.11.2 → 1.12.0.pre.1
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 +4 -4
- data/.codeclimate.yml +24 -0
- data/.gitignore +2 -2
- data/.rubocop.yml +17 -2
- data/.rubocop_todo.yml +145 -18
- data/.travis.yml +9 -2
- data/CHANGELOG.md +42 -0
- data/Rakefile +20 -13
- data/bin/rake +5 -0
- data/bin/rspec +5 -0
- data/bin/rubocop +7 -1
- data/bundler.gemspec +2 -1
- data/exe/bundle +10 -2
- data/exe/bundle_ruby +2 -1
- data/exe/bundler +3 -1
- data/lib/bundler.rb +54 -51
- data/lib/bundler/capistrano.rb +1 -0
- data/lib/bundler/cli.rb +26 -4
- data/lib/bundler/cli/binstubs.rb +1 -0
- data/lib/bundler/cli/cache.rb +1 -0
- data/lib/bundler/cli/check.rb +4 -1
- data/lib/bundler/cli/clean.rb +1 -0
- data/lib/bundler/cli/common.rb +1 -0
- data/lib/bundler/cli/config.rb +5 -5
- data/lib/bundler/cli/console.rb +1 -0
- data/lib/bundler/cli/exec.rb +4 -9
- data/lib/bundler/cli/gem.rb +12 -9
- data/lib/bundler/cli/init.rb +1 -0
- data/lib/bundler/cli/inject.rb +1 -0
- data/lib/bundler/cli/install.rb +8 -5
- data/lib/bundler/cli/lock.rb +2 -0
- data/lib/bundler/cli/open.rb +1 -0
- data/lib/bundler/cli/outdated.rb +36 -9
- data/lib/bundler/cli/package.rb +1 -0
- data/lib/bundler/cli/platform.rb +4 -1
- data/lib/bundler/cli/show.rb +1 -0
- data/lib/bundler/cli/update.rb +6 -6
- data/lib/bundler/cli/viz.rb +4 -6
- data/lib/bundler/constants.rb +1 -0
- data/lib/bundler/current_ruby.rb +34 -168
- data/lib/bundler/definition.rb +41 -15
- data/lib/bundler/dep_proxy.rb +1 -0
- data/lib/bundler/dependency.rb +10 -0
- data/lib/bundler/deployment.rb +1 -0
- data/lib/bundler/deprecate.rb +1 -0
- data/lib/bundler/dsl.rb +19 -9
- data/lib/bundler/endpoint_specification.rb +37 -8
- data/lib/bundler/env.rb +4 -3
- data/lib/bundler/environment.rb +1 -0
- data/lib/bundler/errors.rb +51 -32
- data/lib/bundler/fetcher.rb +44 -30
- data/lib/bundler/fetcher/base.rb +3 -2
- data/lib/bundler/fetcher/compact_index.rb +98 -0
- data/lib/bundler/fetcher/dependency.rb +36 -36
- data/lib/bundler/fetcher/downloader.rb +14 -8
- data/lib/bundler/fetcher/index.rb +28 -5
- data/lib/bundler/friendly_errors.rb +93 -85
- data/lib/bundler/gem_helper.rb +20 -21
- data/lib/bundler/gem_helpers.rb +9 -2
- data/lib/bundler/gem_remote_fetcher.rb +1 -0
- data/lib/bundler/gem_tasks.rb +1 -0
- data/lib/bundler/graph.rb +16 -17
- data/lib/bundler/index.rb +4 -6
- data/lib/bundler/injector.rb +1 -0
- data/lib/bundler/inline.rb +8 -2
- data/lib/bundler/installer.rb +4 -4
- data/lib/bundler/installer/gem_installer.rb +1 -0
- data/lib/bundler/installer/parallel_installer.rb +3 -2
- data/lib/bundler/installer/standalone.rb +5 -1
- data/lib/bundler/lazy_specification.rb +5 -2
- data/lib/bundler/lockfile_parser.rb +22 -15
- data/lib/bundler/match_platform.rb +1 -0
- data/lib/bundler/mirror.rb +218 -0
- data/lib/bundler/path_preserver.rb +12 -0
- data/lib/bundler/psyched_yaml.rb +1 -0
- data/lib/bundler/remote_specification.rb +4 -1
- data/lib/bundler/resolver.rb +17 -16
- data/lib/bundler/retry.rb +1 -0
- data/lib/bundler/ruby_dsl.rb +8 -2
- data/lib/bundler/ruby_version.rb +58 -61
- data/lib/bundler/rubygems_ext.rb +4 -3
- data/lib/bundler/rubygems_gem_installer.rb +1 -0
- data/lib/bundler/rubygems_integration.rb +9 -14
- data/lib/bundler/runtime.rb +17 -22
- data/lib/bundler/settings.rb +17 -21
- data/lib/bundler/setup.rb +1 -0
- data/lib/bundler/shared_helpers.rb +47 -17
- data/lib/bundler/similarity_detector.rb +1 -0
- data/lib/bundler/source.rb +2 -1
- data/lib/bundler/source/git.rb +2 -1
- data/lib/bundler/source/git/git_proxy.rb +33 -7
- data/lib/bundler/source/path.rb +17 -10
- data/lib/bundler/source/path/installer.rb +1 -0
- data/lib/bundler/source/rubygems.rb +4 -3
- data/lib/bundler/source/rubygems/remote.rb +16 -0
- data/lib/bundler/source_list.rb +1 -0
- data/lib/bundler/spec_set.rb +1 -0
- data/lib/bundler/ssl_certs/certificate_manager.rb +1 -0
- data/lib/bundler/stub_specification.rb +1 -0
- data/lib/bundler/templates/Executable +1 -0
- data/lib/bundler/templates/Gemfile +1 -0
- data/lib/bundler/templates/newgem/.travis.yml.tt +1 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -2
- data/lib/bundler/ui.rb +1 -0
- data/lib/bundler/ui/rg_proxy.rb +1 -0
- data/lib/bundler/ui/shell.rb +2 -1
- data/lib/bundler/ui/silent.rb +1 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +78 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/cache.rb +97 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +55 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/version.rb +3 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +4 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +13 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +5 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +37 -14
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +7 -7
- data/lib/bundler/vendored_molinillo.rb +1 -0
- data/lib/bundler/vendored_persistent.rb +1 -0
- data/lib/bundler/vendored_thor.rb +1 -0
- data/lib/bundler/version.rb +6 -1
- data/lib/bundler/vlad.rb +1 -0
- data/lib/bundler/worker.rb +12 -2
- data/man/bundle-config.ronn +6 -0
- data/man/bundle-gem.ronn +5 -5
- metadata +14 -6
- data/lib/bundler/gem_path_manipulation.rb +0 -8
data/lib/bundler/fetcher.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "bundler/vendored_persistent"
|
2
3
|
require "cgi"
|
3
4
|
require "securerandom"
|
@@ -6,6 +7,7 @@ require "zlib"
|
|
6
7
|
module Bundler
|
7
8
|
# Handles all the fetching with the rubygems server
|
8
9
|
class Fetcher
|
10
|
+
autoload :CompactIndex, "bundler/fetcher/compact_index"
|
9
11
|
autoload :Downloader, "bundler/fetcher/downloader"
|
10
12
|
autoload :Dependency, "bundler/fetcher/dependency"
|
11
13
|
autoload :Index, "bundler/fetcher/index"
|
@@ -52,10 +54,17 @@ module Bundler
|
|
52
54
|
|
53
55
|
# Exceptions classes that should bypass retry attempts. If your password didn't work the
|
54
56
|
# first time, it's not going to the third time.
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
NET_ERRORS = [:HTTPBadGateway, :HTTPBadRequest, :HTTPFailedDependency,
|
58
|
+
:HTTPForbidden, :HTTPInsufficientStorage, :HTTPMethodNotAllowed,
|
59
|
+
:HTTPMovedPermanently, :HTTPNoContent, :HTTPNotFound,
|
60
|
+
:HTTPNotImplemented, :HTTPPreconditionFailed, :HTTPRequestEntityTooLarge,
|
61
|
+
:HTTPRequestURITooLong, :HTTPUnauthorized, :HTTPUnprocessableEntity,
|
62
|
+
:HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze
|
63
|
+
FAIL_ERRORS = begin
|
64
|
+
fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError]
|
65
|
+
fail_errors << Gem::Requirement::BadRequirementError if defined?(Gem::Requirement::BadRequirementError)
|
66
|
+
fail_errors.push(*NET_ERRORS.map {|e| SharedHelpers.const_get_safely(e, Net) }.compact)
|
67
|
+
end.freeze
|
59
68
|
|
60
69
|
class << self
|
61
70
|
attr_accessor :disable_endpoint, :api_timeout, :redirect_limit, :max_retries
|
@@ -87,7 +96,7 @@ module Bundler
|
|
87
96
|
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
|
88
97
|
Bundler.load_gemspec(cached_spec_path)
|
89
98
|
else
|
90
|
-
Bundler.load_marshal Gem.inflate(downloader.fetch
|
99
|
+
Bundler.load_marshal Gem.inflate(downloader.fetch(uri).body)
|
91
100
|
end
|
92
101
|
rescue MarshalError
|
93
102
|
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
|
@@ -96,7 +105,7 @@ module Bundler
|
|
96
105
|
|
97
106
|
# return the specs in the bundler format as an index with retries
|
98
107
|
def specs_with_retry(gem_names, source)
|
99
|
-
Bundler::Retry.new("fetcher").attempts do
|
108
|
+
Bundler::Retry.new("fetcher", FAIL_ERRORS).attempts do
|
100
109
|
specs(gem_names, source)
|
101
110
|
end
|
102
111
|
end
|
@@ -106,20 +115,25 @@ module Bundler
|
|
106
115
|
old = Bundler.rubygems.sources
|
107
116
|
index = Bundler::Index.new
|
108
117
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
118
|
+
if Bundler::Fetcher.disable_endpoint
|
119
|
+
@use_api = false
|
120
|
+
specs = fetchers.last.specs(gem_names)
|
121
|
+
else
|
122
|
+
specs = []
|
123
|
+
fetchers.shift until fetchers.first.available? || fetchers.empty?
|
124
|
+
fetchers.dup.each do |f|
|
125
|
+
break unless f.api_fetcher? && !gem_names || !specs = f.specs(gem_names)
|
126
|
+
fetchers.delete(f)
|
127
|
+
end
|
128
|
+
@use_api = false if fetchers.none?(&:api_fetcher?)
|
113
129
|
end
|
114
|
-
@use_api = false if fetchers.none?(&:api_fetcher?)
|
115
130
|
|
116
|
-
specs
|
131
|
+
specs.each do |name, version, platform, dependencies|
|
117
132
|
next if name == "bundler"
|
118
|
-
spec =
|
119
|
-
|
120
|
-
spec = EndpointSpecification.new(name, version, platform, dependencies)
|
133
|
+
spec = if dependencies
|
134
|
+
EndpointSpecification.new(name, version, platform, dependencies)
|
121
135
|
else
|
122
|
-
|
136
|
+
RemoteSpecification.new(name, version, platform, self)
|
123
137
|
end
|
124
138
|
spec.source = source
|
125
139
|
spec.remote = @remote
|
@@ -137,32 +151,33 @@ module Bundler
|
|
137
151
|
def use_api
|
138
152
|
return @use_api if defined?(@use_api)
|
139
153
|
|
140
|
-
|
141
|
-
|
154
|
+
fetchers.shift until fetchers.first.available?
|
155
|
+
|
156
|
+
@use_api = if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
|
157
|
+
false
|
142
158
|
else
|
143
|
-
fetchers.
|
144
|
-
@use_api = fetchers.any?(&:api_fetcher?)
|
159
|
+
fetchers.first.api_fetcher?
|
145
160
|
end
|
146
161
|
end
|
147
162
|
|
148
163
|
def user_agent
|
149
164
|
@user_agent ||= begin
|
150
|
-
ruby = Bundler.
|
165
|
+
ruby = Bundler::RubyVersion.system
|
151
166
|
|
152
|
-
agent = "bundler/#{Bundler::VERSION}"
|
167
|
+
agent = String.new("bundler/#{Bundler::VERSION}")
|
153
168
|
agent << " rubygems/#{Gem::VERSION}"
|
154
|
-
agent << " ruby/#{ruby.
|
169
|
+
agent << " ruby/#{ruby.versions_string(ruby.versions)}"
|
155
170
|
agent << " (#{ruby.host})"
|
156
171
|
agent << " command/#{ARGV.first}"
|
157
172
|
|
158
173
|
if ruby.engine != "ruby"
|
159
174
|
# engine_version raises on unknown engines
|
160
175
|
engine_version = begin
|
161
|
-
ruby.
|
176
|
+
ruby.engine_versions
|
162
177
|
rescue
|
163
178
|
"???"
|
164
179
|
end
|
165
|
-
agent << " #{ruby.engine}/#{engine_version}"
|
180
|
+
agent << " #{ruby.engine}/#{ruby.versions_string(engine_version)}"
|
166
181
|
end
|
167
182
|
|
168
183
|
agent << " options/#{Bundler.settings.all.join(",")}"
|
@@ -185,9 +200,8 @@ module Bundler
|
|
185
200
|
end
|
186
201
|
|
187
202
|
def http_proxy
|
188
|
-
|
189
|
-
|
190
|
-
end
|
203
|
+
return unless uri = connection.proxy_uri
|
204
|
+
uri.to_s
|
191
205
|
end
|
192
206
|
|
193
207
|
def inspect
|
@@ -196,7 +210,7 @@ module Bundler
|
|
196
210
|
|
197
211
|
private
|
198
212
|
|
199
|
-
FETCHERS = [Dependency, Index]
|
213
|
+
FETCHERS = [CompactIndex, Dependency, Index].freeze
|
200
214
|
|
201
215
|
def cis
|
202
216
|
env_cis = {
|
@@ -256,7 +270,7 @@ module Bundler
|
|
256
270
|
Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
|
257
271
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
|
258
272
|
Net::HTTP::Persistent::Error, Zlib::BufError
|
259
|
-
]
|
273
|
+
].freeze
|
260
274
|
|
261
275
|
def bundler_cert_store
|
262
276
|
store = OpenSSL::X509::Store.new
|
data/lib/bundler/fetcher/base.rb
CHANGED
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "bundler/fetcher/base"
|
3
|
+
require "bundler/worker"
|
4
|
+
|
5
|
+
module Bundler
|
6
|
+
class Fetcher
|
7
|
+
class CompactIndex < Base
|
8
|
+
require "bundler/vendor/compact_index_client/lib/compact_index_client"
|
9
|
+
|
10
|
+
def self.compact_index_request(method_name)
|
11
|
+
method = instance_method(method_name)
|
12
|
+
undef_method(method_name)
|
13
|
+
define_method(method_name) do |*args, &blk|
|
14
|
+
begin
|
15
|
+
method.bind(self).call(*args, &blk)
|
16
|
+
rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
|
17
|
+
raise HTTPError, e.message
|
18
|
+
rescue AuthenticationRequiredError
|
19
|
+
# We got a 401 from the server. Just fail.
|
20
|
+
raise
|
21
|
+
rescue HTTPError => e
|
22
|
+
Bundler.ui.trace(e)
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def specs(gem_names)
|
29
|
+
specs_for_names(gem_names)
|
30
|
+
end
|
31
|
+
compact_index_request :specs
|
32
|
+
|
33
|
+
def specs_for_names(gem_names)
|
34
|
+
gem_info = []
|
35
|
+
complete_gems = []
|
36
|
+
remaining_gems = gem_names.dup
|
37
|
+
|
38
|
+
until remaining_gems.empty?
|
39
|
+
Bundler.ui.debug "Looking up gems #{remaining_gems.inspect}"
|
40
|
+
|
41
|
+
deps = compact_index_client.dependencies(remaining_gems)
|
42
|
+
next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
|
43
|
+
deps.each {|dep| gem_info << dep }
|
44
|
+
complete_gems.push(*deps.map(&:first)).uniq!
|
45
|
+
remaining_gems = next_gems - complete_gems
|
46
|
+
end
|
47
|
+
|
48
|
+
gem_info
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_spec(spec)
|
52
|
+
spec -= [nil, "ruby", ""]
|
53
|
+
contents = compact_index_client.spec(*spec)
|
54
|
+
return nil if contents.nil?
|
55
|
+
contents.unshift(spec.first)
|
56
|
+
contents[3].map! {|d| Gem::Dependency.new(*d) }
|
57
|
+
EndpointSpecification.new(*contents)
|
58
|
+
end
|
59
|
+
compact_index_request :fetch_spec
|
60
|
+
|
61
|
+
def available?
|
62
|
+
# Read info file checksums out of /versions, so we can know if gems are up to date
|
63
|
+
fetch_uri.scheme != "file" && compact_index_client.update_and_parse_checksums!
|
64
|
+
end
|
65
|
+
compact_index_request :available?
|
66
|
+
|
67
|
+
def api_fetcher?
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def compact_index_client
|
74
|
+
@compact_index_client ||= begin
|
75
|
+
compact_fetcher = lambda do |path, headers|
|
76
|
+
downloader.fetch(fetch_uri + path, headers)
|
77
|
+
end
|
78
|
+
|
79
|
+
SharedHelpers.filesystem_access(cache_path) do
|
80
|
+
CompactIndexClient.new(cache_path, compact_fetcher)
|
81
|
+
end.tap do |client|
|
82
|
+
client.in_parallel = lambda do |inputs, &blk|
|
83
|
+
func = lambda {|object, _index| blk.call(object) }
|
84
|
+
worker_name = "Compact Index (#{display_uri.host})"
|
85
|
+
worker = Bundler::Worker.new(25, worker_name, func)
|
86
|
+
inputs.each {|input| worker.enq(input) }
|
87
|
+
inputs.map { worker.deq }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def cache_path
|
94
|
+
Bundler.user_cache.join("compact_index", remote.cache_slug)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -1,17 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "bundler/fetcher/base"
|
2
3
|
require "cgi"
|
3
4
|
|
4
5
|
module Bundler
|
5
6
|
class Fetcher
|
6
7
|
class Dependency < Base
|
7
|
-
def
|
8
|
-
downloader.fetch(dependency_api_uri)
|
8
|
+
def available?
|
9
|
+
fetch_uri.scheme != "file" && downloader.fetch(dependency_api_uri)
|
9
10
|
rescue NetworkDownError => e
|
10
11
|
raise HTTPError, e.message
|
11
12
|
rescue AuthenticationRequiredError
|
12
13
|
# We got a 401 from the server. Just fail.
|
13
14
|
raise
|
14
15
|
rescue HTTPError
|
16
|
+
false
|
15
17
|
end
|
16
18
|
|
17
19
|
def api_fetcher?
|
@@ -19,51 +21,50 @@ module Bundler
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def specs(gem_names, full_dependency_list = [], last_spec_list = [])
|
22
|
-
query_list = gem_names - full_dependency_list
|
24
|
+
query_list = gem_names.uniq - full_dependency_list
|
23
25
|
|
24
|
-
|
25
|
-
if Bundler.ui.debug?
|
26
|
-
Bundler.ui.debug "Query List: #{query_list.inspect}"
|
27
|
-
else
|
28
|
-
Bundler.ui.info ".", false
|
29
|
-
end
|
26
|
+
log_specs(query_list)
|
30
27
|
|
31
|
-
return
|
28
|
+
return last_spec_list if query_list.empty?
|
32
29
|
|
33
|
-
|
30
|
+
spec_list, deps_list = Bundler::Retry.new("dependency api", FAIL_ERRORS).attempts do
|
34
31
|
dependency_specs(query_list)
|
35
32
|
end
|
36
33
|
|
37
|
-
spec_list, deps_list = remote_specs
|
38
34
|
returned_gems = spec_list.map(&:first).uniq
|
39
35
|
specs(deps_list, full_dependency_list + returned_gems, spec_list + last_spec_list)
|
40
36
|
rescue HTTPError, MarshalError, GemspecError
|
41
37
|
Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
|
42
38
|
Bundler.ui.debug "could not fetch from the dependency API, trying the full index"
|
43
|
-
|
39
|
+
nil
|
44
40
|
end
|
45
41
|
|
46
42
|
def dependency_specs(gem_names)
|
47
43
|
Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(",")}"
|
48
|
-
gem_list = []
|
49
|
-
deps_list = []
|
50
44
|
|
45
|
+
gem_list = unmarshalled_dep_gems(gem_names)
|
46
|
+
get_formatted_specs_and_deps(gem_list)
|
47
|
+
end
|
48
|
+
|
49
|
+
def unmarshalled_dep_gems(gem_names)
|
50
|
+
gem_list = []
|
51
51
|
gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names|
|
52
|
-
marshalled_deps = downloader.fetch
|
53
|
-
gem_list
|
52
|
+
marshalled_deps = downloader.fetch(dependency_api_uri(names)).body
|
53
|
+
gem_list.push(*Bundler.load_marshal(marshalled_deps))
|
54
54
|
end
|
55
|
+
gem_list
|
56
|
+
end
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
deps_list << dep.name
|
60
|
-
dep
|
61
|
-
end
|
58
|
+
def get_formatted_specs_and_deps(gem_list)
|
59
|
+
deps_list = []
|
60
|
+
spec_list = []
|
62
61
|
|
63
|
-
|
62
|
+
gem_list.each do |s|
|
63
|
+
deps_list.push(*s[:dependencies].map(&:first))
|
64
|
+
deps = s[:dependencies].map {|n, d| [n, d.split(", ")] }
|
65
|
+
spec_list.push([s[:name], s[:number], s[:platform], deps])
|
64
66
|
end
|
65
|
-
|
66
|
-
[spec_list, deps_list.uniq]
|
67
|
+
[spec_list, deps_list]
|
67
68
|
end
|
68
69
|
|
69
70
|
def dependency_api_uri(gem_names = [])
|
@@ -72,16 +73,15 @@ module Bundler
|
|
72
73
|
uri
|
73
74
|
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
"
|
83
|
-
|
84
|
-
"this issue. For more information, see http://bit.ly/syck-defaultkey."
|
76
|
+
private
|
77
|
+
|
78
|
+
def log_specs(query_list)
|
79
|
+
# only display the message on the first run
|
80
|
+
if Bundler.ui.debug?
|
81
|
+
Bundler.ui.debug "Query List: #{query_list.inspect}"
|
82
|
+
else
|
83
|
+
Bundler.ui.info ".", false
|
84
|
+
end
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Bundler
|
2
3
|
class Fetcher
|
3
4
|
class Downloader
|
@@ -9,40 +10,45 @@ module Bundler
|
|
9
10
|
@redirect_limit = redirect_limit
|
10
11
|
end
|
11
12
|
|
12
|
-
def fetch(uri, counter = 0)
|
13
|
+
def fetch(uri, options = {}, counter = 0)
|
13
14
|
raise HTTPError, "Too many redirects" if counter >= redirect_limit
|
14
15
|
|
15
|
-
response = request(uri)
|
16
|
+
response = request(uri, options)
|
16
17
|
Bundler.ui.debug("HTTP #{response.code} #{response.message}")
|
17
18
|
|
18
19
|
case response
|
20
|
+
when Net::HTTPSuccess, Net::HTTPNotModified
|
21
|
+
response
|
19
22
|
when Net::HTTPRedirection
|
20
23
|
new_uri = URI.parse(response["location"])
|
21
24
|
if new_uri.host == uri.host
|
22
25
|
new_uri.user = uri.user
|
23
26
|
new_uri.password = uri.password
|
24
27
|
end
|
25
|
-
fetch(new_uri, counter + 1)
|
26
|
-
when Net::HTTPSuccess
|
27
|
-
response.body
|
28
|
+
fetch(new_uri, options, counter + 1)
|
28
29
|
when Net::HTTPRequestEntityTooLarge
|
29
30
|
raise FallbackError, response.body
|
30
31
|
when Net::HTTPUnauthorized
|
31
32
|
raise AuthenticationRequiredError, uri.host
|
33
|
+
when Net::HTTPNotFound
|
34
|
+
raise FallbackError, "Net::HTTPNotFound"
|
32
35
|
else
|
33
|
-
raise HTTPError, "#{response.class}: #{response.body}"
|
36
|
+
raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
37
|
-
def request(uri)
|
40
|
+
def request(uri, options)
|
38
41
|
Bundler.ui.debug "HTTP GET #{uri}"
|
39
|
-
req = Net::HTTP::Get.new uri.request_uri
|
42
|
+
req = Net::HTTP::Get.new uri.request_uri, options
|
40
43
|
if uri.user
|
41
44
|
user = CGI.unescape(uri.user)
|
42
45
|
password = uri.password ? CGI.unescape(uri.password) : nil
|
43
46
|
req.basic_auth(user, password)
|
44
47
|
end
|
45
48
|
connection.request(uri, req)
|
49
|
+
rescue NoMethodError => e
|
50
|
+
raise unless ["undefined method", "use_ssl="].all? {|snippet| e.message.include? snippet }
|
51
|
+
raise LoadError.new("cannot load such file -- openssl")
|
46
52
|
rescue OpenSSL::SSL::SSLError
|
47
53
|
raise CertificateFailureError.new(uri)
|
48
54
|
rescue *HTTP_ERRORS => e
|