bundler 1.2.5 → 1.3.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.
- data/.gitignore +10 -7
- data/.travis.yml +12 -3
- data/CHANGELOG.md +26 -19
- data/CONTRIBUTE.md +97 -0
- data/README.md +4 -2
- data/Rakefile +17 -59
- data/bundler.gemspec +2 -1
- data/lib/bundler.rb +23 -20
- data/lib/bundler/cli.rb +68 -22
- data/lib/bundler/definition.rb +3 -2
- data/lib/bundler/deprecate.rb +15 -0
- data/lib/bundler/dsl.rb +14 -16
- data/lib/bundler/environment.rb +0 -5
- data/lib/bundler/fetcher.rb +23 -78
- data/lib/bundler/friendly_errors.rb +4 -5
- data/lib/bundler/gem_helper.rb +14 -16
- data/lib/bundler/injector.rb +64 -0
- data/lib/bundler/installer.rb +1 -7
- data/lib/bundler/lazy_specification.rb +6 -3
- data/lib/bundler/lockfile_parser.rb +25 -13
- data/lib/bundler/resolver.rb +0 -1
- data/lib/bundler/rubygems_integration.rb +83 -17
- data/lib/bundler/settings.rb +4 -2
- data/lib/bundler/similarity_detector.rb +63 -0
- data/lib/bundler/source.rb +3 -886
- data/lib/bundler/source/git.rb +267 -0
- data/lib/bundler/source/git/git_proxy.rb +142 -0
- data/lib/bundler/source/path.rb +209 -0
- data/lib/bundler/source/path/installer.rb +33 -0
- data/lib/bundler/source/rubygems.rb +261 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -0
- data/lib/bundler/templates/newgem/rspec.tt +2 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -0
- data/lib/bundler/templates/newgem/test/minitest_helper.rb.tt +4 -0
- data/lib/bundler/templates/newgem/test/test_newgem.rb.tt +11 -0
- data/lib/bundler/ui.rb +20 -5
- data/lib/bundler/vendor/.document +0 -0
- data/lib/bundler/vendor/thor.rb +74 -5
- data/lib/bundler/vendor/thor/actions.rb +5 -5
- data/lib/bundler/vendor/thor/actions/directory.rb +1 -0
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +7 -1
- data/lib/bundler/vendor/thor/base.rb +44 -11
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +5 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +14 -7
- data/lib/bundler/vendor/thor/parser/arguments.rb +7 -1
- data/lib/bundler/vendor/thor/parser/option.rb +8 -8
- data/lib/bundler/vendor/thor/parser/options.rb +62 -24
- data/lib/bundler/vendor/thor/runner.rb +1 -1
- data/lib/bundler/vendor/thor/shell/basic.rb +2 -2
- data/lib/bundler/vendor/thor/task.rb +2 -2
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/vendored_persistent.rb +3 -15
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-exec.ronn +1 -1
- data/man/bundle-update.ronn +1 -1
- data/man/bundle.ronn +4 -1
- data/spec/bundler/bundler_spec.rb +2 -28
- data/spec/bundler/cli_rspec.rb +9 -0
- data/spec/bundler/definition_spec.rb +1 -1
- data/spec/bundler/dsl_spec.rb +15 -8
- data/spec/bundler/gem_helper_spec.rb +38 -21
- data/spec/bundler/psyched_yaml_spec.rb +1 -0
- data/spec/bundler/source_spec.rb +3 -3
- data/spec/cache/gems_spec.rb +24 -24
- data/spec/cache/git_spec.rb +21 -23
- data/spec/cache/path_spec.rb +11 -11
- data/spec/cache/platform_spec.rb +6 -6
- data/spec/install/deploy_spec.rb +38 -38
- data/spec/install/gems/c_ext_spec.rb +2 -2
- data/spec/install/gems/dependency_api_spec.rb +23 -116
- data/spec/install/gems/env_spec.rb +1 -1
- data/spec/install/gems/flex_spec.rb +7 -8
- data/spec/install/gems/groups_spec.rb +10 -10
- data/spec/install/gems/packed_spec.rb +4 -4
- data/spec/install/gems/platform_spec.rb +3 -3
- data/spec/install/gems/post_install_spec.rb +9 -9
- data/spec/install/gems/resolving_spec.rb +2 -2
- data/spec/install/gems/simple_case_spec.rb +50 -53
- data/spec/install/gems/standalone_spec.rb +19 -19
- data/spec/install/gems/sudo_spec.rb +31 -16
- data/spec/install/gems/win32_spec.rb +1 -1
- data/spec/install/gemspec_spec.rb +6 -6
- data/spec/install/git_spec.rb +34 -34
- data/spec/install/invalid_spec.rb +3 -3
- data/spec/install/path_spec.rb +71 -8
- data/spec/install/upgrade_spec.rb +2 -2
- data/spec/integration/inject.rb +78 -0
- data/spec/lock/git_spec.rb +2 -2
- data/spec/lock/lockfile_spec.rb +14 -14
- data/spec/other/check_spec.rb +29 -29
- data/spec/other/clean_spec.rb +47 -48
- data/spec/other/config_spec.rb +20 -20
- data/spec/other/console_spec.rb +5 -5
- data/spec/other/exec_spec.rb +48 -28
- data/spec/other/ext_spec.rb +3 -3
- data/spec/other/help_spec.rb +6 -6
- data/spec/other/init_spec.rb +8 -8
- data/spec/other/newgem_spec.rb +95 -15
- data/spec/other/open_spec.rb +10 -5
- data/spec/other/outdated_spec.rb +8 -8
- data/spec/other/platform_spec.rb +45 -45
- data/spec/other/show_spec.rb +10 -10
- data/spec/quality_spec.rb +2 -2
- data/spec/realworld/dependency_api_spec.rb +61 -0
- data/spec/realworld/edgecases_spec.rb +8 -8
- data/spec/runtime/executable_spec.rb +13 -13
- data/spec/runtime/load_spec.rb +12 -12
- data/spec/runtime/platform_spec.rb +1 -1
- data/spec/runtime/require_spec.rb +24 -24
- data/spec/runtime/setup_spec.rb +113 -56
- data/spec/runtime/with_clean_env_spec.rb +11 -13
- data/spec/spec_helper.rb +6 -0
- data/spec/support/artifice/endpoint.rb +28 -13
- data/spec/support/artifice/endpoint_extra.rb +4 -0
- data/spec/support/builders.rb +1 -1
- data/spec/support/helpers.rb +2 -7
- data/spec/support/indexes.rb +3 -3
- data/spec/support/matchers.rb +6 -6
- data/spec/update/gems_spec.rb +19 -8
- data/spec/update/git_spec.rb +10 -10
- data/spec/update/source_spec.rb +1 -1
- metadata +86 -55
- data/.rspec +0 -2
data/lib/bundler/cli.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'bundler/vendored_thor'
|
2
2
|
require 'rubygems/user_interaction'
|
3
3
|
require 'rubygems/config_file'
|
4
|
+
require 'bundler/similarity_detector'
|
4
5
|
|
5
6
|
module Bundler
|
6
7
|
class CLI < Thor
|
@@ -8,15 +9,18 @@ module Bundler
|
|
8
9
|
|
9
10
|
def initialize(*)
|
10
11
|
super
|
11
|
-
the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell)
|
12
|
-
Bundler.ui = UI::Shell.new(the_shell)
|
13
|
-
Bundler.ui.debug! if options["verbose"]
|
14
12
|
Bundler.rubygems.ui = UI::RGProxy.new(Bundler.ui)
|
15
|
-
|
13
|
+
rescue UnknownArgumentError => e
|
14
|
+
raise InvalidOption, e.message
|
15
|
+
ensure
|
16
|
+
Bundler.ui = UI::Shell.new(options)
|
17
|
+
Bundler.ui.debug! if options["verbose"]
|
16
18
|
end
|
17
19
|
|
18
20
|
check_unknown_options!(:except => [:config, :exec])
|
19
21
|
|
22
|
+
stop_on_unknown_option! :exec
|
23
|
+
|
20
24
|
default_task :install
|
21
25
|
class_option "no-color", :type => :boolean, :banner => "Disable colorization in output"
|
22
26
|
class_option "verbose", :type => :boolean, :banner => "Enable verbose output mode", :aliases => "-V"
|
@@ -219,7 +223,7 @@ module Bundler
|
|
219
223
|
Bundler.settings[:no_prune] = true if opts["no-prune"]
|
220
224
|
Bundler.settings[:disable_shared_gems] = Bundler.settings[:path] ? '1' : nil
|
221
225
|
Bundler.settings.without = opts[:without]
|
222
|
-
Bundler.ui.
|
226
|
+
Bundler.ui.be_quiet! if opts[:quiet]
|
223
227
|
Bundler.settings[:clean] = opts[:clean] if opts[:clean]
|
224
228
|
|
225
229
|
Bundler::Fetcher.disable_endpoint = opts["full-index"]
|
@@ -273,12 +277,14 @@ module Bundler
|
|
273
277
|
"Use the rubygems modern index instead of the API endpoint"
|
274
278
|
def update(*gems)
|
275
279
|
sources = Array(options[:source])
|
276
|
-
Bundler.ui.
|
280
|
+
Bundler.ui.be_quiet! if options[:quiet]
|
277
281
|
|
278
282
|
if gems.empty? && sources.empty?
|
279
283
|
# We're doing a full update
|
280
284
|
Bundler.definition(true)
|
281
285
|
else
|
286
|
+
# cycle through the requested gems, just to make sure they exist
|
287
|
+
gems.each{ |n| gem_dependency_with_name(n) }
|
282
288
|
Bundler.definition(:gems => gems, :sources => sources)
|
283
289
|
end
|
284
290
|
|
@@ -346,11 +352,6 @@ module Bundler
|
|
346
352
|
options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely!
|
347
353
|
|
348
354
|
Bundler.ui.info ""
|
349
|
-
if options["pre"]
|
350
|
-
Bundler.ui.info "Outdated gems included in the bundle (including pre-releases):"
|
351
|
-
else
|
352
|
-
Bundler.ui.info "Outdated gems included in the bundle:"
|
353
|
-
end
|
354
355
|
|
355
356
|
out_count = 0
|
356
357
|
# Loop through the current specs
|
@@ -369,6 +370,14 @@ module Bundler
|
|
369
370
|
gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
|
370
371
|
git_outdated = current_spec.git_version != active_spec.git_version
|
371
372
|
if gem_outdated || git_outdated
|
373
|
+
if out_count == 0
|
374
|
+
if options["pre"]
|
375
|
+
Bundler.ui.info "Outdated gems included in the bundle (including pre-releases):"
|
376
|
+
else
|
377
|
+
Bundler.ui.info "Outdated gems included in the bundle:"
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
372
381
|
spec_version = "#{active_spec.version}#{active_spec.git_version}"
|
373
382
|
current_version = "#{current_spec.version}#{current_spec.git_version}"
|
374
383
|
Bundler.ui.info " * #{active_spec.name} (#{spec_version} > #{current_version})"
|
@@ -377,7 +386,7 @@ module Bundler
|
|
377
386
|
Bundler.ui.debug "from #{active_spec.loaded_from}"
|
378
387
|
end
|
379
388
|
|
380
|
-
Bundler.ui.info "
|
389
|
+
Bundler.ui.info "Your bundle is up to date!" if out_count < 1
|
381
390
|
Bundler.ui.info ""
|
382
391
|
end
|
383
392
|
|
@@ -581,6 +590,7 @@ module Bundler
|
|
581
590
|
|
582
591
|
desc "gem GEM", "Creates a skeleton for creating a rubygem"
|
583
592
|
method_option :bin, :type => :boolean, :default => false, :aliases => '-b', :banner => "Generate a binary for your library."
|
593
|
+
method_option :test, :type => :string, :default => 'rspec', :aliases => '-t', :banner => "Generate a test directory for your library: 'rspec' is the default, but 'minitest' is also supported."
|
584
594
|
def gem(name)
|
585
595
|
name = name.chomp("/") # remove trailing slash if present
|
586
596
|
target = File.join(Dir.pwd, name)
|
@@ -608,6 +618,15 @@ module Bundler
|
|
608
618
|
if options[:bin]
|
609
619
|
template(File.join("newgem/bin/newgem.tt"), File.join(target, 'bin', name), opts)
|
610
620
|
end
|
621
|
+
case options[:test]
|
622
|
+
when 'rspec'
|
623
|
+
template(File.join("newgem/rspec.tt"), File.join(target, ".rspec"), opts)
|
624
|
+
template(File.join("newgem/spec/spec_helper.rb.tt"), File.join(target, "spec/spec_helper.rb"), opts)
|
625
|
+
template(File.join("newgem/spec/newgem_spec.rb.tt"), File.join(target, "spec/#{name}_spec.rb"), opts)
|
626
|
+
when 'minitest'
|
627
|
+
template(File.join("newgem/test/minitest_helper.rb.tt"), File.join(target, "test/minitest_helper.rb"), opts)
|
628
|
+
template(File.join("newgem/test/test_newgem.rb.tt"), File.join(target, "test/test_#{name}.rb"), opts)
|
629
|
+
end
|
611
630
|
Bundler.ui.info "Initializating git repo in #{target}"
|
612
631
|
Dir.chdir(target) { `git init`; `git add .` }
|
613
632
|
end
|
@@ -663,6 +682,28 @@ module Bundler
|
|
663
682
|
Bundler.ui.info output.join("\n\n")
|
664
683
|
end
|
665
684
|
|
685
|
+
desc "add GEM VERSION ...", "Add the named gem(s), with version requirements, to the resolved Gemfile"
|
686
|
+
def inject(name, version, *gems)
|
687
|
+
# The required arguments allow Thor to give useful feedback when the arguments
|
688
|
+
# are incorrect. This adds those first two arguments onto the list as a whole.
|
689
|
+
gems.unshift(version).unshift(name)
|
690
|
+
|
691
|
+
# Build an array of Dependency objects out of the arguments
|
692
|
+
deps = []
|
693
|
+
gems.each_slice(2) do |name, version|
|
694
|
+
deps << Bundler::Dependency.new(name, version)
|
695
|
+
end
|
696
|
+
|
697
|
+
added = Injector.inject(deps)
|
698
|
+
|
699
|
+
if added.any?
|
700
|
+
Bundler.ui.confirm "Added to Gemfile:"
|
701
|
+
Bundler.ui.confirm added.map{ |g| " #{g}" }.join("\n")
|
702
|
+
else
|
703
|
+
Bundler.ui.confirm "All injected gems were already present in the Gemfile"
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
666
707
|
private
|
667
708
|
|
668
709
|
def setup_cache_all
|
@@ -681,23 +722,28 @@ module Bundler
|
|
681
722
|
|
682
723
|
def locate_gem(name)
|
683
724
|
spec = Bundler.load.specs.find{|s| s.name == name }
|
684
|
-
raise GemNotFound,
|
725
|
+
raise GemNotFound, not_found_message(name, Bundler.load.specs) unless spec
|
685
726
|
if spec.name == 'bundler'
|
686
727
|
return File.expand_path('../../../', __FILE__)
|
687
728
|
end
|
688
729
|
spec.full_gem_path
|
689
730
|
end
|
690
731
|
|
691
|
-
def
|
692
|
-
|
693
|
-
|
694
|
-
|
732
|
+
def gem_dependency_with_name(name)
|
733
|
+
dep = Bundler.load.dependencies.find{|d| d.name == name }
|
734
|
+
raise GemNotFound, not_found_message(name, Bundler.load.dependencies) unless dep
|
735
|
+
dep
|
736
|
+
end
|
695
737
|
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
738
|
+
def not_found_message(missing_gem_name, alternatives)
|
739
|
+
message = "Could not find gem '#{missing_gem_name}'."
|
740
|
+
|
741
|
+
# This is called as the result of a GemNotFound, let's see if
|
742
|
+
# there's any similarly named ones we can propose instead
|
743
|
+
alternate_names = alternatives.map{|a| a.name}
|
744
|
+
suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name)
|
745
|
+
message += "\nDid you mean #{suggestions}?" if suggestions
|
746
|
+
message
|
701
747
|
end
|
702
748
|
|
703
749
|
end
|
data/lib/bundler/definition.rb
CHANGED
@@ -5,7 +5,8 @@ module Bundler
|
|
5
5
|
class Definition
|
6
6
|
include GemHelpers
|
7
7
|
|
8
|
-
attr_reader :dependencies, :platforms, :sources, :ruby_version
|
8
|
+
attr_reader :dependencies, :platforms, :sources, :ruby_version,
|
9
|
+
:locked_deps
|
9
10
|
|
10
11
|
def self.build(gemfile, lockfile, unlock)
|
11
12
|
unlock ||= {}
|
@@ -225,7 +226,7 @@ module Bundler
|
|
225
226
|
return if @lockfile_contents == contents
|
226
227
|
|
227
228
|
if Bundler.settings[:frozen]
|
228
|
-
|
229
|
+
Bundler.ui.error "Cannot write a changed lockfile while frozen."
|
229
230
|
return
|
230
231
|
end
|
231
232
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Bundler
|
2
|
+
|
3
|
+
if defined? ::Deprecate
|
4
|
+
Deprecate = ::Deprecate
|
5
|
+
elsif defined? Gem::Deprecate
|
6
|
+
Deprecate = Gem::Deprecate
|
7
|
+
else
|
8
|
+
class Deprecate; end
|
9
|
+
end
|
10
|
+
|
11
|
+
unless Deprecate.respond_to?(:skip_during)
|
12
|
+
def Deprecate.skip_during; yield; end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/lib/bundler/dsl.rb
CHANGED
@@ -6,11 +6,6 @@ module Bundler
|
|
6
6
|
builder = new
|
7
7
|
builder.eval_gemfile(gemfile)
|
8
8
|
builder.to_definition(lockfile, unlock)
|
9
|
-
rescue ScriptError, RegexpError, NameError, ArgumentError => e
|
10
|
-
e.backtrace[0] = "#{e.backtrace[0]}: #{e.message} (#{e.class})"
|
11
|
-
Bundler.ui.info e.backtrace.join("\n ")
|
12
|
-
raise GemfileError, "There was an error in your Gemfile," \
|
13
|
-
" and Bundler cannot continue."
|
14
9
|
end
|
15
10
|
|
16
11
|
VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze
|
@@ -28,11 +23,17 @@ module Bundler
|
|
28
23
|
@ruby_version = nil
|
29
24
|
end
|
30
25
|
|
31
|
-
def eval_gemfile(gemfile)
|
32
|
-
|
26
|
+
def eval_gemfile(gemfile, contents = nil)
|
27
|
+
contents ||= Bundler.read_file(gemfile.to_s)
|
28
|
+
instance_eval(contents, gemfile.to_s, 1)
|
33
29
|
rescue SyntaxError => e
|
34
30
|
bt = e.message.split("\n")[1..-1]
|
35
31
|
raise GemfileError, ["Gemfile syntax error:", *bt].join("\n")
|
32
|
+
rescue ScriptError, RegexpError, NameError, ArgumentError => e
|
33
|
+
e.backtrace[0] = "#{e.backtrace[0]}: #{e.message} (#{e.class})"
|
34
|
+
Bundler.ui.warn e.backtrace.join("\n ")
|
35
|
+
raise GemfileError, "There was an error in your Gemfile," \
|
36
|
+
" and Bundler cannot continue."
|
36
37
|
end
|
37
38
|
|
38
39
|
def gemspec(opts = nil)
|
@@ -79,9 +80,9 @@ module Bundler
|
|
79
80
|
elsif dep.type == :development
|
80
81
|
return
|
81
82
|
else
|
82
|
-
raise DslError, "You cannot specify the same gem twice with different version requirements. " \
|
83
|
+
raise DslError, "You cannot specify the same gem twice with different version requirements. \n" \
|
83
84
|
"You specified: #{current.name} (#{current.requirement}) and " \
|
84
|
-
"#{dep.name} (#{dep.requirement})"
|
85
|
+
"#{dep.name} (#{dep.requirement})\n"
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
@@ -91,9 +92,9 @@ module Bundler
|
|
91
92
|
elsif dep.type == :development
|
92
93
|
return
|
93
94
|
else
|
94
|
-
raise DslError, "You cannot specify the same gem twice coming from different sources
|
95
|
-
"specified that #{dep.name} (#{dep.requirement}) should come from " \
|
96
|
-
"#{current.source || 'an unspecified source'} and #{dep.source}"
|
95
|
+
raise DslError, "You cannot specify the same gem twice coming from different sources.\n" \
|
96
|
+
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
|
97
|
+
"#{current.source || 'an unspecified source'} and #{dep.source}\n"
|
97
98
|
end
|
98
99
|
end
|
99
100
|
end
|
@@ -104,9 +105,6 @@ module Bundler
|
|
104
105
|
def source(source, options = {})
|
105
106
|
case source
|
106
107
|
when :gemcutter, :rubygems, :rubyforge then
|
107
|
-
Bundler.ui.warn "The source :#{source} is deprecated because HTTP " \
|
108
|
-
"requests are insecure.\nPlease change your source to 'https://" \
|
109
|
-
"rubygems.org' if possible, or 'http://rubygems.org' if not."
|
110
108
|
@rubygems_source.add_remote "http://rubygems.org"
|
111
109
|
return
|
112
110
|
when String
|
@@ -233,7 +231,7 @@ module Bundler
|
|
233
231
|
end
|
234
232
|
|
235
233
|
if github = opts.delete("github")
|
236
|
-
github = "#{github}/#{
|
234
|
+
github = "#{github}/#{name}" unless github.include?("/")
|
237
235
|
opts["git"] = "git://github.com/#{github}.git"
|
238
236
|
end
|
239
237
|
|
data/lib/bundler/environment.rb
CHANGED
data/lib/bundler/fetcher.rb
CHANGED
@@ -1,27 +1,13 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'bundler/vendored_persistent'
|
3
|
+
require 'openssl' if defined?(JRUBY_VERSION)
|
3
4
|
|
4
5
|
module Bundler
|
5
6
|
# Handles all the fetching with the rubygems server
|
6
7
|
class Fetcher
|
7
|
-
# How many redirects to allew in one request
|
8
8
|
REDIRECT_LIMIT = 5
|
9
9
|
# how long to wait for each gemcutter API call
|
10
|
-
API_TIMEOUT
|
11
|
-
|
12
|
-
# This error is raised if the API returns a 413 (only printed in verbose)
|
13
|
-
class FallbackError < HTTPError; end
|
14
|
-
# This is the error raised if OpenSSL fails the cert verification
|
15
|
-
class CertificateFailureError < HTTPError
|
16
|
-
def initialize(remote_uri)
|
17
|
-
super "Could not verify the SSL certificate for #{remote_uri}.\nThere" \
|
18
|
-
" is a chance you are experiencing a man-in-the-middle attack, but" \
|
19
|
-
" most likely your system doesn't have the CA certificates needed" \
|
20
|
-
" for verification. For information about OpenSSL certificates, see" \
|
21
|
-
" bit.ly/ssl-certs. To connect without using SSL, edit your Gemfile" \
|
22
|
-
" sources and change 'https' to 'http'."
|
23
|
-
end
|
24
|
-
end
|
10
|
+
API_TIMEOUT = 10
|
25
11
|
|
26
12
|
attr_reader :has_api
|
27
13
|
|
@@ -60,21 +46,8 @@ module Bundler
|
|
60
46
|
def initialize(remote_uri)
|
61
47
|
@remote_uri = remote_uri
|
62
48
|
@has_api = true # will be set to false if the rubygems index is ever fetched
|
63
|
-
|
64
|
-
|
65
|
-
@connection ||= Net::HTTP::Persistent.new 'bundler', :ENV
|
66
|
-
else
|
67
|
-
if @remote_uri.scheme == "https"
|
68
|
-
raise Bundler::HTTPError, "Could not load OpenSSL.\n" \
|
69
|
-
"You must recompile Ruby with OpenSSL support or change the sources in your " \
|
70
|
-
"Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL " \
|
71
|
-
"using RVM are available at rvm.io/packages/openssl."
|
72
|
-
end
|
73
|
-
@connection ||= Net::HTTP.new(@remote_uri.host, @remote_uri.port)
|
74
|
-
end
|
75
|
-
@connection.read_timeout = API_TIMEOUT
|
76
|
-
|
77
|
-
Socket.do_not_reverse_lookup = true
|
49
|
+
@@connection ||= Net::HTTP::Persistent.new nil, :ENV
|
50
|
+
@@connection.read_timeout = API_TIMEOUT
|
78
51
|
end
|
79
52
|
|
80
53
|
# fetch a gem specification
|
@@ -91,9 +64,10 @@ module Bundler
|
|
91
64
|
# return the specs in the bundler format as an index
|
92
65
|
def specs(gem_names, source)
|
93
66
|
index = Index.new
|
94
|
-
use_full_source_index = !gem_names || @remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
|
95
67
|
|
96
|
-
|
68
|
+
specs = nil
|
69
|
+
|
70
|
+
if !gem_names || @remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
|
97
71
|
Bundler.ui.info "Fetching source index from #{strip_user_pass_from_uri(@remote_uri)}"
|
98
72
|
specs = fetch_all_remote_specs
|
99
73
|
else
|
@@ -108,11 +82,11 @@ module Bundler
|
|
108
82
|
# new line now that the dots are over
|
109
83
|
Bundler.ui.info "" unless Bundler.ui.debug?
|
110
84
|
|
111
|
-
if
|
112
|
-
Bundler.ui.
|
113
|
-
else
|
114
|
-
Bundler.ui.debug "Error during API request. #{e.class}: #{e.message}"
|
85
|
+
if @remote_uri.to_s.include?("rubygems.org")
|
86
|
+
Bundler.ui.info "Error #{e.class} during request to dependency API"
|
115
87
|
end
|
88
|
+
Bundler.ui.debug e.message
|
89
|
+
Bundler.ui.debug e.backtrace
|
116
90
|
|
117
91
|
Bundler.ui.info "Fetching full source index from #{strip_user_pass_from_uri(@remote_uri)}"
|
118
92
|
specs = fetch_all_remote_specs
|
@@ -136,9 +110,6 @@ module Bundler
|
|
136
110
|
end
|
137
111
|
|
138
112
|
index
|
139
|
-
rescue OpenSSL::SSL::SSLError
|
140
|
-
Bundler.ui.info "" if !use_full_source_index # newline after dots
|
141
|
-
raise CertificateFailureError.new(strip_user_pass_from_uri(@remote_uri))
|
142
113
|
end
|
143
114
|
|
144
115
|
# fetch index
|
@@ -162,25 +133,15 @@ module Bundler
|
|
162
133
|
|
163
134
|
private
|
164
135
|
|
165
|
-
HTTP_ERRORS = [
|
166
|
-
Timeout::Error, EOFError, SocketError,
|
167
|
-
Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
|
168
|
-
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
|
169
|
-
]
|
170
|
-
HTTP_ERRORS << Net::HTTP::Persistent::Error if defined?(Net::HTTP::Persistent)
|
171
|
-
|
172
136
|
def fetch(uri, counter = 0)
|
173
137
|
raise HTTPError, "Too many redirects" if counter >= REDIRECT_LIMIT
|
174
138
|
|
175
139
|
begin
|
176
140
|
Bundler.ui.debug "Fetching from: #{uri}"
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
response = @connection.request(req)
|
182
|
-
end
|
183
|
-
rescue *HTTP_ERRORS
|
141
|
+
response = @@connection.request(uri)
|
142
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT,
|
143
|
+
EOFError, SocketError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
144
|
+
Errno::EAGAIN, Net::HTTP::Persistent::Error, Net::ProtocolError => e
|
184
145
|
raise HTTPError, "Network error while fetching #{uri}"
|
185
146
|
end
|
186
147
|
|
@@ -188,18 +149,15 @@ module Bundler
|
|
188
149
|
when Net::HTTPRedirection
|
189
150
|
Bundler.ui.debug("HTTP Redirection")
|
190
151
|
new_uri = URI.parse(response["location"])
|
191
|
-
|
192
|
-
|
193
|
-
new_uri.password = uri.password
|
194
|
-
end
|
152
|
+
new_uri.user = uri.user
|
153
|
+
new_uri.password = uri.password
|
195
154
|
fetch(new_uri, counter + 1)
|
196
155
|
when Net::HTTPSuccess
|
197
156
|
Bundler.ui.debug("HTTP Success")
|
198
157
|
response.body
|
199
|
-
when Net::HTTPRequestEntityTooLarge
|
200
|
-
raise FallbackError, response.body
|
201
158
|
else
|
202
|
-
|
159
|
+
Bundler.ui.debug("HTTP Error")
|
160
|
+
raise HTTPError, "Don't know how to process #{response.class}"
|
203
161
|
end
|
204
162
|
end
|
205
163
|
|
@@ -244,25 +202,12 @@ module Bundler
|
|
244
202
|
def fetch_all_remote_specs
|
245
203
|
@has_api = false
|
246
204
|
Gem.sources = ["#{@remote_uri}"]
|
247
|
-
|
205
|
+
|
248
206
|
begin
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
begin
|
253
|
-
Gem::SpecFetcher.new.list(false, true).each {|k, v| spec_list[k] += v }
|
254
|
-
rescue Gem::RemoteFetcher::FetchError
|
255
|
-
Bundler.ui.debug "Could not fetch prerelease specs from #{strip_user_pass_from_uri(@remote_uri)}"
|
256
|
-
end
|
257
|
-
rescue Gem::RemoteFetcher::FetchError => e
|
258
|
-
if e.message.match("certificate verify failed")
|
259
|
-
raise CertificateFailureError.new(strip_user_pass_from_uri(@remote_uri))
|
260
|
-
else
|
261
|
-
raise HTTPError, "Could not fetch specs from #{strip_user_pass_from_uri(@remote_uri)}"
|
262
|
-
end
|
207
|
+
Bundler.rubygems.fetch_all_remote_specs
|
208
|
+
rescue Gem::RemoteFetcher::FetchError
|
209
|
+
raise HTTPError, "Could not reach #{strip_user_pass_from_uri(@remote_uri)}"
|
263
210
|
end
|
264
|
-
|
265
|
-
return spec_list
|
266
211
|
end
|
267
212
|
|
268
213
|
def strip_user_pass_from_uri(uri)
|