bundler 1.0.22 → 1.1.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.

Files changed (114) hide show
  1. data/CHANGELOG.md +15 -181
  2. data/ISSUES.md +11 -26
  3. data/LICENSE +0 -2
  4. data/Rakefile +67 -116
  5. data/UPGRADING.md +4 -4
  6. data/bin/bundle +10 -10
  7. data/bundler.gemspec +5 -5
  8. data/lib/bundler.rb +15 -25
  9. data/lib/bundler/capistrano.rb +2 -2
  10. data/lib/bundler/cli.rb +41 -72
  11. data/lib/bundler/definition.rb +11 -37
  12. data/lib/bundler/dependency.rb +9 -13
  13. data/lib/bundler/deployment.rb +3 -8
  14. data/lib/bundler/dsl.rb +10 -24
  15. data/lib/bundler/fetcher.rb +101 -0
  16. data/lib/bundler/gem_helper.rb +6 -11
  17. data/lib/bundler/index.rb +8 -15
  18. data/lib/bundler/installer.rb +55 -35
  19. data/lib/bundler/lazy_specification.rb +7 -10
  20. data/lib/bundler/remote_specification.rb +6 -8
  21. data/lib/bundler/resolver.rb +18 -12
  22. data/lib/bundler/rubygems_ext.rb +3 -20
  23. data/lib/bundler/runtime.rb +57 -8
  24. data/lib/bundler/settings.rb +6 -4
  25. data/lib/bundler/setup.rb +5 -12
  26. data/lib/bundler/shared_helpers.rb +100 -4
  27. data/lib/bundler/source.rb +61 -106
  28. data/lib/bundler/spec_set.rb +8 -9
  29. data/lib/bundler/templates/newgem/Rakefile.tt +2 -1
  30. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +0 -2
  31. data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -6
  32. data/lib/bundler/ui.rb +1 -4
  33. data/lib/bundler/vendor/net/http/faster.rb +27 -0
  34. data/lib/bundler/vendor/net/http/persistent.rb +464 -0
  35. data/lib/bundler/vendor/thor.rb +4 -43
  36. data/lib/bundler/vendor/thor/actions.rb +11 -28
  37. data/lib/bundler/vendor/thor/actions/create_file.rb +2 -2
  38. data/lib/bundler/vendor/thor/actions/directory.rb +2 -2
  39. data/lib/bundler/vendor/thor/actions/empty_directory.rb +0 -0
  40. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +15 -56
  41. data/lib/bundler/vendor/thor/actions/inject_into_file.rb +10 -15
  42. data/lib/bundler/vendor/thor/base.rb +4 -24
  43. data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +0 -0
  44. data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +0 -0
  45. data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +0 -0
  46. data/lib/bundler/vendor/thor/error.rb +0 -0
  47. data/lib/bundler/vendor/thor/invocation.rb +0 -0
  48. data/lib/bundler/vendor/thor/parser.rb +0 -0
  49. data/lib/bundler/vendor/thor/parser/argument.rb +0 -0
  50. data/lib/bundler/vendor/thor/parser/arguments.rb +2 -2
  51. data/lib/bundler/vendor/thor/parser/option.rb +1 -1
  52. data/lib/bundler/vendor/thor/parser/options.rb +16 -17
  53. data/lib/bundler/vendor/thor/shell.rb +0 -0
  54. data/lib/bundler/vendor/thor/shell/basic.rb +13 -40
  55. data/lib/bundler/vendor/thor/shell/color.rb +0 -0
  56. data/lib/bundler/vendor/thor/task.rb +4 -3
  57. data/lib/bundler/vendor/thor/util.rb +2 -2
  58. data/lib/bundler/vendor/thor/version.rb +1 -1
  59. data/lib/bundler/version.rb +1 -1
  60. data/lib/bundler/vlad.rb +0 -2
  61. data/man/bundle-install.ronn +3 -6
  62. data/man/gemfile.5.ronn +2 -7
  63. data/spec/cache/gems_spec.rb +0 -11
  64. data/spec/cache/git_spec.rb +2 -5
  65. data/spec/install/deploy_spec.rb +8 -8
  66. data/spec/install/gems/dependency_api_spec.rb +85 -0
  67. data/spec/install/gems/flex_spec.rb +4 -4
  68. data/spec/install/gems/groups_spec.rb +3 -17
  69. data/spec/install/gems/platform_spec.rb +16 -0
  70. data/spec/install/gems/simple_case_spec.rb +24 -88
  71. data/spec/install/gems/standalone_spec.rb +162 -0
  72. data/spec/install/gems/sudo_spec.rb +2 -3
  73. data/spec/install/gemspec_spec.rb +0 -38
  74. data/spec/install/git_spec.rb +4 -3
  75. data/spec/install/invalid_spec.rb +0 -18
  76. data/spec/install/path_spec.rb +1 -53
  77. data/spec/lock/git_spec.rb +1 -1
  78. data/spec/lock/lockfile_spec.rb +16 -72
  79. data/spec/other/check_spec.rb +6 -6
  80. data/spec/other/clean_spec.rb +202 -0
  81. data/spec/other/exec_spec.rb +7 -14
  82. data/spec/other/ext_spec.rb +0 -21
  83. data/spec/{bundler → other}/gem_helper_spec.rb +1 -16
  84. data/spec/other/help_spec.rb +1 -2
  85. data/spec/other/init_spec.rb +3 -3
  86. data/spec/other/newgem_spec.rb +1 -23
  87. data/spec/pack/gems_spec.rb +22 -0
  88. data/spec/quality_spec.rb +2 -6
  89. data/spec/runtime/require_spec.rb +10 -10
  90. data/spec/runtime/setup_spec.rb +12 -54
  91. data/spec/spec_helper.rb +7 -14
  92. data/spec/support/artifice/endpoint.rb +50 -0
  93. data/spec/support/artifice/endpoint_fallback.rb +22 -0
  94. data/spec/support/artifice/endpoint_marshal_fail.rb +11 -0
  95. data/spec/support/artifice/endpoint_redirect.rb +11 -0
  96. data/spec/support/builders.rb +2 -25
  97. data/spec/support/fakeweb/rack-1.0.0.marshal +2 -0
  98. data/spec/support/fakeweb/windows.rb +23 -0
  99. data/spec/support/helpers.rb +12 -5
  100. data/spec/support/matchers.rb +16 -4
  101. data/spec/support/path.rb +2 -0
  102. data/spec/support/rubygems_ext.rb +2 -6
  103. data/spec/update/gems_spec.rb +2 -3
  104. data/spec/update/git_spec.rb +2 -2
  105. metadata +41 -24
  106. data/.travis.yml +0 -31
  107. data/lib/bundler/gem_installer.rb +0 -9
  108. data/lib/bundler/gem_tasks.rb +0 -2
  109. data/lib/bundler/rubygems_integration.rb +0 -344
  110. data/lib/bundler/vendor/thor/actions/create_link.rb +0 -57
  111. data/lib/bundler/vendor/thor/group.rb +0 -273
  112. data/lib/bundler/vendor/thor/rake_compat.rb +0 -66
  113. data/lib/bundler/vendor/thor/runner.rb +0 -309
  114. data/lib/bundler/vendored_thor.rb +0 -7
