warbler 0.9.14 → 1.0

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.
@@ -0,0 +1,425 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ require File.dirname(__FILE__) + '/../spec_helper'
8
+
9
+ describe Warbler::War do
10
+ before(:each) do
11
+ @rake = Rake::Application.new
12
+ Rake.application = @rake
13
+ verbose(false)
14
+ @pwd = Dir.getwd
15
+ Dir.chdir("spec/sample")
16
+ mkdir_p "log"
17
+ touch "log/test.log"
18
+ @config = Warbler::Config.new do |config|
19
+ config.war_name = "warbler"
20
+ config.gems = ["rake"]
21
+ config.webxml.jruby.max.runtimes = 5
22
+ end
23
+ @war = Warbler::War.new
24
+ end
25
+
26
+ after(:each) do
27
+ rm_rf "log"
28
+ rm_rf ".bundle"
29
+ rm_f FileList["*.war", "config.ru", "*web.xml*", "config/web.xml*",
30
+ "config/warble.rb", "file.txt", 'manifest', 'Gemfile*']
31
+ Dir.chdir(@pwd)
32
+ end
33
+
34
+ def file_list(regex)
35
+ @war.files.keys.select {|f| f =~ regex }
36
+ end
37
+
38
+ it "should collect files in public" do
39
+ @war.apply(@config)
40
+ file_list(%r{^index\.html}).should_not be_empty
41
+ end
42
+
43
+ it "should collect gem files" do
44
+ @config.gems << "rake"
45
+ @war.apply(@config)
46
+ file_list(%r{WEB-INF/gems/gems/rake.*/lib/rake.rb}).should_not be_empty
47
+ file_list(%r{WEB-INF/gems/specifications/rake.*\.gemspec}).should_not be_empty
48
+ end
49
+
50
+ it "should not include log files by default" do
51
+ @war.apply(@config)
52
+ file_list(%r{WEB-INF/log}).should_not be_empty
53
+ file_list(%r{WEB-INF/log/.*\.log}).should be_empty
54
+ end
55
+
56
+ def expand_webxml
57
+ @war.apply(@config)
58
+ @war.files.should include("WEB-INF/web.xml")
59
+ require 'rexml/document'
60
+ REXML::Document.new(@war.files["WEB-INF/web.xml"]).root.elements
61
+ end
62
+
63
+ it "should create a web.xml file" do
64
+ elements = expand_webxml
65
+ elements.to_a(
66
+ "context-param/param-name[text()='jruby.max.runtimes']"
67
+ ).should_not be_empty
68
+ elements.to_a(
69
+ "context-param/param-name[text()='jruby.max.runtimes']/../param-value"
70
+ ).first.text.should == "5"
71
+ end
72
+
73
+ it "should include custom context parameters in web.xml" do
74
+ @config.webxml.some.custom.config = "myconfig"
75
+ elements = expand_webxml
76
+ elements.to_a(
77
+ "context-param/param-name[text()='some.custom.config']"
78
+ ).should_not be_empty
79
+ elements.to_a(
80
+ "context-param/param-name[text()='some.custom.config']/../param-value"
81
+ ).first.text.should == "myconfig"
82
+ end
83
+
84
+ it "should allow one jndi resource to be included" do
85
+ @config.webxml.jndi = 'jndi/rails'
86
+ elements = expand_webxml
87
+ elements.to_a(
88
+ "resource-ref/res-ref-name[text()='jndi/rails']"
89
+ ).should_not be_empty
90
+ end
91
+
92
+ it "should allow multiple jndi resources to be included" do
93
+ @config.webxml.jndi = ['jndi/rails1', 'jndi/rails2']
94
+ elements = expand_webxml
95
+ elements.to_a(
96
+ "resource-ref/res-ref-name[text()='jndi/rails1']"
97
+ ).should_not be_empty
98
+ elements.to_a(
99
+ "resource-ref/res-ref-name[text()='jndi/rails2']"
100
+ ).should_not be_empty
101
+ end
102
+
103
+ it "should not include any ignored context parameters" do
104
+ @config.webxml.foo = "bar"
105
+ @config.webxml.ignored << "foo"
106
+ elements = expand_webxml
107
+ elements.to_a(
108
+ "context-param/param-name[text()='foo']"
109
+ ).should be_empty
110
+ elements.to_a(
111
+ "context-param/param-name[text()='ignored']"
112
+ ).should be_empty
113
+ elements.to_a(
114
+ "context-param/param-name[text()='jndi']"
115
+ ).should be_empty
116
+ end
117
+
118
+ it "should use a config/web.xml if it exists" do
119
+ mkdir_p "config"
120
+ touch "config/web.xml"
121
+ @war.apply(Warbler::Config.new)
122
+ @war.files["WEB-INF/web.xml"].should == "config/web.xml"
123
+ end
124
+
125
+ it "should use a config/web.xml.erb if it exists" do
126
+ mkdir_p "config"
127
+ File.open("config/web.xml.erb", "w") {|f| f << "Hi <%= webxml.public.root %>" }
128
+ @war.apply(Warbler::Config.new)
129
+ @war.files["WEB-INF/web.xml"].should_not be_nil
130
+ @war.files["WEB-INF/web.xml"].read.should == "Hi /"
131
+ end
132
+
133
+ it "should collect java libraries" do
134
+ @war.apply(@config)
135
+ file_list(%r{WEB-INF/lib/jruby-.*\.jar$}).should_not be_empty
136
+ end
137
+
138
+ it "should collect application files" do
139
+ @war.apply(@config)
140
+ file_list(%r{WEB-INF/app$}).should_not be_empty
141
+ file_list(%r{WEB-INF/config$}).should_not be_empty
142
+ file_list(%r{WEB-INF/lib$}).should_not be_empty
143
+ end
144
+
145
+ it "should accept an autodeploy directory where the war should be created" do
146
+ require 'tmpdir'
147
+ @config.autodeploy_dir = Dir::tmpdir
148
+ touch "file.txt"
149
+ @war.files["file.txt"] = "file.txt"
150
+ silence { @war.create(@config) }
151
+ File.exist?(File.join("#{Dir::tmpdir}","warbler.war")).should == true
152
+ end
153
+
154
+ it "should accept a custom manifest file" do
155
+ touch 'manifest'
156
+ @config.manifest_file = 'manifest'
157
+ @war.apply(@config)
158
+ @war.files['META-INF/MANIFEST.MF'].should == "manifest"
159
+ end
160
+
161
+ it "should be able to exclude files from the .war" do
162
+ @config.excludes += FileList['lib/tasks/utils.rake']
163
+ @war.apply(@config)
164
+ file_list(%r{lib/tasks/utils.rake}).should be_empty
165
+ end
166
+
167
+ it "should read configuration from #{Warbler::Config::FILE}" do
168
+ mkdir_p "config"
169
+ File.open(Warbler::Config::FILE, "w") do |dest|
170
+ contents =
171
+ File.open("#{Warbler::WARBLER_HOME}/warble.rb") do |src|
172
+ src.read
173
+ end
174
+ dest << contents.sub(/# config\.war_name/, 'config.war_name'
175
+ ).sub(/# config.gems << "tzinfo"/, 'config.gems = []')
176
+ end
177
+ t = Warbler::Task.new "warble"
178
+ t.config.war_name.should == "mywar"
179
+ end
180
+
181
+ it "should fail if a gem is requested that is not installed" do
182
+ @config.gems = ["nonexistent-gem"]
183
+ lambda {
184
+ Warbler::Task.new "warble", @config
185
+ @war.apply(@config)
186
+ }.should raise_error
187
+ end
188
+
189
+ it "should allow specification of dependency by Gem::Dependency" do
190
+ spec = mock "gem spec"
191
+ spec.stub!(:full_name).and_return "hpricot-0.6.157"
192
+ spec.stub!(:full_gem_path).and_return "hpricot-0.6.157"
193
+ spec.stub!(:loaded_from).and_return "hpricot.gemspec"
194
+ spec.stub!(:files).and_return ["Rakefile"]
195
+ spec.stub!(:dependencies).and_return []
196
+ Gem.source_index.should_receive(:search).and_return do |gem|
197
+ gem.name.should == "hpricot"
198
+ [spec]
199
+ end
200
+ @config.gems = [Gem::Dependency.new("hpricot", "> 0.6")]
201
+ @war.apply(@config)
202
+ end
203
+
204
+ it "should copy loose java classes to WEB-INF/classes" do
205
+ @config.java_classes = FileList["Rakefile"]
206
+ @war.apply(@config)
207
+ file_list(%r{WEB-INF/classes/Rakefile$}).should_not be_empty
208
+ end
209
+
210
+ def mock_rails_module
211
+ rails = Module.new
212
+ Object.const_set("Rails", rails)
213
+ version = Module.new
214
+ rails.const_set("VERSION", version)
215
+ version.const_set("STRING", "2.1.0")
216
+ rails
217
+ end
218
+
219
+ def mock_merb_module
220
+ merb = Module.new
221
+ silence { Object.const_set("Merb", merb) }
222
+ boot_loader = Module.new
223
+ merb.const_set("BootLoader", boot_loader)
224
+ merb.const_set("VERSION", "1.0")
225
+ dependencies = Class.new do
226
+ @@dependencies = []
227
+ def self.dependencies
228
+ @@dependencies
229
+ end
230
+ def self.dependencies=(deps)
231
+ @@dependencies = deps
232
+ end
233
+ end
234
+ boot_loader.const_set("Dependencies", dependencies)
235
+ dependencies
236
+ end
237
+
238
+ it "should auto-detect a Rails application" do
239
+ task :environment do
240
+ mock_rails_module
241
+ end
242
+ @config = Warbler::Config.new
243
+ @config.webxml.booter.should == :rails
244
+ @config.gems["rails"].should == "2.1.0"
245
+ end
246
+
247
+ it "should provide Rails gems by default, unless vendor/rails is present" do
248
+ rails = nil
249
+ task :environment do
250
+ rails = mock_rails_module
251
+ end
252
+
253
+ config = Warbler::Config.new
254
+ config.gems.should have_key("rails")
255
+
256
+ mkdir_p "vendor/rails"
257
+ config = Warbler::Config.new
258
+ config.gems.should be_empty
259
+
260
+ rm_rf "vendor/rails"
261
+ rails.stub!(:vendor_rails?).and_return true
262
+ config = Warbler::Config.new
263
+ config.gems.should be_empty
264
+ end
265
+
266
+ it "should not try to autodetect frameworks when Warbler.framework_detection is false" do
267
+ begin
268
+ Warbler.framework_detection = false
269
+ task :environment
270
+ config = Warbler::Config.new
271
+ config.webxml.booter.should_not == :rails
272
+ t = Rake::Task['environment']
273
+ class << t; public :instance_variable_get; end
274
+ t.instance_variable_get("@already_invoked").should == false
275
+ ensure
276
+ Warbler.framework_detection = true
277
+ end
278
+ end
279
+
280
+ it "should auto-detect a Merb application" do
281
+ task :merb_env do
282
+ mock_merb_module
283
+ end
284
+ @config = Warbler::Config.new
285
+ @config.webxml.booter.should == :merb
286
+ @config.gems.keys.should_not include("rails")
287
+ end
288
+
289
+ it "should auto-detect a Rack application with a config.ru file" do
290
+ rackup = "run Proc.new {|env| [200, {}, ['Hello World']]}"
291
+ File.open("config.ru", "w") {|f| f << rackup }
292
+ @config = Warbler::Config.new
293
+ @config.webxml.booter.should == :rack
294
+ @config.webxml.rackup.should == rackup
295
+ end
296
+
297
+ it "should automatically add Rails.configuration.gems to the list of gems" do
298
+ task :environment do
299
+ rails = mock_rails_module
300
+ config = mock "config"
301
+ rails.stub!(:configuration).and_return(config)
302
+ gem = mock "gem"
303
+ gem.stub!(:name).and_return "hpricot"
304
+ gem.stub!(:requirement).and_return Gem::Requirement.new("=0.6")
305
+ config.stub!(:gems).and_return [gem]
306
+ end
307
+
308
+ @config = Warbler::Config.new
309
+ @config.webxml.booter.should == :rails
310
+ @config.gems.keys.should include(Gem::Dependency.new("hpricot", Gem::Requirement.new("=0.6")))
311
+ end
312
+
313
+ it "should automatically add Merb::BootLoader::Dependencies.dependencies to the list of gems" do
314
+ task :merb_env do
315
+ deps = mock_merb_module
316
+ deps.dependencies = [Gem::Dependency.new("merb-core", ">= 1.0.6.1")]
317
+ end
318
+ @config = Warbler::Config.new
319
+ @config.webxml.booter.should == :merb
320
+ @config.gems.keys.should include(Gem::Dependency.new("merb-core", ">= 1.0.6.1"))
321
+ end
322
+
323
+ it "should skip Merb development dependencies" do
324
+ task :merb_env do
325
+ deps = mock_merb_module
326
+ deps.dependencies = [Gem::Dependency.new("rake", "= #{RAKEVERSION}", :development)]
327
+ end
328
+ @war.apply(Warbler::Config.new)
329
+ file_list(/rake-#{RAKEVERSION}/).should be_empty
330
+ end
331
+
332
+ it "should warn about using Merb < 1.0" do
333
+ task :merb_env do
334
+ silence { Object.const_set("Merb", Module.new) }
335
+ end
336
+ @config = silence { Warbler::Config.new }
337
+ @config.webxml.booter.should == :merb
338
+ end
339
+
340
+ it "should set the jruby max runtimes to 1 when MT Rails is detected" do
341
+ task :environment do
342
+ rails = mock_rails_module
343
+ config = mock "config"
344
+ rails.stub!(:configuration).and_return(config)
345
+ config.stub!(:threadsafe!)
346
+ config.should_receive(:allow_concurrency).and_return true
347
+ config.should_receive(:preload_frameworks).and_return true
348
+ end
349
+ @config = Warbler::Config.new
350
+ @config.webxml.booter.should == :rails
351
+ @config.webxml.jruby.max.runtimes.should == 1
352
+ end
353
+
354
+ it "should skip directories that don't exist in config.dirs and print a warning" do
355
+ @config.dirs = %w(lib notexist)
356
+ silence { @war.apply(@config) }
357
+ file_list(%r{WEB-INF/lib}).should_not be_empty
358
+ file_list(%r{WEB-INF/notexist}).should be_empty
359
+ end
360
+
361
+ it "should write gems to location specified by gem_path" do
362
+ @config = Warbler::Config.new {|c| c.gem_path = "/WEB-INF/jewels"; c.gems << 'rake' }
363
+ elements = expand_webxml
364
+ file_list(%r{WEB-INF/jewels}).should_not be_empty
365
+ elements.to_a(
366
+ "context-param/param-name[text()='gem.path']"
367
+ ).should_not be_empty
368
+ elements.to_a(
369
+ "context-param/param-name[text()='gem.path']/../param-value"
370
+ ).first.text.should == "/WEB-INF/jewels"
371
+
372
+ end
373
+
374
+ it "should detect a Bundler Gemfile and process only its gems" do
375
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
376
+ @war.apply(Warbler::Config.new {|c| c.gems << "rake"})
377
+ file_list(%r{WEB-INF/Gemfile}).should_not be_empty
378
+ file_list(%r{WEB-INF/gems/specifications/rspec}).should_not be_empty
379
+ file_list(%r{WEB-INF/gems/specifications/rake}).should be_empty
380
+ end
381
+
382
+ it "should write a Bundler environment file into the war" do
383
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
384
+ @war.apply(Warbler::Config.new)
385
+ file_list(%r{WEB-INF/\.bundle/environment\.rb}).should_not be_empty
386
+ end
387
+
388
+ it "should allow overriding of the gem path when using Bundler" do
389
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
390
+ @war.apply(Warbler::Config.new {|c| c.gem_path = '/WEB-INF/jewels' })
391
+ file_list(%r{WEB-INF/jewels/specifications/rspec}).should_not be_empty
392
+ IO.readlines(".bundle/war-environment.rb").grep(/rspec/).last.should =~ %r{jewels/specifications}m
393
+ end
394
+
395
+ it "should not let the framework load Bundler from the locked environment" do
396
+ task :environment do
397
+ File.exist?('.bundle/environment.rb').should_not be_true
398
+ mock_rails_module
399
+ end
400
+
401
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
402
+ `ruby -S bundle lock`
403
+ File.exist?('.bundle/environment.rb').should be_true
404
+ @war.apply(Warbler::Config.new)
405
+ hash = eval("[" + IO.readlines(".bundle/environment.rb").grep(/rspec/).last + "]").first
406
+ hash[:load_paths].each {|p| File.exist?(p).should be_true }
407
+ end
408
+
409
+ it "should allow adding additional WEB-INF files via config.webinf_files" do
410
+ File.open("myserver-web.xml", "w") do |f|
411
+ f << "<web-app></web-app>"
412
+ end
413
+ @war.apply(Warbler::Config.new {|c| c.webinf_files = FileList['myserver-web.xml'] })
414
+ file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
415
+ end
416
+
417
+ it "should allow expanding of additional WEB-INF files via config.webinf_files" do
418
+ File.open("myserver-web.xml.erb", "w") do |f|
419
+ f << "<web-app><%= webxml.rails.env %></web-app>"
420
+ end
421
+ @war.apply(Warbler::Config.new {|c| c.webinf_files = FileList['myserver-web.xml.erb'] })
422
+ file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
423
+ @war.files['WEB-INF/myserver-web.xml'].read.should =~ /web-app.*production/
424
+ end
425
+ end
@@ -3,9 +3,6 @@
3
3
 
4
4
  # Warbler web application assembly configuration file
5
5
  Warbler::Config.new do |config|
6
- # Temporary directory where the application is staged
7
- # config.staging_dir = "tmp/war"
8
-
9
6
  # Application directories to be included in the webapp.
10
7
  config.dirs = %w(app config lib log vendor tmp)
11
8
 
@@ -30,9 +27,28 @@ Warbler::Config.new do |config|
30
27
  # for details of how to specify a pathmap.
31
28
  # config.pathmaps.java_classes << "%{target/classes/,}p"
32
29
 
33
- # Gems to be included. You need to tell Warbler which gems your application needs
34
- # so that they can be packaged in the war file.
35
- # The Rails gems are included by default unless the vendor/rails directory is present.
30
+ # Path to the pre-bundled gem directory inside the war file. Default
31
+ # is 'WEB-INF/gems'. Specify path if gems are already bundled
32
+ # before running Warbler. This also sets 'gem.path' inside web.xml.
33
+ # config.gem_path = "WEB-INF/vendor/bundler_gems"
34
+
35
+ # Bundler support is built-in. If Warbler finds a Gemfile in the
36
+ # project directory, it will be used to collect the gems to bundle
37
+ # in your application. If you wish to explicitly disable this
38
+ # functionality, uncomment here.
39
+ # config.bundler = false
40
+
41
+ # Files for WEB-INF directory (next to web.xml). This contains
42
+ # web.xml by default. If there is an .erb-File it will be processed
43
+ # with webxml-config. You may want to exclude this file via
44
+ # config.excludes.
45
+ # config.webinf_files += FileList["jboss-web.xml"]
46
+
47
+ # Other gems to be included. You need to tell Warbler which gems
48
+ # your application needs so that they can be packaged in the war
49
+ # file.
50
+ # The Rails gems are included by default unless the vendor/rails
51
+ # directory is present.
36
52
  # config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl"]
37
53
  # config.gems << "tzinfo"
38
54
 
@@ -48,8 +64,9 @@ Warbler::Config.new do |config|
48
64
  # config.gems << /^merb-/
49
65
  # config.gems << Gem::Dependency.new("merb-core", "= 0.9.3")
50
66
 
51
- # Include gem dependencies not mentioned specifically
52
- config.gem_dependencies = true
67
+ # Include gem dependencies not mentioned specifically. Default is true, uncomment
68
+ # to turn off.
69
+ # config.gem_dependencies = false
53
70
 
54
71
  # Files to be included in the root of the webapp. Note that files in public
55
72
  # will have the leading 'public/' part of the path stripped during staging.
@@ -58,6 +75,9 @@ Warbler::Config.new do |config|
58
75
  # Pathmaps for controlling how public HTML files are copied into the .war
59
76
  # config.pathmaps.public_html = ["%{public/,}p"]
60
77
 
78
+ # Pathmaps for controlling how application files are copied into the .war
79
+ # config.pathmaps.application = ["WEB-INF/%p"]
80
+
61
81
  # Name of the war file (without the .war) -- defaults to the basename
62
82
  # of RAILS_ROOT
63
83
  # config.war_name = "mywar"
@@ -69,7 +89,7 @@ Warbler::Config.new do |config|
69
89
  # Value of RAILS_ENV for the webapp -- default as shown below
70
90
  # config.webxml.rails.env = ENV['RAILS_ENV'] || 'production'
71
91
 
72
- # Application booter to use, one of :rack, :rails, or :merb. (Default :rails)
92
+ # Application booter to use, one of :rack, :rails, or :merb (autodetected by default)
73
93
  # config.webxml.booter = :rails
74
94
 
75
95
  # When using the :rack booter, "Rackup" script to use.