220 lines
7.4 KiB
Ruby
Executable File
220 lines
7.4 KiB
Ruby
Executable File
#
|
|
# File:: %RS_TOOLSLIB%/pipeline/util/rage.rb
|
|
# Description:: Rage gem and Rage project config XML interface.
|
|
#
|
|
# Author:: Greg Smith <greg@rockstarnorth.com>
|
|
# Author:: David Muir <david.muir@rockstarnorth.com>
|
|
# Date:: 22 February 2008
|
|
#
|
|
# To avoid problems with incompatible Rage and XCompress libraries we are now
|
|
# storing the gem version as well as the Ragebuilder executable configuration
|
|
# in each project's config XML file.
|
|
#
|
|
# This means we cannot just require the Rage gem anymore, but must require a
|
|
# particular version of it.
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'rexml/document'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
module Pipeline
|
|
|
|
#
|
|
# == Description
|
|
# The description of a command line to convert rage assets. This can parse
|
|
# the project XML files to determine the correct versions of Ragebuilder
|
|
# to use for a branch and platform combination.
|
|
#
|
|
class RageConvertTool
|
|
class XMLParseError < Exception; end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Attributes
|
|
#---------------------------------------------------------------------
|
|
attr_reader :name
|
|
attr_reader :path
|
|
attr_reader :gem_version
|
|
attr_reader :split_packs
|
|
attr_reader :options
|
|
|
|
#---------------------------------------------------------------------
|
|
# Instance Methods
|
|
#---------------------------------------------------------------------
|
|
def initialize( name, path, gem_version, split_packs, options )
|
|
@name = name
|
|
@path = path
|
|
@gem_version = gem_version
|
|
@split_packs = split_packs
|
|
@options = options
|
|
end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Class Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
#
|
|
# Fill a hash with the tool used to convert to Rage for each platform
|
|
# for a specific project and branch. If branch is not specified then
|
|
# the project's default branch is used.
|
|
#
|
|
def RageConvertTool.parse( proj, branch = nil )
|
|
proj.load_config( )
|
|
branch = proj.default_branch if ( branch.nil? )
|
|
tools = {}
|
|
|
|
File.open( proj.config ) do |file|
|
|
doc = Document.new( file )
|
|
|
|
doc.elements.each( 'project/branches/branch' ) do |branch_elem|
|
|
branch_name = branch_elem.attributes['name']
|
|
throw XMLParseError.new( 'XML Parse Error, no branch name specified. Fix project XML configuration.' ) \
|
|
if ( branch_name.nil? )
|
|
|
|
# Skip branches we ain't interested in.
|
|
next unless ( branch_name == branch )
|
|
|
|
# Parse Rage Gem Version
|
|
gem_version = branch_elem.elements['rage'].attributes['gem']
|
|
split_packs = ( 'false' == branch_elem.elements['rage'].attributes['split_packs'] ) ? false : true
|
|
|
|
# Parse Rage XML
|
|
branch_elem.elements.each( 'rage/ragebuilders/ragebuilder' ) do |target|
|
|
|
|
platform = target.attributes['platform']
|
|
exe = target.attributes['exe']
|
|
|
|
options = " -options #{target.attributes['options']}"
|
|
|
|
proj.in_env do |e|
|
|
exe = e.subst( exe )
|
|
end
|
|
|
|
tools[platform] = RageConvertTool.new( platform, exe, gem_version, split_packs, options )
|
|
end
|
|
end
|
|
end
|
|
tools
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# RageUtils class provides access into Ragebuilder functionality for
|
|
# RPF/Pack, Image files and some misc. utilities.
|
|
#
|
|
class RageUtils
|
|
#---------------------------------------------------------------------
|
|
# Attributes
|
|
#---------------------------------------------------------------------
|
|
attr_reader :project # Project object
|
|
attr_reader :branch # Branch object
|
|
attr_reader :tools # RageConvertTool Hash (platform key)
|
|
|
|
# Function Interfaces
|
|
attr_reader :util # Utility functions
|
|
attr_reader :rage # Low-level RAGE functions (e.g. hashing)
|
|
|
|
#---------------------------------------------------------------------
|
|
# Class Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
# Method that maps between our Ruby pipeline friendly platform key
|
|
# names to Ragebuilder platform names.
|
|
def RageUtils.rage_platform( platform )
|
|
rage_platform = platform
|
|
case platform
|
|
when 'xbox360'
|
|
rage_platform = 'xenon'
|
|
end
|
|
rage_platform
|
|
end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Instance Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
# Class constructor.
|
|
def initialize( project, branch = nil )
|
|
@project = project
|
|
@branch = branch.nil? ? branch : project.default_branch
|
|
|
|
@tools = RageConvertTool::parse( @project, @branch )
|
|
first_key = tools.keys[0]
|
|
throw RuntimeError.new( "No tools information or gem version for project branch." ) \
|
|
unless ( tools.is_a?( Hash ) )
|
|
unless ( @@gem_initialized ) then
|
|
begin
|
|
# Always use xenon gem. Saves large refactor to pass the
|
|
# platform for every convert. This currently means all
|
|
# platforms must share the same Rage gem.
|
|
$rage_gem_version = tools[first_key].gem_version if ( ( not defined? $rage_gem_version ) or $rage_gem_version.nil? )
|
|
if ( $rage_gem_version != tools[first_key].gem_version )
|
|
throw RuntimeError.new( "Attempting to load different RAGE Gem versions in same script (#{$rage_gem_version}, #{tools[first_key].gem_version})." )
|
|
end
|
|
gem 'rage', "= #{tools[first_key].gem_version}"
|
|
require 'rage'
|
|
LogSystem::instance().rootlog.info( "RAGE Gem version: #{$rage_gem_version}" )
|
|
rescue LoadError => ex
|
|
throw RuntimeError.new( "Invalid Rage gem version: #{tools[first_key].gem_version}. Is it installed?" )
|
|
end
|
|
end
|
|
|
|
# Create our interfaces.
|
|
@util = Rage::Util.instance( )
|
|
@rage = Rage::Rage::instance( )
|
|
|
|
# Initialise our RAGE Gem only once, as if we attempt to do it again
|
|
# RAGE Param::Init assets and we fail badly.
|
|
@util.init() unless ( @@gem_initialized )
|
|
@@gem_initialized = true unless ( @@gem_initialized )
|
|
end
|
|
|
|
# Zip compatibility catch.
|
|
def zip
|
|
throw RuntimeError::new( "zip feature removed; script update required. Contact tools." )
|
|
end
|
|
|
|
# RPF compatibility catch
|
|
def pack
|
|
throw RuntimeError::new( "pack feature removed; script update required. Contact tools." )
|
|
end
|
|
|
|
#
|
|
# Find files wrapper to take care of some housekeeping. This handles
|
|
# the Ragebuilder function returning a single string with files
|
|
# separated by ',' characters.
|
|
#
|
|
# Returns an Array of filename strings.
|
|
#
|
|
def find_files( search )
|
|
@util.find_files( search, true, true ).split( "," )
|
|
end
|
|
|
|
#
|
|
# Find dirs wrapper to take care of some housekeeping. This handles
|
|
# the Ragebuilder function returning a single string with directories
|
|
# separated by ',' characters.
|
|
#
|
|
# Returns an Array of directory strings.
|
|
#
|
|
def find_dirs( search )
|
|
@util.find_dirs( search ).split( "," )
|
|
end
|
|
|
|
private
|
|
#
|
|
# Class (static) variable to store our initialised RAGE Gem state.
|
|
# Initially false so we init the RAGE Gem once.
|
|
#
|
|
@@gem_initialized = false
|
|
end
|
|
|
|
end # Pipeline module
|
|
|
|
# %RS_TOOLSLIB%/pipeline/util/rage.rb
|