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.
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/warbler/jar.rb', line 260 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
276 277 278 279 280 |
# File 'lib/warbler/jar.rb', line 276 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
282 283 284 |
# File 'lib/warbler/jar.rb', line 282 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
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/warbler/jar.rb', line 307 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
297 298 299 300 301 302 303 304 305 |
# File 'lib/warbler/jar.rb', line 297 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
330 331 332 333 334 |
# File 'lib/warbler/jar.rb', line 330 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
292 293 294 295 |
# File 'lib/warbler/jar.rb', line 292 def erb_binding(config) webxml = config.webxml binding end |
#expand_erb(file, config) ⇒ Object
286 287 288 289 290 |
# File 'lib/warbler/jar.rb', line 286 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.
245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/warbler/jar.rb', line 245 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 238 239 240 241 242 |
# 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 if File.exist?(spec.gem_build_complete_path) base_dir = Pathname.new(spec.base_dir) gem_build_complete_path = Pathname.new(spec.gem_build_complete_path) @files[File.join(config.relative_gem_path, gem_build_complete_path.relative_path_from(base_dir))] = spec.gem_build_complete_path 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 |