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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +105 -0
  3. data/.rubocop_todo.yml +120 -0
  4. data/.travis.yml +8 -23
  5. data/CHANGELOG.md +95 -0
  6. data/CODE_OF_CONDUCT.md +6 -4
  7. data/DEVELOPMENT.md +4 -5
  8. data/README.md +2 -2
  9. data/Rakefile +71 -88
  10. data/bin/rake +14 -0
  11. data/bin/rspec +10 -0
  12. data/bin/rubocop +11 -0
  13. data/bundler.gemspec +17 -15
  14. data/exe/bundle +20 -0
  15. data/{bin → exe}/bundle_ruby +6 -4
  16. data/exe/bundler +20 -0
  17. data/lib/bundler/capistrano.rb +2 -2
  18. data/lib/bundler/cli/binstubs.rb +1 -2
  19. data/lib/bundler/cli/cache.rb +0 -1
  20. data/lib/bundler/cli/check.rb +7 -5
  21. data/lib/bundler/cli/clean.rb +0 -1
  22. data/lib/bundler/cli/common.rb +6 -7
  23. data/lib/bundler/cli/config.rb +69 -56
  24. data/lib/bundler/cli/console.rb +8 -8
  25. data/lib/bundler/cli/exec.rb +5 -4
  26. data/lib/bundler/cli/gem.rb +52 -40
  27. data/lib/bundler/cli/init.rb +5 -6
  28. data/lib/bundler/cli/inject.rb +1 -2
  29. data/lib/bundler/cli/install.rb +18 -21
  30. data/lib/bundler/cli/lock.rb +8 -3
  31. data/lib/bundler/cli/open.rb +4 -5
  32. data/lib/bundler/cli/outdated.rb +7 -8
  33. data/lib/bundler/cli/package.rb +1 -1
  34. data/lib/bundler/cli/platform.rb +2 -3
  35. data/lib/bundler/cli/show.rb +9 -9
  36. data/lib/bundler/cli/update.rb +2 -3
  37. data/lib/bundler/cli/viz.rb +1 -2
  38. data/lib/bundler/cli.rb +85 -74
  39. data/lib/bundler/constants.rb +1 -1
  40. data/lib/bundler/current_ruby.rb +38 -3
  41. data/lib/bundler/definition.rb +83 -88
  42. data/lib/bundler/dep_proxy.rb +11 -9
  43. data/lib/bundler/dependency.rb +17 -11
  44. data/lib/bundler/deployment.rb +2 -2
  45. data/lib/bundler/deprecate.rb +3 -3
  46. data/lib/bundler/dsl.rb +62 -43
  47. data/lib/bundler/env.rb +19 -12
  48. data/lib/bundler/environment.rb +1 -2
  49. data/lib/bundler/errors.rb +82 -0
  50. data/lib/bundler/fetcher/base.rb +20 -7
  51. data/lib/bundler/fetcher/dependency.rb +5 -5
  52. data/lib/bundler/fetcher/downloader.rb +1 -2
  53. data/lib/bundler/fetcher/index.rb +4 -7
  54. data/lib/bundler/fetcher.rb +49 -40
  55. data/lib/bundler/friendly_errors.rb +15 -8
  56. data/lib/bundler/gem_helper.rb +44 -35
  57. data/lib/bundler/gem_helpers.rb +7 -8
  58. data/lib/bundler/gem_remote_fetcher.rb +41 -0
  59. data/lib/bundler/gem_tasks.rb +4 -1
  60. data/lib/bundler/graph.rb +25 -24
  61. data/lib/bundler/index.rb +21 -18
  62. data/lib/bundler/injector.rb +2 -4
  63. data/lib/bundler/inline.rb +3 -3
  64. data/lib/bundler/installer/gem_installer.rb +76 -0
  65. data/lib/bundler/installer/parallel_installer.rb +22 -13
  66. data/lib/bundler/installer/standalone.rb +48 -0
  67. data/lib/bundler/installer.rb +57 -144
  68. data/lib/bundler/lazy_specification.rb +4 -5
  69. data/lib/bundler/lockfile_parser.rb +21 -19
  70. data/lib/bundler/man/bundle +2 -2
  71. data/lib/bundler/man/bundle-config +2 -2
  72. data/lib/bundler/man/bundle-config.txt +6 -4
  73. data/lib/bundler/man/bundle-exec +1 -1
  74. data/lib/bundler/man/bundle-exec.txt +1 -1
  75. data/lib/bundler/man/bundle-gem +80 -0
  76. data/lib/bundler/man/bundle-gem.txt +90 -0
  77. data/lib/bundler/man/bundle-install +37 -6
  78. data/lib/bundler/man/bundle-install.txt +68 -44
  79. data/lib/bundler/man/bundle-lock +55 -0
  80. data/lib/bundler/man/bundle-lock.txt +60 -0
  81. data/lib/bundler/man/bundle-package +1 -1
  82. data/lib/bundler/man/bundle-package.txt +1 -1
  83. data/lib/bundler/man/bundle-platform +1 -1
  84. data/lib/bundler/man/bundle-platform.txt +1 -1
  85. data/lib/bundler/man/bundle-update +1 -1
  86. data/lib/bundler/man/bundle-update.txt +1 -1
  87. data/lib/bundler/man/bundle.txt +2 -2
  88. data/lib/bundler/man/gemfile.5 +17 -1
  89. data/lib/bundler/man/gemfile.5.txt +12 -1
  90. data/lib/bundler/match_platform.rb +4 -4
  91. data/lib/bundler/psyched_yaml.rb +5 -5
  92. data/lib/bundler/remote_specification.rb +1 -1
  93. data/lib/bundler/resolver.rb +93 -88
  94. data/lib/bundler/retry.rb +9 -10
  95. data/lib/bundler/ruby_dsl.rb +1 -1
  96. data/lib/bundler/ruby_version.rb +7 -10
  97. data/lib/bundler/rubygems_ext.rb +32 -27
  98. data/lib/bundler/{gem_installer.rb → rubygems_gem_installer.rb} +2 -2
  99. data/lib/bundler/rubygems_integration.rb +85 -70
  100. data/lib/bundler/runtime.rb +65 -61
  101. data/lib/bundler/settings.rb +27 -26
  102. data/lib/bundler/setup.rb +3 -3
  103. data/lib/bundler/shared_helpers.rb +45 -20
  104. data/lib/bundler/similarity_detector.rb +19 -21
  105. data/lib/bundler/source/git/git_proxy.rb +52 -26
  106. data/lib/bundler/source/git.rb +29 -31
  107. data/lib/bundler/source/path/installer.rb +4 -4
  108. data/lib/bundler/source/path.rb +25 -28
  109. data/lib/bundler/source/rubygems/remote.rb +3 -3
  110. data/lib/bundler/source/rubygems.rb +62 -48
  111. data/lib/bundler/source.rb +4 -5
  112. data/lib/bundler/source_list.rb +4 -4
  113. data/lib/bundler/spec_set.rb +17 -15
  114. data/lib/bundler/ssl_certs/certificate_manager.rb +5 -6
  115. data/lib/bundler/stub_specification.rb +2 -2
  116. data/lib/bundler/templates/Executable +5 -5
  117. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +42 -6
  118. data/lib/bundler/templates/newgem/README.md.tt +1 -1
  119. data/lib/bundler/templates/newgem/Rakefile.tt +4 -2
  120. data/lib/bundler/templates/newgem/bin/setup.tt +2 -1
  121. data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -2
  122. data/lib/bundler/ui/rg_proxy.rb +2 -2
  123. data/lib/bundler/ui/shell.rb +10 -6
  124. data/lib/bundler/ui.rb +3 -3
  125. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +82 -71
  126. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  127. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +9 -0
  128. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +40 -21
  129. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +8 -0
  130. data/lib/bundler/vendored_molinillo.rb +1 -1
  131. data/lib/bundler/vendored_persistent.rb +3 -3
  132. data/lib/bundler/vendored_thor.rb +2 -2
  133. data/lib/bundler/version.rb +1 -1
  134. data/lib/bundler/vlad.rb +1 -1
  135. data/lib/bundler/worker.rb +4 -5
  136. data/lib/bundler.rb +99 -120
  137. data/man/bundle-config.ronn +4 -2
  138. data/man/bundle-gem.ronn +77 -0
  139. data/man/bundle-install.ronn +13 -6
  140. data/man/bundle-lock.ronn +47 -0
  141. data/man/bundle.ronn +1 -1
  142. data/man/gemfile.5.ronn +8 -0
  143. data/man/index.txt +1 -0
  144. metadata +36 -8
  145. data/bin/bundle +0 -21
  146. data/bin/bundler +0 -21
