bundler 1.10.6 → 1.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +105 -0
- data/.rubocop_todo.yml +120 -0
- data/.travis.yml +8 -23
- data/CHANGELOG.md +95 -0
- data/CODE_OF_CONDUCT.md +6 -4
- data/DEVELOPMENT.md +4 -5
- data/README.md +2 -2
- data/Rakefile +71 -88
- data/bin/rake +14 -0
- data/bin/rspec +10 -0
- data/bin/rubocop +11 -0
- data/bundler.gemspec +17 -15
- data/exe/bundle +20 -0
- data/{bin → exe}/bundle_ruby +6 -4
- data/exe/bundler +20 -0
- data/lib/bundler/capistrano.rb +2 -2
- data/lib/bundler/cli/binstubs.rb +1 -2
- data/lib/bundler/cli/cache.rb +0 -1
- data/lib/bundler/cli/check.rb +7 -5
- data/lib/bundler/cli/clean.rb +0 -1
- data/lib/bundler/cli/common.rb +6 -7
- data/lib/bundler/cli/config.rb +69 -56
- data/lib/bundler/cli/console.rb +8 -8
- data/lib/bundler/cli/exec.rb +5 -4
- data/lib/bundler/cli/gem.rb +52 -40
- data/lib/bundler/cli/init.rb +5 -6
- data/lib/bundler/cli/inject.rb +1 -2
- data/lib/bundler/cli/install.rb +18 -21
- data/lib/bundler/cli/lock.rb +8 -3
- data/lib/bundler/cli/open.rb +4 -5
- data/lib/bundler/cli/outdated.rb +7 -8
- data/lib/bundler/cli/package.rb +1 -1
- data/lib/bundler/cli/platform.rb +2 -3
- data/lib/bundler/cli/show.rb +9 -9
- data/lib/bundler/cli/update.rb +2 -3
- data/lib/bundler/cli/viz.rb +1 -2
- data/lib/bundler/cli.rb +85 -74
- data/lib/bundler/constants.rb +1 -1
- data/lib/bundler/current_ruby.rb +38 -3
- data/lib/bundler/definition.rb +83 -88
- data/lib/bundler/dep_proxy.rb +11 -9
- data/lib/bundler/dependency.rb +17 -11
- data/lib/bundler/deployment.rb +2 -2
- data/lib/bundler/deprecate.rb +3 -3
- data/lib/bundler/dsl.rb +62 -43
- data/lib/bundler/env.rb +19 -12
- data/lib/bundler/environment.rb +1 -2
- data/lib/bundler/errors.rb +82 -0
- data/lib/bundler/fetcher/base.rb +20 -7
- data/lib/bundler/fetcher/dependency.rb +5 -5
- data/lib/bundler/fetcher/downloader.rb +1 -2
- data/lib/bundler/fetcher/index.rb +4 -7
- data/lib/bundler/fetcher.rb +49 -40
- data/lib/bundler/friendly_errors.rb +15 -8
- data/lib/bundler/gem_helper.rb +44 -35
- data/lib/bundler/gem_helpers.rb +7 -8
- data/lib/bundler/gem_remote_fetcher.rb +41 -0
- data/lib/bundler/gem_tasks.rb +4 -1
- data/lib/bundler/graph.rb +25 -24
- data/lib/bundler/index.rb +21 -18
- data/lib/bundler/injector.rb +2 -4
- data/lib/bundler/inline.rb +3 -3
- data/lib/bundler/installer/gem_installer.rb +76 -0
- data/lib/bundler/installer/parallel_installer.rb +22 -13
- data/lib/bundler/installer/standalone.rb +48 -0
- data/lib/bundler/installer.rb +57 -144
- data/lib/bundler/lazy_specification.rb +4 -5
- data/lib/bundler/lockfile_parser.rb +21 -19
- data/lib/bundler/man/bundle +2 -2
- data/lib/bundler/man/bundle-config +2 -2
- data/lib/bundler/man/bundle-config.txt +6 -4
- data/lib/bundler/man/bundle-exec +1 -1
- data/lib/bundler/man/bundle-exec.txt +1 -1
- data/lib/bundler/man/bundle-gem +80 -0
- data/lib/bundler/man/bundle-gem.txt +90 -0
- data/lib/bundler/man/bundle-install +37 -6
- data/lib/bundler/man/bundle-install.txt +68 -44
- data/lib/bundler/man/bundle-lock +55 -0
- data/lib/bundler/man/bundle-lock.txt +60 -0
- data/lib/bundler/man/bundle-package +1 -1
- data/lib/bundler/man/bundle-package.txt +1 -1
- data/lib/bundler/man/bundle-platform +1 -1
- data/lib/bundler/man/bundle-platform.txt +1 -1
- data/lib/bundler/man/bundle-update +1 -1
- data/lib/bundler/man/bundle-update.txt +1 -1
- data/lib/bundler/man/bundle.txt +2 -2
- data/lib/bundler/man/gemfile.5 +17 -1
- data/lib/bundler/man/gemfile.5.txt +12 -1
- data/lib/bundler/match_platform.rb +4 -4
- data/lib/bundler/psyched_yaml.rb +5 -5
- data/lib/bundler/remote_specification.rb +1 -1
- data/lib/bundler/resolver.rb +93 -88
- data/lib/bundler/retry.rb +9 -10
- data/lib/bundler/ruby_dsl.rb +1 -1
- data/lib/bundler/ruby_version.rb +7 -10
- data/lib/bundler/rubygems_ext.rb +32 -27
- data/lib/bundler/{gem_installer.rb → rubygems_gem_installer.rb} +2 -2
- data/lib/bundler/rubygems_integration.rb +85 -70
- data/lib/bundler/runtime.rb +65 -61
- data/lib/bundler/settings.rb +27 -26
- data/lib/bundler/setup.rb +3 -3
- data/lib/bundler/shared_helpers.rb +45 -20
- data/lib/bundler/similarity_detector.rb +19 -21
- data/lib/bundler/source/git/git_proxy.rb +52 -26
- data/lib/bundler/source/git.rb +29 -31
- data/lib/bundler/source/path/installer.rb +4 -4
- data/lib/bundler/source/path.rb +25 -28
- data/lib/bundler/source/rubygems/remote.rb +3 -3
- data/lib/bundler/source/rubygems.rb +62 -48
- data/lib/bundler/source.rb +4 -5
- data/lib/bundler/source_list.rb +4 -4
- data/lib/bundler/spec_set.rb +17 -15
- data/lib/bundler/ssl_certs/certificate_manager.rb +5 -6
- data/lib/bundler/stub_specification.rb +2 -2
- data/lib/bundler/templates/Executable +5 -5
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +42 -6
- data/lib/bundler/templates/newgem/README.md.tt +1 -1
- data/lib/bundler/templates/newgem/Rakefile.tt +4 -2
- data/lib/bundler/templates/newgem/bin/setup.tt +2 -1
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -2
- data/lib/bundler/ui/rg_proxy.rb +2 -2
- data/lib/bundler/ui/shell.rb +10 -6
- data/lib/bundler/ui.rb +3 -3
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +82 -71
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +9 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +40 -21
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +8 -0
- data/lib/bundler/vendored_molinillo.rb +1 -1
- data/lib/bundler/vendored_persistent.rb +3 -3
- data/lib/bundler/vendored_thor.rb +2 -2
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/vlad.rb +1 -1
- data/lib/bundler/worker.rb +4 -5
- data/lib/bundler.rb +99 -120
- data/man/bundle-config.ronn +4 -2
- data/man/bundle-gem.ronn +77 -0
- data/man/bundle-install.ronn +13 -6
- data/man/bundle-lock.ronn +47 -0
- data/man/bundle.ronn +1 -1
- data/man/gemfile.5.ronn +8 -0
- data/man/index.txt +1 -0
- metadata +36 -8
- data/bin/bundle +0 -21
- data/bin/bundler +0 -21
data/lib/bundler/fetcher.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
1
|
+
require "bundler/vendored_persistent"
|
|
2
|
+
require "cgi"
|
|
3
|
+
require "securerandom"
|
|
4
|
+
require "zlib"
|
|
4
5
|
|
|
5
6
|
module Bundler
|
|
6
|
-
|
|
7
7
|
# Handles all the fetching with the rubygems server
|
|
8
8
|
class Fetcher
|
|
9
|
-
autoload :Downloader,
|
|
10
|
-
autoload :Dependency,
|
|
11
|
-
autoload :Index,
|
|
9
|
+
autoload :Downloader, "bundler/fetcher/downloader"
|
|
10
|
+
autoload :Dependency, "bundler/fetcher/dependency"
|
|
11
|
+
autoload :Index, "bundler/fetcher/index"
|
|
12
12
|
|
|
13
13
|
# This error is raised when it looks like the network is down
|
|
14
14
|
class NetworkDownError < HTTPError; end
|
|
@@ -21,7 +21,7 @@ module Bundler
|
|
|
21
21
|
" is a chance you are experiencing a man-in-the-middle attack, but" \
|
|
22
22
|
" most likely your system doesn't have the CA certificates needed" \
|
|
23
23
|
" for verification. For information about OpenSSL certificates, see" \
|
|
24
|
-
" bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile" \
|
|
24
|
+
" http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile" \
|
|
25
25
|
" sources and change 'https' to 'http'."
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -52,13 +52,16 @@ module Bundler
|
|
|
52
52
|
|
|
53
53
|
# Exceptions classes that should bypass retry attempts. If your password didn't work the
|
|
54
54
|
# first time, it's not going to the third time.
|
|
55
|
-
AUTH_ERRORS = [AuthenticationRequiredError, BadAuthenticationError
|
|
55
|
+
AUTH_ERRORS = [AuthenticationRequiredError, BadAuthenticationError, Net::HTTPBadGateway,
|
|
56
|
+
Net::HTTPBadRequest, Net::HTTPForbidden, Net::HTTPMethodNotAllowed,
|
|
57
|
+
Net::HTTPMovedPermanently, Net::HTTPNotImplemented, Net::HTTPNotFound,
|
|
58
|
+
Net::HTTPRequestEntityTooLarge, Net::HTTPNoContent]
|
|
56
59
|
|
|
57
60
|
class << self
|
|
58
61
|
attr_accessor :disable_endpoint, :api_timeout, :redirect_limit, :max_retries
|
|
59
62
|
end
|
|
60
63
|
|
|
61
|
-
self.redirect_limit = Bundler.settings[:redirect]
|
|
64
|
+
self.redirect_limit = Bundler.settings[:redirect] # How many redirects to allow in one request
|
|
62
65
|
self.api_timeout = Bundler.settings[:timeout] # How long to wait for each API call
|
|
63
66
|
self.max_retries = Bundler.settings[:retry] # How many retries for the API call
|
|
64
67
|
|
|
@@ -75,11 +78,11 @@ module Bundler
|
|
|
75
78
|
|
|
76
79
|
# fetch a gem specification
|
|
77
80
|
def fetch_spec(spec)
|
|
78
|
-
spec
|
|
79
|
-
spec_file_name = "#{spec.join
|
|
81
|
+
spec -= [nil, "ruby", ""]
|
|
82
|
+
spec_file_name = "#{spec.join "-"}.gemspec"
|
|
80
83
|
|
|
81
84
|
uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
|
|
82
|
-
if uri.scheme ==
|
|
85
|
+
if uri.scheme == "file"
|
|
83
86
|
Bundler.load_marshal Gem.inflate(Gem.read_binary(uri.path))
|
|
84
87
|
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
|
|
85
88
|
Bundler.load_gemspec(cached_spec_path)
|
|
@@ -91,6 +94,13 @@ module Bundler
|
|
|
91
94
|
"Your network or your gem server is probably having issues right now."
|
|
92
95
|
end
|
|
93
96
|
|
|
97
|
+
# return the specs in the bundler format as an index with retries
|
|
98
|
+
def specs_with_retry(gem_names, source)
|
|
99
|
+
Bundler::Retry.new("fetcher").attempts do
|
|
100
|
+
specs(gem_names, source)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
94
104
|
# return the specs in the bundler format as an index
|
|
95
105
|
def specs(gem_names, source)
|
|
96
106
|
old = Bundler.rubygems.sources
|
|
@@ -98,15 +108,13 @@ module Bundler
|
|
|
98
108
|
|
|
99
109
|
specs = {}
|
|
100
110
|
fetchers.dup.each do |f|
|
|
101
|
-
unless f.api_fetcher? && !gem_names
|
|
102
|
-
break if specs = f.specs(gem_names)
|
|
103
|
-
end
|
|
111
|
+
break unless f.api_fetcher? && !gem_names || !specs = f.specs(gem_names)
|
|
104
112
|
fetchers.delete(f)
|
|
105
113
|
end
|
|
106
114
|
@use_api = false if fetchers.none?(&:api_fetcher?)
|
|
107
115
|
|
|
108
116
|
specs[remote_uri].each do |name, version, platform, dependencies|
|
|
109
|
-
next if name ==
|
|
117
|
+
next if name == "bundler"
|
|
110
118
|
spec = nil
|
|
111
119
|
if dependencies
|
|
112
120
|
spec = EndpointSpecification.new(name, version, platform, dependencies)
|
|
@@ -132,7 +140,7 @@ module Bundler
|
|
|
132
140
|
if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
|
|
133
141
|
@use_api = false
|
|
134
142
|
else
|
|
135
|
-
fetchers.reject! {
|
|
143
|
+
fetchers.reject! {|f| f.api_fetcher? && !f.api_available? }
|
|
136
144
|
@use_api = fetchers.any?(&:api_fetcher?)
|
|
137
145
|
end
|
|
138
146
|
end
|
|
@@ -149,7 +157,11 @@ module Bundler
|
|
|
149
157
|
|
|
150
158
|
if ruby.engine != "ruby"
|
|
151
159
|
# engine_version raises on unknown engines
|
|
152
|
-
engine_version =
|
|
160
|
+
engine_version = begin
|
|
161
|
+
ruby.engine_version
|
|
162
|
+
rescue
|
|
163
|
+
"???"
|
|
164
|
+
end
|
|
153
165
|
agent << " #{ruby.engine}/#{engine_version}"
|
|
154
166
|
end
|
|
155
167
|
|
|
@@ -169,7 +181,13 @@ module Bundler
|
|
|
169
181
|
end
|
|
170
182
|
|
|
171
183
|
def fetchers
|
|
172
|
-
@fetchers ||= FETCHERS.map {
|
|
184
|
+
@fetchers ||= FETCHERS.map {|f| f.new(downloader, @remote, uri) }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def http_proxy
|
|
188
|
+
if uri = connection.proxy_uri
|
|
189
|
+
uri.to_s
|
|
190
|
+
end
|
|
173
191
|
end
|
|
174
192
|
|
|
175
193
|
def inspect
|
|
@@ -192,7 +210,7 @@ module Bundler
|
|
|
192
210
|
"CI_NAME" => ENV["CI_NAME"],
|
|
193
211
|
"CI" => "ci"
|
|
194
212
|
}
|
|
195
|
-
env_cis.find_all{
|
|
213
|
+
env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci }
|
|
196
214
|
end
|
|
197
215
|
|
|
198
216
|
def connection
|
|
@@ -202,7 +220,10 @@ module Bundler
|
|
|
202
220
|
Bundler.settings[:ssl_client_cert]
|
|
203
221
|
raise SSLError if needs_ssl && !defined?(OpenSSL::SSL)
|
|
204
222
|
|
|
205
|
-
con = Net::HTTP::Persistent.new
|
|
223
|
+
con = Net::HTTP::Persistent.new "bundler", :ENV
|
|
224
|
+
if gem_proxy = Bundler.rubygems.configuration[:http_proxy]
|
|
225
|
+
con.proxy = URI.parse(gem_proxy)
|
|
226
|
+
end
|
|
206
227
|
|
|
207
228
|
if remote_uri.scheme == "https"
|
|
208
229
|
con.verify_mode = (Bundler.settings[:ssl_verify_mode] ||
|
|
@@ -218,22 +239,23 @@ module Bundler
|
|
|
218
239
|
|
|
219
240
|
con.read_timeout = Fetcher.api_timeout
|
|
220
241
|
con.override_headers["User-Agent"] = user_agent
|
|
242
|
+
con.override_headers["X-Gemfile-Source"] = @remote.original_uri.to_s if @remote.original_uri
|
|
221
243
|
con
|
|
222
244
|
end
|
|
223
245
|
end
|
|
224
246
|
|
|
225
247
|
# cached gem specification path, if one exists
|
|
226
|
-
def gemspec_cached_path
|
|
227
|
-
paths = Bundler.rubygems.spec_cache_dirs.map {
|
|
248
|
+
def gemspec_cached_path(spec_file_name)
|
|
249
|
+
paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
|
|
228
250
|
paths = paths.select {|path| File.file? path }
|
|
229
251
|
paths.first
|
|
230
252
|
end
|
|
231
253
|
|
|
232
254
|
HTTP_ERRORS = [
|
|
233
|
-
Timeout::Error, EOFError, SocketError, Errno::ENETDOWN,
|
|
255
|
+
Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
|
|
234
256
|
Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
|
|
235
257
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
|
|
236
|
-
Net::HTTP::Persistent::Error
|
|
258
|
+
Net::HTTP::Persistent::Error, Zlib::BufError
|
|
237
259
|
]
|
|
238
260
|
|
|
239
261
|
def bundler_cert_store
|
|
@@ -247,25 +269,13 @@ module Bundler
|
|
|
247
269
|
else
|
|
248
270
|
store.set_default_paths
|
|
249
271
|
certs = File.expand_path("../ssl_certs/*.pem", __FILE__)
|
|
250
|
-
Dir.glob(certs).each {
|
|
272
|
+
Dir.glob(certs).each {|c| store.add_file c }
|
|
251
273
|
end
|
|
252
274
|
store
|
|
253
275
|
end
|
|
254
276
|
|
|
255
277
|
private
|
|
256
278
|
|
|
257
|
-
def fetch_uri
|
|
258
|
-
@fetch_uri ||= begin
|
|
259
|
-
if remote_uri.host == "rubygems.org"
|
|
260
|
-
uri = remote_uri.dup
|
|
261
|
-
uri.host = "bundler.rubygems.org"
|
|
262
|
-
uri
|
|
263
|
-
else
|
|
264
|
-
remote_uri
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
|
|
269
279
|
def remote_uri
|
|
270
280
|
@remote.uri
|
|
271
281
|
end
|
|
@@ -273,6 +283,5 @@ module Bundler
|
|
|
273
283
|
def downloader
|
|
274
284
|
@downloader ||= Downloader.new(connection, self.class.redirect_limit)
|
|
275
285
|
end
|
|
276
|
-
|
|
277
286
|
end
|
|
278
287
|
end
|
|
@@ -5,9 +5,17 @@ require "bundler/vendored_thor"
|
|
|
5
5
|
module Bundler
|
|
6
6
|
def self.with_friendly_errors
|
|
7
7
|
yield
|
|
8
|
+
rescue Bundler::YamlSyntaxError => e
|
|
9
|
+
Bundler.ui.error e.message
|
|
10
|
+
Bundler.ui.trace e.orig_exception
|
|
11
|
+
exit e.status_code
|
|
8
12
|
rescue Bundler::Dsl::DSLError => e
|
|
9
13
|
Bundler.ui.error e.message
|
|
10
14
|
exit e.status_code
|
|
15
|
+
rescue Bundler::GemRequireError => e
|
|
16
|
+
Bundler.ui.error e.message
|
|
17
|
+
Bundler.ui.trace e.orig_exception, nil, true
|
|
18
|
+
exit e.status_code
|
|
11
19
|
rescue Bundler::BundlerError => e
|
|
12
20
|
Bundler.ui.error e.message, :wrap => true
|
|
13
21
|
Bundler.ui.trace e
|
|
@@ -43,11 +51,11 @@ module Bundler
|
|
|
43
51
|
end
|
|
44
52
|
|
|
45
53
|
def self.request_issue_report_for(e)
|
|
46
|
-
Bundler.ui.info <<-EOS.gsub(/^ {6}/,
|
|
47
|
-
|
|
54
|
+
Bundler.ui.info <<-EOS.gsub(/^ {6}/, "")
|
|
55
|
+
--- ERROR REPORT TEMPLATE -------------------------------------------------------
|
|
48
56
|
- What did you do?
|
|
49
57
|
|
|
50
|
-
I ran the command `#{$PROGRAM_NAME} #{ARGV.join(
|
|
58
|
+
I ran the command `#{$PROGRAM_NAME} #{ARGV.join(" ")}`
|
|
51
59
|
|
|
52
60
|
- What did you expect to happen?
|
|
53
61
|
|
|
@@ -63,14 +71,14 @@ module Bundler
|
|
|
63
71
|
#{e.class}: #{e.message}
|
|
64
72
|
#{e.backtrace.join("\n ")}
|
|
65
73
|
|
|
66
|
-
#{Bundler::Env.new.report(:print_gemfile => false).gsub(/\n/, "\n ").strip}
|
|
67
|
-
|
|
74
|
+
#{Bundler::Env.new.report(:print_gemfile => false, :print_gemspecs => false).gsub(/\n/, "\n ").strip}
|
|
75
|
+
--- TEMPLATE END ----------------------------------------------------------------
|
|
68
76
|
|
|
69
77
|
EOS
|
|
70
78
|
|
|
71
79
|
Bundler.ui.error "Unfortunately, an unexpected error occurred, and Bundler cannot continue."
|
|
72
80
|
|
|
73
|
-
Bundler.ui.warn <<-EOS.gsub(/^ {6}/,
|
|
81
|
+
Bundler.ui.warn <<-EOS.gsub(/^ {6}/, "")
|
|
74
82
|
|
|
75
83
|
First, try this link to see if there are any existing issue reports for this error:
|
|
76
84
|
#{issues_url(e)}
|
|
@@ -81,8 +89,7 @@ module Bundler
|
|
|
81
89
|
end
|
|
82
90
|
|
|
83
91
|
def self.issues_url(exception)
|
|
84
|
-
|
|
92
|
+
"https://github.com/bundler/bundler/search?q=" \
|
|
85
93
|
"#{CGI.escape(exception.message.lines.first.chomp)}&type=Issues"
|
|
86
94
|
end
|
|
87
|
-
|
|
88
95
|
end
|
data/lib/bundler/gem_helper.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "bundler/vendored_thor" unless defined?(Thor)
|
|
2
|
+
require "bundler"
|
|
3
3
|
|
|
4
4
|
module Bundler
|
|
5
5
|
class GemHelper
|
|
@@ -35,35 +35,35 @@ module Bundler
|
|
|
35
35
|
built_gem_path = nil
|
|
36
36
|
|
|
37
37
|
desc "Build #{name}-#{version}.gem into the pkg directory."
|
|
38
|
-
task
|
|
38
|
+
task "build" do
|
|
39
39
|
built_gem_path = build_gem
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
desc "Build and install #{name}-#{version}.gem into system gems."
|
|
43
|
-
task
|
|
43
|
+
task "install" => "build" do
|
|
44
44
|
install_gem(built_gem_path)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
desc "Build and install #{name}-#{version}.gem into system gems without network access."
|
|
48
|
-
task
|
|
48
|
+
task "install:local" => "build" do
|
|
49
49
|
install_gem(built_gem_path, :local)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
desc "Create tag #{version_tag} and build and push #{name}-#{version}.gem to Rubygems\n" \
|
|
53
53
|
"To prevent publishing in Rubygems use `gem_push=no rake release`"
|
|
54
|
-
task
|
|
55
|
-
|
|
54
|
+
task "release", [:remote] => ["build", "release:guard_clean",
|
|
55
|
+
"release:source_control_push", "release:rubygem_push"] do
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
task
|
|
58
|
+
task "release:guard_clean" do
|
|
59
59
|
guard_clean
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
task
|
|
63
|
-
tag_version { git_push } unless already_tagged?
|
|
62
|
+
task "release:source_control_push", [:remote] do |_, args|
|
|
63
|
+
tag_version { git_push(args[:remote]) } unless already_tagged?
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
task
|
|
66
|
+
task "release:rubygem_push" do
|
|
67
67
|
rubygem_push(built_gem_path) if gem_push?
|
|
68
68
|
end
|
|
69
69
|
|
|
@@ -72,57 +72,64 @@ module Bundler
|
|
|
72
72
|
|
|
73
73
|
def build_gem
|
|
74
74
|
file_name = nil
|
|
75
|
-
sh("gem build -V '#{spec_path}'")
|
|
75
|
+
sh("gem build -V '#{spec_path}'") do
|
|
76
76
|
file_name = File.basename(built_gem_path)
|
|
77
|
-
|
|
78
|
-
FileUtils.mv(built_gem_path,
|
|
77
|
+
SharedHelpers.filesystem_access(File.join(base, "pkg")) {|p| FileUtils.mkdir_p(p) }
|
|
78
|
+
FileUtils.mv(built_gem_path, "pkg")
|
|
79
79
|
Bundler.ui.confirm "#{name} #{version} built to pkg/#{file_name}."
|
|
80
|
-
|
|
81
|
-
File.join(base,
|
|
80
|
+
end
|
|
81
|
+
File.join(base, "pkg", file_name)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
def install_gem(built_gem_path = nil, local = false)
|
|
85
85
|
built_gem_path ||= build_gem
|
|
86
|
-
out, _ = sh_with_code("gem install '#{built_gem_path}'#{
|
|
86
|
+
out, _ = sh_with_code("gem install '#{built_gem_path}'#{" --local" if local}")
|
|
87
87
|
raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
|
|
88
88
|
Bundler.ui.confirm "#{name} (#{version}) installed."
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
protected
|
|
92
|
+
|
|
92
93
|
def rubygem_push(path)
|
|
93
94
|
if Pathname.new("~/.gem/credentials").expand_path.exist?
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
allowed_push_host = nil
|
|
96
|
+
gem_command = "gem push '#{path}'"
|
|
97
|
+
if @gemspec.respond_to?(:metadata)
|
|
98
|
+
allowed_push_host = @gemspec.metadata["allowed_push_host"]
|
|
99
|
+
gem_command << " --host #{allowed_push_host}" if allowed_push_host
|
|
100
|
+
end
|
|
101
|
+
sh(gem_command)
|
|
102
|
+
Bundler.ui.confirm "Pushed #{name} #{version} to #{allowed_push_host ? allowed_push_host : "rubygems.org."}"
|
|
96
103
|
else
|
|
97
104
|
raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
|
|
98
105
|
end
|
|
99
106
|
end
|
|
100
107
|
|
|
101
108
|
def built_gem_path
|
|
102
|
-
Dir[File.join(base, "#{name}-*.gem")].sort_by{|f| File.mtime(f)}.last
|
|
109
|
+
Dir[File.join(base, "#{name}-*.gem")].sort_by {|f| File.mtime(f) }.last
|
|
103
110
|
end
|
|
104
111
|
|
|
105
|
-
def git_push
|
|
106
|
-
perform_git_push
|
|
107
|
-
perform_git_push
|
|
112
|
+
def git_push(remote = "")
|
|
113
|
+
perform_git_push remote
|
|
114
|
+
perform_git_push "#{remote} --tags"
|
|
108
115
|
Bundler.ui.confirm "Pushed git commits and tags."
|
|
109
116
|
end
|
|
110
117
|
|
|
111
|
-
def perform_git_push(options =
|
|
118
|
+
def perform_git_push(options = "")
|
|
112
119
|
cmd = "git push #{options}"
|
|
113
120
|
out, code = sh_with_code(cmd)
|
|
114
121
|
raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
|
|
115
122
|
end
|
|
116
123
|
|
|
117
124
|
def already_tagged?
|
|
118
|
-
if sh(
|
|
125
|
+
if sh("git tag").split(/\n/).include?(version_tag)
|
|
119
126
|
Bundler.ui.confirm "Tag #{version_tag} has already been created."
|
|
120
127
|
true
|
|
121
128
|
end
|
|
122
129
|
end
|
|
123
130
|
|
|
124
131
|
def guard_clean
|
|
125
|
-
clean? && committed?
|
|
132
|
+
clean? && committed? || raise("There are files that need to be committed first.")
|
|
126
133
|
end
|
|
127
134
|
|
|
128
135
|
def clean?
|
|
@@ -157,24 +164,26 @@ module Bundler
|
|
|
157
164
|
|
|
158
165
|
def sh(cmd, &block)
|
|
159
166
|
out, code = sh_with_code(cmd, &block)
|
|
160
|
-
code == 0
|
|
167
|
+
if code == 0
|
|
168
|
+
out
|
|
169
|
+
else
|
|
170
|
+
raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
|
|
171
|
+
end
|
|
161
172
|
end
|
|
162
173
|
|
|
163
174
|
def sh_with_code(cmd, &block)
|
|
164
175
|
cmd << " 2>&1"
|
|
165
|
-
outbuf =
|
|
176
|
+
outbuf = ""
|
|
166
177
|
Bundler.ui.debug(cmd)
|
|
167
|
-
SharedHelpers.chdir(base)
|
|
178
|
+
SharedHelpers.chdir(base) do
|
|
168
179
|
outbuf = `#{cmd}`
|
|
169
|
-
if $? == 0
|
|
170
|
-
|
|
171
|
-
end
|
|
172
|
-
}
|
|
180
|
+
block.call(outbuf) if $? == 0 && block
|
|
181
|
+
end
|
|
173
182
|
[outbuf, $?]
|
|
174
183
|
end
|
|
175
184
|
|
|
176
185
|
def gem_push?
|
|
177
|
-
! %w
|
|
186
|
+
! %w(n no nil false off 0).include?(ENV["gem_push"].to_s.downcase)
|
|
178
187
|
end
|
|
179
188
|
end
|
|
180
189
|
end
|
data/lib/bundler/gem_helpers.rb
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
module Bundler
|
|
2
2
|
module GemHelpers
|
|
3
|
-
|
|
4
3
|
GENERIC_CACHE = {}
|
|
5
4
|
GENERICS = [
|
|
6
|
-
[Gem::Platform.new(
|
|
7
|
-
[Gem::Platform.new(
|
|
8
|
-
[Gem::Platform.new(
|
|
9
|
-
[Gem::Platform.new(
|
|
10
|
-
[Gem::Platform.new(
|
|
11
|
-
[Gem::Platform.new(
|
|
12
|
-
[Gem::Platform.new(
|
|
5
|
+
[Gem::Platform.new("java"), Gem::Platform.new("java")],
|
|
6
|
+
[Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")],
|
|
7
|
+
[Gem::Platform.new("mswin64"), Gem::Platform.new("mswin64")],
|
|
8
|
+
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
|
|
9
|
+
[Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
|
|
10
|
+
[Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
|
|
11
|
+
[Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")]
|
|
13
12
|
]
|
|
14
13
|
|
|
15
14
|
def generic(p)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require "rubygems/remote_fetcher"
|
|
2
|
+
|
|
3
|
+
module Bundler
|
|
4
|
+
# Adds support for setting custom HTTP headers when fetching gems from the
|
|
5
|
+
# server.
|
|
6
|
+
#
|
|
7
|
+
# TODO: Get rid of this when and if gemstash only supports RubyGems versions
|
|
8
|
+
# that contain https://github.com/rubygems/rubygems/commit/3db265cc20b2f813.
|
|
9
|
+
class GemRemoteFetcher < Gem::RemoteFetcher
|
|
10
|
+
attr_accessor :headers
|
|
11
|
+
|
|
12
|
+
# Extracted from RubyGems 2.4.
|
|
13
|
+
def fetch_http(uri, last_modified = nil, head = false, depth = 0)
|
|
14
|
+
fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
|
|
15
|
+
# beginning of change
|
|
16
|
+
response = request uri, fetch_type, last_modified do |req|
|
|
17
|
+
headers.each {|k, v| req.add_field(k, v) } if headers
|
|
18
|
+
end
|
|
19
|
+
# end of change
|
|
20
|
+
|
|
21
|
+
case response
|
|
22
|
+
when Net::HTTPOK, Net::HTTPNotModified then
|
|
23
|
+
response.uri = uri if response.respond_to? :uri
|
|
24
|
+
head ? response : response.body
|
|
25
|
+
when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
|
|
26
|
+
Net::HTTPTemporaryRedirect then
|
|
27
|
+
raise FetchError.new("too many redirects", uri) if depth > 10
|
|
28
|
+
|
|
29
|
+
location = URI.parse response["Location"]
|
|
30
|
+
|
|
31
|
+
if https?(uri) && !https?(location)
|
|
32
|
+
raise FetchError.new("redirecting to non-https resource: #{location}", uri)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
fetch_http(location, last_modified, head, depth + 1)
|
|
36
|
+
else
|
|
37
|
+
raise FetchError.new("bad response #{response.message} #{response.code}", uri)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/bundler/gem_tasks.rb
CHANGED
data/lib/bundler/graph.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "set"
|
|
2
2
|
module Bundler
|
|
3
3
|
class Graph
|
|
4
4
|
GRAPH_NAME = :Gemfile
|
|
@@ -12,7 +12,7 @@ module Bundler
|
|
|
12
12
|
@without_groups = without.map(&:to_sym)
|
|
13
13
|
|
|
14
14
|
@groups = []
|
|
15
|
-
@relations = Hash.new {|h, k| h[k] = Set.new}
|
|
15
|
+
@relations = Hash.new {|h, k| h[k] = Set.new }
|
|
16
16
|
@node_options = {}
|
|
17
17
|
@edge_options = {}
|
|
18
18
|
|
|
@@ -26,11 +26,11 @@ module Bundler
|
|
|
26
26
|
GraphVizClient.new(self).run
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
private
|
|
30
30
|
|
|
31
31
|
def _populate_relations
|
|
32
32
|
parent_dependencies = _groups.values.to_set.flatten
|
|
33
|
-
|
|
33
|
+
loop do
|
|
34
34
|
if parent_dependencies.empty?
|
|
35
35
|
break
|
|
36
36
|
else
|
|
@@ -54,7 +54,7 @@ module Bundler
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def _groups
|
|
57
|
-
relations = Hash.new {|h, k| h[k] = Set.new}
|
|
57
|
+
relations = Hash.new {|h, k| h[k] = Set.new }
|
|
58
58
|
@env.current_dependencies.each do |dependency|
|
|
59
59
|
dependency.groups.each do |group|
|
|
60
60
|
next if @without_groups.include?(group)
|
|
@@ -75,7 +75,7 @@ module Bundler
|
|
|
75
75
|
when :node
|
|
76
76
|
if symbol_or_string_or_dependency.is_a?(Gem::Dependency)
|
|
77
77
|
label = symbol_or_string_or_dependency.name.dup
|
|
78
|
-
label << "\n#{symbol_or_string_or_dependency.to_spec.version
|
|
78
|
+
label << "\n#{symbol_or_string_or_dependency.to_spec.version}" if @show_version
|
|
79
79
|
else
|
|
80
80
|
label = symbol_or_string_or_dependency.to_s
|
|
81
81
|
end
|
|
@@ -95,19 +95,19 @@ module Bundler
|
|
|
95
95
|
# method borrow from rubygems/dependency.rb
|
|
96
96
|
# redefinition of matching_specs will also redefine to_spec and to_specs
|
|
97
97
|
Gem::Dependency.class_eval do
|
|
98
|
-
def matching_specs
|
|
99
|
-
matches = Bundler.load.specs.select
|
|
100
|
-
|
|
101
|
-
requirement.satisfied_by?
|
|
102
|
-
|
|
98
|
+
def matching_specs(platform_only = false)
|
|
99
|
+
matches = Bundler.load.specs.select do |spec|
|
|
100
|
+
name == spec.name &&
|
|
101
|
+
requirement.satisfied_by?(spec.version)
|
|
102
|
+
end
|
|
103
103
|
|
|
104
104
|
if platform_only
|
|
105
|
-
matches.
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
matches.select! do |spec|
|
|
106
|
+
Gem::Platform.match spec.platform
|
|
107
|
+
end
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
matches = matches.sort_by
|
|
110
|
+
matches = matches.sort_by(&:sort_obj) # HACK: shouldn't be needed
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
end
|
|
@@ -124,9 +124,9 @@ module Bundler
|
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
def g
|
|
127
|
-
@g ||= ::GraphViz.digraph(@graph_name,
|
|
127
|
+
@g ||= ::GraphViz.digraph(@graph_name, :concentrate => true, :normalize => true, :nodesep => 0.55) do |g|
|
|
128
128
|
g.edge[:weight] = 2
|
|
129
|
-
g.edge[:fontname] = g.node[:fontname] =
|
|
129
|
+
g.edge[:fontname] = g.node[:fontname] = "Arial, Helvetica, SansSerif"
|
|
130
130
|
g.edge[:fontsize] = 12
|
|
131
131
|
end
|
|
132
132
|
end
|
|
@@ -134,19 +134,20 @@ module Bundler
|
|
|
134
134
|
def run
|
|
135
135
|
@groups.each do |group|
|
|
136
136
|
g.add_nodes(
|
|
137
|
-
group,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
137
|
+
group, {
|
|
138
|
+
:style => "filled",
|
|
139
|
+
:fillcolor => "#B9B9D5",
|
|
140
|
+
:shape => "box3d",
|
|
141
|
+
:fontsize => 16
|
|
142
|
+
}.merge(@node_options[group])
|
|
142
143
|
)
|
|
143
144
|
end
|
|
144
145
|
|
|
145
146
|
@relations.each do |parent, children|
|
|
146
147
|
children.each do |child|
|
|
147
148
|
if @groups.include?(parent)
|
|
148
|
-
g.add_nodes(child, {:style =>
|
|
149
|
-
g.add_edges(parent, child, {:constraint => false}.merge(@edge_options["#{parent}_#{child}"]))
|
|
149
|
+
g.add_nodes(child, { :style => "filled", :fillcolor => "#B9B9D5" }.merge(@node_options[child]))
|
|
150
|
+
g.add_edges(parent, child, { :constraint => false }.merge(@edge_options["#{parent}_#{child}"]))
|
|
150
151
|
else
|
|
151
152
|
g.add_nodes(child, @node_options[child])
|
|
152
153
|
g.add_edges(parent, child, @edge_options["#{parent}_#{child}"])
|