# # File:: %RS_TOOLSLIB%/pipeline/resourcing/converters/converter_pack.rb # Description:: RPF builder for convert system. # # Author:: Luke Openshaw # Author:: David Muir # Date:: 14 July 2008 # # Content convert specifics for RPF file assets. This class should not be # used directly - use the ConvertSystem class instead. # #----------------------------------------------------------------------------- # Uses #----------------------------------------------------------------------------- require 'pipeline/config/projects' require 'pipeline/content/content_core' require 'pipeline/os/path' require 'pipeline/projectutil/data_rpf' require 'pipeline/resourcing/common' require 'pipeline/resourcing/converter' require 'pipeline/resourcing/path' require 'pipeline/util/environment' include Pipeline #----------------------------------------------------------------------------- # Implementation #----------------------------------------------------------------------------- module Pipeline module Resourcing module Converters # # == Description # Builds any valid RPF content node. # class PackConverter < ConverterBase # # Setup the converter for a project and branch. # def initialize( project, branch ) super( project, branch ) @r = Pipeline::RageUtils.new( @project, @branch.name ) @rpf_files = [] end # Return whether this converter can convert the specified content node. def can_convert?( content ) ( content.is_a?( Content::RPF ) and ( content.target.is_a?( IndependentTarget ) ) ) end # # Builds the RPF file with all the added content. This method can raise # a BuildError exception which indicates a fatal error in producing the # RPF file. # def build( &block ) PackConverter.log.info( 'No RPF files to build.' ) \ unless ( @rpf_files.size > 0 ) env = Environment.new() @branch.fill_env( env ) result = true @rpf_files.each do |rpffile| rpf_filename = rpffile.content.filename # Ensure our RPF file is writable. if ( ::File::exists?( rpf_filename ) and !::File::writable?( rpf_filename ) ) then message = "File #{rpf_filename} is not writable. Pack failed." PackConverter::log().error( message ) throw BuildError.new( rpffile.content, message ) end # Loop through our pack item content nodes. rpf_dir = OS::Path::get_directory( rpf_filename ) FileUtils::mkdir_p( rpf_dir ) unless ( File::directory?( rpf_dir ) ) file_list = [] rpffile.items.each do |pack_item| entry = {} entry[:src] = env.subst( pack_item.src ) entry[:dst] = pack_item.dst if ( ::File::exists?( pack_item.src ) ) then file_list << entry yield( pack_item.content, true ) if ( block_given? ) else PackConverter::log().warn( "Cannot add #{pack_item.src} to RPF file. File does not exist on disk." ) yield( pack_item.content, false ) if ( block_given? ) end end success = ProjectUtil::data_create_rpf( rpf_filename, file_list, rpffile.content.compress ) yield( rpffile.content, success ) if ( block_given? ) result = false unless ( success ) end { :success => result } end # Clear the content from the build list. def clear( ) @rpf_files.clear( ) end # Add content to be put into this RPF file. def add_content( content ) path_stack = [] if ( content.is_a?( Pipeline::Content::RPF ) ) then rpf = PackFile.new( content ) if ( content.methods.include?( 'inputs' ) ) then content.inputs.each do |child| add_content_recursive( child, path_stack, rpf ) end end @rpf_files << rpf true else PackConverter.log().warn("couldn't convert #{content}") false end end # RPF converter's log object. def PackConverter::log( ) @@log = Log.new( 'convert_pack' ) if ( @@log.nil? ) @@log end #-------------------------------------------------------------------- # Private #-------------------------------------------------------------------- private @@log = nil # # Internal class to represent a single RPF file. # class PackFile attr_reader :content # RPF content node attr_reader :items # Array of PackItem objects def initialize( content ) @content = content @items = [] end end # # Internal class to represent a single file being added to an RPF file. # We store the source and destination paths and the content node the # file came from. # class PackItem attr_reader :content attr_reader :src attr_reader :dst def initialize( content, src, dst ) @content = content @src = src @dst = dst end end # Add content to be put into this RPF file. def add_content_recursive( content, path_stack, rpffile ) # Handle content type pre-recursion if ( content.is_a?( Pipeline::Content::RPF ) ) then pre_handle_rpf_node( content, path_stack, rpffile ) elsif ( content.is_a?( Pipeline::Content::File ) ) then pre_handle_file_node( content, path_stack, rpffile ) elsif ( content.is_a?( Pipeline::Content::Group ) ) then pre_handle_group_node( content, path_stack, rpffile ) end content.inputs.each do |child| add_content_recursive( child, path_stack, rpffile ) end if ( content.methods.include?( 'children' ) ) then content.children.each do |child| add_content_recursive( child, path_stack, rpffile ) end end if ( content.is_a?( Pipeline::Content::Group ) ) then post_handle_group_node( content, path_stack, rpffile ) end end #--------------------------------------------------------------------- # Content-node Specific Handling Methods # "pre_" - handlers pre-recurse # "post_" - handlers post-recuse #--------------------------------------------------------------------- # def pre_handle_rpf_node( content, path_stack, rpffile ) src = "" dst = "" @branch.in_env() do | e | src = e.subst( content.filename ) if ( rpffile.content.stack_path ) then dst = e.subst( "#{OS::Path.combine( OS::Path.combine(*path_stack), OS::Path::get_filename( content.filename ) )}" ) else dst = e.subst( OS::Path::get_filename( content.filename ) ) end end rpffile.items << PackItem.new( content, src, dst ) end # def pre_handle_file_node( content, path_stack, rpffile ) src = "" dst = "" @branch.in_env() do | e | src = e.subst( content.filename ) if ( rpffile.content.stack_path ) then dst = e.subst( "#{OS::Path.combine( OS::Path.combine(*path_stack), OS::Path::get_filename( content.filename ) )}" ) else dst = e.subst( OS::Path::get_filename( content.filename ) ) end end rpffile.items << PackItem.new( content, src, dst ) end # def pre_handle_group_node( content, path_stack, rpffile ) if ( nil != content.path and '' != content.path ) then path_stack.push( content.path ) end end # def post_handle_group_node( content, path_stack, rpffile ) if ( nil != content.path and '' != content.path ) then path_stack.pop() end end end # PackConverter class end # Converters module end # Resourcing module end # Pipeline module # %RS_TOOLSLIB%/pipeline/resourcing/converters/converter_pack.rb