@@ -15,7 +15,6 @@ module Bundler
15
15
  :mri => Gem::Platform::RUBY,
16
16
  :mri_18 => Gem::Platform::RUBY,
17
17
  :mri_19 => Gem::Platform::RUBY,
18
- :rbx => Gem::Platform::RUBY,
19
18
  :jruby => Gem::Platform::JAVA,
20
19
  :mswin => Gem::Platform::MSWIN,
21
20
  :mingw => Gem::Platform::MINGW,
@@ -24,8 +23,7 @@ module Bundler
24
23
  }.freeze
25
24
 
26
25
  def initialize(name, version, options = {}, &blk)
27
- type = options["type"] || :runtime
28
- super(name, version, type)
26
+ super(name, version)
29
27
 
30
28
  @autorequire = nil
31
29
  @groups = Array(options["group"] || :default).map { |g| g.to_sym }
@@ -71,15 +69,21 @@ module Bundler
71
69
  end
72
70
 
73
71
  def to_lock
74
- out = super
72
+ out = " #{name}"
73
+
74
+ unless requirement == Gem::Requirement.default
75
+ out << " (#{requirement.to_s})"
76
+ end
77
+
75
78
  out << '!' if source
79
+
76
80
  out << "\n"
77
81
  end
78
82
 
79
83
  private