data/lib/bundler/index.rb CHANGED
@@ -11,21 +11,24 @@ module Bundler
11
11
  end
12
12
 
13
13
  attr_reader :specs, :all_specs, :sources
14
- protected :specs, :all_specs
14
+ protected :specs, :all_specs
15
+
16
+ RUBY = "ruby".freeze
17
+ NULL = "\0".freeze
15
18
 
16
19
  def initialize
17
20
  @sources = []
18
21
  @cache = {}
19
- @specs = Hash.new { |h,k| h[k] = Hash.new }
20
- @all_specs = Hash.new { |h,k| h[k] = [] }
22
+ @specs = Hash.new {|h, k| h[k] = {} }
23
+ @all_specs = Hash.new {|h, k| h[k] = [] }
21
24
  end
22
25
 
23
26
  def initialize_copy(o)
24
27
  super
25
28
  @sources = @sources.dup
26
29
  @cache = {}
27
- @specs = Hash.new { |h,k| h[k] = Hash.new }
28
- @all_specs = Hash.new { |h,k| h[k] = [] }
30
+ @specs = Hash.new {|h, k| h[k] = {} }
31
+ @all_specs = Hash.new {|h, k| h[k] = [] }
29
32
 
30
33
  o.specs.each do |name, hash|
31
34
  @specs[name] = hash.dup
