lucidimagination-warbler 1.3.2.dev

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 (75) hide show
  1. data/Gemfile +16 -0
  2. data/History.txt +217 -0
  3. data/LICENSE.txt +26 -0
  4. data/Manifest.txt +92 -0
  5. data/README.txt +255 -0
  6. data/Rakefile +103 -0
  7. data/bin/warble +11 -0
  8. data/ext/JarMain.java +148 -0
  9. data/ext/WarMain.java +112 -0
  10. data/ext/WarblerJar.java +182 -0
  11. data/ext/WarblerJarService.java +18 -0
  12. data/lib/warbler.rb +33 -0
  13. data/lib/warbler/application.rb +86 -0
  14. data/lib/warbler/config.rb +223 -0
  15. data/lib/warbler/gems.rb +37 -0
  16. data/lib/warbler/jar.rb +253 -0
  17. data/lib/warbler/task.rb +183 -0
  18. data/lib/warbler/templates/bundler.erb +3 -0
  19. data/lib/warbler/templates/config.erb +1 -0
  20. data/lib/warbler/templates/jar.erb +5 -0
  21. data/lib/warbler/templates/rack.erb +1 -0
  22. data/lib/warbler/templates/rails.erb +1 -0
  23. data/lib/warbler/templates/war.erb +1 -0
  24. data/lib/warbler/traits.rb +107 -0
  25. data/lib/warbler/traits/bundler.rb +104 -0
  26. data/lib/warbler/traits/gemspec.rb +59 -0
  27. data/lib/warbler/traits/jar.rb +56 -0
  28. data/lib/warbler/traits/merb.rb +35 -0
  29. data/lib/warbler/traits/nogemspec.rb +42 -0
  30. data/lib/warbler/traits/rack.rb +33 -0
  31. data/lib/warbler/traits/rails.rb +62 -0
  32. data/lib/warbler/traits/war.rb +197 -0
  33. data/lib/warbler/version.rb +10 -0
  34. data/lib/warbler/war.rb +8 -0
  35. data/lib/warbler_jar.jar +0 -0
  36. data/spec/drb_helper.rb +41 -0
  37. data/spec/sample_bundler/Gemfile.lock +10 -0
  38. data/spec/sample_bundler/config.ru +0 -0
  39. data/spec/sample_jar/History.txt +6 -0
  40. data/spec/sample_jar/Manifest.txt +8 -0
  41. data/spec/sample_jar/README.txt +30 -0
  42. data/spec/sample_jar/lib/sample_jar.rb +6 -0
  43. data/spec/sample_jar/sample_jar.gemspec +40 -0
  44. data/spec/sample_jar/test/test_sample_jar.rb +8 -0
  45. data/spec/sample_war/app/controllers/application.rb +15 -0
  46. data/spec/sample_war/app/helpers/application_helper.rb +3 -0
  47. data/spec/sample_war/config/boot.rb +109 -0
  48. data/spec/sample_war/config/database.yml +19 -0
  49. data/spec/sample_war/config/environment.rb +67 -0
  50. data/spec/sample_war/config/environments/development.rb +17 -0
  51. data/spec/sample_war/config/environments/production.rb +25 -0
  52. data/spec/sample_war/config/environments/test.rb +22 -0
  53. data/spec/sample_war/config/initializers/inflections.rb +10 -0
  54. data/spec/sample_war/config/initializers/mime_types.rb +5 -0
  55. data/spec/sample_war/config/initializers/new_rails_defaults.rb +15 -0
  56. data/spec/sample_war/config/routes.rb +41 -0
  57. data/spec/sample_war/lib/tasks/utils.rake +0 -0
  58. data/spec/sample_war/public/404.html +30 -0
  59. data/spec/sample_war/public/422.html +30 -0
  60. data/spec/sample_war/public/500.html +30 -0
  61. data/spec/sample_war/public/favicon.ico +0 -0
  62. data/spec/sample_war/public/index.html +274 -0
  63. data/spec/sample_war/public/robots.txt +5 -0
  64. data/spec/spec_helper.rb +112 -0
  65. data/spec/warbler/application_spec.rb +95 -0
  66. data/spec/warbler/bundler_spec.rb +136 -0
  67. data/spec/warbler/config_spec.rb +130 -0
  68. data/spec/warbler/gems_spec.rb +40 -0
  69. data/spec/warbler/jar_spec.rb +718 -0
  70. data/spec/warbler/task_spec.rb +170 -0
  71. data/spec/warbler/traits_spec.rb +17 -0
  72. data/spec/warbler/war_spec.rb +14 -0
  73. data/warble.rb +142 -0
  74. data/web.xml.erb +32 -0
  75. metadata +198 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2010-2011 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
