bowline-bundler 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +291 -0
  3. data/Rakefile +45 -0
  4. data/VERSION +1 -0
  5. data/bin/bowline-bundle +59 -0
  6. data/lib/bowline/bundler/bundle.rb +323 -0
  7. data/lib/bowline/bundler/cli.rb +87 -0
  8. data/lib/bowline/bundler/dependency.rb +62 -0
  9. data/lib/bowline/bundler/dsl.rb +182 -0
  10. data/lib/bowline/bundler/environment.rb +87 -0
  11. data/lib/bowline/bundler/finder.rb +51 -0
  12. data/lib/bowline/bundler/gem_bundle.rb +11 -0
  13. data/lib/bowline/bundler/gem_ext.rb +34 -0
  14. data/lib/bowline/bundler/remote_specification.rb +53 -0
  15. data/lib/bowline/bundler/resolver.rb +250 -0
  16. data/lib/bowline/bundler/runtime.rb +2 -0
  17. data/lib/bowline/bundler/source.rb +361 -0
  18. data/lib/bowline/bundler/templates/app_script.erb +3 -0
  19. data/lib/bowline/bundler/templates/environment.erb +156 -0
  20. data/lib/bowline/bundler/templates/environment_picker.erb +4 -0
  21. data/lib/bowline/bundler.rb +35 -0
  22. data/spec/bundler/cli_spec.rb +558 -0
  23. data/spec/bundler/directory_spec.rb +255 -0
  24. data/spec/bundler/dsl_spec.rb +126 -0
  25. data/spec/bundler/fetcher_spec.rb +138 -0
  26. data/spec/bundler/git_spec.rb +266 -0
  27. data/spec/bundler/installer_spec.rb +155 -0
  28. data/spec/bundler/manifest_file_spec.rb +105 -0
  29. data/spec/bundler/manifest_spec.rb +257 -0
  30. data/spec/bundler/runtime_spec.rb +141 -0
  31. data/spec/bundler/system_gems_spec.rb +42 -0
  32. data/spec/quality_spec.rb +57 -0
  33. data/spec/resolver/engine_spec.rb +112 -0
  34. data/spec/resolver/error_spec.rb +50 -0
  35. data/spec/resolver/fake_source_index_spec.rb +43 -0
  36. data/spec/resolver/prerelease_spec.rb +113 -0
  37. data/spec/spec_helper.rb +46 -0
  38. data/spec/support/builders.rb +257 -0
  39. data/spec/support/core_ext.rb +18 -0
  40. data/spec/support/helpers.rb +126 -0
  41. data/spec/support/matchers.rb +201 -0
  42. data/spec/support/path_utils.rb +63 -0
  43. metadata +126 -0