@@ -36,7 +39,7 @@ module Bundler
36
39
  end
37
40
 
38
41
  def inspect
39
- "#<#{self.class}:0x#{object_id} sources=#{sources.map{|s| s.inspect}} specs.size=#{specs.size}>"
42
+ "#<#{self.class}:0x#{object_id} sources=#{sources.map(&:inspect)} specs.size=#{specs.size}>"
40
43
  end
41
44
 
42
45
  def empty?
@@ -56,7 +59,7 @@ module Bundler
56
59
  # about, returning all of the results.
57
60
  def search(query, base = nil)
58
61
  results = local_search(query, base)
59
- seen = Set.new(results.map { |spec| [spec.name, spec.version, spec.platform] })
62
+ seen = Set.new(results.map {|spec| [spec.name, spec.version, spec.platform] })
60
63
 
61
64
  @sources.each do |source|
62
65
  source.search(query, base).each do |spec|
@@ -68,7 +71,7 @@ module Bundler
68
71
  end
69
72
  end
70
73
 
71
- results.sort_by {|s| [s.version, s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s] }
74
+ results.sort_by {|s| [s.version, s.platform.to_s == RUBY ? NULL : s.platform.to_s] }
72
75
  end
73
76
 
74
77
  def local_search(query, base = nil)
@@ -76,12 +79,13 @@ module Bundler
76
79
  when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query)
77
80
  when String then specs_by_name(query)
78
81
  when Gem::Dependency then search_by_dependency(query, base)
82
+ when DepProxy then search_by_dependency(query.dep, base)
79
83
  else
80
84
  raise "You can't search for a #{query.inspect}."
81
85
  end
82
86
  end
83
87
 
84
- alias [] search
88
+ alias_method :[], :search
85
89
 
86
90
  def <<(spec)
87
91
  @specs[spec.name]["#{spec.version}-#{spec.platform}"] = spec
@@ -98,13 +102,13 @@ module Bundler
98
102
  # returns a list of the dependencies
99
103
  def unmet_dependency_names
100
104
  names = dependency_names
101
- names.delete_if{|n| n == "bundler" }
102
- names.select{|n| search(n).empty? }
105
+ names.delete_if {|n| n == "bundler" }
106
+ names.select {|n| search(n).empty? }
103
107
  end
104
108
 
105
109
  def dependency_names
106
110
  names = []
107
- each{|s| names.push(*s.dependencies.map{|d| d.name }) }
111
+ each {|s| names.push(*s.dependencies.map(&:name)) }
108
112
  names.uniq
109
113
  end
110
114
 
@@ -127,10 +131,10 @@ module Bundler
127
131
  end
128
132
  end
129
133
 
130
- def ==(o)
134
+ def ==(other)
131
135
  all? do |spec|
132
- other_spec = o[spec].first
133
- (spec.dependencies & other_spec.dependencies).empty? && spec.source == other_spec.source
136
+ other_spec = other[spec].first
137
+ other_spec && (spec.dependencies & other_spec.dependencies).empty? && spec.source == other_spec.source
134
138
  end
135
139
  end
136
140
 
@@ -165,7 +169,7 @@ module Bundler
165
169
  only_prerelease = specs.all? {|spec| spec.version.prerelease? }
166
170
 
167
171
  unless wants_prerelease || only_prerelease
168
- found.reject! { |spec| spec.version.prerelease? }
172
+ found.reject! {|spec| spec.version.prerelease? }
169
173
  end
170
174
 
171
175
  found