80
84
 
81
85
  def ruby?
82
- !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev")
86
+ !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx")
83
87
  end
84
88
 
85
89
  def ruby_18?
@@ -102,18 +106,10 @@ module Bundler
102
106
  mri? && RUBY_VERSION >= "1.9"
103
107
  end
104
108
 
105
- def rbx?
106
- ruby? && defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
107
- end
108
-
109
109
  def jruby?
110
110
  defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
111
111
  end
112
112
 
113
- def maglev?
114
- defined?(RUBY_ENGINE) && RUBY_ENGINE == "maglev"
115
- end
116
-
117
113
  def mswin?
118
114
  Bundler::WINDOWS
119
115
  end
@@ -4,11 +4,9 @@ module Bundler
4
4
  if defined?(Capistrano) && context.is_a?(Capistrano::Configuration)
5
5
  context_name = "capistrano"
6
6
  role_default = "{:except => {:no_release => true}}"
7
- error_type = ::Capistrano::CommandError
8
7
  else
9
8
  context_name = "vlad"
10
9
  role_default = "[:app]"
11
- error_type = ::Rake::CommandFailedError
12
10
  end
13
11
 
14
12
  roles = context.fetch(:bundle_roles, false)
@@ -41,16 +39,13 @@ module Bundler
41
39
  bundle_dir = context.fetch(:bundle_dir, File.join(context.fetch(:shared_path), 'bundle'))
42
40
  bundle_gemfile = context.fetch(:bundle_gemfile, "Gemfile")
43
41
  bundle_without = [*context.fetch(:bundle_without, [:development, :test])].compact
44
- current_release = context.fetch(:current_release)
45
- if current_release.to_s.empty?
46
- raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
47
- end
48
- args = ["--gemfile #{File.join(current_release, bundle_gemfile)}"]
42
+
43
+ args = ["--gemfile #{File.join(context.fetch(:current_release), bundle_gemfile)}"]
49
44
  args << "--path #{bundle_dir}" unless bundle_dir.to_s.empty?
50
45
  args << bundle_flags.to_s
51
46
  args << "--without #{bundle_without.join(" ")}" unless bundle_without.empty?
52
47
 
53
- run "cd #{current_release} && #{bundle_cmd} install #{args.join(' ')}"
48
+ run "#{bundle_cmd} install #{args.join(' ')}"
54
49
  end
55
50
  end
56
51
  end
@@ -22,7 +22,7 @@ module Bundler
22
22
 
23
23
  def gemspec(opts = nil)
24
24
  path = opts && opts[:path] || '.'
25
- name = opts && opts[:name] || '{,*}'
25
+ name = opts && opts[:name] || '*'
26
26
  development_group = opts && opts[:development_group] || :development
27
27
  path = File.expand_path(path, Bundler.default_gemfile.dirname)
28
28
  gemspecs = Dir[File.join(path, "#{name}.gemspec")]
@@ -34,7 +34,7 @@ module Bundler
34
34
  gem spec.name, :path => path
35
35
  group(development_group) do
36
36
  spec.development_dependencies.each do |dep|
37
- gem dep.name, *(dep.requirement.as_list + [:type => :development])
37
+ gem dep.name, *dep.requirement.as_list
38
38
  end
39
39
  end
40
40
  when 0
@@ -57,34 +57,20 @@ module Bundler
57
57
 
58
58
  dep = Dependency.new(name, version, options)
59
59
 
