Files
gtav-src/tools_ng/lib/pipeline/config/branch.rb
T
2025-09-29 00:52:08 +02:00

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