@@ -177,7 +181,7 @@ module Bundler
177
181
  spec ? [spec] : []
178
182
  end
179
183
 
180
- if RUBY_VERSION < '1.9'
184
+ if RUBY_VERSION < "1.9"
181
185
  def same_version?(a, b)
182
186
  regex = /^(.*?)(?:\.0)*$/
183
187
  a.to_s[regex, 1] == b.to_s[regex, 1]
@@ -192,6 +196,5 @@ module Bundler
192
196
  return false unless dep.name == spec.name
193
197
  dep.requirement.satisfied_by?(spec.version)
194
198
  end
195
-
196
199
  end
197
200
  end
@@ -40,14 +40,14 @@ module Bundler
40
40
  # return an array of the deps that we added
41
41
  return @new_deps
42
42
  ensure
43
- Bundler.settings[:frozen] = '1' if frozen
43
+ Bundler.settings[:frozen] = "1" if frozen
44
44
  end
45
45
 
46
46
  private
47
47
 
48
48
  def new_gem_lines
49
49
  @new_deps.map do |d|
50
- %|gem '#{d.name}', '#{d.requirement}'|
50
+ %(gem '#{d.name}', '#{d.requirement}')
51
51
  end.join("\n")
52
52
  end
53
53
 
@@ -58,7 +58,5 @@ module Bundler
58
58
  f.puts new_gem_lines
59
59
  end
60
60
  end
61
-
62
-
63
61
  end
64
62
  end
@@ -28,12 +28,12 @@
28
28
  # puts Pod::VERSION # => "0.34.4"
29
29
  #
30
30
  def gemfile(install = false, &gemfile)
31
- require 'bundler'
31
+ require "bundler"
32
32
  old_root = Bundler.method(:root)
33
33
  def Bundler.root
34
- Pathname.pwd.expand_path
34
+ Bundler::SharedHelpers.pwd.expand_path
35
35
  end
36
- ENV['BUNDLE_GEMFILE'] ||= 'Gemfile'
36
+ ENV["BUNDLE_GEMFILE"] ||= "Gemfile"
37
37
 
38
38
  builder = Bundler::Dsl.new
39
39
  builder.instance_eval(&gemfile)
@@ -0,0 +1,76 @@
1
+ module Bundler
2
+ class GemInstaller
3
+ attr_reader :spec, :standalone, :worker, :force, :installer
4
+
5
+ def initialize(spec, installer, standalone = false, worker = 0, force = false)
6
+ @spec = spec
7
+ @installer = installer
8
+ @standalone = standalone
9
+ @worker = worker
10
+ @force = force
11
+ end
12
+
13
+ def install_from_spec
14
+ post_install_message = spec_settings ? install_with_settings : install
15
+ Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
16
+ generate_executable_stubs
17
+ post_install_message
18
+
19
+ rescue Errno::ENOSPC
20
+ raise Bundler::InstallError, out_of_space_message
21
+ rescue => e
22
+ handle_exception(e)
23
+ end
24
+
25
+ private
26
+
27
+ def failure_message
28
+ return install_error_message if spec.source.options["git"]
29
+ "#{install_error_message}\n#{gem_install_message}"
30
+ end
31
+
32
+ def install_error_message
33
+ "An error occurred while installing #{spec.name} (#{spec.version}), and Bundler cannot continue."
34
+ end
35
+
36
+ def gem_install_message
37
+ "Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
38
+ end
39
+
40
+ def handle_exception(e)
41
+ # if install hook failed or gem signature is bad, just die
42
+ raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError)
43
+ # other failure, likely a native extension build failure
44
+ Bundler.ui.info ""
45
+ Bundler.ui.warn "#{e.class}: #{e.message}"
46
+ Bundler.ui.debug e.backtrace.join("\n")
47
+ raise Bundler::InstallError, failure_message
48
+ end
49
+
50
+ def spec_settings
51
+ # Fetch the build settings, if there are any
52
+ Bundler.settings["build.#{spec.name}"]
53
+ end
54
+
55
+ def install
56
+ spec.source.install(spec, :force => force, :ensure_builtin_gems_cached => standalone)
57
+ end
58
+
59
+ def install_with_settings
60
+ # Build arguments are global, so this is mutexed
61
+ Bundler.rubygems.with_build_args([spec_settings]) { install }
62
+ end
63
+
64
+ def out_of_space_message
65
+ "Your disk is out of space. Free some space to be able to install your bundle."
66
+ end
67
+
68
+ def generate_executable_stubs
69
+ if Bundler.settings[:bin] && standalone
70
+ installer.generate_standalone_bundler_executable_stubs(spec)
71
+ elsif Bundler.settings[:bin]
72
+ installer.generate_bundler_executable_stubs(spec, :force => true)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,13 +1,12 @@
1
- require 'bundler/worker'
2
-
1
+ require "bundler/worker"
2
+ require "bundler/installer/gem_installer"
3
3
 