60
- # if there's already a dependency with this name we try to prefer one
61
60
  if current = @dependencies.find { |d| d.name == dep.name }
62
61
  if current.requirement != dep.requirement
63
- if current.type == :development
64
- @dependencies.delete current
65
- elsif dep.type == :development
66
- return
67
- else
68
- raise DslError, "You cannot specify the same gem twice with different version requirements. " \
69
- "You specified: #{current.name} (#{current.requirement}) and " \
70
- "#{dep.name} (#{dep.requirement})"
71
- end
62
+ raise DslError, "You cannot specify the same gem twice with different version requirements. " \
63
+ "You specified: #{current.name} (#{current.requirement}) and " \
64
+ "#{dep.name} (#{dep.requirement})"
72
65
  end
73
66
 
74
67
  if current.source != dep.source
75
- if current.type == :development
76
- @dependencies.delete current
77
- elsif dep.type == :development
78
- return
79
- else
80
- raise DslError, "You cannot specify the same gem twice coming from different sources. You " \
81
- "specified that #{dep.name} (#{dep.requirement}) should come from " \
82
- "#{current.source || 'an unspecfied source'} and #{dep.source}"
83
- end
68
+ raise DslError, "You cannot specify the same gem twice coming from different sources. You " \
69
+ "specified that #{dep.name} (#{dep.requirement}) should come from " \
70
+ "#{current.source || 'an unspecfied source'} and #{dep.source}"
84
71
  end
85
72
  end
86
-
87
- @dependencies << dep
73
+ @dependencies << Dependency.new(name, version, options)
88
74
  end
89
75
 
90
76
  def source(source, options = {})
@@ -197,7 +183,7 @@ module Bundler
197
183
  def _normalize_options(name, version, opts)
198
184
  _normalize_hash(opts)
199
185
 
200
- invalid_keys = opts.keys - %w(group groups git path name branch ref tag require submodules platform platforms type)
186
+ invalid_keys = opts.keys - %w(group groups git path name branch ref tag require submodules platform platforms)
201
187
  if invalid_keys.any?
202
188
  plural = invalid_keys.size > 1
203
189
  message = "You passed #{invalid_keys.map{|k| ':'+k }.join(", ")} "
