rdmopensource-warbler 1.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.
- 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
|