4
4
  class ParallelInstaller
5
-
6
5
  class SpecInstallation
7
-
8
6
  attr_accessor :spec, :name, :post_install_message, :state
9
7
  def initialize(spec)
10
- @spec, @name = spec, spec.name
8
+ @spec = spec
9
+ @name = spec.name
11
10
  @state = :none
12
11
  @post_install_message = ""
13
12
  end
@@ -37,13 +36,21 @@ class ParallelInstaller
37
36
  # sure needed dependencies have been installed.
38
37
  def dependencies_installed?(all_specs)
39
38
  installed_specs = all_specs.select(&:installed?).map(&:name)
40
- dependencies.all? {|d| installed_specs.include? d.name }
39
+ dependencies(all_specs.map(&:name)).all? {|d| installed_specs.include? d.name }
41
40
  end
42
41
 
43
- # Represents only the non-development dependencies and the ones that
44
- # are itself.
45
- def dependencies
46
- @dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
42
+ # Represents only the non-development dependencies, the ones that are
43
+ # itself and are in the total list.
44
+ def dependencies(all_spec_names)
45
+ @dependencies ||= begin
46
+ deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
47
+ missing = deps.reject {|dep| all_spec_names.include? dep.name }
48
+ if missing.size > 0
49
+ raise Bundler::LockfileError, "Your Gemfile.lock is corrupt. The following #{missing.size > 1 ? "gems are" : "gem is"} missing " \
50
+ "from the DEPENDENCIES section: '#{missing.map(&:name).join('\' \'')}'"
51
+ end
52
+ deps
53
+ end
47
54
  end
48
55
 
49
56
  # Represents all dependencies
@@ -58,7 +65,7 @@ class ParallelInstaller
58
65
 
59
66
  # Returns max number of threads machine can handle with a min of 1
60
67
  def self.max_threads
61
- [Bundler.settings[:jobs].to_i-1, 1].max
68
+ [Bundler.settings[:jobs].to_i - 1, 1].max
62
69
  end
63
70
 
64
71
  def initialize(installer, all_specs, size, standalone, force)
@@ -66,7 +73,7 @@ class ParallelInstaller
66
73
  @size = size
67
74
  @standalone = standalone
68
75
  @force = force
69
- @specs = all_specs.map { |s| SpecInstallation.new(s) }
76
+ @specs = all_specs.map {|s| SpecInstallation.new(s) }
70
77
  end
71
78
 
72
79
  def call
@@ -78,7 +85,9 @@ class ParallelInstaller
78
85
 
79
86
  def worker_pool
80
87
  @worker_pool ||= Bundler::Worker.new @size, lambda { |spec_install, worker_num|
81
- message = @installer.install_gem_from_spec spec_install.spec, @standalone, worker_num, @force
88
+ message = Bundler::GemInstaller.new(
89
+ spec_install.spec, @installer, @standalone, worker_num, @force
90
+ ).install_from_spec
82
91
  spec_install.post_install_message = message unless message.nil?
83
92
  spec_install
84
93
  }
@@ -0,0 +1,48 @@
1
+ module Bundler
2
+ class Standalone
3
+ def initialize(groups, definition)
4
+ @specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
5
+ end
6
+
7
+ def generate
8
+ SharedHelpers.filesystem_access(bundler_path) do |p|
9
+ FileUtils.mkdir_p(p)
10
+ end
11
+ File.open File.join(bundler_path, "setup.rb"), "w" do |file|
12
+ file.puts "require 'rbconfig'"
13
+ file.puts "# ruby 1.8.7 doesn't define RUBY_ENGINE"
14
+ file.puts "ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'"
15
+ file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
16
+ file.puts "path = File.expand_path('..', __FILE__)"
17
+ paths.each do |path|
18
+ file.puts %($:.unshift "\#{path}/#{path}")
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def paths
26
+ @specs.map do |spec|
27
+ next if spec.name == "bundler"
28
+ Array(spec.require_paths).map do |path|
29
+ gem_path(path, spec).sub(version_dir, '#{ruby_engine}/#{ruby_version}')
30
+ # This is a static string intentionally. It's interpolated at a later time.
31
+ end
32
+ end.flatten
33
+ end
34
+
35
+ def version_dir
36
+ "#{Bundler.ruby_version.engine}/#{RbConfig::CONFIG["ruby_version"]}"
37
+ end
38
+
39
+ def bundler_path
40
+ File.join(Bundler.settings[:path], "bundler")
41
+ end
42
+
43
+ def gem_path(path, spec)
44
+ full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
45
+ Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,9 @@
1
- require 'erb'
2
- require 'rubygems/dependency_installer'
3
- require 'bundler/worker'
1
+ require "erb"
2
+ require "rubygems/dependency_installer"
3
+ require "bundler/worker"
4
+ require "bundler/installer/parallel_installer"
5
+ require "bundler/installer/standalone"
6
+ require "bundler/installer/gem_installer"
4
7
 
