warbler 1.2.1 → 1.3.0.beta1
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 +8 -5
- data/History.txt +5 -0
- data/Manifest.txt +43 -23
- data/README.txt +67 -26
- data/Rakefile +17 -6
- data/ext/JarMain.java +147 -0
- data/ext/{Main.java → WarMain.java} +4 -4
- data/ext/{WarblerWar.java → WarblerJar.java} +79 -13
- data/ext/{WarblerWarService.java → WarblerJarService.java} +2 -2
- data/lib/warbler/application.rb +9 -9
- data/lib/warbler/config.rb +58 -204
- data/lib/warbler/gems.rb +2 -2
- data/lib/warbler/jar.rb +247 -0
- data/lib/warbler/task.rb +28 -60
- data/lib/warbler/templates/config.erb +1 -1
- data/lib/warbler/templates/rack.erb +1 -1
- data/lib/warbler/templates/rails.erb +1 -1
- data/lib/warbler/traits/bundler.rb +58 -0
- data/lib/warbler/traits/gemspec.rb +64 -0
- data/lib/warbler/traits/jar.rb +53 -0
- data/lib/warbler/traits/merb.rb +34 -0
- data/lib/warbler/traits/nogemspec.rb +41 -0
- data/lib/warbler/traits/rack.rb +31 -0
- data/lib/warbler/traits/rails.rb +57 -0
- data/lib/warbler/traits/war.rb +191 -0
- data/lib/warbler/traits.rb +105 -0
- data/lib/warbler/version.rb +1 -1
- data/lib/warbler/war.rb +1 -247
- data/lib/warbler.rb +2 -5
- data/lib/warbler_jar.jar +0 -0
- data/spec/sample_jar/History.txt +6 -0
- data/spec/sample_jar/Manifest.txt +8 -0
- data/spec/sample_jar/README.txt +30 -0
- data/spec/sample_jar/lib/sample_jar.rb +6 -0
- data/spec/sample_jar/sample_jar.gemspec +41 -0
- data/spec/sample_jar/test/test_sample_jar.rb +8 -0
- data/spec/{sample → sample_war}/app/controllers/application.rb +0 -0
- data/spec/{sample → sample_war}/app/helpers/application_helper.rb +0 -0
- data/spec/{sample → sample_war}/config/boot.rb +0 -0
- data/spec/{sample → sample_war}/config/database.yml +0 -0
- data/spec/{sample → sample_war}/config/environment.rb +0 -0
- data/spec/{sample → sample_war}/config/environments/development.rb +0 -0
- data/spec/{sample → sample_war}/config/environments/production.rb +0 -0
- data/spec/{sample → sample_war}/config/environments/test.rb +0 -0
- data/spec/{sample → sample_war}/config/initializers/inflections.rb +0 -0
- data/spec/{sample → sample_war}/config/initializers/mime_types.rb +0 -0
- data/spec/{sample → sample_war}/config/initializers/new_rails_defaults.rb +0 -0
- data/spec/{sample → sample_war}/config/routes.rb +0 -0
- data/spec/{sample → sample_war}/lib/tasks/utils.rake +0 -0
- data/spec/{sample → sample_war}/public/404.html +0 -0
- data/spec/{sample → sample_war}/public/422.html +0 -0
- data/spec/{sample → sample_war}/public/500.html +0 -0
- data/spec/{sample → sample_war}/public/favicon.ico +0 -0
- data/spec/{sample → sample_war}/public/index.html +0 -0
- data/spec/{sample → sample_war}/public/robots.txt +0 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/warbler/application_spec.rb +2 -9
- data/spec/warbler/config_spec.rb +101 -83
- data/spec/warbler/jar_spec.rb +763 -0
- data/spec/warbler/task_spec.rb +56 -41
- data/spec/warbler/traits_spec.rb +16 -0
- data/spec/warbler/war_spec.rb +2 -492
- data/warble.rb +36 -32
- metadata +57 -35
- data/lib/warbler_war.jar +0 -0
data/lib/warbler/application.rb
CHANGED
@@ -22,27 +22,27 @@ class Warbler::Application < Rake::Application
|
|
22
22
|
@name = 'warble'
|
23
23
|
|
24
24
|
# Load the main warbler tasks
|
25
|
-
Warbler::Task.new
|
25
|
+
wt = Warbler::Task.new
|
26
26
|
|
27
|
-
task :default =>
|
27
|
+
task :default => wt.name
|
28
28
|
|
29
|
-
desc "Generate a configuration file to customize your
|
30
|
-
task :config => "
|
29
|
+
desc "Generate a configuration file to customize your archive"
|
30
|
+
task :config => "#{wt.name}:config"
|
31
31
|
|
32
32
|
desc "Install Warbler tasks in your Rails application"
|
33
|
-
task :pluginize => "
|
33
|
+
task :pluginize => "#{wt.name}:pluginize"
|
34
34
|
|
35
35
|
desc "Feature: package gem repository inside a jar"
|
36
|
-
task :gemjar => "
|
36
|
+
task :gemjar => "#{wt.name}:gemjar"
|
37
37
|
|
38
38
|
desc "Feature: make an executable archive"
|
39
|
-
task :executable => "
|
39
|
+
task :executable => "#{wt.name}:executable"
|
40
40
|
|
41
41
|
desc "Feature: precompile all Ruby files"
|
42
|
-
task :compiled => "
|
42
|
+
task :compiled => "#{wt.name}:compiled"
|
43
43
|
|
44
44
|
desc "Display version of Warbler"
|
45
|
-
task :version => "
|
45
|
+
task :version => "#{wt.name}:version"
|
46
46
|
end
|
47
47
|
|
48
48
|
# Loads the project Rakefile in a separate application
|
data/lib/warbler/config.rb
CHANGED
@@ -5,16 +5,19 @@
|
|
5
5
|
# See the file LICENSE.txt for details.
|
6
6
|
#++
|
7
7
|
|
8
|
-
require '
|
8
|
+
require 'set'
|
9
|
+
require 'warbler/gems'
|
10
|
+
require 'warbler/traits'
|
9
11
|
|
10
12
|
module Warbler
|
11
|
-
# Warbler
|
13
|
+
# Warbler archive assembly configuration class.
|
12
14
|
class Config
|
13
15
|
TOP_DIRS = %w(app config lib log vendor)
|
14
16
|
FILE = "config/warble.rb"
|
15
|
-
DEFAULT_GEM_PATH = '/WEB-INF/gems'
|
16
17
|
BUILD_GEMS = %w(warbler rake rcov)
|
17
18
|
|
19
|
+
include Traits
|
20
|
+
|
18
21
|
# Features: additional options controlling how the jar is built.
|
19
22
|
# Currently the following features are supported:
|
20
23
|
# - gemjar: package the gem repository in a jar file in WEB-INF/lib
|
@@ -22,6 +25,11 @@ module Warbler
|
|
22
25
|
# - compiled: compile .rb files to .class files
|
23
26
|
attr_accessor :features
|
24
27
|
|
28
|
+
# Traits: an array of trait classes corresponding to
|
29
|
+
# characteristics of the project that are either auto-detected or
|
30
|
+
# configured.
|
31
|
+
attr_accessor :traits
|
32
|
+
|
25
33
|
# Deprecated: No longer has any effect.
|
26
34
|
attr_accessor :staging_dir
|
27
35
|
|
@@ -68,9 +76,12 @@ module Warbler
|
|
68
76
|
# entries in this structure).
|
69
77
|
attr_accessor :pathmaps
|
70
78
|
|
71
|
-
# Name of war file (without the
|
72
|
-
# the
|
73
|
-
attr_accessor :
|
79
|
+
# Name of jar or war file (without the extension), defaults to the
|
80
|
+
# directory name containing the application.
|
81
|
+
attr_accessor :jar_name
|
82
|
+
|
83
|
+
# Extension of jar file. Defaults to <tt>jar</tt> or <tt>war</tt> depending on the project.
|
84
|
+
attr_accessor :jar_extension
|
74
85
|
|
75
86
|
# Name of a MANIFEST.MF template to use.
|
76
87
|
attr_accessor :manifest_file
|
@@ -130,39 +141,36 @@ module Warbler
|
|
130
141
|
# <%= webxml.context_params['maybe.present.key'] || 'default' %>
|
131
142
|
attr_accessor :webxml
|
132
143
|
|
144
|
+
attr_reader :warbler_templates
|
145
|
+
|
133
146
|
def initialize(warbler_home = WARBLER_HOME)
|
134
|
-
|
147
|
+
super()
|
148
|
+
|
149
|
+
@warbler_home = warbler_home
|
135
150
|
@warbler_templates = "#{WARBLER_HOME}/lib/warbler/templates"
|
136
|
-
@features
|
137
|
-
@dirs
|
138
|
-
@includes
|
139
|
-
@excludes
|
140
|
-
@java_libs
|
141
|
-
@java_classes
|
142
|
-
@gems
|
143
|
-
@
|
144
|
-
@
|
145
|
-
@
|
146
|
-
@
|
147
|
-
@
|
148
|
-
@
|
149
|
-
@
|
150
|
-
@
|
151
|
-
@
|
152
|
-
|
153
|
-
|
154
|
-
@webinf_files = default_webinf_files
|
155
|
-
@init_filename = 'META-INF/init.rb'
|
156
|
-
@init_contents = ["#{@warbler_templates}/config.erb"]
|
157
|
-
|
158
|
-
auto_detect_frameworks
|
151
|
+
@features = Set.new
|
152
|
+
@dirs = TOP_DIRS.select {|d| File.directory?(d)}
|
153
|
+
@includes = FileList[]
|
154
|
+
@excludes = FileList[]
|
155
|
+
@java_libs = FileList[]
|
156
|
+
@java_classes = FileList[]
|
157
|
+
@gems = Warbler::Gems.new
|
158
|
+
@gem_dependencies = true
|
159
|
+
@gem_excludes = []
|
160
|
+
@exclude_logs = true
|
161
|
+
@public_html = FileList[]
|
162
|
+
@jar_name = File.basename(Dir.getwd)
|
163
|
+
@jar_extension = 'jar'
|
164
|
+
@webinf_files = FileList[]
|
165
|
+
@init_filename = 'META-INF/init.rb'
|
166
|
+
@init_contents = ["#{@warbler_templates}/config.erb"]
|
167
|
+
|
168
|
+
before_configure
|
159
169
|
yield self if block_given?
|
160
|
-
|
161
|
-
detect_bundler_gems
|
170
|
+
after_configure
|
162
171
|
|
163
|
-
framework_init = "#{@warbler_templates}/#{@webxml.booter}.erb"
|
164
|
-
@init_contents << framework_init if File.exist?(framework_init)
|
165
172
|
@compiled_ruby_files ||= FileList[*@dirs.map {|d| "#{d}/**/*.rb"}]
|
173
|
+
|
166
174
|
@excludes += ["tmp/war"] if File.directory?("tmp/war")
|
167
175
|
@excludes += warbler_vendor_excludes(warbler_home)
|
168
176
|
@excludes += FileList["**/*.log"] if @exclude_logs
|
@@ -176,185 +184,31 @@ module Warbler
|
|
176
184
|
@gem_path[1..-1]
|
177
185
|
end
|
178
186
|
|
187
|
+
# Deprecated
|
188
|
+
def war_name
|
189
|
+
warn "config.war_name deprecated; replace with config.jar_name" #:nocov:
|
190
|
+
jar_name #:nocov:
|
191
|
+
end
|
192
|
+
|
193
|
+
# Deprecated
|
194
|
+
def war_name=(w)
|
195
|
+
warn "config.war_name deprecated; replace with config.jar_name" #:nocov:
|
196
|
+
self.jar_name = w #:nocov:
|
197
|
+
end
|
198
|
+
|
179
199
|
private
|
180
200
|
def warbler_vendor_excludes(warbler_home)
|
181
201
|
warbler = File.expand_path(warbler_home)
|
182
|
-
if warbler =~ %r{^#{
|
202
|
+
if warbler =~ %r{^#{Dir.getwd}/(.*)}
|
183
203
|
FileList["#{$1}"]
|
184
204
|
else
|
185
205
|
[]
|
186
206
|
end
|
187
207
|
end
|
188
208
|
|
189
|
-
def
|
190
|
-
|
191
|
-
p.public_html = ["%{public/,}p"]
|
192
|
-
p.java_libs = ["WEB-INF/lib/%f"]
|
193
|
-
p.java_classes = ["WEB-INF/classes/%p"]
|
194
|
-
p.application = ["WEB-INF/%p"]
|
195
|
-
p.webinf = ["WEB-INF/%{.erb$,}f"]
|
196
|
-
p.gemspecs = ["#{relative_gem_path}/specifications/%f"]
|
197
|
-
p.gems = ["#{relative_gem_path}/gems/%p"]
|
198
|
-
p
|
199
|
-
end
|
200
|
-
|
201
|
-
def default_webxml_config
|
202
|
-
c = WebxmlOpenStruct.new
|
203
|
-
c.rails.env = ENV['RAILS_ENV'] || 'production'
|
204
|
-
c.public.root = '/'
|
205
|
-
c.jndi = nil
|
206
|
-
c.ignored = %w(jndi booter)
|
207
|
-
c
|
208
|
-
end
|
209
|
-
|
210
|
-
def default_rails_root
|
211
|
-
File.expand_path(defined?(Rails.root) ? Rails.root : (defined?(RAILS_ROOT) ? RAILS_ROOT : Dir.getwd))
|
212
|
-
end
|
213
|
-
|
214
|
-
def default_webinf_files
|
215
|
-
webxml = if File.exist?("config/web.xml")
|
216
|
-
"config/web.xml"
|
217
|
-
elsif File.exist?("config/web.xml.erb")
|
218
|
-
"config/web.xml.erb"
|
219
|
-
else
|
220
|
-
"#{WARBLER_HOME}/web.xml.erb"
|
221
|
-
end
|
222
|
-
FileList[webxml]
|
223
|
-
end
|
224
|
-
|
225
|
-
def update_gem_path
|
226
|
-
if @gem_path != DEFAULT_GEM_PATH
|
227
|
-
@gem_path = "/#{@gem_path}" unless @gem_path =~ %r{^/}
|
228
|
-
sub_gem_path = @gem_path[1..-1]
|
229
|
-
@pathmaps.gemspecs.each {|p| p.sub!(DEFAULT_GEM_PATH[1..-1], sub_gem_path)}
|
230
|
-
@pathmaps.gems.each {|p| p.sub!(DEFAULT_GEM_PATH[1..-1], sub_gem_path)}
|
231
|
-
@webxml["gem"]["path"] = @gem_path
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
def detect_bundler_gems
|
236
|
-
if @bundler && File.exist?("Gemfile")
|
237
|
-
@gems.clear
|
238
|
-
@gem_dependencies = false # Bundler takes care of these
|
239
|
-
require 'bundler'
|
240
|
-
gemfile = Pathname.new("Gemfile").expand_path
|
241
|
-
root = gemfile.dirname
|
242
|
-
lockfile = root.join('Gemfile.lock')
|
243
|
-
definition = Bundler::Definition.build(gemfile, lockfile, nil)
|
244
|
-
groups = definition.groups - @bundle_without.map {|g| g.to_sym}
|
245
|
-
definition.specs_for(groups).each {|spec| @gems << spec }
|
246
|
-
@init_contents << StringIO.new("ENV['BUNDLE_WITHOUT'] = '#{@bundle_without.join(':')}'\n")
|
247
|
-
else
|
248
|
-
@bundler = false
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def default_jar_files
|
253
|
-
require 'jruby-jars'
|
254
|
-
require 'jruby-rack'
|
255
|
-
FileList[JRubyJars.core_jar_path, JRubyJars.stdlib_jar_path, JRubyJars.jruby_rack_jar_path]
|
256
|
-
end
|
257
|
-
|
258
|
-
def auto_detect_frameworks
|
259
|
-
return unless Warbler.framework_detection
|
260
|
-
auto_detect_rails || auto_detect_merb || auto_detect_rackup
|
261
|
-
end
|
262
|
-
|
263
|
-
def auto_detect_rails
|
264
|
-
return false unless task = Warbler.project_application.lookup("environment")
|
265
|
-
task.invoke rescue nil
|
266
|
-
return false unless defined?(::Rails)
|
267
|
-
@dirs << "tmp" if File.directory?("tmp")
|
268
|
-
@webxml.booter = :rails
|
269
|
-
unless (defined?(Rails.vendor_rails?) && Rails.vendor_rails?) || File.directory?("vendor/rails")
|
270
|
-
@gems["rails"] = Rails::VERSION::STRING
|
271
|
-
end
|
272
|
-
if defined?(Rails.configuration.gems)
|
273
|
-
Rails.configuration.gems.each do |g|
|
274
|
-
@gems << Gem::Dependency.new(g.name, g.requirement) if Dir["vendor/gems/#{g.name}*"].empty?
|
275
|
-
end
|
276
|
-
end
|
277
|
-
if defined?(Rails.configuration.threadsafe!) &&
|
278
|
-
(defined?(Rails.configuration.allow_concurrency) && # Rails 3
|
279
|
-
Rails.configuration.allow_concurrency && Rails.configuration.preload_frameworks) ||
|
280
|
-
(defined?(Rails.configuration.action_controller.allow_concurrency) && # Rails 2
|
281
|
-
Rails.configuration.action_controller.allow_concurrency && Rails.configuration.action_controller.preload_frameworks)
|
282
|
-
@webxml.jruby.max.runtimes = 1
|
283
|
-
end
|
284
|
-
true
|
285
|
-
end
|
286
|
-
|
287
|
-
def auto_detect_merb
|
288
|
-
return false unless task = Warbler.project_application.lookup("merb_env")
|
289
|
-
task.invoke rescue nil
|
290
|
-
return false unless defined?(::Merb)
|
291
|
-
@webxml.booter = :merb
|
292
|
-
if defined?(Merb::BootLoader::Dependencies.dependencies)
|
293
|
-
Merb::BootLoader::Dependencies.dependencies.each {|g| @gems << g }
|
294
|
-
else
|
295
|
-
warn "unable to auto-detect Merb dependencies; upgrade to Merb 1.0 or greater"
|
296
|
-
end
|
297
|
-
true
|
298
|
-
end
|
299
|
-
|
300
|
-
def auto_detect_rackup
|
301
|
-
return false unless File.exist?("config.ru") || !Dir['*/config.ru'].empty?
|
302
|
-
@webxml.booter = :rack
|
303
|
-
@webinf_files += [FileList['config.ru', '*/config.ru'].detect {|f| File.exist?(f)}]
|
304
|
-
true
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
# Helper class for holding arbitrary config.webxml values for injecting into +web.xml+.
|
309
|
-
class WebxmlOpenStruct < OpenStruct
|
310
|
-
%w(java com org javax gem).each {|name| undef_method name if Object.methods.include?(name) }
|
311
|
-
|
312
|
-
def initialize(key = 'webxml')
|
313
|
-
@key = key
|
314
|
-
@table = Hash.new {|h,k| h[k] = WebxmlOpenStruct.new(k) }
|
315
|
-
end
|
316
|
-
|
317
|
-
def servlet_context_listener
|
318
|
-
case self.booter
|
319
|
-
when :rack
|
320
|
-
"org.jruby.rack.RackServletContextListener"
|
321
|
-
when :merb
|
322
|
-
"org.jruby.rack.merb.MerbServletContextListener"
|
323
|
-
else # :rails, default
|
324
|
-
"org.jruby.rack.rails.RailsServletContextListener"
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
def [](key)
|
329
|
-
new_ostruct_member(key)
|
330
|
-
send(key)
|
331
|
-
end
|
332
|
-
|
333
|
-
def []=(key, value)
|
334
|
-
new_ostruct_member(key)
|
335
|
-
send("#{key}=", value)
|
336
|
-
end
|
337
|
-
|
338
|
-
def context_params(escape = true)
|
339
|
-
require 'cgi'
|
340
|
-
params = {}
|
341
|
-
@table.each do |k,v|
|
342
|
-
case v
|
343
|
-
when WebxmlOpenStruct
|
344
|
-
nested_params = v.context_params
|
345
|
-
nested_params.each do |nk,nv|
|
346
|
-
params["#{escape ? CGI::escapeHTML(k.to_s) : k.to_s}.#{nk}"] = nv
|
347
|
-
end
|
348
|
-
else
|
349
|
-
params[escape ? CGI::escapeHTML(k.to_s) : k.to_s] = escape ? CGI::escapeHTML(v.to_s) : v.to_s
|
350
|
-
end
|
351
|
-
end
|
352
|
-
params.delete_if {|k,v| ['ignored', *ignored].include?(k.to_s) }
|
353
|
-
params
|
354
|
-
end
|
355
|
-
|
356
|
-
def to_s
|
357
|
-
"No value for '#@key' found"
|
209
|
+
def dump
|
210
|
+
YAML::dump(self.dup.tap{|c| c.dump_traits })
|
358
211
|
end
|
212
|
+
public :dump
|
359
213
|
end
|
360
214
|
end
|
data/lib/warbler/gems.rb
CHANGED
@@ -11,7 +11,7 @@ module Warbler
|
|
11
11
|
# It would be easier to just use a hash.
|
12
12
|
class Gems < Hash
|
13
13
|
ANY_VERSION = nil
|
14
|
-
|
14
|
+
|
15
15
|
def initialize(gems = nil)
|
16
16
|
if gems.is_a?(Hash)
|
17
17
|
self.merge!(gems)
|
@@ -19,7 +19,7 @@ module Warbler
|
|
19
19
|
gems.each {|gem| self << gem }
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def <<(gem)
|
24
24
|
self[gem] ||= ANY_VERSION
|
25
25
|
end
|
data/lib/warbler/jar.rb
ADDED
@@ -0,0 +1,247 @@
|
|
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 'zip/zip'
|
8
|
+
require 'stringio'
|
9
|
+
|
10
|
+
module Warbler
|
11
|
+
# Class that holds the files that will be stored in the jar file.
|
12
|
+
# The #files attribute contains a hash of pathnames inside the jar
|
13
|
+
# file to their contents. Contents can be one of:
|
14
|
+
# * +nil+ representing a directory entry
|
15
|
+
# * Any object responding to +read+ representing an in-memory blob
|
16
|
+
# * A String filename pointing to a file on disk
|
17
|
+
class Jar
|
18
|
+
DEFAULT_MANIFEST = %{Manifest-Version: 1.0\nCreated-By: Warbler #{Warbler::VERSION}\n\n}
|
19
|
+
|
20
|
+
attr_reader :files
|
21
|
+
attr_reader :app_filelist
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@files = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def compile(config)
|
28
|
+
# Compiling all Ruby files we can find -- do we need to allow an
|
29
|
+
# option to configure what gets compiled?
|
30
|
+
return if config.compiled_ruby_files.nil? || config.compiled_ruby_files.empty?
|
31
|
+
|
32
|
+
run_javac(config, config.compiled_ruby_files)
|
33
|
+
replace_compiled_ruby_files(config, config.compiled_ruby_files)
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_javac(config, compiled_ruby_files)
|
37
|
+
# Need to use the version of JRuby in the application to compile it
|
38
|
+
%x{java -classpath #{config.java_libs.join(File::PATH_SEPARATOR)} org.jruby.Main -S jrubyc \"#{compiled_ruby_files.join('" "')}\"}
|
39
|
+
end
|
40
|
+
|
41
|
+
def replace_compiled_ruby_files(config, compiled_ruby_files)
|
42
|
+
# Exclude the rb files and recreate them. This
|
43
|
+
# prevents the original contents being used.
|
44
|
+
config.excludes += compiled_ruby_files
|
45
|
+
|
46
|
+
compiled_ruby_files.each do |ruby_source|
|
47
|
+
files[apply_pathmaps(config, ruby_source, :application)] = StringIO.new("require __FILE__.sub(/\.rb$/, '.class')")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Apply the information in a Warbler::Config object in order to
|
52
|
+
# look for files to put into this war file.
|
53
|
+
def apply(config)
|
54
|
+
find_application_files(config)
|
55
|
+
find_java_libs(config)
|
56
|
+
find_java_classes(config)
|
57
|
+
find_gems_files(config)
|
58
|
+
add_manifest(config)
|
59
|
+
add_init_file(config)
|
60
|
+
apply_traits(config)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Create the jar or war file. The single argument can either be a
|
64
|
+
# Warbler::Config or a filename of the file to create.
|
65
|
+
def create(config_or_path)
|
66
|
+
path = config_or_path
|
67
|
+
if Warbler::Config === config_or_path
|
68
|
+
path = "#{config_or_path.jar_name}.#{config_or_path.jar_extension}"
|
69
|
+
path = File.join(config_or_path.autodeploy_dir, path) if config_or_path.autodeploy_dir
|
70
|
+
end
|
71
|
+
rm_f path
|
72
|
+
ensure_directory_entries
|
73
|
+
puts "Creating #{path}"
|
74
|
+
create_jar path, @files
|
75
|
+
end
|
76
|
+
|
77
|
+
# Invoke a hook to allow the project traits to add or modify the archive contents.
|
78
|
+
def apply_traits(config)
|
79
|
+
config.update_archive(self)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Add a manifest file either from config or by making a default manifest.
|
83
|
+
def add_manifest(config = nil)
|
84
|
+
unless @files.keys.detect{|k| k =~ /^META-INF\/MANIFEST\.MF$/i}
|
85
|
+
if config && config.manifest_file
|
86
|
+
@files['META-INF/MANIFEST.MF'] = config.manifest_file
|
87
|
+
else
|
88
|
+
@files['META-INF/MANIFEST.MF'] = StringIO.new(DEFAULT_MANIFEST)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Add java libraries to WEB-INF/lib.
|
94
|
+
def find_java_libs(config)
|
95
|
+
config.java_libs.map {|lib| add_with_pathmaps(config, lib, :java_libs) }
|
96
|
+
end
|
97
|
+
|
98
|
+
# Add java classes to WEB-INF/classes.
|
99
|
+
def find_java_classes(config)
|
100
|
+
config.java_classes.map {|f| add_with_pathmaps(config, f, :java_classes) }
|
101
|
+
end
|
102
|
+
|
103
|
+
# Add gems to WEB-INF/gems
|
104
|
+
def find_gems_files(config)
|
105
|
+
config.gems.each {|gem, version| find_single_gem_files(config, gem, version) }
|
106
|
+
end
|
107
|
+
|
108
|
+
# Add a single gem to WEB-INF/gems
|
109
|
+
def find_single_gem_files(config, gem_pattern, version = nil)
|
110
|
+
if Gem::Specification === gem_pattern
|
111
|
+
spec = gem_pattern
|
112
|
+
else
|
113
|
+
gem = case gem_pattern
|
114
|
+
when Gem::Dependency
|
115
|
+
gem_pattern
|
116
|
+
else
|
117
|
+
Gem::Dependency.new(gem_pattern, Gem::Requirement.create(version))
|
118
|
+
end
|
119
|
+
|
120
|
+
# skip development dependencies
|
121
|
+
return if gem.respond_to?(:type) and gem.type != :runtime
|
122
|
+
|
123
|
+
matched = Gem.source_index.search(gem)
|
124
|
+
fail "gem '#{gem}' not installed" if matched.empty?
|
125
|
+
spec = matched.last
|
126
|
+
end
|
127
|
+
|
128
|
+
# skip gems with no load path
|
129
|
+
return if spec.loaded_from == ""
|
130
|
+
|
131
|
+
add_with_pathmaps(config, spec.loaded_from, :gemspecs)
|
132
|
+
spec.files.each do |f|
|
133
|
+
f = f[2..-1] if f =~ /^\.\//
|
134
|
+
next if config.gem_excludes && config.gem_excludes.any? {|rx| f =~ rx }
|
135
|
+
src = File.join(spec.full_gem_path, f)
|
136
|
+
# some gemspecs may have incorrect file listings
|
137
|
+
next unless File.exist?(src)
|
138
|
+
@files[apply_pathmaps(config, File.join(spec.full_name, f), :gems)] = src
|
139
|
+
end
|
140
|
+
|
141
|
+
spec.dependencies.each {|dep| find_single_gem_files(config, dep) } if config.gem_dependencies
|
142
|
+
end
|
143
|
+
|
144
|
+
# Add all application directories and files to the archive.
|
145
|
+
def find_application_files(config)
|
146
|
+
config.dirs.select do |d|
|
147
|
+
exists = File.directory?(d)
|
148
|
+
warn "warning: application directory `#{d}' does not exist or is not a directory; skipping" unless exists
|
149
|
+
exists
|
150
|
+
end.each do |d|
|
151
|
+
@files[apply_pathmaps(config, d, :application)] = nil
|
152
|
+
end
|
153
|
+
@app_filelist = FileList[*(config.dirs.map{|d| "#{d}/**/*"})]
|
154
|
+
@app_filelist.include *(config.includes.to_a)
|
155
|
+
@app_filelist.exclude *(config.excludes.to_a)
|
156
|
+
@app_filelist.map {|f| add_with_pathmaps(config, f, :application) }
|
157
|
+
end
|
158
|
+
|
159
|
+
# Add init.rb file to the war file.
|
160
|
+
def add_init_file(config)
|
161
|
+
if config.init_contents
|
162
|
+
contents = ''
|
163
|
+
config.init_contents.each do |file|
|
164
|
+
if file.respond_to?(:read)
|
165
|
+
contents << file.read
|
166
|
+
elsif File.extname(file) == '.erb'
|
167
|
+
contents << expand_erb(file, config).read
|
168
|
+
else
|
169
|
+
contents << File.read(file)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
@files[config.init_filename] = StringIO.new(contents)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_with_pathmaps(config, f, map_type)
|
177
|
+
@files[apply_pathmaps(config, f, map_type)] = f
|
178
|
+
end
|
179
|
+
|
180
|
+
def expand_erb(file, config)
|
181
|
+
require 'erb'
|
182
|
+
erb = ERB.new(File.open(file) {|f| f.read })
|
183
|
+
StringIO.new(erb.result(erb_binding(config)))
|
184
|
+
end
|
185
|
+
|
186
|
+
def erb_binding(config)
|
187
|
+
webxml = config.webxml
|
188
|
+
binding
|
189
|
+
end
|
190
|
+
|
191
|
+
def apply_pathmaps(config, file, pathmaps)
|
192
|
+
file = file[2..-1] if file =~ /^\.\//
|
193
|
+
pathmaps = config.pathmaps.send(pathmaps)
|
194
|
+
pathmaps.each do |p|
|
195
|
+
file = file.pathmap(p)
|
196
|
+
end if pathmaps
|
197
|
+
file
|
198
|
+
end
|
199
|
+
|
200
|
+
def ensure_directory_entries
|
201
|
+
files.select {|k,v| !v.nil? }.each do |k,v|
|
202
|
+
dir = File.dirname(k)
|
203
|
+
while dir != "." && !files.has_key?(dir)
|
204
|
+
files[dir] = nil
|
205
|
+
dir = File.dirname(dir)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def create_jar(war_file, entries)
|
211
|
+
Zip::ZipFile.open(war_file, Zip::ZipFile::CREATE) do |zipfile|
|
212
|
+
entries.keys.sort.each do |entry|
|
213
|
+
src = entries[entry]
|
214
|
+
if src.respond_to?(:read)
|
215
|
+
zipfile.get_output_stream(entry) {|f| f << src.read }
|
216
|
+
elsif src.nil? || File.directory?(src)
|
217
|
+
warn "directory symlinks are not followed unless using JRuby; #{entry} contents not in archive" \
|
218
|
+
if File.symlink?(entry) && !defined?(JRUBY_VERSION)
|
219
|
+
zipfile.mkdir(entry)
|
220
|
+
elsif File.symlink?(src)
|
221
|
+
zipfile.get_output_stream(entry) {|f| f << File.read(src) }
|
222
|
+
else
|
223
|
+
zipfile.add(entry, src)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def entry_in_jar(jar, entry)
|
230
|
+
Zip::ZipFile.open(jar) do |zf|
|
231
|
+
zf.get_input_stream(entry) {|io| StringIO.new(io.read) }
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# Java-boosted jar creation for JRuby; replaces #create_jar and
|
236
|
+
# #entry_in_jar with Java version
|
237
|
+
require 'warbler_jar' if defined?(JRUBY_VERSION) && JRUBY_VERSION >= "1.5"
|
238
|
+
end
|
239
|
+
|
240
|
+
# Warbler::War is Deprecated. Please use Warbler::Jar.
|
241
|
+
class War < Jar
|
242
|
+
def initialize(*)
|
243
|
+
super
|
244
|
+
warn "Warbler::War is deprecated. Please replace all occurrences with Warbler::Jar."
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|