rdmopensource-warbler 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +11 -0
- data/History.txt +167 -0
- data/LICENSE.txt +26 -0
- data/Manifest.txt +48 -0
- data/README.txt +194 -0
- data/Rakefile +92 -0
- data/bin/warble +11 -0
- data/ext/Main.java +110 -0
- data/ext/WarblerWar.java +115 -0
- data/ext/WarblerWarService.java +17 -0
- data/lib/warbler.rb +37 -0
- data/lib/warbler/application.rb +67 -0
- data/lib/warbler/config.rb +349 -0
- data/lib/warbler/gems.rb +37 -0
- data/lib/warbler/runtime.rb +44 -0
- data/lib/warbler/task.rb +224 -0
- data/lib/warbler/version.rb +10 -0
- data/lib/warbler/war.rb +226 -0
- data/lib/warbler_war.jar +0 -0
- data/spec/sample/app/controllers/application.rb +15 -0
- data/spec/sample/app/helpers/application_helper.rb +3 -0
- data/spec/sample/config/boot.rb +109 -0
- data/spec/sample/config/database.yml +19 -0
- data/spec/sample/config/environment.rb +67 -0
- data/spec/sample/config/environments/development.rb +17 -0
- data/spec/sample/config/environments/production.rb +22 -0
- data/spec/sample/config/environments/test.rb +22 -0
- data/spec/sample/config/initializers/inflections.rb +10 -0
- data/spec/sample/config/initializers/mime_types.rb +5 -0
- data/spec/sample/config/initializers/new_rails_defaults.rb +15 -0
- data/spec/sample/config/routes.rb +41 -0
- data/spec/sample/lib/tasks/utils.rake +0 -0
- data/spec/sample/public/404.html +30 -0
- data/spec/sample/public/422.html +30 -0
- data/spec/sample/public/500.html +30 -0
- data/spec/sample/public/favicon.ico +0 -0
- data/spec/sample/public/index.html +274 -0
- data/spec/sample/public/robots.txt +5 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/warbler/application_spec.rb +93 -0
- data/spec/warbler/config_spec.rb +112 -0
- data/spec/warbler/gems_spec.rb +40 -0
- data/spec/warbler/task_spec.rb +146 -0
- data/spec/warbler/war_spec.rb +441 -0
- data/warble.rb +121 -0
- data/web.xml.erb +32 -0
- metadata +202 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 Engine Yard, Inc.
|
3
|
+
# Copyright (c) 2007-2009 Sun Microsystems, Inc.
|
4
|
+
# This source code is available under the MIT license.
|
5
|
+
# See the file LICENSE.txt for details.
|
6
|
+
#++
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'spec'
|
10
|
+
|
11
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
12
|
+
require 'warbler'
|
13
|
+
|
14
|
+
raise %{Error: detected running Warbler specs in a Rails app;
|
15
|
+
Warbler specs are destructive to application directories.} if File.directory?("app")
|
16
|
+
|
17
|
+
def silence(io = nil)
|
18
|
+
require 'stringio'
|
19
|
+
old_stdout = $stdout
|
20
|
+
old_stderr = $stderr
|
21
|
+
$stdout = io || StringIO.new
|
22
|
+
$stderr = io || StringIO.new
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
$stdout = old_stdout
|
26
|
+
$stderr = old_stderr
|
27
|
+
end
|
28
|
+
|
29
|
+
def capture(&block)
|
30
|
+
require 'stringio'
|
31
|
+
io = StringIO.new
|
32
|
+
silence(io, &block)
|
33
|
+
io.string
|
34
|
+
end
|
35
|
+
|
36
|
+
Spec::Runner.configure do |config|
|
37
|
+
config.after(:each) do
|
38
|
+
class << Object
|
39
|
+
public :remove_const
|
40
|
+
end
|
41
|
+
Object.remove_const("Rails") rescue nil
|
42
|
+
rm_rf "vendor"
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 Engine Yard, Inc.
|
3
|
+
# Copyright (c) 2007-2009 Sun Microsystems, Inc.
|
4
|
+
# This source code is available under the MIT license.
|
5
|
+
# See the file LICENSE.txt for details.
|
6
|
+
#++
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
9
|
+
|
10
|
+
describe Warbler::Application do
|
11
|
+
before :each do
|
12
|
+
verbose(false)
|
13
|
+
@pwd = Dir.getwd
|
14
|
+
Dir.chdir("spec/sample")
|
15
|
+
@argv = ARGV.dup
|
16
|
+
ARGV.clear
|
17
|
+
@app = Rake.application
|
18
|
+
rm_f "config/warble.rb"
|
19
|
+
@detection = Warbler.framework_detection
|
20
|
+
Warbler.framework_detection = false
|
21
|
+
end
|
22
|
+
|
23
|
+
after :each do
|
24
|
+
Rake.application = @app
|
25
|
+
Warbler.project_application = nil
|
26
|
+
Warbler.application = nil
|
27
|
+
Warbler.framework_detection = @detection
|
28
|
+
@argv.reverse.each {|a| ARGV.unshift a}
|
29
|
+
rm_rf FileList['vendor/plugins/warbler']
|
30
|
+
Dir.chdir(@pwd)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be able to list its tasks" do
|
34
|
+
ARGV.unshift "-T"
|
35
|
+
output = capture do
|
36
|
+
Warbler::Application.new.run
|
37
|
+
end
|
38
|
+
output.should =~ /warble war\s/
|
39
|
+
output.should =~ /warble war:clean/
|
40
|
+
output.should =~ /warble war:debug/
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should display the version" do
|
44
|
+
ARGV.unshift "version"
|
45
|
+
capture { Warbler::Application.new.run }.should =~ /#{Warbler::VERSION}/
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should copy a fresh config file into place" do
|
49
|
+
File.exists?("config/warble.rb").should_not be_true
|
50
|
+
ARGV.unshift "config"
|
51
|
+
silence { Warbler::Application.new.run }
|
52
|
+
File.exists?("config/warble.rb").should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should refuse to copy over an existing config file" do
|
56
|
+
touch "config/warble.rb"
|
57
|
+
ARGV.unshift "config"
|
58
|
+
capture { Warbler::Application.new.run }.should =~ /already exists/
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should complain if the config directory is missing" do
|
62
|
+
begin
|
63
|
+
mv "config", "config-tmp"
|
64
|
+
ARGV.unshift "config"
|
65
|
+
capture { Warbler::Application.new.run }.should =~ /missing/
|
66
|
+
ensure
|
67
|
+
mv "config-tmp", "config"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should refuse to pluginize if the vendor/plugins/warbler directory exists" do
|
72
|
+
mkdir_p "vendor/plugins/warbler"
|
73
|
+
ARGV.unshift "pluginize"
|
74
|
+
silence { Warbler::Application.new.run }
|
75
|
+
File.exist?("vendor/plugins/warbler/tasks/warbler.rake").should_not be_true
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should define a pluginize task for adding the tasks to a Rails application" do
|
79
|
+
ARGV.unshift "pluginize"
|
80
|
+
Warbler::Application.new.run
|
81
|
+
File.exist?("vendor/plugins/warbler/tasks/warbler.rake").should be_true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should provide a means to load the project Rakefile" do
|
85
|
+
Warbler::Application.new.load_project_rakefile
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should define a gemjar task for setting up gem packaging inside a jar" do
|
89
|
+
ARGV.unshift "gemjar"
|
90
|
+
Warbler::Application.new.run
|
91
|
+
Rake::Task['war:jar'].prerequisites.should include('war:make_gemjar')
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 Engine Yard, Inc.
|
3
|
+
# Copyright (c) 2007-2009 Sun Microsystems, Inc.
|
4
|
+
# This source code is available under the MIT license.
|
5
|
+
# See the file LICENSE.txt for details.
|
6
|
+
#++
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
9
|
+
|
10
|
+
describe Warbler::Config do
|
11
|
+
before :each do
|
12
|
+
verbose(false)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have suitable default values" do
|
16
|
+
config = Warbler::Config.new
|
17
|
+
config.dirs.should include(*Warbler::Config::TOP_DIRS.select{|d| File.directory?(d)})
|
18
|
+
config.includes.should be_empty
|
19
|
+
config.java_libs.should_not be_empty
|
20
|
+
config.war_name.size.should > 0
|
21
|
+
config.webxml.should be_kind_of(OpenStruct)
|
22
|
+
config.pathmaps.should be_kind_of(OpenStruct)
|
23
|
+
config.pathmaps.public_html.should == ["%{public/,}p"]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should allow configuration through an initializer block" do
|
27
|
+
config = Warbler::Config.new do |c|
|
28
|
+
c.war_name = "mywar"
|
29
|
+
end
|
30
|
+
config.war_name.should == "mywar"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should allow gems to be added/changed with =, +=, -=, <<" do
|
34
|
+
config = Warbler::Config.new do |c|
|
35
|
+
c.gems += ["activerecord-jdbc-adapter"]
|
36
|
+
c.gems -= ["rails"]
|
37
|
+
c.gems << "tzinfo"
|
38
|
+
c.gems = ["camping"]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should exclude log files by default" do
|
43
|
+
mkdir_p "vendor"
|
44
|
+
touch "vendor/test.log"
|
45
|
+
config = Warbler::Config.new
|
46
|
+
config.exclude_logs.should == true
|
47
|
+
config.excludes.include?("vendor/test.log").should == true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should include log files if exclude_logs is false" do
|
51
|
+
mkdir_p "vendor"
|
52
|
+
touch "vendor/test.log"
|
53
|
+
config = Warbler::Config.new {|c| c.exclude_logs = false }
|
54
|
+
config.exclude_logs.should == false
|
55
|
+
config.excludes.include?("vendor/test.log").should == false
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should exclude Warbler itself when run as a plugin" do
|
59
|
+
config = Warbler::Config.new
|
60
|
+
config.excludes.include?("vendor/plugins/warbler").should == false
|
61
|
+
config = Warbler::Config.new File.join(Dir.getwd, "vendor", "plugins", "warbler")
|
62
|
+
config.excludes.include?("vendor/plugins/warbler").should == true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should generate context parameters from the webxml openstruct" do
|
66
|
+
config = Warbler::Config.new
|
67
|
+
config.webxml.a.b.c = "123"
|
68
|
+
config.webxml.com.example.config = "blah"
|
69
|
+
config.webxml.rails.env = 'staging'
|
70
|
+
config.webxml.jruby.min.runtimes = 2
|
71
|
+
config.webxml.jruby.max.runtimes = 4
|
72
|
+
config.webxml['org']['jruby']['rack'] = "rails"
|
73
|
+
params = config.webxml.context_params
|
74
|
+
params.should have_key('a.b.c')
|
75
|
+
params.should have_key('rails.env')
|
76
|
+
params.should have_key('jruby.min.runtimes')
|
77
|
+
params.should have_key('jruby.max.runtimes')
|
78
|
+
params['a.b.c'].should == "123"
|
79
|
+
params['com.example.config'].should == "blah"
|
80
|
+
params['rails.env'].should == "staging"
|
81
|
+
params['jruby.min.runtimes'].should == "2"
|
82
|
+
params['jruby.max.runtimes'].should == "4"
|
83
|
+
params['org.jruby.rack'].should == "rails"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should determine the context listener from the webxml.booter parameter" do
|
87
|
+
config = Warbler::Config.new
|
88
|
+
config.webxml.booter = :rack
|
89
|
+
config.webxml.servlet_context_listener.should == "org.jruby.rack.RackServletContextListener"
|
90
|
+
config = Warbler::Config.new
|
91
|
+
config.webxml.booter = :merb
|
92
|
+
config.webxml.servlet_context_listener.should == "org.jruby.rack.merb.MerbServletContextListener"
|
93
|
+
config = Warbler::Config.new
|
94
|
+
config.webxml.servlet_context_listener.should == "org.jruby.rack.rails.RailsServletContextListener"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should not include ignored webxml keys in the context params hash" do
|
98
|
+
Warbler::Config.new.webxml.context_params.should_not have_key('ignored')
|
99
|
+
Warbler::Config.new.webxml.context_params.should_not have_key('jndi')
|
100
|
+
Warbler::Config.new.webxml.context_params.should_not have_key('booter')
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should have a helpful string representation for an empty key" do
|
104
|
+
Warbler::Config.new.webxml.missing_key.to_s.should =~ /No value for 'missing_key' found/
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should HTML-escape all webxml keys and values" do
|
108
|
+
config = Warbler::Config.new
|
109
|
+
config.webxml.a["b&"].c = "123<hi>456"
|
110
|
+
config.webxml.context_params['a.b&.c'].should == "123<hi>456"
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 Engine Yard, Inc.
|
3
|
+
# Copyright (c) 2007-2009 Sun Microsystems, Inc.
|
4
|
+
# This source code is available under the MIT license.
|
5
|
+
# See the file LICENSE.txt for details.
|
6
|
+
#++
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
9
|
+
|
10
|
+
describe Warbler::Gems do
|
11
|
+
it "should accept a hash for initialization" do
|
12
|
+
gems = Warbler::Gems.new({"actionpack" => "1.2.3"})
|
13
|
+
gems.should have_key("actionpack")
|
14
|
+
gems["actionpack"].should == "1.2.3"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept an array for initialization" do
|
18
|
+
gems = Warbler::Gems.new ["activerecord"]
|
19
|
+
gems.should have_key("activerecord")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow gems with a version" do
|
23
|
+
gems = Warbler::Gems.new
|
24
|
+
gems["actionpack"] = "> 1.2.3"
|
25
|
+
gems["actionpack"].should == "> 1.2.3"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should allow gems without an explicit version" do
|
29
|
+
gems = Warbler::Gems.new
|
30
|
+
gems << "actionpack"
|
31
|
+
gems.should have_key("actionpack")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should allow to add gems" do
|
35
|
+
gems = Warbler::Gems.new
|
36
|
+
gems << "rails"
|
37
|
+
gems += ["activerecord-jdbcmysql-adapter", "jdbc-mysql", "jruby-openssl"]
|
38
|
+
["rails", "activerecord-jdbcmysql-adapter", "jdbc-mysql", "jruby-openssl"].each {|g| gems.should have_key(g)}
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 Engine Yard, Inc.
|
3
|
+
# Copyright (c) 2007-2009 Sun Microsystems, Inc.
|
4
|
+
# This source code is available under the MIT license.
|
5
|
+
# See the file LICENSE.txt for details.
|
6
|
+
#++
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
9
|
+
|
10
|
+
describe Warbler::Task do
|
11
|
+
before(:each) do
|
12
|
+
@rake = Rake::Application.new
|
13
|
+
Rake.application = @rake
|
14
|
+
verbose(false)
|
15
|
+
@pwd = Dir.getwd
|
16
|
+
Dir.chdir("spec/sample")
|
17
|
+
mkdir_p "log"
|
18
|
+
touch "log/test.log"
|
19
|
+
@config = Warbler::Config.new do |config|
|
20
|
+
config.war_name = "warbler"
|
21
|
+
config.gems = ["rake"]
|
22
|
+
config.webxml.jruby.max.runtimes = 5
|
23
|
+
end
|
24
|
+
@task = Warbler::Task.new "warble", @config
|
25
|
+
end
|
26
|
+
|
27
|
+
after(:each) do
|
28
|
+
Rake::Task["warble:clean"].invoke
|
29
|
+
rm_rf "log"
|
30
|
+
rm_f FileList["config.ru", "*web.xml", "config/web.xml*", "config/warble.rb",
|
31
|
+
"config/special.txt", "config/link.txt", "tmp/gems.jar",
|
32
|
+
"file.txt", 'Gemfile', 'lib/rakelib']
|
33
|
+
Dir.chdir(@pwd)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should define a clean task for removing the war file" do
|
37
|
+
war_file = "#{@config.war_name}.war"
|
38
|
+
touch war_file
|
39
|
+
Rake::Task["warble:clean"].invoke
|
40
|
+
File.exist?(war_file).should == false
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should define a make_gemjar task for storing gems in a jar file" do
|
44
|
+
silence { Rake::Task["warble:make_gemjar"].invoke }
|
45
|
+
File.exist?("tmp/gems.jar").should == true
|
46
|
+
@task.war.files.keys.should_not include(%r{WEB-INF\/gems})
|
47
|
+
@task.war.files.keys.should include("WEB-INF/lib/gems.jar")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should define a war task for bundling up everything" do
|
51
|
+
files_ran = false; task "warble:files" do; files_ran = true; end
|
52
|
+
jar_ran = false; task "warble:jar" do; jar_ran = true; end
|
53
|
+
silence { Rake::Task["warble"].invoke }
|
54
|
+
files_ran.should == true
|
55
|
+
jar_ran.should == true
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should define a jar task for creating the .war" do
|
59
|
+
touch "file.txt"
|
60
|
+
@task.war.files["file.txt"] = "file.txt"
|
61
|
+
silence { Rake::Task["warble:jar"].invoke }
|
62
|
+
File.exist?("#{@config.war_name}.war").should == true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should invoke feature tasks configured in config.features" do
|
66
|
+
@config.features << "gemjar"
|
67
|
+
silence { Rake::Task["warble"].invoke }
|
68
|
+
@task.war.files.keys.should include("WEB-INF/lib/gems.jar")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should warn and skip unknown features configured in config.features" do
|
72
|
+
@config.features << "bogus"
|
73
|
+
capture { Rake::Task["warble"].invoke }.should =~ /unknown feature `bogus'/
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should define an executable task for embedding a server in the war file" do
|
77
|
+
silence { Rake::Task["warble:executable"].invoke }
|
78
|
+
@task.war.files.keys.should include('WEB-INF/winstone.jar')
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be able to define all tasks successfully" do
|
82
|
+
Warbler::Task.new "warble", @config
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should compile any ruby files specified" do
|
86
|
+
@config.compiled_ruby_files = FileList["app/helpers/application_helper.rb"]
|
87
|
+
silence { Rake::Task["warble"].invoke }
|
88
|
+
|
89
|
+
java_class_magic_number = [0xCA,0xFE,0xBA,0xBE].map { |magic_char| magic_char.chr }.join
|
90
|
+
|
91
|
+
Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
|
92
|
+
java_class_header = zf.get_input_stream('WEB-INF/app/helpers/application_helper.class') {|io| io.read }[0..3]
|
93
|
+
ruby_class_definition = zf.get_input_stream('WEB-INF/app/helpers/application_helper.rb') {|io| io.read }
|
94
|
+
|
95
|
+
java_class_header.should == java_class_magic_number
|
96
|
+
ruby_class_definition.should == %{require __FILE__.sub(/.rb$/, '.class')}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should process symlinks by storing a file in the archive that has the same contents as the source" do
|
101
|
+
File.open("config/special.txt", "wb") {|f| f << "special"}
|
102
|
+
Dir.chdir("config") { ln_s "special.txt", "link.txt" }
|
103
|
+
silence { Rake::Task["warble"].invoke }
|
104
|
+
Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
|
105
|
+
special = zf.get_input_stream('WEB-INF/config/special.txt') {|io| io.read }
|
106
|
+
link = zf.get_input_stream('WEB-INF/config/link.txt') {|io| io.read }
|
107
|
+
link.should == special
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should process directory symlinks by copying the whole subdirectory" do
|
112
|
+
Dir.chdir("lib") { ln_s "tasks", "rakelib" }
|
113
|
+
silence { Rake::Task["warble"].invoke }
|
114
|
+
Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
|
115
|
+
zf.find_entry("WEB-INF/lib/tasks/utils.rake").should_not be_nil
|
116
|
+
zf.find_entry("WEB-INF/lib/rakelib/").should_not be_nil
|
117
|
+
zf.find_entry("WEB-INF/lib/rakelib/utils.rake").should_not be_nil if defined?(JRUBY_VERSION)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should use a Bundler Gemfile to include gems" do
|
122
|
+
File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
|
123
|
+
@config.bundler = true
|
124
|
+
@config.send(:detect_bundler_gems)
|
125
|
+
silence { Rake::Task["warble"].invoke }
|
126
|
+
Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
|
127
|
+
rspec_version = @config.gems.keys.detect {|k| k.name == 'rspec'}.version
|
128
|
+
zf.find_entry("WEB-INF/gems/specifications/rspec-#{rspec_version}.gemspec").should_not be_nil
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "Debug targets" do
|
134
|
+
before(:each) do
|
135
|
+
@rake = Rake::Application.new
|
136
|
+
Rake.application = @rake
|
137
|
+
verbose(false)
|
138
|
+
silence { Warbler::Task.new :war, Object.new }
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should print out lists of files" do
|
142
|
+
capture { Rake::Task["war:debug:includes"].invoke }.should =~ /include/
|
143
|
+
capture { Rake::Task["war:debug:excludes"].invoke }.should =~ /exclude/
|
144
|
+
capture { Rake::Task["war:debug"].invoke }.should =~ /Config/
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,441 @@
|
|
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 not add a manifest if one already exists" do
|
162
|
+
@war.files['META-INF/MANIFEST.MF'] = 'manifest'
|
163
|
+
@war.add_manifest(@config)
|
164
|
+
@war.files['META-INF/MANIFEST.MF'].should == "manifest"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should be able to exclude files from the .war" do
|
168
|
+
@config.excludes += FileList['lib/tasks/utils.rake']
|
169
|
+
@war.apply(@config)
|
170
|
+
file_list(%r{lib/tasks/utils.rake}).should be_empty
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should read configuration from #{Warbler::Config::FILE}" do
|
174
|
+
mkdir_p "config"
|
175
|
+
File.open(Warbler::Config::FILE, "w") do |dest|
|
176
|
+
contents =
|
177
|
+
File.open("#{Warbler::WARBLER_HOME}/warble.rb") do |src|
|
178
|
+
src.read
|
179
|
+
end
|
180
|
+
dest << contents.sub(/# config\.war_name/, 'config.war_name'
|
181
|
+
).sub(/# config.gems << "tzinfo"/, 'config.gems = []')
|
182
|
+
end
|
183
|
+
t = Warbler::Task.new "warble"
|
184
|
+
t.config.war_name.should == "mywar"
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should fail if a gem is requested that is not installed" do
|
188
|
+
@config.gems = ["nonexistent-gem"]
|
189
|
+
lambda {
|
190
|
+
Warbler::Task.new "warble", @config
|
191
|
+
@war.apply(@config)
|
192
|
+
}.should raise_error
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should allow specification of dependency by Gem::Dependency" do
|
196
|
+
spec = mock "gem spec"
|
197
|
+
spec.stub!(:full_name).and_return "hpricot-0.6.157"
|
198
|
+
spec.stub!(:full_gem_path).and_return "hpricot-0.6.157"
|
199
|
+
spec.stub!(:loaded_from).and_return "hpricot.gemspec"
|
200
|
+
spec.stub!(:files).and_return ["Rakefile"]
|
201
|
+
spec.stub!(:dependencies).and_return []
|
202
|
+
Gem.source_index.should_receive(:search).and_return do |gem|
|
203
|
+
gem.name.should == "hpricot"
|
204
|
+
[spec]
|
205
|
+
end
|
206
|
+
@config.gems = [Gem::Dependency.new("hpricot", "> 0.6")]
|
207
|
+
@war.apply(@config)
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should copy loose java classes to WEB-INF/classes" do
|
211
|
+
@config.java_classes = FileList["Rakefile"]
|
212
|
+
@war.apply(@config)
|
213
|
+
file_list(%r{WEB-INF/classes/Rakefile$}).should_not be_empty
|
214
|
+
end
|
215
|
+
|
216
|
+
def mock_rails_module
|
217
|
+
rails = Module.new
|
218
|
+
Object.const_set("Rails", rails)
|
219
|
+
version = Module.new
|
220
|
+
rails.const_set("VERSION", version)
|
221
|
+
version.const_set("STRING", "2.1.0")
|
222
|
+
rails
|
223
|
+
end
|
224
|
+
|
225
|
+
def mock_merb_module
|
226
|
+
merb = Module.new
|
227
|
+
silence { Object.const_set("Merb", merb) }
|
228
|
+
boot_loader = Module.new
|
229
|
+
merb.const_set("BootLoader", boot_loader)
|
230
|
+
merb.const_set("VERSION", "1.0")
|
231
|
+
dependencies = Class.new do
|
232
|
+
@@dependencies = []
|
233
|
+
def self.dependencies
|
234
|
+
@@dependencies
|
235
|
+
end
|
236
|
+
def self.dependencies=(deps)
|
237
|
+
@@dependencies = deps
|
238
|
+
end
|
239
|
+
end
|
240
|
+
boot_loader.const_set("Dependencies", dependencies)
|
241
|
+
dependencies
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should auto-detect a Rails application" do
|
245
|
+
task :environment do
|
246
|
+
mock_rails_module
|
247
|
+
end
|
248
|
+
@config = Warbler::Config.new
|
249
|
+
@config.webxml.booter.should == :rails
|
250
|
+
@config.gems["rails"].should == "2.1.0"
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should provide Rails gems by default, unless vendor/rails is present" do
|
254
|
+
rails = nil
|
255
|
+
task :environment do
|
256
|
+
rails = mock_rails_module
|
257
|
+
end
|
258
|
+
|
259
|
+
config = Warbler::Config.new
|
260
|
+
config.gems.should have_key("rails")
|
261
|
+
|
262
|
+
mkdir_p "vendor/rails"
|
263
|
+
config = Warbler::Config.new
|
264
|
+
config.gems.should be_empty
|
265
|
+
|
266
|
+
rm_rf "vendor/rails"
|
267
|
+
rails.stub!(:vendor_rails?).and_return true
|
268
|
+
config = Warbler::Config.new
|
269
|
+
config.gems.should be_empty
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should not try to autodetect frameworks when Warbler.framework_detection is false" do
|
273
|
+
begin
|
274
|
+
Warbler.framework_detection = false
|
275
|
+
task :environment
|
276
|
+
config = Warbler::Config.new
|
277
|
+
config.webxml.booter.should_not == :rails
|
278
|
+
t = Rake::Task['environment']
|
279
|
+
class << t; public :instance_variable_get; end
|
280
|
+
t.instance_variable_get("@already_invoked").should == false
|
281
|
+
ensure
|
282
|
+
Warbler.framework_detection = true
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should auto-detect a Merb application" do
|
287
|
+
task :merb_env do
|
288
|
+
mock_merb_module
|
289
|
+
end
|
290
|
+
@config = Warbler::Config.new
|
291
|
+
@config.webxml.booter.should == :merb
|
292
|
+
@config.gems.keys.should_not include("rails")
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should auto-detect a Rack application with a config.ru file" do
|
296
|
+
rackup = "run Proc.new {|env| [200, {}, ['Hello World']]}"
|
297
|
+
File.open("config.ru", "w") {|f| f << rackup }
|
298
|
+
@config = Warbler::Config.new
|
299
|
+
@war.apply(@config)
|
300
|
+
@war.files['WEB-INF/config.ru'].should == 'config.ru'
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should automatically add Rails.configuration.gems to the list of gems" do
|
304
|
+
task :environment do
|
305
|
+
rails = mock_rails_module
|
306
|
+
config = mock "config"
|
307
|
+
rails.stub!(:configuration).and_return(config)
|
308
|
+
gem = mock "gem"
|
309
|
+
gem.stub!(:name).and_return "hpricot"
|
310
|
+
gem.stub!(:requirement).and_return Gem::Requirement.new("=0.6")
|
311
|
+
config.stub!(:gems).and_return [gem]
|
312
|
+
end
|
313
|
+
|
314
|
+
@config = Warbler::Config.new
|
315
|
+
@config.webxml.booter.should == :rails
|
316
|
+
@config.gems.keys.should include(Gem::Dependency.new("hpricot", Gem::Requirement.new("=0.6")))
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should automatically add Merb::BootLoader::Dependencies.dependencies to the list of gems" do
|
320
|
+
task :merb_env do
|
321
|
+
deps = mock_merb_module
|
322
|
+
deps.dependencies = [Gem::Dependency.new("merb-core", ">= 1.0.6.1")]
|
323
|
+
end
|
324
|
+
@config = Warbler::Config.new
|
325
|
+
@config.webxml.booter.should == :merb
|
326
|
+
@config.gems.keys.should include(Gem::Dependency.new("merb-core", ">= 1.0.6.1"))
|
327
|
+
end
|
328
|
+
|
329
|
+
it "should skip Merb development dependencies" do
|
330
|
+
task :merb_env do
|
331
|
+
deps = mock_merb_module
|
332
|
+
deps.dependencies = [Gem::Dependency.new("rake", "= #{RAKEVERSION}", :development)]
|
333
|
+
end
|
334
|
+
@war.apply(Warbler::Config.new)
|
335
|
+
file_list(/rake-#{RAKEVERSION}/).should be_empty
|
336
|
+
end
|
337
|
+
|
338
|
+
it "should warn about using Merb < 1.0" do
|
339
|
+
task :merb_env do
|
340
|
+
silence { Object.const_set("Merb", Module.new) }
|
341
|
+
end
|
342
|
+
@config = silence { Warbler::Config.new }
|
343
|
+
@config.webxml.booter.should == :merb
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should set the jruby max runtimes to 1 when MT Rails is detected" do
|
347
|
+
task :environment do
|
348
|
+
rails = mock_rails_module
|
349
|
+
config = mock "config"
|
350
|
+
rails.stub!(:configuration).and_return(config)
|
351
|
+
config.stub!(:threadsafe!)
|
352
|
+
config.should_receive(:allow_concurrency).and_return true
|
353
|
+
config.should_receive(:preload_frameworks).and_return true
|
354
|
+
end
|
355
|
+
@config = Warbler::Config.new
|
356
|
+
@config.webxml.booter.should == :rails
|
357
|
+
@config.webxml.jruby.max.runtimes.should == 1
|
358
|
+
end
|
359
|
+
|
360
|
+
it "should skip directories that don't exist in config.dirs and print a warning" do
|
361
|
+
@config.dirs = %w(lib notexist)
|
362
|
+
silence { @war.apply(@config) }
|
363
|
+
file_list(%r{WEB-INF/lib}).should_not be_empty
|
364
|
+
file_list(%r{WEB-INF/notexist}).should be_empty
|
365
|
+
end
|
366
|
+
|
367
|
+
it "should write gems to location specified by gem_path" do
|
368
|
+
@config = Warbler::Config.new {|c| c.gem_path = "/WEB-INF/jewels"; c.gems << 'rake' }
|
369
|
+
elements = expand_webxml
|
370
|
+
file_list(%r{WEB-INF/jewels}).should_not be_empty
|
371
|
+
elements.to_a(
|
372
|
+
"context-param/param-name[text()='gem.path']"
|
373
|
+
).should_not be_empty
|
374
|
+
elements.to_a(
|
375
|
+
"context-param/param-name[text()='gem.path']/../param-value"
|
376
|
+
).first.text.should == "/WEB-INF/jewels"
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
it "should detect a Bundler Gemfile and process only its gems" do
|
381
|
+
File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
|
382
|
+
@war.apply(Warbler::Config.new {|c| c.gems << "rake"})
|
383
|
+
file_list(%r{WEB-INF/Gemfile}).should_not be_empty
|
384
|
+
file_list(%r{WEB-INF/gems/specifications/rspec}).should_not be_empty
|
385
|
+
file_list(%r{WEB-INF/gems/specifications/rake}).should be_empty
|
386
|
+
end
|
387
|
+
|
388
|
+
it "should write a Bundler environment file into the war" do
|
389
|
+
File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
|
390
|
+
@war.apply(Warbler::Config.new)
|
391
|
+
file_list(%r{WEB-INF/Gemfile}).should_not be_empty
|
392
|
+
file_list(%r{WEB-INF/Gemfile.lock}).should be_empty
|
393
|
+
file_list(%r{WEB-INF/\.bundle/environment\.rb}).should be_empty
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should only include Bundler lockfiles if Gemfile.lock exists" do
|
397
|
+
File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
|
398
|
+
`ruby -S bundle lock`
|
399
|
+
@war.apply(Warbler::Config.new)
|
400
|
+
file_list(%r{WEB-INF/Gemfile.lock}).should_not be_empty
|
401
|
+
file_list(%r{WEB-INF/\.bundle/environment\.rb}).should_not be_empty
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should allow overriding of the gem path when using Bundler" do
|
405
|
+
File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
|
406
|
+
@war.apply(Warbler::Config.new {|c| c.gem_path = '/WEB-INF/jewels' })
|
407
|
+
file_list(%r{WEB-INF/jewels/specifications/rspec}).should_not be_empty
|
408
|
+
IO.readlines(".bundle/war-environment.rb").grep(/rspec/).last.should =~ %r{jewels/specifications}m
|
409
|
+
end
|
410
|
+
|
411
|
+
it "should not let the framework load Bundler from the locked environment" do
|
412
|
+
task :environment do
|
413
|
+
File.exist?('.bundle/environment.rb').should_not be_true
|
414
|
+
mock_rails_module
|
415
|
+
end
|
416
|
+
|
417
|
+
File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
|
418
|
+
`ruby -S bundle lock`
|
419
|
+
File.exist?('.bundle/environment.rb').should be_true
|
420
|
+
@war.apply(Warbler::Config.new)
|
421
|
+
hash = eval("[" + IO.readlines(".bundle/environment.rb").grep(/rspec/).last + "]").first
|
422
|
+
hash[:load_paths].each {|p| File.exist?(p).should be_true }
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should allow adding additional WEB-INF files via config.webinf_files" do
|
426
|
+
File.open("myserver-web.xml", "w") do |f|
|
427
|
+
f << "<web-app></web-app>"
|
428
|
+
end
|
429
|
+
@war.apply(Warbler::Config.new {|c| c.webinf_files = FileList['myserver-web.xml'] })
|
430
|
+
file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
|
431
|
+
end
|
432
|
+
|
433
|
+
it "should allow expanding of additional WEB-INF files via config.webinf_files" do
|
434
|
+
File.open("myserver-web.xml.erb", "w") do |f|
|
435
|
+
f << "<web-app><%= webxml.rails.env %></web-app>"
|
436
|
+
end
|
437
|
+
@war.apply(Warbler::Config.new {|c| c.webinf_files = FileList['myserver-web.xml.erb'] })
|
438
|
+
file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
|
439
|
+
@war.files['WEB-INF/myserver-web.xml'].read.should =~ /web-app.*production/
|
440
|
+
end
|
441
|
+
end
|