5
8
  module Bundler
6
9
  class Installer < Environment
@@ -63,83 +66,11 @@ module Bundler
63
66
  return
64
67
  end
65
68
 
66
- if Bundler.default_lockfile.exist? && !options["update"]
67
- local = Bundler.ui.silence do
68
- begin
69
- tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
70
- true unless tmpdef.new_platform? || tmpdef.missing_specs.any?
71
- rescue BundlerError
72
- end
73
- end
74
- end
75
-
76
- # Since we are installing, we can resolve the definition
77
- # using remote specs
78
- unless local
79
- options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
80
- end
81
-
82
- force = options["force"]
83
-
84
- # the order that the resolver provides is significant, since
85
- # dependencies might actually affect the installation of a gem.
86
- # that said, it's a rare situation (other than rake), and parallel
87
- # installation is just SO MUCH FASTER. so we let people opt in.
88
- jobs = [Bundler.settings[:jobs].to_i-1, 1].max
89
- if jobs > 1 && can_install_in_parallel?
90
- require 'bundler/installer/parallel_installer'
91
- install_in_parallel jobs, options[:standalone], force
92
- else
93
- install_sequentially options[:standalone], force
94
- end
69
+ resolve_if_need(options)
70
+ install(options)
95
71
 
96
72
  lock unless Bundler.settings[:frozen]
97
- generate_standalone(options[:standalone]) if options[:standalone]
98
- end
99
-
100
- def install_gem_from_spec(spec, standalone = false, worker = 0, force = false)
101
- # Fetch the build settings, if there are any
102
- settings = Bundler.settings["build.#{spec.name}"]
103
- install_options = { :force => force, :ensure_builtin_gems_cached => standalone }
104
-
105
- post_install_message = nil
106
- if settings
107
- # Build arguments are global, so this is mutexed
108
- Bundler.rubygems.with_build_args [settings] do
109
- post_install_message = spec.source.install(spec, install_options)
110
- end
111
- else
112
- post_install_message = spec.source.install(spec, install_options)
113
- end
114
-
115
- Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
116
-
117
- if Bundler.settings[:bin] && standalone
118
- generate_standalone_bundler_executable_stubs(spec)
119
- elsif Bundler.settings[:bin]
120
- generate_bundler_executable_stubs(spec, :force => true)
121
- end
122
-
123
- post_install_message
124
- rescue Errno::ENOSPC
125
- raise Bundler::InstallError, "Your disk is out of space. Free some " \
126
- "space to be able to install your bundle."
127
- rescue Exception => e
128
- # if install hook failed or gem signature is bad, just die
129
- raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError)
130
-
131
- # other failure, likely a native extension build failure
132
- Bundler.ui.info ""
133
- Bundler.ui.warn "#{e.class}: #{e.message}"
134
- msg = "An error occurred while installing #{spec.name} (#{spec.version}),"
135
- msg << " and Bundler cannot continue."
136
-
137
- unless spec.source.options["git"]
138
- msg << "\nMake sure that `gem install"
139
- msg << " #{spec.name} -v '#{spec.version}'` succeeds before bundling."
140
- end
141
- Bundler.ui.debug e.backtrace.join("\n")
142
- raise Bundler::InstallError, msg
73
+ Standalone.new(options[:standalone], @definition).generate if options[:standalone]
143
74
  end
144
75
 
145
76
  def generate_bundler_executable_stubs(spec, options = {})
@@ -150,9 +81,9 @@ module Bundler
150
81
  options[dep.name] = bins unless bins.empty?
151
82
  end
152
83
  if options.any?
153
- Bundler.ui.warn "#{spec.name} has no executables, but you may want " +
84
+ Bundler.ui.warn "#{spec.name} has no executables, but you may want " \
154
85
  "one from a gem it depends on."