@@ -0,0 +1,101 @@
1
+ require 'uri'
2
+ require 'net/http/persistent'
3
+
4
+ module Bundler
5
+ class Fetcher
6
+ REDIRECT_LIMIT = 5
7
+
8
+ def initialize(remote_uri)
9
+ @remote_uri = remote_uri
10
+ @@connection ||= Net::HTTP::Persistent.new
11
+ end
12
+
13
+ # fetch a gem specification
14
+ def fetch_spec(spec)
15
+ spec = spec - [nil, 'ruby', '']
16
+ spec_file_name = "#{spec.join '-'}.gemspec.rz"
17
+
18
+ uri = URI.parse("#{@remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}")
19
+
20
+ spec_rz = (uri.scheme == "file") ? Gem.read_binary(uri.path) : fetch(uri)
21
+ Marshal.load Gem.inflate(spec_rz)
22
+ end
23
+
24
+ # fetch index
25
+ def fetch_remote_specs(gem_names, full_dependency_list = [], last_spec_list = [], &blk)
26
+ return fetch_all_remote_specs(&blk) unless gem_names && @remote_uri.scheme != "file"
27
+
28
+ query_list = gem_names - full_dependency_list
29
+ Bundler.ui.debug "Query List: #{query_list.inspect}"
30
+ return {@remote_uri => last_spec_list}.each(&blk) if query_list.empty?
31
+
32
+ spec_list, deps_list = fetch_dependency_remote_specs(query_list, &blk)
33
+ returned_gems = spec_list.map {|spec| spec.first }.uniq
34
+
35
+ fetch_remote_specs(deps_list, full_dependency_list + returned_gems, spec_list + last_spec_list, &blk)
36
+ # fall back to the legacy index in the following cases
37
+ # 1.) Gemcutter Endpoint doesn't return a 200
38
+ # 2.) Marshal blob doesn't load properly
39
+ rescue HTTPError, TypeError => e
40
+ Bundler.ui.debug "Error #{e.class} from Gemcutter Dependency Endpoint API: #{e.message}"
41
+ Bundler.ui.debug e.backtrace
42
+ fetch_all_remote_specs(&blk)
43
+ end
44
+
45
+ private
46
+
47
+ def fetch(uri, counter = 0)
48
+ raise HTTPError, "Too many redirects" if counter >= REDIRECT_LIMIT
49
+
50
+ Bundler.ui.debug "Fetching from: #{uri}"
51
+ response = @@connection.request(uri)
52
+ case response
53
+ when Net::HTTPRedirection
54
+ Bundler.ui.debug("HTTP Redirection")
55
+ uri = URI.parse(response["location"])
56
+ fetch(uri, counter + 1)
57
+ when Net::HTTPSuccess
58
+ Bundler.ui.debug("HTTP Success")
59
+ response.body
60
+ else
61
+ Bundler.ui.debug("HTTP Error")
62
+ raise HTTPError
63
+ end
64
+ end
65
+
66
+ # fetch from Gemcutter Dependency Endpoint API
67
+ def fetch_dependency_remote_specs(gem_names, &blk)
68
+ Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(' ')}"
69
+ uri = URI.parse("#{@remote_uri}api/v1/dependencies?gems=#{gem_names.join(",")}")
70
+ marshalled_deps = fetch(uri)
71
+ gem_list = Marshal.load(marshalled_deps)
72
+
73
+ spec_list = gem_list.map do |s|
74
+ [s[:name], Gem::Version.new(s[:number]), s[:platform]]
75
+ end
76
+ deps_list = gem_list.map do |s|
77
+ s[:dependencies].collect {|d| d.first }
78
+ end.flatten.uniq
79
+
80
+ [spec_list, deps_list]
81
+ end
82
+
83
+ # fetch from modern index: specs.4.8.gz
84
+ def fetch_all_remote_specs(&blk)
85
+ Bundler.ui.debug "Fetching modern index"
86
+ Gem.sources = ["#{@remote_uri}"]
87
+ begin
88
+ # Fetch all specs, minus prerelease specs
89
+ Gem::SpecFetcher.new.list(true, false).each(&blk)
90
+ # Then fetch the prerelease specs
91
+ begin
92
+ Gem::SpecFetcher.new.list(false, true).each(&blk)
93
+ rescue Gem::RemoteFetcher::FetchError
94
+ Bundler.ui.warn "Could not fetch prerelease specs from #{self}"
95
+ end
96
+ rescue Gem::RemoteFetcher::FetchError
97
+ Bundler.ui.warn "Could not reach #{self}"
98
+ end
99
+ end
100
+ end
101
+ end
@@ -4,8 +4,6 @@ require 'bundler'
4
4
 
5
5
  module Bundler
6
6
  class GemHelper
7
- include Rake::DSL if defined? Rake::DSL
8
-
9
7
  def self.install_tasks(opts = {})
10
8
  dir = opts[:dir] || Dir.pwd
11
9
  self.new(dir, opts[:name]).install
@@ -16,7 +14,7 @@ module Bundler
16
14
  def initialize(base, name = nil)
17
15
  Bundler.ui = UI::Shell.new(Thor::Base.shell.new)
18
16
  @base = base
19
- gemspecs = name ? [File.join(base, "#{name}.gemspec")] : Dir[File.join(base, "{,*}.gemspec")]
17
+ gemspecs = name ? [File.join(base, "#{name}.gemspec")] : Dir[File.join(base, "*.gemspec")]
20
18
  raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1
21
19
  @spec_path = gemspecs.first
22
20
  @gemspec = Bundler.load_gemspec(@spec_path)
@@ -41,7 +39,7 @@ module Bundler
41
39
 
42
40
  def build_gem
43
41
  file_name = nil