@@ -0,0 +1,558 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Bundler::CLI" do
4
+
5
+ describe "it compiles gems that take options" do
6
+ before(:each) do
7
+ build_manifest <<-Gemfile
8
+ clear_sources
9
+ source "file://#{gem_repo1}"
10
+ gem "very_simple_binary"
11
+ Gemfile
12
+
13
+ File.open("#{bundled_app}/build.yml", "w+") do |file|
14
+ file.puts <<-build_options.gsub(/^ /, '')
15
+ very_simple_binary:
16
+ simple: wot
17
+ build_options
18
+ end
19
+ end
20
+
21
+ it "fails if the option is not provided" do
22
+ Dir.chdir(bundled_app) do
23
+ @output = gem_command :bundle, "2>&1"
24
+ end
25
+
26
+ @output.should =~ /Failed to build gem native extension/
27
+ end
28
+
29
+ it "passes if a yaml is specified that contains the necessary options" do
30
+ Dir.chdir(bundled_app) do
31
+ @output = gem_command :bundle, "--build-options=build.yml 2>&1"
32
+ end
33
+
34
+ @output.should_not =~ /Failed to build gem native extension/
35
+
36
+ out = run_in_context <<-RUBY
37
+ require 'very_simple_binary_c'
38
+ puts VerySimpleBinaryInC
39
+ RUBY
40
+
41
+ out.should == "VerySimpleBinaryInC"
42
+ end
43
+
44
+ it "does not skip the binary gem if compiling failed in a previous bundle" do
45
+ Dir.chdir(bundled_app)
46
+
47
+ gem_command :bundle, "--backtrace 2>&1" # will fail
48
+ gem_command :bundle, "--build-options=build.yml 2>&1"
49
+
50
+ out = run_in_context <<-RUBY
51
+ require "very_simple_binary_c"
52
+ puts VerySimpleBinaryInC
53
+ RUBY
54
+ out.should == "VerySimpleBinaryInC"
55
+ end
56
+ end
57
+
58
+ describe "it working" do
59
+ before :each do
60
+ @manifest = build_manifest <<-Gemfile
61
+ clear_sources
62
+ source "file://#{gem_repo1}"
63
+ gem "rake"
64
+ gem "activesupport"
65
+ gem "rack", :only => :web
66
+ Gemfile
67
+
68
+ Dir.chdir(bundled_app) do
69
+ @output = gem_command :bundle
70
+ end
71
+ end
72
+
73
+ it "caches and installs rake" do
74
+ gems = %w(rake-0.8.7 activesupport-2.3.2 rack-1.0.0)
75
+ @manifest.gem_path.should have_cached_gems(*gems)
76
+ @manifest.gem_path.should have_installed_gems(*gems)
77
+ end
78
+
79
+ it "creates a default environment file with the appropriate load paths" do
80
+ out = run_in_context <<-RUBY
81
+ require "rake"
82
+ require "activesupport"
83
+ require "rack"
84
+ puts "\#{RAKE} - \#{ACTIVESUPPORT} - \#{RACK}"
85
+ RUBY
86
+
87
+ out.should == "0.8.7 - 2.3.2 - 1.0.0"
88
+ end
89
+
90
+ it "creates a platform-independent environment picker" do
91
+ @manifest.gem_path.join('../../environment.rb').file?.should == true
92
+ end
93
+
94
+ it "creates valid executables in ./bin" do
95
+ app_root do
96
+ `bin/rake`.should == "0.8.7\n"
97
+ end
98
+ end
99
+
100
+ it "runs exec correctly" do
101
+ app_root do
102
+ out = gem_command :exec, %[ruby -e 'require "rake" ; puts RAKE']
103
+ out.should == "0.8.7"
104
+ end
105
+ end
106
+
107
+ it "runs exec with options correctly" do
108
+ Dir.chdir(bundled_app) do
109
+ out = gem_command :exec, %[ruby -e 'puts "hello"'], :no_quote => true
110
+ out.should == "hello"
111
+ end
112
+ end
113
+
114
+ it "maintains the correct environment when shelling out" do
115
+ out = run_in_context "exec %{#{Gem.ruby} -e 'require %{rake} ; puts RAKE'}"
116
+ out.should == "0.8.7"
117
+ end
118
+
119
+ it "logs the correct information messages" do
120
+ [ "Updating source: file:#{gem_repo1}",
121
+ "Calculating dependencies...",
122
+ "Downloading rake-0.8.7.gem",
123
+ "Downloading activesupport-2.3.2.gem",
124
+ "Downloading rack-1.0.0.gem",
125
+ "Installing rake (0.8.7)",
126
+ "Installing activesupport (2.3.2)",
127
+ "Installing rack (1.0.0)",
128
+ "Done." ].each do |message|
129
+ @output.should =~ /^#{Regexp.escape(message)}$/
130
+ end
131
+ end
132
+
133
+ it "already has gems in the loaded_specs" do
134
+ out = run_in_context "puts Gem.loaded_specs.key?('activesupport')"
135
+ out.should == "true"
136
+ end
137
+
138
+ it "does already has rubygems required" do
139
+ out = run_in_context "puts Gem.respond_to?(:sources)"
140
+ out.should == "true"
141
+ end
142
+
143
+ # TODO: Remove this when rubygems is fixed
144
+ it "adds the gem to Gem.source_index" do
145
+ out = run_in_context "puts Gem.source_index.find_name('activesupport').first.version"
146
+ out.should == "2.3.2"
147
+ end
148
+ end
149
+
150
+ describe "error cases" do
151
+ before :each do
152
+ bundled_app.mkdir_p
153
+ Dir.chdir(bundled_app)
154
+ end
155
+
156
+ it "displays a friendly error message when there is no Gemfile" do
157
+ out = gem_command :bundle
158
+ out.should == "Could not find a Gemfile to use"
159
+ end
160
+
161
+ it "fails when a root level gem does not exist" do
162
+ build_manifest <<-Gemfile
163
+ clear_sources
164
+ source "file://#{gem_repo1}"
165
+ gem "monk"
166
+ Gemfile
167
+
168
+ out = gem_command :bundle
169
+ out.should include("Could not find gem 'monk (>= 0, runtime)' in any of the sources")
170
+ end
171
+
172
+ it "outputs a warning when a child gem dependency is missing dependencies" do
173
+ build_manifest <<-Gemfile
174
+ clear_sources
175
+ source "file://#{gem_repo1}"
176
+ gem "missing_dep"
177
+ Gemfile
178
+
179
+ out = gem_command :bundle
180
+ out.should include("Could not find gem 'not_here (>= 0, runtime)' (required by 'missing_dep (>= 0, runtime)') in any of the sources")
181
+ end
182
+ end
183
+
184
+ it "raises when providing a bad manifest" do
185
+ out = gem_command :bundle, "-m manifest_not_here"
186
+ out.should =~ /Manifest file not found: \".*manifest_not_here\"/
187
+ end
188
+
189
+ describe "it working while specifying the manifest file name" do
190
+ it "works when the manifest is in the root directory" do
191
+ manifest = build_manifest bundled_app('manifest.rb'), <<-Gemfile
192
+ bundle_path "gems"
193
+ clear_sources
194
+ source "file://#{gem_repo1}"
195
+ gem "rake"
196
+ Gemfile
197
+
198
+ Dir.chdir(bundled_app) do
199
+ out = gem_command :bundle, "-m #{bundled_app('manifest.rb')}"
200
+ out.should include('Done.')
201
+ manifest.gem_path.should have_cached_gems("rake-0.8.7")
202
+ tmp_bindir('rake').should exist
203
+ end
204
+ end
205
+
206
+ it "works when the manifest is in a different directory" do
207
+ manifest = build_manifest bundled_app('config', 'manifest.rb'), <<-Gemfile
208
+ bundle_path "../gems"
209
+ clear_sources
210
+ source "file://#{gem_repo1}"
211
+ gem "rake"
212
+ Gemfile
213
+
214
+ Dir.chdir(bundled_app)
215
+ out = gem_command :bundle, "-m #{bundled_app('config', 'manifest.rb')}"
216
+ out.should include('Done.')
217
+ manifest.gem_path.should have_cached_gems("rake-0.8.7")
218
+ end
219
+
220
+ it "works when using a relative path to the manifest file" do
221
+ build_manifest_file bundled_app('manifest_file'), <<-Gemfile
222
+ clear_sources
223
+ source "file://#{gem_repo1}"
224
+ gem "rake"
225
+ Gemfile
226
+
227
+ Dir.chdir(bundled_app) do
228
+ out = gem_command :bundle, "-m manifest_file"
229
+ out.should include('Done.')
230
+ tmp_gem_path.should have_cached_gems("rake-0.8.7")
231
+ tmp_bindir('rake').should exist
232
+ end
233
+ end
234
+ end
235
+
236
+ describe "it working without rubygems" do
237
+ before(:each) do
238
+ @manifest = build_manifest <<-Gemfile
239
+ clear_sources
240
+ source "file://#{gem_repo1}"
241
+ gem "rake"
242
+ gem "rack", :only => :web
243
+
244
+ disable_rubygems
245
+ Gemfile
246
+
247
+ Dir.chdir(bundled_app) do
248
+ @output = gem_command :bundle
249
+ end
250
+ end
251
+
252
+ it "does not load rubygems when required" do
253
+ out = run_in_context 'require "rubygems" ; puts Gem.respond_to?(:sources)'
254
+ out.should == "false"
255
+ end
256
+
257
+ it "does not blow up if #gem is used" do
258
+ out = run_in_context 'gem("merb-core") ; puts "Win!"'
259
+ out.should == "Win!"
260
+ end
261
+
262
+ it "does not blow up if Gem errors are referred to" do
263
+ out = run_in_context 'Gem::LoadError ; Gem::Exception ; puts "Win!"'
264
+ out.should == "Win!"
265
+ end
266
+
267
+ it "stubs out Gem.ruby" do
268
+ out = run_in_context "puts Gem.ruby"
269
+ out.should == Gem.ruby
270
+ end
271
+
272
+ it "stubs out Gem.dir" do
273
+ out = run_in_context "puts Gem.dir"
274
+ out.should == @manifest.gem_path.to_s
275
+ end
276
+
277
+ it "stubs out Gem.default_dir" do
278
+ out = run_in_context "puts Gem.default_dir"
279
+ out.should == @manifest.gem_path.to_s
280
+ end
281
+
282
+ it "stubs out Gem.path" do
283
+ out = run_in_context "puts Gem.path"
284
+ out.should == @manifest.gem_path.to_s
285
+ end
286
+ end
287
+
288
+ describe "relative paths everywhere" do
289
+ it "still works when you move the app directory" do
290
+ install_manifest <<-Gemfile
291
+ clear_sources
292
+ source "file://#{gem_repo1}"
293
+ gem "rack"
294
+ Gemfile
295
+
296
+ FileUtils.mv bundled_app, tmp_path("bundled_app2")
297
+
298
+ Dir.chdir(tmp_path('bundled_app2')) do
299
+ out = gem_command :exec, "ruby -e 'Bundler.require_env :default ; puts RACK'"
300
+ out.should == "1.0.0"
301
+ `bin/rackup`.strip.should == "1.0.0"
302
+ end
303
+ end
304
+ end
305
+
306
+ describe "forcing an update" do
307
+ it "forces checking for remote updates if --update is used" do
308
+ m = build_manifest <<-Gemfile
309
+ clear_sources
310
+ source "file://#{gem_repo1}"
311
+ gem "rack", "0.9.1"
312
+ Gemfile
313
+ m.install
314
+
315
+ m = build_manifest <<-Gemfile
316
+ clear_sources
317
+ source "file://#{gem_repo1}"
318
+ gem "rack"
319
+ Gemfile
320
+
321
+ Dir.chdir(bundled_app) do
322
+ gem_command :bundle, "--update"
323
+ end
324
+ m.gem_path.should include_cached_gems("rack-1.0.0")
325
+ m.gem_path.should have_installed_gems("rack-1.0.0")
326
+ end
327
+ end
328
+
329
+ describe "bundling from the local cache" do
330
+ before(:each) do
331
+ install_manifest <<-Gemfile
332
+ clear_sources
333
+ source "file://#{gem_repo1}"
334
+ gem "rack", "0.9.1"
335
+ Gemfile
336
+
337
+ %w(doc environment.rb gems specifications).each do |f|
338
+ FileUtils.rm_rf(tmp_gem_path.join(f))
339
+ end
340
+ end
341
+
342
+ it "only uses the localy cached gems when bundling with --cache" do
343
+ build_manifest <<-Gemfile
344
+ clear_sources
345
+ source "file://#{gem_repo1}"
346
+ gem "rack"
347
+ Gemfile
348
+
349
+ Dir.chdir(bundled_app) do
350
+ gem_command :bundle, "--cached"
351
+ tmp_gem_path.should include_cached_gems("rack-0.9.1")
352
+ tmp_gem_path.should have_installed_gems("rack-0.9.1")
353
+ end
354
+ end
355
+
356
+ it "raises an exception when there are missing gems in the cache" do
357
+ Dir["#{tmp_gem_path}/cache/*"].each { |f| FileUtils.rm_rf(f) }
358
+
359
+ build_manifest <<-Gemfile
360
+ clear_sources
361
+ source "file://#{gem_repo1}"
362
+ gem "rack"
363
+ Gemfile
364
+
365
+ Dir.chdir(bundled_app) do
366
+ out = gem_command :bundle, "--cached"
367
+ out.should include("Could not find gem 'rack (>= 0, runtime)' in any of the sources")
368
+ tmp_gem_path.should_not include_cached_gems("rack-0.9.1", "rack-1.0.0")
369
+ tmp_gem_path.should_not include_installed_gems("rack-0.9.1", "rack-1.0.0")
370
+ end
371
+ end
372
+ end
373
+
374
+ describe "bundling only given environments" do
375
+ before(:each) do
376
+ build_manifest <<-Gemfile
377
+ clear_sources
378
+ source "file://#{gem_repo1}"
379
+ gem "activesupport"
380
+ gem "very-simple", :only => :server
381
+ gem "rack", :only => :test
382
+ Gemfile
383
+ end
384
+
385
+ it "install gems for environments specified in --only line" do
386
+ system_gems do
387
+ app_root do
388
+ gem_command :bundle, "--only test"
389
+ out = run_in_context "require 'activesupport' ; require 'rack' ; puts ACTIVESUPPORT"
390
+ out.should == "2.3.2"
391
+
392
+ out = run_in_context <<-RUBY
393
+ begin ;require 'very-simple'
394
+ rescue LoadError ; puts 'awesome' ; end
395
+ RUBY
396
+ out.should == 'awesome'
397
+ end
398
+ end
399
+ end
400
+ end
401
+
402
+ describe "caching gems to the bundle" do
403
+ before(:each) do
404
+ build_manifest <<-Gemfile
405
+ clear_sources
406
+ Gemfile
407
+ end
408
+
409
+ it "adds a single gem to the cache" do
410
+ build_manifest <<-Gemfile
411
+ clear_sources
412
+ gem "rack"
413
+ Gemfile
414
+
415
+ Dir.chdir(bundled_app) do
416
+ out = gem_command :bundle, "--cache #{gem_repo1}/gems/rack-0.9.1.gem"
417
+ gem_command :bundle, "--cached"
418
+ out.should include("Caching: rack-0.9.1.gem")
419
+ tmp_gem_path.should include_cached_gems("rack-0.9.1")
420
+ tmp_gem_path.should include_installed_gems("rack-0.9.1")
421
+ end
422
+ end
423
+
424
+ it "adds a gem directory to the cache" do
425
+ m = build_manifest <<-Gemfile
426
+ clear_sources
427
+ gem "rack"
428
+ gem "activesupport"
429
+ Gemfile
430
+
431
+ Dir.chdir(bundled_app) do
432
+ out = gem_command :bundle, "--cache #{gem_repo1}/gems"
433
+ gem_command :bundle, "--cached"
434
+
435
+ %w(actionmailer-2.3.2 activerecord-2.3.2 rake-0.8.7 rack-0.9.1 rack-1.0.0).each do |gemfile|
436
+ out.should include("Caching: #{gemfile}.gem")
437
+ end
438
+ m.gem_path.should include_cached_gems("rack-1.0.0", "activesupport-2.3.2")
439
+ m.gem_path.should have_installed_gems("rack-1.0.0", "activesupport-2.3.2")
440
+ end
441
+ end
442
+
443
+ it "adds a gem from the local repository" do
444
+ system_gems "rake-0.8.7" do
445
+ build_manifest <<-Gemfile
446
+ clear_sources
447
+ gem "rake"
448
+ disable_system_gems
449
+ Gemfile
450
+
451
+ Dir.chdir(bundled_app) do
452
+ # out = gem_command :bundle, "--cache rake"
453
+ gem_command :bundle
454
+ out = run_in_context "require 'rake' ; puts RAKE"
455
+ out.should == "0.8.7"
456
+ end
457
+ end
458
+ end
459
+
460
+ it "outputs an error when trying to cache a gem that doesn't exist." do
461
+ Dir.chdir(bundled_app) do
462
+ out = gem_command :bundle, "--cache foo/bar.gem"
463
+ out.should == "'foo/bar.gem' does not exist."
464
+ end
465
+ end
466
+
467
+ it "outputs an error when trying to cache a directory that doesn't exist." do
468
+ Dir.chdir(bundled_app) do
469
+ out = gem_command :bundle, "--cache foo/bar"
470
+ out.should == "'foo/bar' does not exist."
471
+ end
472
+ end
473
+
474
+ it "outputs an error when trying to cache a directory with no gems." do
475
+ Dir.chdir(bundled_app) do
476
+ FileUtils.mkdir_p("foo/bar")
477
+ out = gem_command :bundle, "--cache foo/bar"
478
+ out.should == "'foo/bar' contains no gemfiles"
479
+ end
480
+ end
481
+ end
482
+
483
+ describe "pruning the cache" do
484
+ it "works" do
485
+ manifest = install_manifest <<-Gemfile
486
+ clear_sources
487
+ source "file://#{gem_repo1}"
488
+ gem "rack", "0.9.1"
489
+ Gemfile
490
+
491
+ manifest.gem_path.should have_cached_gems("rack-0.9.1")
492
+
493
+ manifest = install_manifest <<-Gemfile
494
+ clear_sources
495
+ source "file://#{gem_repo1}"
496
+ Gemfile
497
+
498
+ manifest.gem_path.should have_cached_gems("rack-0.9.1")
499
+ Dir.chdir bundled_app
500
+ out = gem_command :bundle, "--prune-cache"
501
+ manifest.gem_path.should_not have_cached_gems("rack-0.9.1")
502
+ end
503
+ end
504
+
505
+ describe "listing gems" do
506
+ it "works" do
507
+ install_manifest <<-Gemfile
508
+ clear_sources
509
+ source "file://#{gem_repo1}"
510
+ gem "rack", "0.9.1"
511
+ Gemfile
512
+
513
+ Dir.chdir bundled_app
514
+ out = gem_command :bundle, "--list"
515
+ out.should =~ /rack/
516
+ end
517
+ end
518
+
519
+ describe "listing outdated gems" do
520
+ it "shows a message when there are no outdated gems" do
521
+ m = build_manifest <<-Gemfile
522
+ clear_sources
523
+ Gemfile
524
+ m.install
525
+
526
+ Dir.chdir(bundled_app) do
527
+ @output = gem_command :bundle, "--list-outdated"
528
+ end
529
+
530
+ @output.should =~ /All gems are up to date/
531
+ end
532
+
533
+ it "shows all the outdated gems" do
534
+ m = build_manifest <<-Gemfile
535
+ clear_sources
536
+ source "file://#{gem_repo1}"
537
+ gem "rack", "0.9.1"
538
+ gem "rails"
539
+ Gemfile
540
+ m.install
541
+
542
+ app_root do
543
+ @output = gem_command :bundle, "--list-outdated"
544
+ end
545
+
546
+ [ "Outdated gems:",
547
+ " * actionmailer",
548
+ " * actionpack",
549
+ " * activerecord",
550
+ " * activeresource",
551
+ " * activesupport",
552
+ " * rack",
553
+ " * rails"].each do |message|
554
+ @output.should =~ /^#{Regexp.escape(message)}$/
555
+ end
556
+ end
557
+ end
558
+ end