Class: Warbler::War

Inherits:
Object
  • Object
show all
Defined in:
lib/warbler/war.rb

Overview

Class that holds the files that will be stored in the war file. The #files attribute contains a hash of pathnames inside the war 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

Constant Summary collapse

DEFAULT_MANIFEST =
%{Manifest-Version: 1.0\nCreated-By: Warbler #{Warbler::VERSION}\n\n}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeWar

Returns a new instance of War.



16
17
18
# File 'lib/warbler/war.rb', line 16

def initialize
  @files = {}
end

Instance Attribute Details

#filesObject (readonly)

Returns the value of attribute files.



13
14
15
# File 'lib/warbler/war.rb', line 13

def files
  @files
end

#webinf_filelistObject (readonly)

Returns the value of attribute webinf_filelist.



14
15
16
# File 'lib/warbler/war.rb', line 14

def webinf_filelist
  @webinf_filelist
end

Instance Method Details

#add_bundler_files(config) ⇒ Object

Add Bundler Gemfiles to the war file.



168
169
170
171
172
173
174
175
# File 'lib/warbler/war.rb', line 168

def add_bundler_files(config)
  if config.bundler
    @files[apply_pathmaps(config, 'Gemfile', :application)] = 'Gemfile'
    if File.exist?('Gemfile.lock')
      @files[apply_pathmaps(config, 'Gemfile.lock', :application)] = 'Gemfile.lock'
    end
  end
end

#add_manifest(config = nil) ⇒ Object

Add a manifest file either from config or by making a default manifest.



87
88
89
90
91
92
93
94
95
# File 'lib/warbler/war.rb', line 87

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_webxml(config) ⇒ Object

Add web.xml and other WEB-INF configuration files from config.webinf_files to the war file.



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/warbler/war.rb', line 73

def add_webxml(config)
  config.webinf_files.each do |wf|
    if wf =~ /\.erb$/
      require 'erb'
      erb = ERB.new(File.open(wf) {|f| f.read })
      contents = StringIO.new(erb.result(erb_binding(config.webxml)))
      @files[apply_pathmaps(config, wf, :webinf)] = contents
    else
      @files[apply_pathmaps(config, wf, :webinf)] = wf
    end
  end
end

#apply(config) ⇒ Object

Apply the information in a Warbler::Config object in order to look for files to put into this war file.



46
47
48
49
50
51
52
53
54
55
# File 'lib/warbler/war.rb', line 46

def apply(config)
  find_webinf_files(config)
  find_java_libs(config)
  find_java_classes(config)
  find_gems_files(config)
  find_public_files(config)
  add_webxml(config)
  add_manifest(config)
  add_bundler_files(config)
end

#compile(config) ⇒ Object



20
21
22
23
24
25
26
27
# File 'lib/warbler/war.rb', line 20

def compile(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?

  run_javac(config, config.compiled_ruby_files)
  replace_compiled_ruby_files(config, config.compiled_ruby_files)
end

#create(config_or_path) ⇒ Object

Create the war file. The single argument can either be a Warbler::Config or a filename of the war file to create.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/warbler/war.rb', line 59

def create(config_or_path)
  war_path = config_or_path
  if Warbler::Config === config_or_path
    war_path = "#{config_or_path.war_name}.war"
    war_path = File.join(config_or_path.autodeploy_dir, war_path) if config_or_path.autodeploy_dir
  end
  rm_f war_path
  ensure_directory_entries
  puts "Creating #{war_path}"
  create_war war_path, @files
end

#find_gems_files(config) ⇒ Object

Add gems to WEB-INF/gems



113
114
115
# File 'lib/warbler/war.rb', line 113

def find_gems_files(config)
  config.gems.each {|gem, version| find_single_gem_files(config, gem, version) }
end

#find_java_classes(config) ⇒ Object

Add java classes to WEB-INF/classes.



103
104
105
# File 'lib/warbler/war.rb', line 103

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.



98
99
100
# File 'lib/warbler/war.rb', line 98

def find_java_libs(config)
  config.java_libs.map {|lib| add_with_pathmaps(config, lib, :java_libs) }
end

#find_public_files(config) ⇒ Object

Add public/static assets to the root of the war file.



108
109
110
# File 'lib/warbler/war.rb', line 108

def find_public_files(config)
  config.public_html.map {|f| add_with_pathmaps(config, f, :public_html) }
end

#find_single_gem_files(config, gem_pattern, version = nil) ⇒ Object

Add a single gem to WEB-INF/gems



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/warbler/war.rb', line 118

def find_single_gem_files(config, gem_pattern, version = nil)
  if Gem::Specification === gem_pattern
    spec = gem_pattern
  else
    gem = case gem_pattern
          when Gem::Dependency
            gem_pattern
          else
            Gem::Dependency.new(gem_pattern, Gem::Requirement.create(version))
          end

    # skip development dependencies
    return if gem.respond_to?(:type) and gem.type != :runtime

    matched = Gem.source_index.search(gem)
    fail "gem '#{gem}' not installed" if matched.empty?
    spec = matched.last
  end

  # skip gems with no load path
  return if spec.loaded_from == ""

  add_with_pathmaps(config, spec.loaded_from, :gemspecs)
  spec.files.each do |f|
    next if config.gem_excludes && config.gem_excludes.any? {|rx| f =~ rx }
    src = File.join(spec.full_gem_path, f)
    # some gemspecs may have incorrect file listings
    next unless File.exist?(src)
    @files[apply_pathmaps(config, File.join(spec.full_name, f), :gems)] = src
  end

  spec.dependencies.each {|dep| find_single_gem_files(config, dep) } if config.gem_dependencies
end

#find_webinf_files(config) ⇒ Object

Add all application directories and files to WEB-INF.



153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/warbler/war.rb', line 153

def find_webinf_files(config)
  config.dirs.select do |d|
    exists = File.directory?(d)
    warn "warning: 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
  @webinf_filelist = FileList[*(config.dirs.map{|d| "#{d}/**/*"})]
  @webinf_filelist.include *(config.includes.to_a)
  @webinf_filelist.exclude *(config.excludes.to_a)
  @webinf_filelist.map {|f| add_with_pathmaps(config, f, :application) }
end

#replace_compiled_ruby_files(config, compiled_ruby_files) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/warbler/war.rb', line 34

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("require __FILE__.sub(/\.rb$/, '.class')")
  end
end

#run_javac(config, compiled_ruby_files) ⇒ Object



29
30
31
32
# File 'lib/warbler/war.rb', line 29

def run_javac(config, compiled_ruby_files)
  # Need to use the version of JRuby in the application to compile it
  %x{java -classpath #{config.java_libs.join(File::PATH_SEPARATOR)} org.jruby.Main -S jrubyc \"#{compiled_ruby_files.join('" "')}\"}
end