155
- options.each{|name,bins| Bundler.ui.warn " #{name} has: #{bins.join(', ')}" }
86
+ options.each {|name, bins| Bundler.ui.warn " #{name} has: #{bins.join(", ")}" }
156
87
  else
157
88
  Bundler.ui.warn "There are no executables for the gem #{spec.name}."
158
89
  end
@@ -161,7 +92,7 @@ module Bundler
161
92
 
162
93
  # double-assignment to avoid warnings about variables that will be used by ERB
163
94
  bin_path = bin_path = Bundler.bin_path
164
- template = template = File.read(File.expand_path('../templates/Executable', __FILE__))
95
+ template = template = File.read(File.expand_path("../templates/Executable", __FILE__))
165
96
  relative_gemfile_path = relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
166
97
  ruby_command = ruby_command = Thor::Util.ruby_command
167
98
 
@@ -175,8 +106,8 @@ module Bundler
175
106
  next
176
107
  end
177
108
 
178
- File.open(binstub_path, 'w', 0777 & ~File.umask) do |f|
179
- f.puts ERB.new(template, nil, '-').result(binding)
109
+ File.open(binstub_path, "w", 0777 & ~File.umask) do |f|
110
+ f.puts ERB.new(template, nil, "-").result(binding)
180
111
  end
181
112
  end
182
113
 
@@ -185,88 +116,53 @@ module Bundler
185
116
  when 1
186
117
  Bundler.ui.warn "Skipped #{exists[0]} since it already exists."
187
118
  when 2
188
- Bundler.ui.warn "Skipped #{exists.join(' and ')} since they already exist."
119
+ Bundler.ui.warn "Skipped #{exists.join(" and ")} since they already exist."
189
120
  else
190
- items = exists[0...-1].empty? ? nil : exists[0...-1].join(', ')
191
- skipped = [items, exists[-1]].compact.join(' and ')
121
+ items = exists[0...-1].empty? ? nil : exists[0...-1].join(", ")
122
+ skipped = [items, exists[-1]].compact.join(" and ")
192
123
  Bundler.ui.warn "Skipped #{skipped} since they already exist."
193
124
  end
194
125
  Bundler.ui.warn "If you want to overwrite skipped stubs, use --force."
195
126
  end
196
127
  end
197
128
 
198
- private
199
-
200
- def can_install_in_parallel?
201
- if Bundler.rubygems.provides?(">= 2.1.0")
202
- true
203
- else
204
- Bundler.ui.warn "Rubygems #{Gem::VERSION} is not threadsafe, so your "\
205
- "gems must be installed one at a time. Upgrade to Rubygems 2.1.0 " \
206
- "or higher to enable parallel gem installation."
207
- false
208
- end
209
- end
210
-
211
129
  def generate_standalone_bundler_executable_stubs(spec)
212
130
  # double-assignment to avoid warnings about variables that will be used by ERB
213
131
  bin_path = Bundler.bin_path
214
- template = File.read(File.expand_path('../templates/Executable.standalone', __FILE__))
132
+ template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__))
215
133
  ruby_command = ruby_command = Thor::Util.ruby_command
216
134
 
217
135
  spec.executables.each do |executable|
218
136
  next if executable == "bundle"
219
137
  standalone_path = standalone_path = Pathname(Bundler.settings[:path]).expand_path.relative_path_from(bin_path)
220
138
  executable_path = executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
221
- File.open "#{bin_path}/#{executable}", 'w', 0755 do |f|
222
- f.puts ERB.new(template, nil, '-').result(binding)
139
+ File.open "#{bin_path}/#{executable}", "w", 0755 do |f|
140
+ f.puts ERB.new(template, nil, "-").result(binding)
223
141
  end
224
142
  end
225
143
  end
226
144
 
227
- def generate_standalone(groups)
228
- standalone_path = Bundler.settings[:path]
229
- bundler_path = File.join(standalone_path, "bundler")
230
- FileUtils.mkdir_p(bundler_path)
231
-
232
- paths = []
233
-
234
- if groups.empty?
235
- specs = @definition.requested_specs
236
- else
237
- specs = @definition.specs_for groups.map { |g| g.to_sym }
238
- end
239
-
240
- specs.each do |spec|
241
- next if spec.name == "bundler"
242
- next if spec.require_paths.nil? # builtin gems
243
-
244
- spec.require_paths.each do |path|
245
- full_path = File.join(spec.full_gem_path, path)
246
- gem_path = Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path))
247
- paths << gem_path.to_s.sub("#{Bundler.ruby_version.engine}/#{RbConfig::CONFIG['ruby_version']}", '#{ruby_engine}/#{ruby_version}')
248
- end
249
- end
250
-
145
+ private
251
146
 
