lib/appengine-tools/bundler.rb in appengine-tools-0.0.2 vs lib/appengine-tools/bundler.rb in appengine-tools-0.0.3

- old
+ new

@@ -14,10 +14,11 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require 'appengine-rack' +require 'appengine-tools/boot' require 'appengine-tools/web-xml' require 'appengine-tools/xml-formatter' require 'fileutils' require 'yaml' @@ -76,29 +77,33 @@ end end class AppBundler - EXISTING_JRUBY = /^appengine-jruby-.*jar$/ + EXISTING_JRUBY = /^(jruby-abridged|appengine-jruby)-.*jar$/ EXISTING_RACK = /jruby-rack.*jar$/ EXISTING_APIS = /^appengine-api.*jar$/ - JRUBY_RACK = 'jruby-rack-0.9.4.jar' + JRUBY_RACK = 'jruby-rack-0.9.5.jar' JRUBY_RACK_URL = 'http://kenai.com/projects/jruby-rack/' + "downloads/download/#{JRUBY_RACK}" RACKUP = %q{Dir.chdir('..') if Dir.pwd =~ /WEB-INF$/;} + %q{eval IO.read('config.ru'), nil, 'config.ru', 1} def initialize(root_path) @app = Application.new(root_path) end def bundle + bundle_deps + convert_config_ru + end + + def bundle_deps create_webinf copy_jruby copy_rack copy_sdk - convert_config_ru end def app @app end @@ -115,11 +120,10 @@ token = app.persistent_path_token FileUtils.touch(token) unless File.exists?(token) end def convert_config_ru - AppEngine::Development.boot_jruby(app.root) if !File.exists?(app.config_ru) if File.exists?(app.web_xml) unless File.exists?(app.aeweb_xml) puts "!! Error: you either need a #{app.config_ru} or " puts " #{app.aeweb_xml}." @@ -135,53 +139,74 @@ create_public end end def copy_jruby - current_jruby = find_jars(EXISTING_JRUBY) - if current_jruby.empty? - puts "=> Installing JRuby" - require 'appengine-jruby-jars' - FileUtils.cp([AppEngine::JRubyJars.jruby_jar, - AppEngine::JRubyJars.rubygems_jar], - app.webinf_lib) - end - # TODO else warn if out of date + require 'appengine-jruby-jars' + update_jars( + "JRuby", EXISTING_JRUBY, [AppEngine::JRubyJars.jruby_jar], + /rubygems/, [AppEngine::JRubyJars.rubygems_jar]) end def copy_rack - current_rack = find_jars(EXISTING_RACK) - if current_rack.empty? - # TODO cache this somewhere - puts "=> Retrieving jruby-rack" + update_jars('jruby-rack', EXISTING_RACK, [JRUBY_RACK]) do require 'open-uri' open(JRUBY_RACK_URL) do |src| open(File.join(app.webinf_lib, JRUBY_RACK), 'wb') do |dest| dest.write(src.read) end end end end def copy_sdk - current_apis = find_jars(EXISTING_APIS) - if current_apis.empty? - puts "=> Installing appengine-sdk" - require 'appengine-sdk' - jars = Dir.glob( - "#{AppEngine::SDK::SDK_ROOT}/lib/user/appengine-api*.jar") - # TODO if there's more than 1 we need to check the api version. - FileUtils.cp(jars[0], app.webinf_lib) - end + require 'appengine-sdk' + glob = "appengine-api-1.0-sdk-*.jar" + jars = Dir.glob("#{AppEngine::SDK::SDK_ROOT}/lib/user/#{glob}") + update_jars('appengine-sdk', EXISTING_APIS, jars) end private def find_jars(regex) Dir.entries(app.webinf_lib).grep(regex) rescue [] end + def update_jars(name, regex, jars, opt_regex=nil, opt_jars=[]) + existing = find_jars(regex) + if existing.empty? + message = "Installing #{name}" + jars_to_install = jars + opt_jars + else + has_optional_jars = existing.any? {|j| j =~ opt_regex} + expected_jars = jars + expected_jars.concat(opt_jars) if has_optional_jars + expected = expected_jars.map {|path| File.basename(path)} + if existing.size != expected.size || + (expected & existing) != expected + message = "Updating #{name}" + jars_to_install = expected_jars + end + end + if jars_to_install + puts message + remove_jars(existing) + if block_given? + yield + else + FileUtils.cp(jars_to_install, app.webinf_lib) + end + end + end + + def remove_jars(jars) + paths = jars.map do |jar| + "#{app.webinf_lib}/#{jar}" + end + FileUtils.rm_f(paths) + end + def valid_build return false unless File.exists? app.build_status return false unless File.exists? app.web_xml return false unless File.exists? app.aeweb_xml yaml = YAML.load_file app.build_status @@ -191,43 +216,53 @@ return false unless File.stat(app.aeweb_xml).mtime.eql? yaml[:aeweb_xml] true end def generate_xml - return if valid_build - puts "=> Generating configuration files" - Dir.glob("#{app.webinf_lib}/*.jar").each do |path| - $: << path - end - app_root = app.root - builder = WebXmlBuilder.new do - # First configure the basic jruby-rack settings. - add_jruby_rack_defaults(RACKUP) + return if valid_build + if defined? JRUBY_VERSION + puts "=> Generating configuration files" + Dir.glob("#{app.webinf_lib}/*.jar").each do |path| + $: << path + end + app_root = app.root + builder = WebXmlBuilder.new do + # First configure the basic jruby-rack settings. + add_jruby_rack_defaults(RACKUP) - # Now read the user's rackup file - # TODO generate a skeleton if it's missing - Dir.chdir(app_root) do - eval IO.read('config.ru'), nil, 'config.ru', 1 + # Now read the user's rackup file + # TODO generate a skeleton if it's missing + Dir.chdir(app_root) do + eval IO.read('config.ru'), nil, 'config.ru', 1 + end end + open(app.web_xml, 'w') do |webxml| + xml = AppEngine::Rack::XmlFormatter.format(builder.to_xml) + webxml.write(xml) + end + open(app.aeweb_xml, 'w') do |aeweb| + xml = AppEngine::Rack::XmlFormatter.format(app.rack_app.to_xml) + aeweb.write(xml) + end + yaml = { + :config_ru => File.stat(app.config_ru).mtime, + :aeweb_xml => File.stat(app.aeweb_xml).mtime, + :web_xml => File.stat(app.web_xml).mtime } + open(app.build_status, 'w') { |f| YAML.dump(yaml, f) } + else + AppEngine::Development.boot_jruby(app.root, + :args => ['bundle', app.root], + :exec => false) end - open(app.web_xml, 'w') do |webxml| - xml = AppEngine::Rack::XmlFormatter.format(builder.to_xml) - webxml.write(xml) - end - open(app.aeweb_xml, 'w') do |aeweb| - xml = AppEngine::Rack::XmlFormatter.format(app.rack_app.to_xml) - aeweb.write(xml) - end - yaml = { - :config_ru => File.stat(app.config_ru).mtime, - :aeweb_xml => File.stat(app.aeweb_xml).mtime, - :web_xml => File.stat(app.web_xml).mtime } - open(app.build_status, 'w') { |f| YAML.dump(yaml, f) } end end def self.bundle_app(root_path) AppBundler.new(root_path).bundle + end + + def self.bundle_deps(root_path) + AppBundler.new(root_path).bundle_deps end end end