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
@@ -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
|