Class: Warbler::Jar
- Inherits:
-
Object
- Object
- Warbler::Jar
- Includes:
- PathmapHelper, PlatformHelper, RakeHelper
- Defined in:
- lib/warbler/jar.rb
Overview
Class that holds the files that will be stored in the jar file. The #files attribute contains a hash of pathnames inside the jar file to their contents. Contents can be one of:
-
nil
representing a directory entry -
Any object responding to
read
representing an in-memory blob -
A String filename pointing to a file on disk
Direct Known Subclasses
Constant Summary collapse
- DEFAULT_MANIFEST =
%{Manifest-Version: 1.0\nCreated-By: Warbler #{Warbler::VERSION}\n\n}
- DEFAULT_COMPILED_FILES_SLICE =
2500
Instance Attribute Summary collapse
-
#app_filelist ⇒ Object
readonly
Returns the value of attribute app_filelist.
-
#files ⇒ Object
readonly
Returns the value of attribute files.
Instance Method Summary collapse
-
#add_init_file(config) ⇒ Object
Add init.rb file to the war file.
-
#add_manifest(config = nil) ⇒ Object
Add a manifest file either from config or by making a default manifest.
- #add_script_files(config) ⇒ Object
- #add_with_pathmaps(config, f, map_type) ⇒ Object
-
#apply(config) ⇒ Object
Apply the information in a Warbler::Config object in order to look for files to put into this war file.
-
#apply_traits(config) ⇒ Object
Invoke a hook to allow the project traits to add or modify the archive contents.
- #compile(config) ⇒ Object
- #contents(entry) ⇒ Object
-
#create(config_or_path) ⇒ Object
Create the jar or war file.
- #create_jar(jar_path, entries) ⇒ Object
- #ensure_directory_entries ⇒ Object
- #entry_in_jar(jar, entry) ⇒ Object
- #erb_binding(config) ⇒ Object
- #expand_erb(file, config) ⇒ Object
-
#find_application_files(config) ⇒ Object
Add all application directories and files to the archive.
-
#find_gems_files(config) ⇒ Object
Add gems to WEB-INF/gems.
-
#find_java_classes(config) ⇒ Object
Add java classes to WEB-INF/classes.
-
#find_java_libs(config) ⇒ Object
Add java libraries to WEB-INF/lib.
-
#find_single_gem_files(config, spec) ⇒ Object
Add a single gem to WEB-INF/gems.
- #gather_all_rb_files(config) ⇒ Object
-
#initialize ⇒ Jar
constructor
A new instance of Jar.
- #java_version(config) ⇒ Object
- #replace_compiled_ruby_files(config, compiled_ruby_files) ⇒ Object
- #replace_compiled_ruby_files_and_gems(config, compiled_ruby_files) ⇒ Object
- #run_jrubyc(config, compiled_ruby_files) ⇒ Object (also: #run_javac)
Methods included from PlatformHelper
Methods included from RakeHelper
Methods included from PathmapHelper
Constructor Details
#initialize ⇒ Jar
Returns a new instance of Jar.
29 30 31 |
# File 'lib/warbler/jar.rb', line 29 def initialize @files = {} end |
Instance Attribute Details
#app_filelist ⇒ Object (readonly)
Returns the value of attribute app_filelist.
27 28 29 |
# File 'lib/warbler/jar.rb', line 27 def app_filelist @app_filelist end |
#files ⇒ Object (readonly)
Returns the value of attribute files.
26 27 28 |
# File 'lib/warbler/jar.rb', line 26 def files @files end |
Instance Method Details
#add_init_file(config) ⇒ Object
Add init.rb file to the war file.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/warbler/jar.rb', line 255 def add_init_file(config) if config.init_contents contents = '' config.init_contents.each do |file| if file.respond_to?(:read) contents << file.read elsif File.extname(file) == '.erb' contents << (file, config).read else contents << File.read(file) end end @files[config.init_filename] = StringIO.new(contents) end end |
#add_manifest(config = nil) ⇒ Object
Add a manifest file either from config or by making a default manifest.
185 186 187 188 189 190 191 192 193 |
# File 'lib/warbler/jar.rb', line 185 def add_manifest(config = nil) unless @files.keys.detect{ |k| k =~ /^META-INF\/MANIFEST\.MF$/i } if config && config.manifest_file @files['META-INF/MANIFEST.MF'] = config.manifest_file else @files['META-INF/MANIFEST.MF'] = StringIO.new(DEFAULT_MANIFEST) end end end |
#add_script_files(config) ⇒ Object
271 272 273 274 275 |
# File 'lib/warbler/jar.rb', line 271 def add_script_files(config) config.script_files.each do |file| @files["META-INF/#{File.basename(file)}"] = StringIO.new(File.read(file)) end end |
#add_with_pathmaps(config, f, map_type) ⇒ Object
277 278 279 |
# File 'lib/warbler/jar.rb', line 277 def add_with_pathmaps(config, f, map_type) @files[apply_pathmaps(config, f, map_type)] = f end |
#apply(config) ⇒ Object
Apply the information in a Warbler::Config object in order to look for files to put into this war file.
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/warbler/jar.rb', line 151 def apply(config) find_application_files(config) find_java_libs(config) find_java_classes(config) find_gems_files(config) add_manifest(config) add_init_file(config) add_script_files(config) apply_traits(config) end |
#apply_traits(config) ⇒ Object
Invoke a hook to allow the project traits to add or modify the archive contents.
180 181 182 |
# File 'lib/warbler/jar.rb', line 180 def apply_traits(config) config.update_archive(self) end |
#compile(config) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/warbler/jar.rb', line 38 def compile(config) find_gems_files(config) # Compiling all Ruby files we can find -- do we need to allow an # option to configure what gets compiled? return if (config.compiled_ruby_files.nil? || config.compiled_ruby_files.empty?) && files.empty? if config.compile_gems ruby_files = gather_all_rb_files(config) run_jrubyc(config, ruby_files.values) replace_compiled_ruby_files_and_gems(config, ruby_files) else compiled_ruby_files = config.compiled_ruby_files - config.excludes.to_a run_jrubyc(config, compiled_ruby_files) replace_compiled_ruby_files(config, compiled_ruby_files) end end |
#contents(entry) ⇒ Object
33 34 35 36 |
# File 'lib/warbler/jar.rb', line 33 def contents(entry) file = files[entry] file.respond_to?(:read) ? file.read : File.read(file) end |
#create(config_or_path) ⇒ Object
Create the jar or war file. The single argument can either be a Warbler::Config or a filename of the file to create.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/warbler/jar.rb', line 164 def create(config_or_path) path = config_or_path if Warbler::Config === config_or_path path = "#{config_or_path.jar_name}.#{config_or_path.jar_extension}" path = File.join(config_or_path.autodeploy_dir, path) if config_or_path.autodeploy_dir end rm_f path ensure_directory_entries if Warbler::Config === config_or_path @files.delete("#{config_or_path.jar_name}/#{path}") end puts "Creating #{path}" unless silent? create_jar path, @files end |
#create_jar(jar_path, entries) ⇒ Object
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/warbler/jar.rb', line 302 def create_jar(jar_path, entries) ZipSupport.create(jar_path) do |zipfile| entries.keys.sort.each do |entry| src = entries[entry] if src.respond_to?(:read) zipfile.get_output_stream(entry) { |f| f << src.read } elsif src.nil? || File.directory?(src) if File.symlink?(entry) && ! defined?(JRUBY_VERSION) warn "directory symlinks are not followed unless using JRuby; " + "#{entry.inspect} contents not in archive" end zipfile.mkdir(entry.dup) # in case it's frozen rubyzip 0.9.6.1 workaround elsif File.symlink?(src) zipfile.get_output_stream(entry) { |f| f << File.read(src) } elsif File.exist?(src) zipfile.add(entry, src) else warn "file not found; #{entry.inspect} not in archive" end end end end |
#ensure_directory_entries ⇒ Object
292 293 294 295 296 297 298 299 300 |
# File 'lib/warbler/jar.rb', line 292 def ensure_directory_entries files.select {|k,v| !v.nil? }.each do |k,v| dir = File.dirname(k) while dir != "." && !files.has_key?(dir) files[dir] = nil dir = File.dirname(dir) end end end |
#entry_in_jar(jar, entry) ⇒ Object
325 326 327 328 329 |
# File 'lib/warbler/jar.rb', line 325 def entry_in_jar(jar, entry) ZipSupport.open(jar) do |zf| zf.get_input_stream(entry) {|io| StringIO.new(io.read) } end end |
#erb_binding(config) ⇒ Object
287 288 289 290 |
# File 'lib/warbler/jar.rb', line 287 def erb_binding(config) webxml = config.webxml binding end |
#expand_erb(file, config) ⇒ Object
281 282 283 284 285 |
# File 'lib/warbler/jar.rb', line 281 def (file, config) require 'erb' erb = ERB.new(File.read(file), nil, '-') StringIO.new(erb.result(erb_binding(config))) end |
#find_application_files(config) ⇒ Object
Add all application directories and files to the archive.
240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/warbler/jar.rb', line 240 def find_application_files(config) config.dirs.select do |d| exists = File.directory?(d) warn "application directory `#{d}' does not exist or is not a directory; skipping" unless exists exists end.each do |d| @files[apply_pathmaps(config, d, :application)] = nil end @app_filelist = FileList[*(config.dirs.map{|d| %W{#{d}/**/*/**/* #{d}/*}}.flatten)] @app_filelist.include( *(config.includes.to_a) ) @app_filelist.exclude( *(config.excludes.to_a) ) @app_filelist.map {|f| add_with_pathmaps(config, f, :application) } end |
#find_gems_files(config) ⇒ Object
Add gems to WEB-INF/gems
206 207 208 209 210 |
# File 'lib/warbler/jar.rb', line 206 def find_gems_files(config) unless @compiled && config.compile_gems config.gems.specs(config.gem_dependencies).each {|spec| find_single_gem_files(config, spec) } end end |
#find_java_classes(config) ⇒ Object
Add java classes to WEB-INF/classes.
201 202 203 |
# File 'lib/warbler/jar.rb', line 201 def find_java_classes(config) config.java_classes.map { |f| add_with_pathmaps(config, f, :java_classes) } end |
#find_java_libs(config) ⇒ Object
Add java libraries to WEB-INF/lib.
196 197 198 |
# File 'lib/warbler/jar.rb', line 196 def find_java_libs(config) config.java_libs.map { |lib| add_with_pathmaps(config, lib, :java_libs) } end |
#find_single_gem_files(config, spec) ⇒ Object
Add a single gem to WEB-INF/gems
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/warbler/jar.rb', line 213 def find_single_gem_files(config, spec) full_gem_path = Pathname.new(spec.full_gem_path) # skip gems whose full_gem_path does not exist unless full_gem_path.exist? # its very likely that its a default gem e.g. json/jruby-openssl : if (Gem.default_dir rescue nil) && full_gem_path.to_s.start_with?(Gem.default_dir) # OK if the gem does not exists as its un-packed on the "shared" path # ... at least gem spec.spec_file should exists although not crucial if JRUBY_VERSION != JRubyJars::VERSION warn "skipping #{spec.name} default gem (assuming its part of jruby-jars #{JRubyJars::VERSION})" unless silent? end else warn "skipping #{spec.name} gem (#{full_gem_path.to_s} does not exist)" end return end @files[apply_pathmaps(config, "#{spec.full_name}.gemspec", :gemspecs)] = StringIO.new(spec.to_ruby) FileList["#{full_gem_path.to_s}/**/*"].each do |src| f = Pathname.new(src).relative_path_from(full_gem_path).to_s next if config.gem_excludes && config.gem_excludes.any? {|rx| f =~ rx } @files[apply_pathmaps(config, File.join(spec.full_name, f), :gems)] = src end end |
#gather_all_rb_files(config) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/warbler/jar.rb', line 125 def gather_all_rb_files(config) FileUtils.mkdir_p('tmp') # Gather all the files in the files list and copy them to the tmp directory files_to_compile = files.select { |_, f| !f.is_a?(StringIO) && f.end_with?('.rb') } files_to_compile.each do |jar_file, rb| FileUtils.mkdir_p(File.dirname(File.join('tmp', jar_file))) new_rb = File.join('tmp', jar_file) FileUtils.copy(rb, new_rb) files_to_compile[jar_file] = new_rb end # Gather all the application files which the user wrote (not dependencies) main_files_to_compile = config.compiled_ruby_files - config.excludes.to_a main_files_to_compile.each do |f| FileUtils.mkdir_p(File.dirname(File.join('tmp', f))) FileUtils.copy(f, File.join('tmp', f)) end main_files_to_compile = main_files_to_compile.inject({}) {|h,f| h.merge!(f => f) } files.keys.each do |k| # Update files list to point to the temporary file files[k] = files_to_compile[k] || main_files_to_compile[k] || files[k] end main_files_to_compile.merge(files_to_compile) end |
#java_version(config) ⇒ Object
90 91 92 |
# File 'lib/warbler/jar.rb', line 90 def java_version(config) config.bytecode_version ? "-Djava.specification.version=#{config.bytecode_version}" : '' end |
#replace_compiled_ruby_files(config, compiled_ruby_files) ⇒ Object
94 95 96 97 98 99 100 101 102 |
# File 'lib/warbler/jar.rb', line 94 def replace_compiled_ruby_files(config, compiled_ruby_files) # Exclude the rb files and recreate them. This # prevents the original contents being used. config.excludes += compiled_ruby_files compiled_ruby_files.each do |ruby_source| files[apply_pathmaps(config, ruby_source, :application)] = StringIO.new("load __FILE__.sub(/\.rb$/, '.class')") end end |
#replace_compiled_ruby_files_and_gems(config, compiled_ruby_files) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/warbler/jar.rb', line 104 def replace_compiled_ruby_files_and_gems(config, compiled_ruby_files) # Exclude the rb files and recreate them. This # prevents the original contents being used. config.excludes += compiled_ruby_files.keys compiled_ruby_files.each do |inside_jar, file_system_location| # The gems are already inside the gems folder inside the jar, however when using the :gems pathmap, they will # get put into the gems/gems folder, to prevent this we chop off the first gems folder directory inside_jar = inside_jar.dup if inside_jar.split(File::SEPARATOR).first == 'gems' inside_jar = inside_jar.split(File::SEPARATOR)[1..-1].join(File::SEPARATOR) pathmap = :gems else pathmap = :application end files[apply_pathmaps(config, inside_jar, pathmap)] = StringIO.new("load __FILE__.sub(/\.rb$/, '.class')") files[apply_pathmaps(config, inside_jar.sub(/\.rb$/, '.class'), pathmap)] = file_system_location.sub(/\.rb$/, '.class') end end |
#run_jrubyc(config, compiled_ruby_files) ⇒ Object Also known as: run_javac
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/warbler/jar.rb', line 57 def run_jrubyc(config, compiled_ruby_files) slice_size = (ENV['WARBLER_COMPILED_FILES_SLICE'] || 0).to_i slice_size = DEFAULT_COMPILED_FILES_SLICE if slice_size <= 0 compiled_ruby_files.each_slice(slice_size) do |files| files = "\"#{files.join('" "')}\"" classpath = config.java_libs.map { |lib| "\"#{lib.gsub('"', '\\"')}\"" }.join(File::PATH_SEPARATOR) # Need to use the version of JRuby in the application to compile it javac_cmd = %Q{java -classpath #{classpath} #{java_version(config)} org.jruby.Main -S jrubyc #{(config)} #{files}} if which('java').nil? && which('env') sh_jrubyc %Q{env -i #{javac_cmd}} else sh_jrubyc javac_cmd end end @compiled = true end |