1# frozen_string_literal: true 2 3RSpec.shared_examples "bundle install --standalone" do 4 shared_examples "common functionality" do 5 it "still makes the gems available to normal bundler" do 6 args = expected_gems.map {|k, v| "#{k} #{v}" } 7 expect(the_bundle).to include_gems(*args) 8 end 9 10 it "generates a bundle/bundler/setup.rb" do 11 expect(bundled_app("bundle/bundler/setup.rb")).to exist 12 end 13 14 it "makes the gems available without bundler" do 15 testrb = String.new <<-RUBY 16 $:.unshift File.expand_path("bundle") 17 require "bundler/setup" 18 19 RUBY 20 expected_gems.each do |k, _| 21 testrb << "\nrequire \"#{k}\"" 22 testrb << "\nputs #{k.upcase}" 23 end 24 Dir.chdir(bundled_app) do 25 ruby testrb, :no_lib => true 26 end 27 28 expect(out).to eq(expected_gems.values.join("\n")) 29 end 30 31 it "works on a different system" do 32 FileUtils.mv(bundled_app, "#{bundled_app}2") 33 34 testrb = String.new <<-RUBY 35 $:.unshift File.expand_path("bundle") 36 require "bundler/setup" 37 38 RUBY 39 expected_gems.each do |k, _| 40 testrb << "\nrequire \"#{k}\"" 41 testrb << "\nputs #{k.upcase}" 42 end 43 Dir.chdir("#{bundled_app}2") do 44 ruby testrb, :no_lib => true 45 end 46 47 expect(out).to eq(expected_gems.values.join("\n")) 48 end 49 end 50 51 describe "with simple gems" do 52 before do 53 gemfile <<-G 54 source "file://#{gem_repo1}" 55 gem "rails" 56 G 57 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true) 58 end 59 60 let(:expected_gems) do 61 { 62 "actionpack" => "2.3.2", 63 "rails" => "2.3.2", 64 } 65 end 66 67 include_examples "common functionality" 68 end 69 70 describe "with gems with native extension", :ruby_repo do 71 before do 72 install_gemfile <<-G, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true) 73 source "file://#{gem_repo1}" 74 gem "very_simple_binary" 75 G 76 end 77 78 it "generates a bundle/bundler/setup.rb with the proper paths", :rubygems => "2.4" do 79 expected_path = bundled_app("bundle/bundler/setup.rb") 80 extension_line = File.read(expected_path).each_line.find {|line| line.include? "/extensions/" }.strip 81 expect(extension_line).to start_with '$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/' 82 expect(extension_line).to end_with '/very_simple_binary-1.0"' 83 end 84 end 85 86 describe "with gem that has an invalid gemspec" do 87 before do 88 build_git "bar", :gemspec => false do |s| 89 s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0') 90 s.write "bar.gemspec", <<-G 91 lib = File.expand_path('../lib/', __FILE__) 92 $:.unshift lib unless $:.include?(lib) 93 require 'bar/version' 94 95 Gem::Specification.new do |s| 96 s.name = 'bar' 97 s.version = BAR_VERSION 98 s.summary = 'Bar' 99 s.files = Dir["lib/**/*.rb"] 100 s.author = 'Anonymous' 101 s.require_path = [1,2] 102 end 103 G 104 end 105 install_gemfile <<-G, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true) 106 gem "bar", :git => "#{lib_path("bar-1.0")}" 107 G 108 end 109 110 it "outputs a helpful error message" do 111 expect(out).to include("You have one or more invalid gemspecs that need to be fixed.") 112 expect(out).to include("bar 1.0 has an invalid gemspec") 113 end 114 end 115 116 describe "with a combination of gems and git repos" do 117 before do 118 build_git "devise", "1.0" 119 120 gemfile <<-G 121 source "file://#{gem_repo1}" 122 gem "rails" 123 gem "devise", :git => "#{lib_path("devise-1.0")}" 124 G 125 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true) 126 end 127 128 let(:expected_gems) do 129 { 130 "actionpack" => "2.3.2", 131 "devise" => "1.0", 132 "rails" => "2.3.2", 133 } 134 end 135 136 include_examples "common functionality" 137 end 138 139 describe "with groups" do 140 before do 141 build_git "devise", "1.0" 142 143 gemfile <<-G 144 source "file://#{gem_repo1}" 145 gem "rails" 146 147 group :test do 148 gem "rspec" 149 gem "rack-test" 150 end 151 G 152 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true) 153 end 154 155 let(:expected_gems) do 156 { 157 "actionpack" => "2.3.2", 158 "rails" => "2.3.2", 159 } 160 end 161 162 include_examples "common functionality" 163 164 it "allows creating a standalone file with limited groups" do 165 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => "default") 166 167 Dir.chdir(bundled_app) do 168 load_error_ruby <<-RUBY, "spec", :no_lib => true 169 $:.unshift File.expand_path("bundle") 170 require "bundler/setup" 171 172 require "actionpack" 173 puts ACTIONPACK 174 require "spec" 175 RUBY 176 end 177 178 expect(last_command.stdout).to eq("2.3.2") 179 expect(last_command.stderr).to eq("ZOMG LOAD ERROR") 180 end 181 182 it "allows --without to limit the groups used in a standalone" do 183 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle"), :without => "test").merge(:standalone => true) 184 185 Dir.chdir(bundled_app) do 186 load_error_ruby <<-RUBY, "spec", :no_lib => true 187 $:.unshift File.expand_path("bundle") 188 require "bundler/setup" 189 190 require "actionpack" 191 puts ACTIONPACK 192 require "spec" 193 RUBY 194 end 195 196 expect(last_command.stdout).to eq("2.3.2") 197 expect(last_command.stderr).to eq("ZOMG LOAD ERROR") 198 end 199 200 it "allows --path to change the location of the standalone bundle", :bundler => "< 2" do 201 bundle! "install", forgotten_command_line_options(:path => "path/to/bundle").merge(:standalone => true) 202 203 Dir.chdir(bundled_app) do 204 ruby <<-RUBY, :no_lib => true 205 $:.unshift File.expand_path("path/to/bundle") 206 require "bundler/setup" 207 208 require "actionpack" 209 puts ACTIONPACK 210 RUBY 211 end 212 213 expect(last_command.stdout).to eq("2.3.2") 214 end 215 216 it "allows --path to change the location of the standalone bundle", :bundler => "2" do 217 bundle! "install", forgotten_command_line_options(:path => "path/to/bundle").merge(:standalone => true) 218 path = File.expand_path("path/to/bundle") 219 220 Dir.chdir(bundled_app) do 221 ruby <<-RUBY, :no_lib => true 222 $:.unshift File.expand_path(#{path.dump}) 223 require "bundler/setup" 224 225 require "actionpack" 226 puts ACTIONPACK 227 RUBY 228 end 229 230 expect(last_command.stdout).to eq("2.3.2") 231 end 232 233 it "allows remembered --without to limit the groups used in a standalone" do 234 bundle! :install, forgotten_command_line_options(:without => "test") 235 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true) 236 237 Dir.chdir(bundled_app) do 238 load_error_ruby <<-RUBY, "spec", :no_lib => true 239 $:.unshift File.expand_path("bundle") 240 require "bundler/setup" 241 242 require "actionpack" 243 puts ACTIONPACK 244 require "spec" 245 RUBY 246 end 247 248 expect(last_command.stdout).to eq("2.3.2") 249 expect(last_command.stderr).to eq("ZOMG LOAD ERROR") 250 end 251 end 252 253 describe "with gemcutter's dependency API" do 254 let(:source_uri) { "http://localgemserver.test" } 255 256 describe "simple gems" do 257 before do 258 gemfile <<-G 259 source "#{source_uri}" 260 gem "rails" 261 G 262 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true, :artifice => "endpoint") 263 end 264 265 let(:expected_gems) do 266 { 267 "actionpack" => "2.3.2", 268 "rails" => "2.3.2", 269 } 270 end 271 272 include_examples "common functionality" 273 end 274 end 275 276 describe "with --binstubs", :bundler => "< 2" do 277 before do 278 gemfile <<-G 279 source "file://#{gem_repo1}" 280 gem "rails" 281 G 282 bundle! :install, forgotten_command_line_options(:path => bundled_app("bundle")).merge(:standalone => true, :binstubs => true) 283 end 284 285 let(:expected_gems) do 286 { 287 "actionpack" => "2.3.2", 288 "rails" => "2.3.2", 289 } 290 end 291 292 include_examples "common functionality" 293 294 it "creates stubs that use the standalone load path" do 295 Dir.chdir(bundled_app) do 296 expect(`bin/rails -v`.chomp).to eql "2.3.2" 297 end 298 end 299 300 it "creates stubs that can be executed from anywhere" do 301 require "tmpdir" 302 Dir.chdir(Dir.tmpdir) do 303 sys_exec!(%(#{bundled_app("bin/rails")} -v)) 304 expect(out).to eq("2.3.2") 305 end 306 end 307 308 it "creates stubs that can be symlinked" do 309 pending "File.symlink is unsupported on Windows" if Bundler::WINDOWS 310 311 symlink_dir = tmp("symlink") 312 FileUtils.mkdir_p(symlink_dir) 313 symlink = File.join(symlink_dir, "rails") 314 315 File.symlink(bundled_app("bin/rails"), symlink) 316 sys_exec!("#{symlink} -v") 317 expect(out).to eq("2.3.2") 318 end 319 320 it "creates stubs with the correct load path" do 321 extension_line = File.read(bundled_app("bin/rails")).each_line.find {|line| line.include? "$:.unshift" }.strip 322 expect(extension_line).to eq %($:.unshift File.expand_path "../../bundle", path.realpath) 323 end 324 end 325end 326 327RSpec.describe "bundle install --standalone" do 328 include_examples("bundle install --standalone") 329end 330 331RSpec.describe "bundle install --standalone run in a subdirectory" do 332 before do 333 Dir.chdir(bundled_app("bob").tap(&:mkpath)) 334 end 335 336 include_examples("bundle install --standalone") 337end 338