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.
Files changed (65) hide show
  1. data/Gemfile +8 -5
  2. data/History.txt +5 -0
  3. data/Manifest.txt +43 -23
  4. data/README.txt +67 -26
  5. data/Rakefile +17 -6
  6. data/ext/JarMain.java +147 -0
  7. data/ext/{Main.java → WarMain.java} +4 -4
  8. data/ext/{WarblerWar.java → WarblerJar.java} +79 -13
  9. data/ext/{WarblerWarService.java → WarblerJarService.java} +2 -2
  10. data/lib/warbler/application.rb +9 -9
  11. data/lib/warbler/config.rb +58 -204
  12. data/lib/warbler/gems.rb +2 -2
  13. data/lib/warbler/jar.rb +247 -0
  14. data/lib/warbler/task.rb +28 -60
  15. data/lib/warbler/templates/config.erb +1 -1
  16. data/lib/warbler/templates/rack.erb +1 -1
  17. data/lib/warbler/templates/rails.erb +1 -1
  18. data/lib/warbler/traits/bundler.rb +58 -0
  19. data/lib/warbler/traits/gemspec.rb +64 -0
  20. data/lib/warbler/traits/jar.rb +53 -0
  21. data/lib/warbler/traits/merb.rb +34 -0
  22. data/lib/warbler/traits/nogemspec.rb +41 -0
  23. data/lib/warbler/traits/rack.rb +31 -0
  24. data/lib/warbler/traits/rails.rb +57 -0
  25. data/lib/warbler/traits/war.rb +191 -0
  26. data/lib/warbler/traits.rb +105 -0
  27. data/lib/warbler/version.rb +1 -1
  28. data/lib/warbler/war.rb +1 -247
  29. data/lib/warbler.rb +2 -5
  30. data/lib/warbler_jar.jar +0 -0
  31. data/spec/sample_jar/History.txt +6 -0
  32. data/spec/sample_jar/Manifest.txt +8 -0
  33. data/spec/sample_jar/README.txt +30 -0
  34. data/spec/sample_jar/lib/sample_jar.rb +6 -0
  35. data/spec/sample_jar/sample_jar.gemspec +41 -0
  36. data/spec/sample_jar/test/test_sample_jar.rb +8 -0
  37. data/spec/{sample → sample_war}/app/controllers/application.rb +0 -0
  38. data/spec/{sample → sample_war}/app/helpers/application_helper.rb +0 -0
  39. data/spec/{sample → sample_war}/config/boot.rb +0 -0
  40. data/spec/{sample → sample_war}/config/database.yml +0 -0
  41. data/spec/{sample → sample_war}/config/environment.rb +0 -0
  42. data/spec/{sample → sample_war}/config/environments/development.rb +0 -0
  43. data/spec/{sample → sample_war}/config/environments/production.rb +0 -0
  44. data/spec/{sample → sample_war}/config/environments/test.rb +0 -0
  45. data/spec/{sample → sample_war}/config/initializers/inflections.rb +0 -0
  46. data/spec/{sample → sample_war}/config/initializers/mime_types.rb +0 -0
  47. data/spec/{sample → sample_war}/config/initializers/new_rails_defaults.rb +0 -0
  48. data/spec/{sample → sample_war}/config/routes.rb +0 -0
  49. data/spec/{sample → sample_war}/lib/tasks/utils.rake +0 -0
  50. data/spec/{sample → sample_war}/public/404.html +0 -0
  51. data/spec/{sample → sample_war}/public/422.html +0 -0
  52. data/spec/{sample → sample_war}/public/500.html +0 -0
  53. data/spec/{sample → sample_war}/public/favicon.ico +0 -0
  54. data/spec/{sample → sample_war}/public/index.html +0 -0
  55. data/spec/{sample → sample_war}/public/robots.txt +0 -0
  56. data/spec/spec_helper.rb +40 -0
  57. data/spec/warbler/application_spec.rb +2 -9
  58. data/spec/warbler/config_spec.rb +101 -83
  59. data/spec/warbler/jar_spec.rb +763 -0
  60. data/spec/warbler/task_spec.rb +56 -41
  61. data/spec/warbler/traits_spec.rb +16 -0
  62. data/spec/warbler/war_spec.rb +2 -492
  63. data/warble.rb +36 -32
  64. metadata +57 -35
  65. data/lib/warbler_war.jar +0 -0
@@ -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 => :war
27
+ task :default => wt.name
28
28
 
29
- desc "Generate a configuration file to customize your war"
30
- task :config => "war: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 => "war:pluginize"
33
+ task :pluginize => "#{wt.name}:pluginize"
34
34
 
35
35
  desc "Feature: package gem repository inside a jar"
36
- task :gemjar => "war:gemjar"
36
+ task :gemjar => "#{wt.name}:gemjar"
37
37
 
38
38
  desc "Feature: make an executable archive"
39
- task :executable => "war:executable"
39
+ task :executable => "#{wt.name}:executable"
40
40
 
41
41
  desc "Feature: precompile all Ruby files"
42
- task :compiled => "war:compiled"
42
+ task :compiled => "#{wt.name}:compiled"
43
43
 
44
44
  desc "Display version of Warbler"
45
- task :version => "war:version"
45
+ task :version => "#{wt.name}:version"
46
46
  end
47
47
 
48
48
  # Loads the project Rakefile in a separate application
@@ -5,16 +5,19 @@
5
5
  # See the file LICENSE.txt for details.
6
6
  #++
7
7
 
8
- require 'ostruct'
8
+ require 'set'
9
+ require 'warbler/gems'
10
+ require 'warbler/traits'
9
11
 
10
12
  module Warbler
11
- # Warbler war file assembly configuration class.
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 .war), defaults to the directory name containing
72
- # the Rails application
73
- attr_accessor :war_name
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
- @warbler_home = warbler_home
147
+ super()
148
+
149
+ @warbler_home = warbler_home
135
150
  @warbler_templates = "#{WARBLER_HOME}/lib/warbler/templates"
136
- @features = []
137
- @dirs = TOP_DIRS.select {|d| File.directory?(d)}
138
- @includes = FileList[]
139
- @excludes = FileList[]
140
- @java_libs = default_jar_files
141
- @java_classes = FileList[]
142
- @gems = Warbler::Gems.new
143
- @gem_path = DEFAULT_GEM_PATH
144
- @gem_dependencies = true
145
- @gem_excludes = []
146
- @exclude_logs = true
147
- @public_html = FileList["public/**/*"]
148
- @pathmaps = default_pathmaps
149
- @webxml = default_webxml_config
150
- @rails_root = default_rails_root
151
- @war_name = File.basename(@rails_root)
152
- @bundler = true
153
- @bundle_without = ["development", "test"]
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
- update_gem_path
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{^#{@rails_root}/(.*)}
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 default_pathmaps
190
- p = OpenStruct.new
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
@@ -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