252
- File.open File.join(bundler_path, "setup.rb"), "w" do |file|
253
- file.puts "require 'rbconfig'"
254
- file.puts "# ruby 1.8.7 doesn't define RUBY_ENGINE"
255
- file.puts "ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'"
256
- file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
257
- file.puts "path = File.expand_path('..', __FILE__)"
258
- paths.each do |path|
259
- file.puts %{$:.unshift "\#{path}/#{path}"}
260
- end
261
- end
147
+ # the order that the resolver provides is significant, since
148
+ # dependencies might actually affect the installation of a gem.
149
+ # that said, it's a rare situation (other than rake), and parallel
150
+ # installation is just SO MUCH FASTER. so we let people opt in.
151
+ def install(options)
152
+ force = options["force"]
153
+ jobs = 1
154
+ jobs = [Bundler.settings[:jobs].to_i - 1, 1].max if can_install_in_parallel?
155
+ install_in_parallel jobs, options[:standalone], force
262
156
  end
263
157
 
264
- def install_sequentially(standalone, force = false)
265
- specs.each do |spec|
266
- message = install_gem_from_spec spec, standalone, 0, force
267
- if message
268
- Installer.post_install_messages[spec.name] = message
269
- end
158
+ def can_install_in_parallel?
159
+ if Bundler.rubygems.provides?(">= 2.1.0")
160
+ true
161
+ else
162
+ Bundler.ui.warn "Rubygems #{Gem::VERSION} is not threadsafe, so your "\
163
+ "gems will be installed one at a time. Upgrade to Rubygems 2.1.0 " \
164
+ "or higher to enable parallel gem installation."
165
+ false
270
166
  end
271
167
  end
272
168
 
@@ -275,11 +171,28 @@ module Bundler
275
171
  end
276
172
 
277
173
  def create_bundle_path
278
- Bundler.mkdir_p(Bundler.bundle_path.to_s) unless Bundler.bundle_path.exist?
174
+ SharedHelpers.filesystem_access(Bundler.bundle_path.to_s) do |p|
175
+ Bundler.mkdir_p(p)
176
+ end unless Bundler.bundle_path.exist?
279
177
  rescue Errno::EEXIST
280
- raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " +
178
+ raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " \
281
179
  "because of an invalid symlink. Remove the symlink so the directory can be created."
282
180
  end
283
181
 
182
+ def resolve_if_need(options)
183
+ if Bundler.default_lockfile.exist? && !options["update"]
184
+ local = Bundler.ui.silence do
185
+ begin
186
+ tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
187
+ true unless tmpdef.new_platform? || tmpdef.missing_specs.any?
188
+ rescue BundlerError
189
+ end
190
+ end
191
+ end
192
+
193
+ unless local
194
+ options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
195
+ end
196
+ end
284
197
  end
285
198
  end
@@ -19,7 +19,7 @@ module Bundler
19
19
  end
20
20
 
21
21
  def full_name
22
- if platform == Gem::Platform::RUBY or platform.nil? then
22
+ if platform == Gem::Platform::RUBY || platform.nil?
23
23
  "#{@name}-#{@version}"
24
24
  else
25
25
  "#{@name}-#{@version}-#{platform}"
@@ -35,13 +35,13 @@ module Bundler
35
35
  end
36
36
 
37
37
  def to_lock
38
- if platform == Gem::Platform::RUBY or platform.nil?
38
+ if platform == Gem::Platform::RUBY || platform.nil?
39
39
  out = " #{name} (#{version})\n"
40
40
  else
41
41
  out = " #{name} (#{version}-#{platform})\n"
42
42
  end
43
43
 
44
- dependencies.sort_by {|d| d.to_s }.uniq.each do |dep|
44
+ dependencies.sort_by(&:to_s).uniq.each do |dep|
45
45
  next if dep.type == :development
46
46
  out << " #{dep.to_lock}\n"
47
47
  end
@@ -54,7 +54,7 @@ module Bundler
54
54
  end
55
55
 
56
56
  def respond_to?(*args)
57
- super || @specification.respond_to?(*args)
57
+ super || @specification ? @specification.respond_to?(*args) : nil
58
58
  end
59
59
 
60
60
  def to_s
@@ -78,6 +78,5 @@ module Bundler
78
78
 
79
79
  @specification.send(method, *args, &blk)
80
80
  end
81
-
82
81
  end
83
82
  end