379 lines
13 KiB
Ruby
Executable File
379 lines
13 KiB
Ruby
Executable File
#
|
|
# File:: branch.rb
|
|
# Description:: Project Branch configuration.
|
|
#
|
|
# Author:: David Muir <david.muir@rockstarnorth.com>
|
|
# Author:: Greg Smith <greg@rockstarnorth.com>
|
|
# Date:: 26 August 2008
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'pipeline/config/targets'
|
|
require 'pipeline/config/script'
|
|
require 'pipeline/util/string'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
module Pipeline
|
|
|
|
#
|
|
# == Description
|
|
# Unity build class.
|
|
#
|
|
class UnityBuildConfig
|
|
attr_accessor :enabled
|
|
def initialize()
|
|
@enabled = true
|
|
end
|
|
end
|
|
|
|
|
|
#
|
|
# == Description
|
|
# Code configuration class.
|
|
#
|
|
class CodeConfig
|
|
attr_accessor :compiler # default compiler version (vs2005, vs2008, vs2010)
|
|
attr_accessor :unity_build # unity build
|
|
def initialize()
|
|
@compiler = :'vs2005'
|
|
@unity_build = UnityBuildConfig.new()
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Project branch configuration class.
|
|
#
|
|
class Branch
|
|
|
|
attr_accessor :name # Branch name
|
|
attr_reader :project # Project reference
|
|
attr_accessor :default # true/false if default project branch
|
|
|
|
# PATHS
|
|
attr_accessor :audio # Branch audio data root path
|
|
attr_accessor :build # Branch build data root path
|
|
attr_accessor :export # Branch export data path (unprocessed, raw)
|
|
attr_accessor :processed # Branch processed data path
|
|
attr_accessor :metadata # Branch metadata data path
|
|
attr_accessor :independent # Branch independent data path (OBSOLETE)
|
|
attr_accessor :common # Branch common data path
|
|
attr_accessor :shaders # Branch shaders path
|
|
attr_accessor :code # Branch code path
|
|
attr_accessor :ragecode # Branch RAGE code path
|
|
attr_accessor :script # Branch script source path
|
|
attr_accessor :art # Branch art path (typically shared between branches)
|
|
attr_accessor :assets # Branch assets path (typically shared between branches)
|
|
attr_accessor :preview # Branch preview directory
|
|
|
|
# CODE CONFIG
|
|
attr_accessor :codeconfigs # CodeConfig objects
|
|
|
|
# SCRIPT CONFIG
|
|
attr_accessor :scriptconfig # ScriptConfig object
|
|
|
|
# TARGETS
|
|
attr_reader :ind_target # Platform-independent target object
|
|
attr_reader :targets # Hash of ProjectTarget objects
|
|
|
|
# BUILDER CONFIG
|
|
attr_accessor :builders # Hash, keys: :assetbuild, :codebuild, :scriptbuild, :assettest
|
|
|
|
def initialize( project, name, build = '', export = '', processed = '', metadata = '', independent = '', common = '', shaders = '', code = nil, script = '', art = '', builders = {}, preview = '', audio = '', assets = '' )
|
|
|
|
@project = project
|
|
@name = name
|
|
@audio = audio
|
|
@build = build
|
|
@export = export
|
|
@processed = processed
|
|
@metadata = metadata
|
|
@independent = independent # +OBSOLETE+
|
|
@common = common
|
|
@shaders = shaders
|
|
@code = code
|
|
@script = script
|
|
@art = art
|
|
@assets = assets
|
|
@preview = preview
|
|
@codeconfigs = []
|
|
@ind_target = IndependentTarget.new( @project, self )
|
|
@targets = {}
|
|
@builders = {}
|
|
end
|
|
|
|
def fill_env( env )
|
|
|
|
# Ensure we get the project's environment but not the default branches
|
|
# environment.
|
|
@project.fill_env( env, false ) unless ( @project.nil? )
|
|
|
|
env.add( 'branch', env.subst( @name ) )
|
|
env.add( 'build', env.subst( @build ) )
|
|
env.add( 'art', env.subst( @art ) ) \
|
|
unless ( not defined? @art ) or @art.nil?
|
|
env.add( 'assets', env.subst( @assets ) ) \
|
|
unless ( not defined? @assets ) or @assets.nil?
|
|
env.add( 'audio', env.subst( @audio ) ) \
|
|
unless ( not defined? @audio ) or @audio.nil?
|
|
|
|
env.add( 'export', env.subst( @export ) )
|
|
env.add( 'processed', env.subst( @processed ) )
|
|
env.add( 'metadata', env.subst( @metadata ) )
|
|
env.add( 'independent', env.subst( @independent ) )
|
|
env.add( 'common', env.subst( @common ) )
|
|
env.add( 'shaders', env.subst( @shaders ) )
|
|
env.add( 'code', env.subst( @code ) ) \
|
|
unless ( not defined? @code ) or @code.nil?
|
|
env.add( 'ragecode', env.subst( @ragecode ) ) \
|
|
unless ( not defined? @ragecode ) or @ragecode.nil?
|
|
env.add( 'script', env.subst( @script ) ) \
|
|
unless ( not defined? @script ) or @script.nil?
|
|
env.add( 'preview', env.subst( @preview ) ) \
|
|
unless ( not defined? @preview ) or @preview.nil?
|
|
end
|
|
|
|
def in_env( &block )
|
|
|
|
env = Environment.new()
|
|
fill_env( env )
|
|
yield( env ) if ( block_given? )
|
|
end
|
|
|
|
#
|
|
# Return true iff the passed in filename is within this project's
|
|
# export directory structure.
|
|
#
|
|
def is_export_file?( filename )
|
|
( filename.starts_with( @export ) )
|
|
end
|
|
|
|
#
|
|
# Return true iff the passed in filename is within this project's
|
|
# processed directory structure.
|
|
#
|
|
def is_processed_file?( filename )
|
|
( filename.starts_with( @processed ) )
|
|
end
|
|
|
|
#
|
|
# Return true iff the passed in filename is within this project's
|
|
# independent directory structure.
|
|
#
|
|
# +OBSOLETE+
|
|
#
|
|
def is_independent_file?( filename )
|
|
( filename.starts_with( @export ) )
|
|
end
|
|
|
|
#
|
|
# Return true iff the passed in filename is within a project target's
|
|
# directory structure.
|
|
#
|
|
def is_platform_file?( filename )
|
|
|
|
@targets.each do |name, target|
|
|
target_prefix = '$(target)'
|
|
target.in_env do |e|
|
|
target_prefix = e.subst( target_prefix )
|
|
end
|
|
return true if ( filename.starts_with( target_prefix ) )
|
|
end
|
|
|
|
false
|
|
end
|
|
|
|
#
|
|
# Return true iff the passed in filename is within this project's
|
|
# audio directory structure.
|
|
#
|
|
# DHM TODO: generalise these methods from all the PATH member data.
|
|
# (incl. is_independent_file? etc)
|
|
#
|
|
def is_audio_file?( filename )
|
|
|
|
return true if ( filename.starts_with( @audio ) )
|
|
false
|
|
end
|
|
|
|
#
|
|
# Return REXML::Element for local XML configuration.
|
|
#
|
|
def to_local_xml( )
|
|
|
|
branch_elem = Element.new( 'branch' )
|
|
branch_elem.attributes['name'] = @name
|
|
|
|
targets_elem = branch_elem.add_element( 'targets' )
|
|
@targets.each_pair do |platform, target|
|
|
|
|
targets_elem.add_element( target.to_local_xml() )
|
|
end
|
|
branch_elem
|
|
end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Class Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
#
|
|
# Parse branch data from an XML node, either creating a new Branch
|
|
# object or overwriting data in the specified branch object.
|
|
#
|
|
# The new (or updated) Branch object is returned.
|
|
#
|
|
# This allows us to have local.xml overwrite anything in config.xml.
|
|
#
|
|
def Branch::from_xml( xml_node, env, project, branch = nil )
|
|
|
|
throw ArgumentError.new( "Invalid Project object specified (#{project.class})." ) \
|
|
unless ( project.is_a?( Pipeline::Project ) )
|
|
throw ArgumentError.new( "Invalid Branch object specified (#{branch.class})." ) \
|
|
unless ( branch.nil? or branch.is_a?( Pipeline::Branch ) )
|
|
|
|
env.push( )
|
|
name = xml_node.attributes['name']
|
|
branch = Branch.new( project, name ) if ( branch.nil? )
|
|
|
|
# Initial environment setup.
|
|
project.fill_env( env )
|
|
|
|
# Loop through our attributes; the attributes collection is a Hash
|
|
# so we immediately lose order. Lets post-process the environment
|
|
# afterwards.
|
|
xml_node.attributes.each_attribute do |attr|
|
|
|
|
# Please keep this case statement in alphabetical order.
|
|
case ( attr.name.downcase.strip )
|
|
when 'art'
|
|
branch.art = env.subst( attr.value )
|
|
env.add( 'art', branch.art ) unless ( branch.art.empty? )
|
|
when 'assets'
|
|
branch.assets = env.subst( attr.value )
|
|
env.add( 'assets', branch.assets ) unless ( branch.assets.empty? )
|
|
when 'audio'
|
|
branch.audio = env.subst( attr.value )
|
|
env.add( 'audio', branch.audio ) unless ( branch.audio.empty? )
|
|
when 'build'
|
|
branch.build = env.subst( attr.value )
|
|
env.add( 'build', branch.build ) unless ( branch.build.empty? )
|
|
when 'code'
|
|
branch.code = env.subst( attr.value )
|
|
env.add( 'code', branch.code ) unless ( branch.code.empty? )
|
|
when 'common'
|
|
branch.common = env.subst( attr.value )
|
|
env.add( 'common', branch.common ) unless ( branch.common.empty? )
|
|
when 'export'
|
|
branch.export = env.subst( attr.value )
|
|
env.add( 'export', branch.export ) unless ( branch.export.empty? )
|
|
when 'independent'
|
|
# !!THIS IS OBSOLETE!!
|
|
branch.independent = env.subst( attr.value )
|
|
env.add( 'independent', branch.independent ) unless ( branch.independent.empty? )
|
|
when 'metadata'
|
|
branch.metadata = env.subst( attr.value )
|
|
env.add( 'metadata', branch.metadata ) unless ( branch.metadata.empty? )
|
|
when 'name'
|
|
branch.name = env.subst( attr.value )
|
|
env.add( 'branch', branch.name ) unless ( branch.name.empty? )
|
|
when 'preview'
|
|
branch.preview = env.subst( attr.value )
|
|
env.add( 'preview', branch.preview ) unless ( branch.preview.empty? )
|
|
when 'processed'
|
|
branch.processed = env.subst( attr.value )
|
|
env.add( 'processed', branch.processed ) unless ( branch.processed.empty? )
|
|
when 'ragecode'
|
|
branch.ragecode = env.subst( attr.value )
|
|
env.add( 'ragecode', branch.ragecode ) unless ( branch.ragecode.empty? )
|
|
when 'script'
|
|
branch.script = env.subst( attr.value )
|
|
env.add( 'script', branch.script ) unless ( branch.script.empty? )
|
|
when 'shaders'
|
|
branch.shaders = env.subst( attr.value )
|
|
env.add( 'shaders', branch.shaders ) unless ( branch.shaders.empty? )
|
|
end # switch attr.name
|
|
end
|
|
|
|
# ENVIRONMENT RESOLVE; because we can't read the attributes in the
|
|
# order in which they were supplied in the XML file.
|
|
branch.art = env.subst( branch.art )
|
|
branch.assets = env.subst( branch.assets )
|
|
branch.audio = env.subst( branch.audio )
|
|
branch.build = env.subst( branch.build )
|
|
branch.code = env.subst( branch.code )
|
|
branch.common = env.subst( branch.common )
|
|
branch.export = env.subst( branch.export )
|
|
# !!THIS IS OBSOLETE!!
|
|
branch.independent = env.subst( branch.independent )
|
|
branch.metadata = env.subst( branch.metadata )
|
|
branch.preview = env.subst( branch.preview )
|
|
branch.processed = env.subst( branch.processed )
|
|
branch.ragecode = env.subst( branch.ragecode )
|
|
branch.script = env.subst( branch.script )
|
|
branch.shaders = env.subst( branch.shaders )
|
|
|
|
# SCRIPT CONFIG
|
|
branch.scriptconfig = ScriptConfig::from_xml( xml_node.elements['script'], env, branch, branch.scriptconfig ) \
|
|
unless ( xml_node.elements['script'].nil? )
|
|
|
|
# CODE CONFIGS : high level build configuration : compiler, unity build.
|
|
xml_node.elements.each( 'code_configs' ) do |code_configs|
|
|
code_configs.elements.each( 'code_config' ) do |code_config|
|
|
new_codeconfig = CodeConfig.new()
|
|
new_codeconfig.compiler = code_config.attributes["compiler"].to_sym
|
|
code_config.elements.each('unity_build') do |unity_build|
|
|
new_codeconfig.unity_build.enabled = ( 'true' == unity_build.attributes['enabled'] ) unless unity_build.attributes['enabled'].nil?
|
|
end
|
|
branch.codeconfigs << new_codeconfig
|
|
end
|
|
end
|
|
|
|
# TARGETS
|
|
xml_node.elements.each( 'targets/target' ) do |target|
|
|
platform = target.attributes['platform']
|
|
platform.downcase!
|
|
target_platform = target.attributes['platform']
|
|
throw XMLParseError.new( 'Target does not specify platform. Fix target configuration.' ) \
|
|
if ( target_platform.nil? )
|
|
|
|
project_target = nil
|
|
project_target = branch.targets[target_platform] if ( branch.targets.has_key?( target_platform ) )
|
|
|
|
project_target = Target::from_xml( target, project, branch, env, project_target )
|
|
|
|
# 2011/03/03 DHM; The unless statement here ensures that targets
|
|
# defined in the local XML that do not have a definition are ignored.
|
|
branch.targets[target_platform] = project_target unless ( project_target.target.nil? )
|
|
end
|
|
|
|
# BUILDERS (only for builder server and client users)
|
|
c = Config::instance()
|
|
if ( c.user.is_builder_client or c.user.is_builder_server ) then
|
|
branch.builders = {}
|
|
xml_node.elements.each( 'builders/builder' ) do |builder_node|
|
|
builder_name = builder_node.attributes['name'].to_sym unless ( builder_node.attributes['name'].nil? )
|
|
queue_port = builder_node.attributes['queue_port'].to_i unless ( builder_node.attributes['queue_port'].nil? )
|
|
|
|
branch.builders[builder_name] = {}
|
|
branch.builders[builder_name][:queue_port] = queue_port
|
|
end
|
|
end
|
|
|
|
env.pop( )
|
|
|
|
# RAGE
|
|
# We do not parse the RAGE XML here, it is parsed in the
|
|
# Pipeline::RageConvertTool class, in pipeline/util/rage.rb.
|
|
|
|
branch
|
|
end
|
|
end
|
|
|
|
end # Pipeline module
|
|
|
|
# branch.rb
|