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
@@ -0,0 +1,349 @@
|
|
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 'ostruct'
|
9
|
+
|
10
|
+
module Warbler
|
11
|
+
# Warbler war file assembly configuration class.
|
12
|
+
class Config
|
13
|
+
TOP_DIRS = %w(app config lib log vendor)
|
14
|
+
FILE = "config/warble.rb"
|
15
|
+
DEFAULT_GEM_PATH = '/WEB-INF/gems'
|
16
|
+
BUILD_GEMS = %w(warbler rake rcov)
|
17
|
+
|
18
|
+
# Features: additional options controlling how the jar is built.
|
19
|
+
# Currently the following features are supported:
|
20
|
+
# - gemjar: package the gem repository in a jar file in WEB-INF/lib
|
21
|
+
# - executable: embed a web server and make the war executable
|
22
|
+
attr_accessor :features
|
23
|
+
|
24
|
+
# Deprecated: No longer has any effect.
|
25
|
+
attr_accessor :staging_dir
|
26
|
+
|
27
|
+
# Directory where the war file will be written. Can be used to direct
|
28
|
+
# Warbler to place your war file directly in your application server's
|
29
|
+
# autodeploy directory. Defaults to the root of the Rails directory.
|
30
|
+
attr_accessor :autodeploy_dir
|
31
|
+
|
32
|
+
# Top-level directories to be copied into WEB-INF. Defaults to
|
33
|
+
# names in TOP_DIRS
|
34
|
+
attr_accessor :dirs
|
35
|
+
|
36
|
+
# Additional files beyond the top-level directories to include in the
|
37
|
+
# WEB-INF directory
|
38
|
+
attr_accessor :includes
|
39
|
+
|
40
|
+
# Files to exclude from the WEB-INF directory
|
41
|
+
attr_accessor :excludes
|
42
|
+
|
43
|
+
# Java classes and other files to copy to WEB-INF/classes
|
44
|
+
attr_accessor :java_classes
|
45
|
+
|
46
|
+
# Java libraries to copy to WEB-INF/lib
|
47
|
+
attr_accessor :java_libs
|
48
|
+
|
49
|
+
# Rubygems to install into the webapp.
|
50
|
+
attr_accessor :gems
|
51
|
+
|
52
|
+
# Whether to include dependent gems (default true)
|
53
|
+
attr_accessor :gem_dependencies
|
54
|
+
|
55
|
+
# Whether to exclude **/*.log files (default is true)
|
56
|
+
attr_accessor :exclude_logs
|
57
|
+
|
58
|
+
# Public HTML directory file list, to be copied into the root of the war
|
59
|
+
attr_accessor :public_html
|
60
|
+
|
61
|
+
# Container of pathmaps used for specifying source-to-destination transformations
|
62
|
+
# under various situations (<tt>public_html</tt> and <tt>java_classes</tt> are two
|
63
|
+
# entries in this structure).
|
64
|
+
attr_accessor :pathmaps
|
65
|
+
|
66
|
+
# Name of war file (without the .war), defaults to the directory name containing
|
67
|
+
# the Rails application
|
68
|
+
attr_accessor :war_name
|
69
|
+
|
70
|
+
# Name of a MANIFEST.MF template to use.
|
71
|
+
attr_accessor :manifest_file
|
72
|
+
|
73
|
+
# Files for WEB-INF directory (next to web.xml). Contains web.xml by default.
|
74
|
+
# If there are .erb files they will be processed with webxml config.
|
75
|
+
attr_accessor :webinf_files
|
76
|
+
|
77
|
+
# Use Bundler to locate gems if Gemfile is found. Default is true.
|
78
|
+
attr_accessor :bundler
|
79
|
+
|
80
|
+
# Path to the pre-bundled gem directory inside the war file. Default is '/WEB-INF/gems'.
|
81
|
+
# This also sets 'gem.path' inside web.xml.
|
82
|
+
attr_accessor :gem_path
|
83
|
+
|
84
|
+
# FileList of ruby files to compile to class files
|
85
|
+
attr_accessor :compiled_ruby_files
|
86
|
+
|
87
|
+
# Extra configuration for web.xml. Controls how the dynamically-generated web.xml
|
88
|
+
# file is generated.
|
89
|
+
#
|
90
|
+
# * <tt>webxml.jndi</tt> -- the name of one or more JNDI data sources name to be
|
91
|
+
# available to the application. Places appropriate <resource-ref> entries
|
92
|
+
# in the file.
|
93
|
+
# * <tt>webxml.ignored</tt> -- array of key names that will be not used to
|
94
|
+
# generate a context param. Defaults to ['jndi', 'booter']
|
95
|
+
#
|
96
|
+
# Any other key/value pair placed in the open structure will be dumped as a
|
97
|
+
# context parameter in the web.xml file. Some of the recognized values are:
|
98
|
+
#
|
99
|
+
# * <tt>webxml.rails.env</tt> -- the Rails environment to use for the
|
100
|
+
# running application, usually either development or production (the
|
101
|
+
# default).
|
102
|
+
# * <tt>webxml.gem.path</tt> -- the path to your bundled gem directory
|
103
|
+
# * <tt>webxml.jruby.min.runtimes</tt> -- minimum number of pooled runtimes to
|
104
|
+
# keep around during idle time
|
105
|
+
# * <tt>webxml.jruby.max.runtimes</tt> -- maximum number of pooled Rails
|
106
|
+
# application runtimes
|
107
|
+
#
|
108
|
+
# Note that if you attempt to access webxml configuration keys in a conditional,
|
109
|
+
# you might not obtain the result you want. For example:
|
110
|
+
# <%= webxml.maybe.present.key || 'default' %>
|
111
|
+
# doesn't yield the right result. Instead, you need to generate the context parameters:
|
112
|
+
# <%= webxml.context_params['maybe.present.key'] || 'default' %>
|
113
|
+
attr_accessor :webxml
|
114
|
+
|
115
|
+
def initialize(warbler_home = WARBLER_HOME)
|
116
|
+
@warbler_home = warbler_home
|
117
|
+
@features = []
|
118
|
+
@dirs = TOP_DIRS.select {|d| File.directory?(d)}
|
119
|
+
@includes = FileList[]
|
120
|
+
@excludes = FileList[]
|
121
|
+
@java_libs = default_jar_files
|
122
|
+
@java_classes = FileList[]
|
123
|
+
@gems = Warbler::Gems.new
|
124
|
+
@gem_path = DEFAULT_GEM_PATH
|
125
|
+
@gem_dependencies = true
|
126
|
+
@exclude_logs = true
|
127
|
+
@public_html = FileList["public/**/*"]
|
128
|
+
@pathmaps = default_pathmaps
|
129
|
+
@webxml = default_webxml_config
|
130
|
+
@rails_root = File.expand_path(defined?(RAILS_ROOT) ? RAILS_ROOT : Dir.getwd)
|
131
|
+
@war_name = File.basename(@rails_root)
|
132
|
+
@bundler = true
|
133
|
+
@webinf_files = default_webinf_files
|
134
|
+
@compiled_ruby_files = FileList[]
|
135
|
+
auto_detect_frameworks
|
136
|
+
yield self if block_given?
|
137
|
+
update_gem_path
|
138
|
+
detect_bundler_gems
|
139
|
+
@excludes += warbler_vendor_excludes(warbler_home)
|
140
|
+
@excludes += FileList["**/*.log"] if @exclude_logs
|
141
|
+
end
|
142
|
+
|
143
|
+
def gems=(value)
|
144
|
+
@gems = Warbler::Gems.new(value)
|
145
|
+
end
|
146
|
+
|
147
|
+
def relative_gem_path
|
148
|
+
@gem_path[1..-1]
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
def warbler_vendor_excludes(warbler_home)
|
153
|
+
warbler = File.expand_path(warbler_home)
|
154
|
+
if warbler =~ %r{^#{@rails_root}/(.*)}
|
155
|
+
FileList["#{$1}"]
|
156
|
+
else
|
157
|
+
[]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def default_pathmaps
|
162
|
+
p = OpenStruct.new
|
163
|
+
p.public_html = ["%{public/,}p"]
|
164
|
+
p.java_libs = ["WEB-INF/lib/%f"]
|
165
|
+
p.java_classes = ["WEB-INF/classes/%p"]
|
166
|
+
p.application = ["WEB-INF/%p"]
|
167
|
+
p.webinf = ["WEB-INF/%{.erb$,}f"]
|
168
|
+
p.gemspecs = ["#{relative_gem_path}/specifications/%f"]
|
169
|
+
p.gems = ["#{relative_gem_path}/gems/%p"]
|
170
|
+
p
|
171
|
+
end
|
172
|
+
|
173
|
+
def default_webxml_config
|
174
|
+
c = WebxmlOpenStruct.new
|
175
|
+
c.rails.env = ENV['RAILS_ENV'] || 'production'
|
176
|
+
c.public.root = '/'
|
177
|
+
c.jndi = nil
|
178
|
+
c.ignored = %w(jndi booter)
|
179
|
+
c
|
180
|
+
end
|
181
|
+
|
182
|
+
def default_webinf_files
|
183
|
+
webxml = if File.exist?("config/web.xml")
|
184
|
+
"config/web.xml"
|
185
|
+
elsif File.exist?("config/web.xml.erb")
|
186
|
+
"config/web.xml.erb"
|
187
|
+
else
|
188
|
+
"#{WARBLER_HOME}/web.xml.erb"
|
189
|
+
end
|
190
|
+
FileList[webxml]
|
191
|
+
end
|
192
|
+
|
193
|
+
def update_gem_path
|
194
|
+
if @gem_path != DEFAULT_GEM_PATH
|
195
|
+
@gem_path = "/#{@gem_path}" unless @gem_path =~ %r{^/}
|
196
|
+
sub_gem_path = @gem_path[1..-1]
|
197
|
+
@pathmaps.gemspecs.each {|p| p.sub!(DEFAULT_GEM_PATH[1..-1], sub_gem_path)}
|
198
|
+
@pathmaps.gems.each {|p| p.sub!(DEFAULT_GEM_PATH[1..-1], sub_gem_path)}
|
199
|
+
@webxml["gem"]["path"] = @gem_path
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def detect_bundler_gems
|
204
|
+
if @bundler && File.exist?("Gemfile")
|
205
|
+
@gems.clear
|
206
|
+
@gem_dependencies = false # Bundler takes care of these
|
207
|
+
begin
|
208
|
+
require 'bundler'
|
209
|
+
env = Bundler::Runtime.new(Bundler.root, Bundler.definition)
|
210
|
+
if bundler_env_file = Bundler.respond_to?(:env_file)
|
211
|
+
class << Bundler
|
212
|
+
alias orig_env_file env_file
|
213
|
+
def env_file; root.join(::Warbler::Runtime::WAR_ENV); end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
env.extend Warbler::Runtime
|
217
|
+
env.gem_path = @gem_path
|
218
|
+
env.write_war_environment
|
219
|
+
env.war_specs.each {|spec| @gems << spec }
|
220
|
+
ensure
|
221
|
+
if bundler_env_file
|
222
|
+
class << Bundler
|
223
|
+
alias env_file orig_env_file
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
else
|
228
|
+
@bundler = false
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def default_jar_files
|
233
|
+
require 'jruby-jars'
|
234
|
+
require 'jruby-rack'
|
235
|
+
FileList[JRubyJars.core_jar_path, JRubyJars.stdlib_jar_path, JRubyJars.jruby_rack_jar_path]
|
236
|
+
end
|
237
|
+
|
238
|
+
def auto_detect_frameworks
|
239
|
+
return unless Warbler.framework_detection
|
240
|
+
if File.exist?(".bundle/environment.rb")
|
241
|
+
begin # Don't want Bundler to load from .bundle/environment
|
242
|
+
mv(".bundle/environment.rb",".bundle/environment-save.rb", :verbose => false)
|
243
|
+
auto_detect_rails || auto_detect_merb || auto_detect_rackup
|
244
|
+
ensure
|
245
|
+
mv(".bundle/environment-save.rb",".bundle/environment.rb", :verbose => false)
|
246
|
+
end
|
247
|
+
else
|
248
|
+
auto_detect_rails || auto_detect_merb || auto_detect_rackup
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def auto_detect_rails
|
253
|
+
return false unless task = Warbler.project_application.lookup("environment")
|
254
|
+
task.invoke rescue nil
|
255
|
+
return false unless defined?(::Rails)
|
256
|
+
@dirs << "tmp" if File.directory?("tmp")
|
257
|
+
@webxml.booter = :rails
|
258
|
+
unless (defined?(Rails.vendor_rails?) && Rails.vendor_rails?) || File.directory?("vendor/rails")
|
259
|
+
@gems["rails"] = Rails::VERSION::STRING
|
260
|
+
end
|
261
|
+
if defined?(Rails.configuration.gems)
|
262
|
+
Rails.configuration.gems.each do |g|
|
263
|
+
@gems << Gem::Dependency.new(g.name, g.requirement) if Dir["vendor/gems/#{g.name}*"].empty?
|
264
|
+
end
|
265
|
+
end
|
266
|
+
if defined?(Rails.configuration.threadsafe!) &&
|
267
|
+
(defined?(Rails.configuration.allow_concurrency) && # Rails 3
|
268
|
+
Rails.configuration.allow_concurrency && Rails.configuration.preload_frameworks) ||
|
269
|
+
(defined?(Rails.configuration.action_controller.allow_concurrency) && # Rails 2
|
270
|
+
Rails.configuration.action_controller.allow_concurrency && Rails.configuration.action_controller.preload_frameworks)
|
271
|
+
@webxml.jruby.max.runtimes = 1
|
272
|
+
end
|
273
|
+
true
|
274
|
+
end
|
275
|
+
|
276
|
+
def auto_detect_merb
|
277
|
+
return false unless task = Warbler.project_application.lookup("merb_env")
|
278
|
+
task.invoke rescue nil
|
279
|
+
return false unless defined?(::Merb)
|
280
|
+
@webxml.booter = :merb
|
281
|
+
if defined?(Merb::BootLoader::Dependencies.dependencies)
|
282
|
+
Merb::BootLoader::Dependencies.dependencies.each {|g| @gems << g }
|
283
|
+
else
|
284
|
+
warn "unable to auto-detect Merb dependencies; upgrade to Merb 1.0 or greater"
|
285
|
+
end
|
286
|
+
true
|
287
|
+
end
|
288
|
+
|
289
|
+
def auto_detect_rackup
|
290
|
+
return false unless File.exist?("config.ru") || !Dir['*/config.ru'].empty?
|
291
|
+
@webxml.booter = :rack
|
292
|
+
@webinf_files += [FileList['config.ru', '*/config.ru'].detect {|f| File.exist?(f)}]
|
293
|
+
true
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Helper class for holding arbitrary config.webxml values for injecting into +web.xml+.
|
298
|
+
class WebxmlOpenStruct < OpenStruct
|
299
|
+
%w(java com org javax).each {|name| undef_method name if Object.methods.include?(name) }
|
300
|
+
|
301
|
+
def initialize(key = 'webxml')
|
302
|
+
@key = key
|
303
|
+
@table = Hash.new {|h,k| h[k] = WebxmlOpenStruct.new(k) }
|
304
|
+
end
|
305
|
+
|
306
|
+
def servlet_context_listener
|
307
|
+
case self.booter
|
308
|
+
when :rack
|
309
|
+
"org.jruby.rack.RackServletContextListener"
|
310
|
+
when :merb
|
311
|
+
"org.jruby.rack.merb.MerbServletContextListener"
|
312
|
+
else # :rails, default
|
313
|
+
"org.jruby.rack.rails.RailsServletContextListener"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def [](key)
|
318
|
+
new_ostruct_member(key)
|
319
|
+
send(key)
|
320
|
+
end
|
321
|
+
|
322
|
+
def []=(key, value)
|
323
|
+
new_ostruct_member(key)
|
324
|
+
send("#{key}=", value)
|
325
|
+
end
|
326
|
+
|
327
|
+
def context_params
|
328
|
+
require 'cgi'
|
329
|
+
params = {}
|
330
|
+
@table.each do |k,v|
|
331
|
+
case v
|
332
|
+
when WebxmlOpenStruct
|
333
|
+
nested_params = v.context_params
|
334
|
+
nested_params.each do |nk,nv|
|
335
|
+
params["#{CGI::escapeHTML(k.to_s)}.#{nk}"] = nv
|
336
|
+
end
|
337
|
+
else
|
338
|
+
params[CGI::escapeHTML(k.to_s)] = CGI::escapeHTML(v.to_s)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
params.delete_if {|k,v| ['ignored', *ignored].include?(k.to_s) }
|
342
|
+
params
|
343
|
+
end
|
344
|
+
|
345
|
+
def to_s
|
346
|
+
"No value for '#@key' found"
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
data/lib/warbler/gems.rb
ADDED
@@ -0,0 +1,37 @@
|
|
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
|
+
module Warbler
|
9
|
+
# A set of gems. This only exists to allow expected operations
|
10
|
+
# to be used to add gems, and for backwards compatibility.
|
11
|
+
# It would be easier to just use a hash.
|
12
|
+
class Gems < Hash
|
13
|
+
ANY_VERSION = nil
|
14
|
+
|
15
|
+
def initialize(gems = nil)
|
16
|
+
if gems.is_a?(Hash)
|
17
|
+
self.merge!(gems)
|
18
|
+
elsif gems.is_a?(Array)
|
19
|
+
gems.each {|gem| self << gem }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def <<(gem)
|
24
|
+
self[gem] ||= ANY_VERSION
|
25
|
+
end
|
26
|
+
|
27
|
+
def +(other)
|
28
|
+
other.each {|g| self[g] ||= ANY_VERSION }
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def -(other)
|
33
|
+
other.each {|g| self.delete(g)}
|
34
|
+
self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Warbler
|
2
|
+
# Extension module for a Bundler::Runtime instance, to add methods
|
3
|
+
# to create a Bundler environment file specific to war packaging.
|
4
|
+
module Runtime
|
5
|
+
WAR_ENV = ".bundle/war-environment.rb"
|
6
|
+
|
7
|
+
attr_writer :gem_path
|
8
|
+
def gem_path
|
9
|
+
@gem_path || Config::DEFAULT_GEM_PATH
|
10
|
+
end
|
11
|
+
|
12
|
+
class Spec
|
13
|
+
def initialize(spec, gem_path)
|
14
|
+
location = spec[:loaded_from][%r{(.*)/specifications}, 1]
|
15
|
+
spec = spec.dup
|
16
|
+
spec[:loaded_from] = spec[:loaded_from].sub(location, gem_path)
|
17
|
+
spec[:load_paths] = spec[:load_paths].map {|p| p.sub(location, gem_path)}
|
18
|
+
@spec = spec
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
str = @spec.inspect
|
23
|
+
str.gsub(%r'"/WEB-INF(/[^"]*)"', 'File.expand_path("../..\1", __FILE__)')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# deprecated; compatibility with Bundler <= 0.9.14
|
28
|
+
def rb_lock_file #:nocov:
|
29
|
+
root.join(WAR_ENV) #:nocov:
|
30
|
+
end #:nocov:
|
31
|
+
|
32
|
+
def specs_for_lock_file
|
33
|
+
super.map {|s| Spec.new(s, gem_path)}
|
34
|
+
end
|
35
|
+
|
36
|
+
def write_war_environment
|
37
|
+
write_rb_lock
|
38
|
+
end
|
39
|
+
|
40
|
+
def war_specs
|
41
|
+
respond_to?(:requested_specs) ? requested_specs : specs_for
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/warbler/task.rb
ADDED
@@ -0,0 +1,224 @@
|
|
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 'rake'
|
9
|
+
require 'rake/tasklib'
|
10
|
+
require 'stringio'
|
11
|
+
require 'zip/zip'
|
12
|
+
|
13
|
+
module Warbler
|
14
|
+
# Warbler Rake task. Allows defining multiple configurations inside the same
|
15
|
+
# Rakefile by using different task names.
|
16
|
+
#
|
17
|
+
# To define multiple Warbler configurations in a single project, use
|
18
|
+
# code like the following in a Rakefile:
|
19
|
+
#
|
20
|
+
# Warbler::Task.new("war1", Warbler::Config.new do |config|
|
21
|
+
# config.war_name = "war1"
|
22
|
+
# # ...
|
23
|
+
# end
|
24
|
+
# Warbler::Task.new("war2", Warbler::Config.new do |config|
|
25
|
+
# config.war_name = "war2"
|
26
|
+
# # ...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# With this setup, you can create two separate war files two
|
30
|
+
# different configurations by running <tt>rake war1 war2</tt>.
|
31
|
+
class Task < Rake::TaskLib
|
32
|
+
# Task name
|
33
|
+
attr_accessor :name
|
34
|
+
|
35
|
+
# Warbler::Config
|
36
|
+
attr_accessor :config
|
37
|
+
|
38
|
+
# Warbler::War
|
39
|
+
attr_accessor :war
|
40
|
+
|
41
|
+
def initialize(name = :war, config = nil)
|
42
|
+
@name = name
|
43
|
+
@config = config
|
44
|
+
if @config.nil? && File.exists?(Config::FILE)
|
45
|
+
@config = eval(File.open(Config::FILE) {|f| f.read})
|
46
|
+
end
|
47
|
+
@config ||= Config.new
|
48
|
+
unless @config.kind_of? Config
|
49
|
+
warn "Warbler::Config not provided by override in initializer or #{Config::FILE}; using defaults"
|
50
|
+
@config = Config.new
|
51
|
+
end
|
52
|
+
@war = Warbler::War.new
|
53
|
+
yield self if block_given?
|
54
|
+
define_tasks
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def define_tasks
|
59
|
+
define_main_task
|
60
|
+
namespace name do
|
61
|
+
define_clean_task
|
62
|
+
define_compile_task
|
63
|
+
define_files_task
|
64
|
+
define_jar_task
|
65
|
+
define_debug_task
|
66
|
+
define_gemjar_task
|
67
|
+
define_config_task
|
68
|
+
define_pluginize_task
|
69
|
+
define_executable_task
|
70
|
+
define_version_task
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def define_main_task
|
75
|
+
desc "Create the project .war file"
|
76
|
+
task @name do
|
77
|
+
unless @config.features.empty?
|
78
|
+
@config.features.each do |feature|
|
79
|
+
t = "#@name:#{feature}"
|
80
|
+
unless Rake.application.lookup(t)
|
81
|
+
warn "unknown feature `#{feature}', ignoring"
|
82
|
+
next
|
83
|
+
end
|
84
|
+
Rake::Task[t].invoke
|
85
|
+
end
|
86
|
+
end
|
87
|
+
# Invoke this way so custom dependencies can be defined before
|
88
|
+
# the file find routine is run
|
89
|
+
["#{@name}:files", "#{@name}:jar"].each do |t|
|
90
|
+
Rake::Task[t].invoke
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def define_clean_task
|
96
|
+
desc "Remove the .war file"
|
97
|
+
task "clean" do
|
98
|
+
rm_f "#{config.war_name}.war"
|
99
|
+
end
|
100
|
+
task "clear" => "#{name}:clean"
|
101
|
+
end
|
102
|
+
|
103
|
+
def define_compile_task
|
104
|
+
task "compile_ruby_files" do
|
105
|
+
war.compile(config)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def define_files_task
|
110
|
+
task "files" => "compile_ruby_files" do
|
111
|
+
war.apply(config)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def define_jar_task
|
116
|
+
task "jar" do
|
117
|
+
war.create(config)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def define_debug_task
|
122
|
+
desc "Dump diagnostic information"
|
123
|
+
task "debug" => "files" do
|
124
|
+
require 'yaml'
|
125
|
+
puts YAML::dump(config)
|
126
|
+
war.files.each {|k,v| puts "#{k} -> #{String === v ? v : '<blob>'}"}
|
127
|
+
end
|
128
|
+
task "debug:includes" => "files" do
|
129
|
+
puts "", "included files:"
|
130
|
+
puts *war.webinf_filelist.include
|
131
|
+
end
|
132
|
+
task "debug:excludes" => "files" do
|
133
|
+
puts "", "excluded files:"
|
134
|
+
puts *war.webinf_filelist.exclude
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def define_gemjar_task
|
139
|
+
task "gemjar" do
|
140
|
+
task "#@name:jar" => "#@name:make_gemjar"
|
141
|
+
end
|
142
|
+
|
143
|
+
gem_jar = Warbler::War.new
|
144
|
+
task "make_gemjar" => "files" do
|
145
|
+
gem_path = Regexp::quote(config.relative_gem_path)
|
146
|
+
gems = war.files.select{|k,v| k =~ %r{#{gem_path}/} }
|
147
|
+
gems.each do |k,v|
|
148
|
+
gem_jar.files[k.sub(%r{#{gem_path}/}, '')] = v
|
149
|
+
end
|
150
|
+
war.files["WEB-INF/lib/gems.jar"] = "tmp/gems.jar"
|
151
|
+
war.files.reject!{|k,v| k =~ /#{gem_path}/ }
|
152
|
+
mkdir_p "tmp"
|
153
|
+
gem_jar.add_manifest
|
154
|
+
gem_jar.create("tmp/gems.jar")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def define_config_task
|
159
|
+
task "config" do
|
160
|
+
if File.exists?(Warbler::Config::FILE) && ENV["FORCE"].nil?
|
161
|
+
puts "There's another bird sitting on my favorite branch"
|
162
|
+
puts "(file '#{Warbler::Config::FILE}' already exists. Pass argument FORCE=1 to override)"
|
163
|
+
elsif !File.directory?("config")
|
164
|
+
puts "I'm confused; my favorite branch is missing"
|
165
|
+
puts "(directory 'config' is missing)"
|
166
|
+
else
|
167
|
+
cp "#{Warbler::WARBLER_HOME}/warble.rb", Warbler::Config::FILE
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def define_pluginize_task
|
173
|
+
task "pluginize" do
|
174
|
+
if !Dir["vendor/plugins/warbler*"].empty? && ENV["FORCE"].nil?
|
175
|
+
puts "I found an old nest in vendor/plugins; please trash it so I can make a new one"
|
176
|
+
puts "(directory vendor/plugins/warbler* exists)"
|
177
|
+
else
|
178
|
+
rm_rf FileList["vendor/plugins/warbler*"], :verbose => false
|
179
|
+
mkdir_p "vendor/plugins/warbler/tasks"
|
180
|
+
File.open("vendor/plugins/warbler/tasks/warbler.rake", "w") do |f|
|
181
|
+
f.puts "require 'warbler'"
|
182
|
+
f.puts "Warbler::Task.new"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def define_executable_task
|
189
|
+
winstone_type = ENV["WINSTONE"] || "winstone-lite"
|
190
|
+
winstone_version = ENV["WINSTONE_VERSION"] || "0.9.10"
|
191
|
+
winstone_path = "net/sourceforge/winstone/#{winstone_type}/#{winstone_version}/#{winstone_type}-#{winstone_version}.jar"
|
192
|
+
winstone_jar = File.expand_path("~/.m2/repository/#{winstone_path}")
|
193
|
+
file winstone_jar do |t|
|
194
|
+
# Not always covered in tests as these lines may not get
|
195
|
+
# executed every time if the jar is cached.
|
196
|
+
puts "Downloading #{winstone_type}.jar" #:nocov:
|
197
|
+
mkdir_p File.dirname(t.name) #:nocov:
|
198
|
+
require 'open-uri' #:nocov:
|
199
|
+
maven_repo = ENV["MAVEN_REPO"] || "http://repo2.maven.org/maven2" #:nocov:
|
200
|
+
open("#{maven_repo}/#{winstone_path}") do |stream| #:nocov:
|
201
|
+
File.open(t.name, "wb") do |f| #:nocov:
|
202
|
+
while buf = stream.read(4096) #:nocov:
|
203
|
+
f << buf #:nocov:
|
204
|
+
end #:nocov:
|
205
|
+
end #:nocov:
|
206
|
+
end #:nocov:
|
207
|
+
end
|
208
|
+
|
209
|
+
task "executable" => winstone_jar do
|
210
|
+
war.files['META-INF/MANIFEST.MF'] = StringIO.new(War::DEFAULT_MANIFEST.chomp + "Main-Class: Main\n")
|
211
|
+
war.files['Main.class'] = Zip::ZipFile.open("#{WARBLER_HOME}/lib/warbler_war.jar") do |zf|
|
212
|
+
zf.get_input_stream('Main.class') {|io| StringIO.new(io.read) }
|
213
|
+
end
|
214
|
+
war.files['WEB-INF/winstone.jar'] = winstone_jar
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def define_version_task
|
219
|
+
task "version" do
|
220
|
+
puts "Warbler version #{Warbler::VERSION}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|