363 lines
8.9 KiB
Ruby
Executable File
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|