Files
2025-09-29 00:52:08 +02:00

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