require 'pathname' module Airake # Project settings for AIR app class Project attr_reader :project_name attr_reader :base_dir, :bin_dir, :src_dir, :lib_dir, :test_dir attr_reader :mxml_path, :appxml_path, :air_path, :swf_path attr_reader :debug attr_reader :mxmlc_path, :adt_path, :adl_path attr_reader :mxmlc_command, :adt_command, :adl_command, :mxmlc_extra_opts Options = [ :mxmlc_path, :adt_path, :bin_dir, :src_dir, :lib_dir, :test_dir, :appxml_path, :air_path, :swf_path, :debug, :mxmlc_command, :adt_command, :adl_command, :mxmlc_extra_opts, :adl_extra_opts, :adt_extra_opts ] # Construct project # # base_dir:: Base (project) directory # mxml_path: Path to the project.mxml (relative) # options:: Override default paths, commands, extra opts, etc; See Options class var def initialize(base_dir, mxml_path, options = {}) @base_dir = base_dir @mxml_path = mxml_path @mxmlc_path = options[:mxmlc_path] || "mxmlc" @adt_path = options[:adt_path] || "adt" @adl_path = options[:adl] || "adl" @bin_dir = options[:bin_dir] || File.join(base_dir, "bin") @src_dir = options[:src_dir] || File.join(base_dir, "src") @lib_dir = options[:lib_dir] || File.join(base_dir, "lib") @test_dir = options[:test_dir] || File.join(base_dir, "test") @project_name = File.basename(@mxml_path, ".mxml") mxml_dir = File.expand_path(File.dirname(@mxml_path)) @appxml_path = options[:appxml_path] || File.join(mxml_dir, "#{project_name}-app.xml") # Dest package files @air_path = options[:air_path] || File.join(@bin_dir, "#{project_name}.air") @swf_path = options[:swf_path] || File.join(@bin_dir, "#{project_name}.swf") @debug = options[:debug].is_a?(TrueClass) || options[:debug] == "true" @mxmlc_extra_opts = options[:mxmlc_extra_opts] @adl_extra_opts = options[:adl_extra_opts] @adt_extra_opts = options[:adt_extra_opts] @mxmlc_command = options[:mxmlc_command] || load_mxmlc_command @adt_command = options[:adt_command] || load_adt_command @adl_command = options[:adl_command] || load_adl_command end # Run the Adobe Developer Tool def run_adt run(adt_command) end # Run the Flex compiler def run_mxmlc run(mxmlc_command) end # Run the Adobe Debug Launcher def run_adl run(adl_command) end # Create project using parameters from rake ENV # # You can set any of the options via ENV; just upcase it. :foo_bar => ENV["FOO_BAR"] # # Booleans must be "true" for true def self.new_from_rake(env, is_test = false) base_dir = env["BASE_DIR"] mxml = is_test ? env["MXML_TEST"] : env["MXML"] # For any option check to see if its in the ENV options = {} Options.each do |option_key| env_key = option_key.to_s.upcase options[option_key] = env[env_key] if env.has_key?(env_key) end puts "Using options: #{options.inspect}" unless options.empty? self.new(base_dir, mxml, options) end protected # Get the mxmlc command def load_mxmlc_command command = [] command << @mxmlc_path command << "+configname=air" command << source_path_option command << "-library-path+=#{@lib_dir}" command << "-output #{@swf_path}" command << debug_option command << @mxmlc_extra_opts command << "-disable-incremental-optimizations=true" command << "-- #{@mxml_path}" command.compact.join(" ") end # Get the ADT command def load_adt_command command = [] command << @adt_path command << @adt_extra_opts command << "-package #{relative_path(@air_path)}" command << relative_path(@appxml_path) command << relative_path(@swf_path) command.compact.join(" ") end # Get the ADL command def load_adl_command command = [] command << @adl_path command << @adl_extra_opts command << @appxml_path command << @base_dir command.compact.join(" ") end # List of directories in lib/ for source_path += def lib_source_paths Dir["#{@lib_dir}/*"].collect { |f| f if File.directory?(f) }.compact + [ @test_dir, @src_dir ] end def source_path_option @source_paths ||= lib_source_paths @source_paths.empty? ? "" : "-source-path #{@source_paths.join(" ")}" end def debug_option "-debug=#{@debug}" if @debug end # Get relative path from base (project) directory def relative_path(path) Pathname.new(path).relative_path_from(Pathname.new(@base_dir)) end # Handle system command failure def fail(cmd, error_status) fail_message = <<-EOS The '#{cmd.split.first}' command failed to run. This could be because this executable isn't in the path. To include mxmlc and fcsh: export PATH="/path_to/flex3sdk_b2_100107/bin:$PATH" To include adl and adt (from AIR SDK): export PATH="/path_to/air_sdk/bin:$PATH" EOS #puts fail_message if error_status != 256 && error_status != 4096 raise "[#{error_status}] Failed to run command: #{cmd}" end # Run the (system) command def run(cmd) puts "Running: #{cmd}" system cmd or fail(cmd, $?) end end end