+ import java.io.IOException;
9
+ import org.jruby.Ruby;
10
+ import org.jruby.runtime.load.BasicLibraryService;
11
+
12
+ public class WarblerJarService implements BasicLibraryService {
13
+ public boolean basicLoad(final Ruby runtime) throws IOException {
14
+ WarblerJar.create(runtime);
15
+ return true;
16
+ }
17
+ }
18
+
@@ -0,0 +1,33 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 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
+ # Warbler is a lightweight, flexible, Rake-based system for packaging
9
+ # your Ruby applications into .jar or .war files.
10
+ module Warbler
11
+ WARBLER_HOME = File.expand_path(File.dirname(__FILE__) + '/..') unless defined?(WARBLER_HOME)
12
+
13
+ class << self
14
+ # An instance of Warbler::Application used by the +warble+ command.
15
+ attr_accessor :application
16
+ # Set Warbler.framework_detection to false to disable
17
+ # auto-detection based on application configuration.
18
+ attr_accessor :framework_detection
19
+ attr_writer :project_application
20
+ end
21
+
22
+ # Warbler loads the project Rakefile in a separate Rake application
23
+ # from the one where the Warbler tasks are run.
24
+ def self.project_application
25
+ application.load_project_rakefile if application
26
+ @project_application || Rake.application
27
+ end
28
+ self.framework_detection = true
29
+ end
30
+
31
+ require 'warbler/version'
32
+ require 'warbler/task'
33
+ require 'warbler/application'
@@ -0,0 +1,86 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 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
+
10
+ # Extension of Rake::Application that allows the +warble+ command to
11
+ # report its name properly and inject its own tasks without a
12
+ # Rakefile.
13
+ class Warbler::Application < Rake::Application
14
+ def initialize
15
+ super
16
+ Warbler.application = self
17
+ @project_loaded = false
18
+ end
19
+
20
+ # Sets the application name and loads Warbler's own tasks
21
+ def load_rakefile
22
+ @name = 'warble'
23
+
24
+ # Load the main warbler tasks
25
+ wt = Warbler::Task.new
26
+
27
+ task :default => wt.name
28
+
29
+ desc "Generate a configuration file to customize your archive"
30
+ task :config => "#{wt.name}:config"
31
+
32
+ desc "Install Warbler tasks in your Rails application"
33
+ task :pluginize => "#{wt.name}:pluginize"
34
+
35
+ desc "Feature: package gem repository inside a jar"
36
+ task :gemjar => "#{wt.name}:gemjar"
37
+
38
+ desc "Feature: make an executable archive"
39
+ task :executable => "#{wt.name}:executable"
40
+
41
+ desc "Feature: precompile all Ruby files"
42
+ task :compiled => "#{wt.name}:compiled"
43
+
44
+ desc "Display version of Warbler"
45
+ task :version => "#{wt.name}:version"
46
+ end
47
+
48
+ # Loads the project Rakefile in a separate application
49
+ def load_project_rakefile
50
+ return if @project_loaded
51
+ # Load any application rakefiles to aid in autodetecting applications
52
+ app = Warbler.project_application = Rake::Application.new
53
+ Rake.application = app
54
+ Rake::Application::DEFAULT_RAKEFILES.each do |rf|
55
+ if File.exist?(rf)
56
+ load rf
57
+ break
58
+ end
59
+ end
60
+ Rake.application = self
61
+ @project_loaded = true
62
+ end
63
+
64
+ # Run the application: The equivalent code for the +warble+ command
65
+ # is simply <tt>Warbler::Application.new.run</tt>.
66
+ def run
67
+ Rake.application = self
68
+ super
69
+ end
70
+
71
+ # Remap the version option to display Warbler version.
72
+ def standard_rake_options
73
+ super.map do |opt|
74
+ if opt.first == '--version'
75
+ ['--version', '-V', "Display the program version.",
76
+ lambda { |value|
77
+ puts "Warbler version #{Warbler::VERSION}"
78
+ exit
79
+ }
80
+ ]
81
+ else
82
+ opt
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,223 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 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 'set'
9
+ require 'warbler/gems'
10
+ require 'warbler/traits'
11
+
12
+ module Warbler
13
+ # Warbler archive assembly configuration class.
14
+ class Config
15
+ TOP_DIRS = %w(app config lib log vendor)
16
+ FILE = "config/warble.rb"
17
+ BUILD_GEMS = %w(warbler rake rcov)
18
+
19
+ include Traits
20
+
21
+ # Features: additional options controlling how the jar is built.
22
+ # Currently the following features are supported:
23
+ # - gemjar: package the gem repository in a jar file in WEB-INF/lib
24
+ # - executable: embed a web server and make the war executable
25
+ # - compiled: compile .rb files to .class files
26
+ attr_accessor :features
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
+
33
+ # Deprecated: No longer has any effect.
34
+ attr_accessor :staging_dir
35
+
36
+ # Directory where the war file will be written. Can be used to direct
37
+ # Warbler to place your war file directly in your application server's
38
+ # autodeploy directory. Defaults to the root of the application directory.
39
+ attr_accessor :autodeploy_dir
40
+
41
+ # Top-level directories to be copied into WEB-INF. Defaults to
42
+ # names in TOP_DIRS
43
+ attr_accessor :dirs
44
+
45
+ # Additional files beyond the top-level directories to include in the
46
+ # WEB-INF directory
47
+ attr_accessor :includes
48
+
49
+ # Files to exclude from the WEB-INF directory
50
+ attr_accessor :excludes
51
+
52
+ # Java classes and other files to copy to WEB-INF/classes
53
+ attr_accessor :java_classes
54
+
55
+ # Java libraries to copy to WEB-INF/lib
56
+ attr_accessor :java_libs
57
+
58
+ # Rubygems to install into the webapp.
59
+ attr_accessor :gems
60
+
61
+ # Whether to include dependent gems (default true)
62
+ attr_accessor :gem_dependencies
63
+
64
+ # Array of regular expressions matching relative paths in gems to
65
+ # be excluded from the war. Default contains no exclusions.
66
+ attr_accessor :gem_excludes
67
+
68
+ # Whether to exclude **/*.log files (default is true)
69
+ attr_accessor :exclude_logs
70
+
71
+ # Public HTML directory file list, to be copied into the root of the war
72
+ attr_accessor :public_html
73
+
74
+ # Container of pathmaps used for specifying source-to-destination transformations
75
+ # under various situations (<tt>public_html</tt> and <tt>java_classes</tt> are two
76
+ # entries in this structure).
77
+ attr_accessor :pathmaps
78
+
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
85
+
86
+ # Name of a MANIFEST.MF template to use.
87
+ attr_accessor :manifest_file
88
+
89
+ # Files for WEB-INF directory (next to web.xml). Contains web.xml by default.
90
+ # If there are .erb files they will be processed with webxml config.
91
+ attr_accessor :webinf_files
92
+
93
+ # Use Bundler to locate gems if Gemfile is found. Default is true.
94
+ attr_accessor :bundler
95
+
96
+ # An array of Bundler groups to avoid including in the war file.
97
+ # Defaults to ["development", "test"].
98
+ attr_accessor :bundle_without
99
+
100
+ # Path to the pre-bundled gem directory inside the war file. Default is '/WEB-INF/gems'.
101
+ # This also sets 'gem.path' inside web.xml.
102
+ attr_accessor :gem_path
103
+
104
+ # List of ruby files to compile to class files. Default is to
105
+ # compile all .rb files in the application.
106
+ attr_accessor :compiled_ruby_files
107
+
108
+ # Warbler writes an "init" file into the war at this location. JRuby-Rack and possibly other
109
+ # launchers may use this to initialize the Ruby environment.
110
+ attr_accessor :init_filename
111
+
112
+ # Array containing filenames or StringIO's to be concatenated together to form the init file.
113
+ # If the filename ends in .erb the file will be expanded the same way web.xml.erb is; see below.
114
+ attr_accessor :init_contents
115
+
116
+ # Extra configuration for web.xml. Controls how the dynamically-generated web.xml
117
+ # file is generated.
118
+ #
119
+ # * <tt>webxml.jndi</tt> -- the name of one or more JNDI data sources name to be
120
+ # available to the application. Places appropriate &lt;resource-ref&gt; entries
121
+ # in the file.
122
+ # * <tt>webxml.ignored</tt> -- array of key names that will be not used to
123
+ # generate a context param. Defaults to ['jndi', 'booter']
124
+ #
125
+ # Any other key/value pair placed in the open structure will be dumped as a
126
+ # context parameter in the web.xml file. Some of the recognized values are:
127
+ #
128
+ # * <tt>webxml.rails.env</tt> -- the Rails environment to use for the
129
+ # running application, usually either development or production (the
130
+ # default).
131
+ # * <tt>webxml.gem.path</tt> -- the path to your bundled gem directory
132
+ # * <tt>webxml.jruby.min.runtimes</tt> -- minimum number of pooled runtimes to
133
+ # keep around during idle time
134
+ # * <tt>webxml.jruby.max.runtimes</tt> -- maximum number of pooled Rails
135
+ # application runtimes
136
+ #
137
+ # Note that if you attempt to access webxml configuration keys in a conditional,
138
+ # you might not obtain the result you want. For example:
139
+ # <%= webxml.maybe.present.key || 'default' %>
140
+ # doesn't yield the right result. Instead, you need to generate the context parameters:
141
+ # <%= webxml.context_params['maybe.present.key'] || 'default' %>
142
+ attr_accessor :webxml
143
+
144
+ attr_reader :warbler_templates
145
+
146
+ def initialize(warbler_home = WARBLER_HOME)
147
+ super()
148
+
149
+ @warbler_home = warbler_home
150
+ @warbler_templates = "#{WARBLER_HOME}/lib/warbler/templates"
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
169
+ yield self if block_given?
170
+ after_configure
171
+
172
+ @compiled_ruby_files ||= FileList[*@dirs.map {|d| "#{d}/**/*.rb"}]
173
+
174
+ @excludes += ["tmp/war"] if File.directory?("tmp/war")
175
+ @excludes += warbler_vendor_excludes(warbler_home)
176
+ @excludes += FileList["**/*.log"] if @exclude_logs
177
+ end
178
+
179
+ def gems=(value)
180
+ @gems = Warbler::Gems.new(value)
181
+ end
182
+
183
+ def relative_gem_path
184
+ @gem_path[1..-1]
185
+ end
186
+
187
+ def define_tasks
188
+ task "gemjar" do
189
+ self.features << "gemjar"
190
+ end
191
+ task "executable" do
192
+ self.features << "executable"
193
+ end
194
+ end
195
+
196
+ # Deprecated
197
+ def war_name
198
+ $stderr.puts "config.war_name deprecated; replace with config.jar_name" #:nocov:
199
+ jar_name #:nocov:
200
+ end
201
+
202
+ # Deprecated
203
+ def war_name=(w)
204
+ $stderr.puts "config.war_name deprecated; replace with config.jar_name" #:nocov:
205
+ self.jar_name = w #:nocov:
206
+ end
207
+
208
+ private
209
+ def warbler_vendor_excludes(warbler_home)
210
+ warbler = File.expand_path(warbler_home)
211
+ if warbler =~ %r{^#{Dir.getwd}/(.*)}
212
+ FileList["#{$1}"]
213
+ else
214
+ []
215
+ end
216
+ end
217
+
218
+ def dump
219
+ YAML::dump(self.dup.tap{|c| c.dump_traits })
220
+ end
221
+ public :dump
222
+ end
223
+ end
@@ -0,0 +1,37 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 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,253 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 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 'zip/zip'
9
+ require 'stringio'
10
+ require 'pathname'
11
+
12
+ module Warbler
13
+ # Class that holds the files that will be stored in the jar file.
14
+ # The #files attribute contains a hash of pathnames inside the jar
15
+ # file to their contents. Contents can be one of:
16
+ # * +nil+ representing a directory entry
17
+ # * Any object responding to +read+ representing an in-memory blob
18
+ # * A String filename pointing to a file on disk
19
+ class Jar
20
+ DEFAULT_MANIFEST = %{Manifest-Version: 1.0\nCreated-By: Warbler #{Warbler::VERSION}\n\n}
21
+
22
+ attr_reader :files
23
+ attr_reader :app_filelist
24
+
25
+ def initialize
26
+ @files = {}
27
+ end
28
+
29
+ def contents(entry)
30
+ file = files[entry]
31
+ file.respond_to?(:read) ? file.read : File.open(file) {|f| f.read }
32
+ end
33
+
34
+ def compile(config)
35
+ # Compiling all Ruby files we can find -- do we need to allow an
36
+ # option to configure what gets compiled?
37
+ return if config.compiled_ruby_files.nil? || config.compiled_ruby_files.empty?
38
+
39
+ run_javac(config, config.compiled_ruby_files)
40
+ replace_compiled_ruby_files(config, config.compiled_ruby_files)
41
+ end
42
+
43
+ def run_javac(config, compiled_ruby_files)
44
+ # Need to use the version of JRuby in the application to compile it
45
+ %x{java -classpath #{config.java_libs.join(File::PATH_SEPARATOR)} org.jruby.Main -S jrubyc \"#{compiled_ruby_files.join('" "')}\"}
46
+ end
47
+
48
+ def replace_compiled_ruby_files(config, compiled_ruby_files)
49
+ # Exclude the rb files and recreate them. This
50
+ # prevents the original contents being used.
51
+ config.excludes += compiled_ruby_files
52
+
53
+ compiled_ruby_files.each do |ruby_source|
54
+ files[apply_pathmaps(config, ruby_source, :application)] = StringIO.new("require __FILE__.sub(/\.rb$/, '.class')")
55
+ end
56
+ end
57
+
58
+ # Apply the information in a Warbler::Config object in order to
59
+ # look for files to put into this war file.
60
+ def apply(config)
61
+ find_application_files(config)
62
+ find_java_libs(config)
63
+ find_java_classes(config)
64
+ find_gems_files(config)
65
+ add_manifest(config)
66
+ add_init_file(config)
67
+ apply_traits(config)
68
+ end
69
+
70
+ # Create the jar or war file. The single argument can either be a
71
+ # Warbler::Config or a filename of the file to create.
72
+ def create(config_or_path)
73
+ path = config_or_path
74
+ if Warbler::Config === config_or_path
75
+ path = "#{config_or_path.jar_name}.#{config_or_path.jar_extension}"
76
+ path = File.join(config_or_path.autodeploy_dir, path) if config_or_path.autodeploy_dir
77
+ end
78
+ rm_f path
79
+ ensure_directory_entries
80
+ puts "Creating #{path}"
81
+ create_jar path, @files
82
+ end
83
+
84
+ # Invoke a hook to allow the project traits to add or modify the archive contents.
85
+ def apply_traits(config)
86
+ config.update_archive(self)
87
+ end
88
+
89
+ # Add a manifest file either from config or by making a default manifest.
90
+ def add_manifest(config = nil)
91
+ unless @files.keys.detect{|k| k =~ /^META-INF\/MANIFEST\.MF$/i}
92
+ if config && config.manifest_file
93
+ @files['META-INF/MANIFEST.MF'] = config.manifest_file
94
+ else
95
+ @files['META-INF/MANIFEST.MF'] = StringIO.new(DEFAULT_MANIFEST)
96
+ end
97
+ end
98
+ end
99
+
100
+ # Add java libraries to WEB-INF/lib.
101
+ def find_java_libs(config)
102
+ config.java_libs.map {|lib| add_with_pathmaps(config, lib, :java_libs) }
103
+ end
104
+
105
+ # Add java classes to WEB-INF/classes.
106
+ def find_java_classes(config)
107
+ config.java_classes.map {|f| add_with_pathmaps(config, f, :java_classes) }
108
+ end
109
+
110
+ # Add gems to WEB-INF/gems
111
+ def find_gems_files(config)
112
+ config.gems.each {|gem, version| find_single_gem_files(config, gem, version) }
113
+ end
114
+
115
+ # Add a single gem to WEB-INF/gems
116
+ def find_single_gem_files(config, gem_pattern, version = nil)
117
+ if Gem::Specification === gem_pattern
118
+ spec = gem_pattern
119
+ else
120
+ gem = case gem_pattern
121
+ when Gem::Dependency
122
+ gem_pattern
123
+ else
124
+ Gem::Dependency.new(gem_pattern, Gem::Requirement.create(version))
125
+ end
126
+
127
+ # skip development dependencies
128
+ return if gem.respond_to?(:type) and gem.type != :runtime
129
+
130
+ matched = Gem.source_index.search(gem)
131
+ fail "gem '#{gem}' not installed" if matched.empty?
132
+ spec = matched.last
133
+ end
134
+
135
+ full_gem_path = Pathname.new(spec.full_gem_path)
136
+
137
+ # skip gems whose full_gem_path does not exist
138
+ ($stderr.puts "warning: skipping #{spec.name} (#{full_gem_path.to_s} does not exist)" ; return) unless full_gem_path.exist?
139
+
140
+ @files[apply_pathmaps(config, "#{spec.full_name}.gemspec", :gemspecs)] = StringIO.new(spec.to_ruby)
141
+ FileList["#{full_gem_path.to_s}/**/*"].each do |src|
142
+ f = Pathname.new(src).relative_path_from(full_gem_path).to_s
143
+ next if config.gem_excludes && config.gem_excludes.any? {|rx| f =~ rx }
144
+ @files[apply_pathmaps(config, File.join(spec.full_name, f), :gems)] = src
145
+ end
146
+
147
+ spec.dependencies.each {|dep| find_single_gem_files(config, dep) } if config.gem_dependencies
148
+ end
149
+
150
+ # Add all application directories and files to the archive.
151
+ def find_application_files(config)
152
+ config.dirs.select do |d|
153
+ exists = File.directory?(d)
154
+ $stderr.puts "warning: application directory `#{d}' does not exist or is not a directory; skipping" unless exists
155
+ exists
156
+ end.each do |d|
157
+ @files[apply_pathmaps(config, d, :application)] = nil
158
+ end
159
+ @app_filelist = FileList[*(config.dirs.map{|d| "#{d}/**/*"})]
160
+ @app_filelist.include *(config.includes.to_a)
161
+ @app_filelist.exclude *(config.excludes.to_a)
162
+ @app_filelist.map {|f| add_with_pathmaps(config, f, :application) }
163
+ end
164
+
165
+ # Add init.rb file to the war file.
166
+ def add_init_file(config)
167
+ if config.init_contents
168
+ contents = ''
169
+ config.init_contents.each do |file|
170
+ if file.respond_to?(:read)
171
+ contents << file.read
172
+ elsif File.extname(file) == '.erb'
173
+ contents << expand_erb(file, config).read
174
+ else
175
+ contents << File.read(file)
176
+ end
177
+ end
178
+ @files[config.init_filename] = StringIO.new(contents)
179
+ end
180
+ end
181
+
182
+ def add_with_pathmaps(config, f, map_type)
183
+ @files[apply_pathmaps(config, f, map_type)] = f
184
+ end
185
+
186
+ def expand_erb(file, config)
187
+ require 'erb'
188
+ erb = ERB.new(File.open(file) {|f| f.read })
189
+ StringIO.new(erb.result(erb_binding(config)))
190
+ end
191
+
192
+ def erb_binding(config)
193
+ webxml = config.webxml
194
+ binding
195
+ end
196
+
197
+ def apply_pathmaps(config, file, pathmaps)
198
+ file = file[2..-1] if file =~ /^\.\//
199
+ pathmaps = config.pathmaps.send(pathmaps)
200
+ pathmaps.each do |p|
201
+ file = file.pathmap(p)
202
+ end if pathmaps
203
+ file
204
+ end
205
+
206
+ def ensure_directory_entries
207
+ files.select {|k,v| !v.nil? }.each do |k,v|
208
+ dir = File.dirname(k)
209
+ while dir != "." && !files.has_key?(dir)
210
+ files[dir] = nil
211
+ dir = File.dirname(dir)
212
+ end
213
+ end
214
+ end
215
+
216
+ def create_jar(war_file, entries)
217
+ Zip::ZipFile.open(war_file, Zip::ZipFile::CREATE) do |zipfile|
218
+ entries.keys.sort.each do |entry|
219
+ src = entries[entry]
220
+ if src.respond_to?(:read)
221
+ zipfile.get_output_stream(entry) {|f| f << src.read }
222
+ elsif src.nil? || File.directory?(src)
223
+ $stderr.puts "directory symlinks are not followed unless using JRuby; #{entry} contents not in archive" \
224
+ if File.symlink?(entry) && !defined?(JRUBY_VERSION)
225
+ zipfile.mkdir(entry)
226
+ elsif File.symlink?(src)
227
+ zipfile.get_output_stream(entry) {|f| f << File.read(src) }
228
+ else
229
+ zipfile.add(entry, src)
230
+ end
231
+ end
232
+ end
233
+ end
234
+
235
+ def entry_in_jar(jar, entry)
236
+ Zip::ZipFile.open(jar) do |zf|
237
+ zf.get_input_stream(entry) {|io| StringIO.new(io.read) }
238
+ end
239
+ end
240
+
241
+ # Java-boosted jar creation for JRuby; replaces #create_jar and
242
+ # #entry_in_jar with Java version
243
+ require 'warbler_jar' if defined?(JRUBY_VERSION) && JRUBY_VERSION >= "1.5"
244
+ end
245
+
246
+ # Warbler::War is Deprecated. Please use Warbler::Jar.
247
+ class War < Jar
248
+ def initialize(*)
249
+ super
250
+ $stderr.puts "Warbler::War is deprecated. Please replace all occurrences with Warbler::Jar."
251
+ end
252
+ end
253
+ end