44
- sh("gem build -V '#{spec_path}'") { |out, code|
42
+ sh("gem build #{spec_path}") { |out, code|
45
43
  raise out unless out[/Successfully/]
46
44
  file_name = File.basename(built_gem_path)
47
45
  FileUtils.mkdir_p(File.join(base, 'pkg'))
@@ -53,7 +51,7 @@ module Bundler
53
51
 
54
52
  def install_gem
55
53
  built_gem_path = build_gem
56
- out, _ = sh_with_code("gem install '#{built_gem_path}'")
54
+ out, _ = sh_with_code("gem install #{built_gem_path}")
57
55
  raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
58
56
  Bundler.ui.confirm "#{name} (#{version}) installed"
59
57
  end
@@ -70,12 +68,9 @@ module Bundler
70
68
 
71
69
  protected
72
70
  def rubygem_push(path)
73
- if Pathname.new("~/.gem/credentials").expand_path.exist?
74
- sh("gem push '#{path}'")
75
- Bundler.ui.confirm "Pushed #{name} #{version} to rubygems.org"
76
- else
77
- raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
78
- end
71
+ out, _ = sh("gem push #{path}")
72
+ raise "Gem push failed due to lack of RubyGems.org credentials." if out[/Enter your RubyGems.org credentials/]
73
+ Bundler.ui.confirm "Pushed #{name} #{version} to rubygems.org"
79
74
  end
80
75
 
81
76
  def built_gem_path
@@ -78,13 +78,10 @@ module Bundler
78
78
  end
79
79
  end
80
80
 
81
- def use(other, override_dupes = false)
81
+ def use(other)
82
82
  return unless other
83
83
  other.each do |s|
84
- if (dupes = search_by_spec(s)) && dupes.any?
85
- next unless override_dupes
86
- @specs[s.name] -= dupes
87
- end
84
+ next if search_by_spec(s).any?
88
85
  @specs[s.name] << s
89
86
  end
90
87
  self
@@ -104,15 +101,10 @@ module Bundler
104
101
  end
105
102
  end
106
103
 
107
- if RUBY_VERSION < '1.9'
108
- def same_version?(a, b)
109
- regex = /^(.*?)(?:\.0)*$/
110
- a.to_s[regex, 1] == b.to_s[regex, 1]
111
- end
112
- else
113
- def same_version?(a, b)
114
- a == b
115
- end
104
+ def same_version?(a, b)
105
+ regex = /^(.*?)(?:\.0)*$/
106
+
107
+ a.to_s[regex, 1] == b.to_s[regex, 1]
116
108
  end
117
109
 
118
110
  def spec_satisfies_dependency?(spec, dep)
@@ -123,10 +115,11 @@ module Bundler
123
115
  def search_by_dependency(dependency)
124
116
  @cache[dependency.hash] ||= begin
125
117
  specs = @specs[dependency.name]
126
- found = specs.select { |spec| dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform) }
127
118
 
128
119
  wants_prerelease = dependency.requirement.prerelease?
129
120
  only_prerelease = specs.all? {|spec| spec.version.prerelease? }
121
+ found = specs.select { |spec| dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform) }
122
+
130
123
  unless wants_prerelease || only_prerelease
131
124
  found.reject! { |spec| spec.version.prerelease? }
132
125
  end
@@ -10,16 +10,8 @@ module Bundler
10
10
  end
11
11
 
12
12
  def run(options)
13
- # Create the BUNDLE_PATH directory
14
- begin
15
- Bundler.bundle_path.mkpath unless Bundler.bundle_path.exist?
16
- rescue Errno::EEXIST
17
- raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " +
18
- "because of an invalid symlink. Remove the symlink so the directory can be created."
19
- end
20
-
21
13
  if Bundler.settings[:frozen]
22
- @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
14
+ @definition.ensure_equivalent_gemfile_and_lockfile
23
15
  end
24
16
 
25
17
  if dependencies.empty?
@@ -43,43 +35,40 @@ module Bundler
43
35
  @definition.resolve_remotely!
44
36
  end
45
37
 
38
+ # Ensure that BUNDLE_PATH exists
39
+ Bundler.mkdir_p(Bundler.bundle_path) unless File.exist?(Bundler.bundle_path)
40
+
46
41
  # Must install gems in the order that the resolver provides
