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

363 lines
8.9 KiB
Ruby
Executable File

#
#
# Author:: Mark Harrison-Ball <Mark.Harrison-Ball@rockstargames.com>
# Date:: 09 September 2014 (AP3)
# Purpose:
# ~ Simple Utility to validate if a cutscene Build was sucessfull or not on the Asset Builder
# ~ Will send email of result
#
# TODO#
# Check logs and (Increadinbuild maybe)
#-----------------------------------------------------------------------------
# Uses
#-----------------------------------------------------------------------------
path = File.expand_path $0
path = File.dirname(path)
require "#{path}/../../Global/email/email.rb"
require "#{path}/../../Global/perforce/p4utils"
require "#{path}/../../Global/logging/logging"
require "#{path}/../../Utils/RunCutsceneBuild/emailUtils"
require "#{path}/../../Utils/RunCutsceneBuild/zipChangeInfo"
require 'RSG.Base.dll'
require 'RSG.Base.Configuration.dll'
include RSG::Base::Configuration
include RSG::Base::Logging
include RSG::Base::Logging::Universal
require 'fileutils'
require 'tmpdir'
require 'socket'
# STATIC PROPERTIES
ASSET_DESC = "Cutscene DLC Animation Dictionaries [Asset Pipeline 3.0]"
@LAST_SYNC_CL = 0
@TEMP_CL = "#{Dir.tmpdir()}/lastSyncCL"
LAST_BUILD_SUCCESS = false
DEBUG = false
# Project Names here.
# TODO: Move to external xml file
DLCPROJECTS = [
#'mpHeist',
#'dlc_agentTrevor',
#'patchDay1NG',
#'patchDay2NG',
#'patchDay3NG',
'mpLowrider'
]
# returns which files we have opened in our passed in CL
# Use for report of Zips submitted
def getZipsinCL( cl )
records = @p4.get_changelistOpened( cl )
fileList = Hash.new()
records.records.each do | record |
fileList[record['depotFile']] = File.basename(record['depotFile']).gsub!('.icd.zip','')
end
fileList
end
# Submit p4 zips if successful
# We only submit valid Zups
# Cutscene DLC Animation Dictionaries [Asset Pipeline 3.0]
def submitSucessZips()
validCL = nil
# Find our chnagelist
pendingCLs = @p4.get_PendingChangeLists(max=50)
pendingCLs.each do | record |
if (record.description.include? ASSET_DESC) and (record.files.count > 0) then
validCL = record.number
#break
elsif (record.description.include? ASSET_DESC) and (record.files.count == 0) then
# revert out CL
@p4.DeleteChangelist(['-d',"#{record.number}"])
end
end
# If we find our valid CL we submit
if validCL != nil then
files = getZipsinCL( validCL )
@glog.message("submitting cl #{validCL}")
result = @p4.submit(['-c',"#{validCL}"]) if not DEBUG
# Get our last actual change number we submitted
submitCL = @p4.describe(["#{validCL}"], '-O')
validCL = submitCL[0]['change']
end
return validCL
end
# This will write out our last chnage number for refernce
def writeOutChangeNumber(currentCL, projectName)
File.open("#{@TEMP_CL}_#{projectName}.txt" , "w") do |f|
f.write(currentCL)
end
end
def readInChangeNumber( projectName )
currentCL = nil
if File.file?("#{@TEMP_CL}_#{projectName}.txt")
currentCL = File.read( "#{@TEMP_CL}_#{projectName}.txt" )
end
return currentCL
end
def deleteChangeNumber( projectName )
if File.file?("#{@TEMP_CL}_#{projectName}.txt")
FileUtils.rm( "#{@TEMP_CL}_#{projectName}.txt" )
end
end
#
# Function to sync our DLC assets and populate a class with the info
def syncDLC( )
# store list of changes in a hastable
@DLC_Changes = Hash.new()
@glog.message('*** Syncing DLC Packs ***')
# go through each DLC we need to sync to and sync up
@g_Config.DLCProjects.each do | project |
if DLCPROJECTS.include?( project.key )
#changeNumber = @p4.get_current_clientchangelist("#{project.value.DefaultBranch.assets}/cuts/...").number
# check if we have a previous CL daved out from a failed build. return nil if not
lastSyncCL = readInChangeNumber(project.key)
@glog.message("last CL from failed Build: #{lastSyncCL}") if not lastSyncCL == nil
_changes = @p4.get_changes_toSync("#{project.value.DefaultBranch.assets}/cuts/...", lastSyncCL)
changes = sortChanges(_changes)
#write out sync changelist for debugging
writeOutChangeNumber( _changes[0].number, project.key ) if changes.count > 0
# Sync our assets for this branch
syncAssets( project.value.DefaultBranch.project.Root )
@DLC_Changes[project.key] = changes
end
end
# get lowest sync'd CL
end
def syncAssets( projRoot )
@glog.message("Syncing #{projRoot}")
@p4.sync(["#{projRoot}/assets/...", "#{projRoot}/assets_ng/...", "#{projRoot}/build/...", "#{projRoot}/drm/...", "#{projRoot}/UI/...", "#{projRoot}/signage/...", "#{projRoot}/*"]) #if not DEBUG
end
# Hardcode Log path for now, but get last log cmd folder created to check for errors
def validateCmdLogs()
latestFolder = Dir.glob('X:/gta5/tools_ng/logs/cmd*').sort {|a,b| File.ctime(a) <=> File.ctime(b) }
@newest = latestFolder.last
checkLogforErrors(@newest)
end
# Go through all the logs in the passed in Log Folder
def checkLogforErrors(filePath)
# store the errors in a dictionary, make sure we clear our Hash
@errorList.clear
Dir.glob("#{filePath}/*.ulog").each do | file |
#puts file
if UniversalLogFile.ContainsErrors(file)
#puts "File #{file} has errors "
@errorList[file] = UniversalLogFile.GetErrors(file);
end
end
end
=begin
# Will go through the zips and look for matching error names in the zips
def findErroredZips(errorList, zipList)
# Filter out our errors
# go through each zip file and do a string match and add to revert list
errorZips = []
# filer out 'name' files from error list first
errorList[0].each do | error |
zipList.each do | key, value |
zipList.each do | value, key |
if error.include?( key ) then
errorZips.push( value )
end
end
end
end
return errorZips
end
# pass in error list and return possible zip files
def filterErrors(errorList , zipList)
#re: ((?<![\\])['"])((?:.(?!(?<![\\])\1))*.?)\1
errorZips = []
# filer out 'name' files from error list first
errorList[0].each do | error |
zipList.each do | key, value |
zipList.each do | value, key |
if error.include?( key ) then
errorZips.push( value )
end
end
end
#result = val.second.match(/((?<![\\])['"])((?:.(?!(?<![\\])\1))*.?)\1/)
end
# remove paths and any extension
end
=end
# Hardcoded path for now: CLears our logs folder as it will get mental
def clearLogsFolder()
@glog.message('Clearing logs in X:/gta5/tools_ng/logs/')
FileUtils.rm_rf Dir.glob("X:/gta5/tools_ng/logs/cmd*")
#FileUtils.rm_rf "X:/gta5/tools_ng/logs/"
end
# Main init Build
def initBuild()
tStart = Time.now
#sendStartEmail()
# Sync our DLC Build
syncDLC()
# Build our Cutscene
if @buildtype == 'NG' then
system('X:/gta5/tools_ng/script/util/anim/cutscene/run_cutscene_dlc_checkout_ng.bat')
else
system('X:/gta5/tools_ng/script/util/anim/cutscene/run_cutscene_dlc_checkout.bat')
end
# Validate our Build:
@errorList = Hash.new
validateCmdLogs()
if @errorList.count > 0
eList = formatError(@errorList)
sendFailourEmail( tStart, eList )
else
cl = submitSucessZips()
# Success build remove last CLS
@DLC_Changes.each do | key, val |
deleteChangeNumber(key.to_s)
end
# if no CL then data has not changed
if cl !=nil then
sendCompleteEmail( tStart, cl )
else
sendCompleteNoUpdateEmail(tStart)
end
end
end
if ( __FILE__ == $0 ) then
begin
# Enable Logging
LogFactory.Initialize()
LogFactory.CreateApplicationConsoleLogTarget( )
g_Log = LogFactory.ApplicationLog
# Config initialisation.
@g_Config = RSG::Base::Configuration::ConfigFactory::CreateConfig( )
@server = @g_Config.studios.this_studio.exchange_server
@glog = Logger.new( @g_Config , g_Log)
clearLogsFolder()
hostname = Socket.gethostname
@buildtype = 'CG'
if hostname == 'EDIW-ANIMBLD1' then
@buildtype = 'NG'
end
# P4 Utils
@p4 = P4Utils.new()
initBuild()
# DEBUG TEST
#syncDLC()
#tStart = Time.now
#@newest = ''
#_changes = @p4.get_changes_toSync("X:/gta5_dlc/mpPacks/mpHeist/assets/cuts...")
#changes = sortChanges(_changes)
#returnEarliestChange(changes)
#@DLC_Changes = Hash.new()
#@DLC_Changes["TEST"] = changes
#sendCompleteEmail( tStart, 34234 )
#cl = readInChangeNumber('mpHeist')
rescue => e
puts e
@glog.errorEmail(e)
raise
end
end