47
42
  # as dependencies might actually affect the installation of
48
43
  # the gem.
49
44
  specs.each do |spec|
50
- install_gem_from_spec(spec)
51
- end
52
-
53
- lock
54
- end
45
+ spec.source.fetch(spec) if spec.source.respond_to?(:fetch)
55
46
 
56
- private
47
+ # unless requested_specs.include?(spec)
48
+ # Bundler.ui.debug " * Not in requested group; skipping."
49
+ # next
50
+ # end
57
51
 
58
- def install_gem_from_spec(spec)
59
- # Download the gem to get the spec, because some specs that are returned
60
- # by rubygems.org are broken and wrong.
61
- spec.source.fetch(spec) if spec.source.respond_to?(:fetch)
52
+ begin
53
+ old_args = Gem::Command.build_args
54
+ Gem::Command.build_args = [Bundler.settings["build.#{spec.name}"]]
55
+ spec.source.install(spec)
56
+ Bundler.ui.debug "from #{spec.loaded_from} "
57
+ ensure
58
+ Gem::Command.build_args = old_args
59
+ end
62
60
 
63
- # Fetch the build settings, if there are any
64
- settings = Bundler.settings["build.#{spec.name}"]
65
- Bundler.rubygems.with_build_args [settings] do
66
- spec.source.install(spec)
67
- Bundler.ui.debug "from #{spec.loaded_from} "
61
+ Bundler.ui.info ""
62
+ generate_bundler_executable_stubs(spec) if Bundler.settings[:bin]
63
+ FileUtils.rm_rf(Bundler.tmp)
68
64
  end
69
65
 
70
- # newline comes after installing, some gems say "with native extensions"
71
- Bundler.ui.info ""
72
- generate_bundler_executable_stubs(spec) if Bundler.settings[:bin]
73
- FileUtils.rm_rf(Bundler.tmp)
74
- rescue Exception => e
75
- Bundler.ui.info ""
76
- Bundler.ui.warn "#{e.class}: #{e.message}"
77
- msg = "An error occured while installing #{spec.name} (#{spec.version}),"
78
- msg << " and Bundler cannot continue.\nMake sure that `gem install"
79
- msg << " #{spec.name} -v '#{spec.version}'` succeeds before bundling."
80
- raise Bundler::InstallError, msg
66
+ lock
67
+ generate_standalone(options[:standalone]) if options[:standalone]
81
68
  end
82
69
 
70
+ private
71
+
83
72
  def generate_bundler_executable_stubs(spec)
84
73
  bin_path = Bundler.bin_path
85
74
  template = File.read(File.expand_path('../templates/Executable', __FILE__))
@@ -93,5 +82,36 @@ module Bundler
93
82
  end
94
83
  end
95
84
  end
85
+
86
+ def generate_standalone(groups)
87
+ path = Bundler.settings[:path]
88
+ bundler_path = File.join(path, "bundler")
89
+ FileUtils.mkdir_p(bundler_path)
90
+
91
+ paths = []
92
+
93
+ if groups.empty?
94
+ specs = Bundler.definition.requested_specs
95
+ else
96
+ specs = Bundler.definition.specs_for groups.map { |g| g.to_sym }
97
+ end
98
+
99
+ specs.each do |spec|
100
+ next if spec.name == "bundler"
101
+
102
+ spec.require_paths.each do |path|
103
+ full_path = File.join(spec.full_gem_path, path)
104
+ paths << Pathname.new(full_path).relative_path_from(Bundler.root.join("bundle/bundler"))
105
+ end
106
+ end
107
+
108
+
109
+ File.open File.join(bundler_path, "setup.rb"), "w" do |file|
110
+ file.puts "path = File.expand_path('..', __FILE__)"
111
+ paths.each do |path|
112
+ file.puts %{$:.unshift File.expand_path("\#{path}/#{path}")}
113
+ end
114
+ end
115
+ end
96
116
  end
97
117
  end