323 lines
9.2 KiB
Python
Executable File
323 lines
9.2 KiB
Python
Executable File
from email.mime.multipart import MIMEMultipart
|
|
from email.mime.text import MIMEText
|
|
|
|
import datetime
|
|
import os
|
|
import smtplib
|
|
import sys
|
|
|
|
# *** SETTINGS ***
|
|
|
|
# SMTP email notification settings
|
|
SMTP_HOST = 'smtp.rockstar.t2.corp'
|
|
SMTP_PORT = 25
|
|
SMTP_USERNAME = ''
|
|
SMTP_PASSWORD = ''
|
|
SMTP_FROM = 'Audio RPFs Generator <rpf-generator@rockstarnorth.com>'
|
|
SMTP_TO = (
|
|
'Matt Hailey <matt.hailey@rockstarnorth.com>',
|
|
'Alastair MacGregor <alastair.macgregor@rockstarnorth.com>',
|
|
#'Matthew Smith <matthew.smith@rockstarnorth.com>',
|
|
)
|
|
|
|
# Logging
|
|
LOG_PATH = None
|
|
PRINT_LOG = True
|
|
|
|
warning_count = 0
|
|
error_count = 0
|
|
logger = ''
|
|
|
|
# Perforce
|
|
PERFORCE_EXE_NAME = r'p4'
|
|
|
|
# Environment
|
|
env_args_keys = (
|
|
'build',
|
|
'audio',
|
|
'platform',
|
|
'ragebuilder',
|
|
'package',
|
|
'RS_TOOLSROOT',
|
|
'RS_BUILDBRANCH',
|
|
)
|
|
env_args = {}
|
|
|
|
packlist_path = None
|
|
input_path = None
|
|
output_path = None
|
|
build_pack_path = None
|
|
working_path = None
|
|
|
|
# *** SETTINGS (END) ***
|
|
|
|
# *** TYPES ***
|
|
|
|
# LogSeverity enums
|
|
class LogSeverity:
|
|
INFO='INFO'
|
|
WARNING='WARNING'
|
|
ERROR='ERROR'
|
|
CRITICAL='CRITICAL'
|
|
|
|
# *** TYPES (END) ***
|
|
|
|
# *** MAIN PROCESS ***
|
|
|
|
def main():
|
|
# Run process
|
|
args = sys.argv
|
|
|
|
# Fetch required environment variables
|
|
if not init_env_vars(env_args_keys, env_args):
|
|
log("Failed to load all required environment variables", LogSeverity.ERROR)
|
|
return -1
|
|
|
|
# Initialise paths to required dirs and files
|
|
if not init_paths():
|
|
log("Failed to initialise paths", LogSeverity.ERROR)
|
|
return -1
|
|
|
|
set_working_path(env_args['build'])
|
|
|
|
# Mark packlist file for edit
|
|
if not run_p4_cmd('edit', packlist_path):
|
|
return -1
|
|
|
|
# Generate RPF files
|
|
rebuild = 'full' in args
|
|
if not generate_rpfs(rebuild):
|
|
return -1
|
|
|
|
# Execute RAGE builder
|
|
if not exec_rage_builder():
|
|
return -1
|
|
|
|
# Revert any unchanged files
|
|
platform = env_args['platform']
|
|
if platform.upper() == 'PC':
|
|
platform = 'x64'
|
|
|
|
path = os.path.join(env_args['build'], platform, 'audio')
|
|
args = '-a %s\\...' % path
|
|
if not run_p4_cmd('revert', args):
|
|
return
|
|
|
|
return 0
|
|
|
|
|
|
def init_paths():
|
|
global packlist_path
|
|
global input_path
|
|
global output_path
|
|
global build_pack_path
|
|
|
|
# Check build path exists
|
|
if not os.path.exists(env_args['build']):
|
|
log("Path does not exist: %s" % env_args['build'], LogSeverity.ERROR)
|
|
return False
|
|
log("Using build path: %s" % env_args['build'], LogSeverity.INFO)
|
|
|
|
# Init config dir
|
|
config_dir = os.path.join(env_args['audio'], env_args['platform'], 'config')
|
|
if not os.path.exists(config_dir):
|
|
log("Creating path: %s" % config_dir, LogSeverity.INFO)
|
|
os.makedirs(config_dir)
|
|
|
|
# Init packlist path (file may not exist locally)
|
|
packlist_path = os.path.join(config_dir, 'packlist.txt')
|
|
log("Using packlist path: %s" % packlist_path, LogSeverity.INFO)
|
|
|
|
# Init input path
|
|
input_path = os.path.join(env_args['audio'], env_args['platform'], 'sfx')
|
|
if not os.path.exists(input_path):
|
|
log("Path does not exist: %s" % input_path, LogSeverity.ERROR)
|
|
return False
|
|
log("Using input path: %s" % input_path, LogSeverity.INFO)
|
|
|
|
# Init output path
|
|
platform = env_args['platform']
|
|
if platform.upper() == 'PC':
|
|
platform = 'x64'
|
|
|
|
output_path = os.path.join(env_args['build'], platform, 'audio', 'sfx')
|
|
if not os.path.exists(output_path):
|
|
log("Path does not exist - creating directory: %s" % output_path, LogSeverity.INFO)
|
|
try:
|
|
os.makedirs(output_path)
|
|
except:
|
|
log("Failed to create directory: %s" % output_path, LogSeverity.ERROR)
|
|
return False
|
|
log("Using output path: %s" % output_path, LogSeverity.INFO)
|
|
|
|
# Init build pack path
|
|
build_pack_path = os.path.join(env_args['RS_TOOLSROOT'], 'bin', 'audio', 'scripts', 'RPFs', 'build_pack.bat')
|
|
if not os.path.exists(build_pack_path):
|
|
log("Path does not exist: %s" % build_pack_path, LogSeverity.ERROR)
|
|
return False
|
|
log("Using build pack path: %s" % build_pack_path, LogSeverity.INFO)
|
|
|
|
return True
|
|
|
|
|
|
def generate_rpfs(rebuild):
|
|
global input_path
|
|
global output_path
|
|
|
|
if rebuild:
|
|
log("Generating all audio RPF files..", LogSeverity.INFO)
|
|
else:
|
|
log("Generating latest audio RPF files..", LogSeverity.INFO)
|
|
|
|
# Open pack list file for writing and overwrite previous data
|
|
pack_list_file = open(packlist_path, 'w')
|
|
|
|
# Generate RPFs for files in each pack (ie sub-dir) in input_path
|
|
for path, packs, files in os.walk(input_path):
|
|
for pack in packs:
|
|
|
|
# Pack needs to be added to pack list file
|
|
pack_list_file.write("%s\n" % pack)
|
|
|
|
if not rebuild and not pack_requires_build(os.path.join(path, pack), pack):
|
|
# Skip current pack if build not required and
|
|
# process not marked for full rebuild
|
|
continue
|
|
|
|
# Init build params
|
|
log("Building pack %s..." % pack, LogSeverity.INFO)
|
|
input_pack_path = os.path.join(input_path, pack)
|
|
output_pack_path = os.path.join(output_path, pack)
|
|
|
|
# Run build command
|
|
cmd = r'%s %s\ %s.rpf %s' % (build_pack_path, input_pack_path, output_pack_path, pack)
|
|
log("Running cmd: %s" % cmd, LogSeverity.INFO)
|
|
if os.system(cmd) != 0:
|
|
log("Failed to successfully run command: %s" % cmd, LogSeverity.ERROR)
|
|
return False
|
|
|
|
pack_list_file.close()
|
|
|
|
return True
|
|
|
|
|
|
def pack_requires_build(pack_path, pack_name):
|
|
global output_path
|
|
|
|
rpf_path = '%s.rpf' % os.path.join(output_path, pack_name)
|
|
|
|
# If output file doesn't exist, it needs to be built
|
|
if not os.path.exists(rpf_path):
|
|
return True
|
|
|
|
for file in os.listdir(pack_path):
|
|
# Only interested in AWC files
|
|
if file.lower().endswith('.awc'):
|
|
awc_path = os.path.join(pack_path, file)
|
|
# If AWC file is newer than RPF file, it needs to be built
|
|
if os.stat(awc_path).st_mtime > os.stat(rpf_path).st_mtime:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def exec_rage_builder():
|
|
platform = env_args['platform']
|
|
if platform.upper() == 'PC':
|
|
platform = 'x64'
|
|
|
|
pack = os.path.join(env_args['build'], platform, 'audio', 'audio.rpf')
|
|
rootpath = os.path.join(env_args['audio'], env_args['platform'])
|
|
cmd = '%s %s -pack %s -rootpath %s\ -extignore .awc -nameheapshift=1' % \
|
|
(env_args['ragebuilder'], env_args['package'], pack, rootpath)
|
|
|
|
# Mark pack file for edit
|
|
if not run_p4_cmd('edit', pack):
|
|
return False
|
|
|
|
log("Running cmd: %s" % cmd, LogSeverity.INFO)
|
|
if os.system(cmd) != 0:
|
|
log("Failed to successfully run command: %s" % cmd, LogSeverity.ERROR)
|
|
return False
|
|
|
|
return True
|
|
|
|
# *** MAIN PROCESS (END) ***
|
|
|
|
# *** HELPER FUNCTIONS ***
|
|
|
|
def set_working_path(path):
|
|
global working_path
|
|
|
|
# Change working path if required
|
|
if working_path != path:
|
|
working_path = path
|
|
msg = "Setting working path as %s" % path
|
|
log(msg, LogSeverity.INFO)
|
|
os.chdir(path)
|
|
|
|
|
|
def init_env_vars(keys, output):
|
|
log("Loading environment variables...", LogSeverity.INFO)
|
|
successful = True
|
|
for key in keys:
|
|
try:
|
|
value = os.environ[key]
|
|
output[key] = value
|
|
log("Loaded environment variable: %s=%s" % (key, value), LogSeverity.INFO)
|
|
except:
|
|
log("Failed to load environment variable: %s" % key, LogSeverity.ERROR)
|
|
successful = False
|
|
return successful
|
|
|
|
|
|
def log(msg, severity):
|
|
global warning_count
|
|
global error_count
|
|
global logger
|
|
|
|
now = datetime.datetime.now()
|
|
now_str = now.strftime('%H:%M:%S')
|
|
|
|
full_msg = "[%s] %s: %s" % (now_str, severity, msg)
|
|
|
|
# Print to console if required
|
|
if PRINT_LOG:
|
|
print full_msg
|
|
|
|
# Increment warning/error counter
|
|
if severity == LogSeverity.WARNING:
|
|
warning_count += 1
|
|
elif severity in (LogSeverity.ERROR, LogSeverity.CRITICAL):
|
|
error_count += 1
|
|
|
|
# Store message in logger
|
|
logger += "%s\n" % full_msg
|
|
|
|
|
|
def save_log():
|
|
# Save log of current process to file
|
|
if LOG_PATH:
|
|
if not os.path.exists(LOG_PATH):
|
|
os.makedirs(LOG_PATH)
|
|
writer = open(LOG_PATH, 'w')
|
|
writer.write(logger)
|
|
writer.close()
|
|
|
|
|
|
def run_p4_cmd(action, args):
|
|
cmd = '%s %s %s' % (PERFORCE_EXE_NAME, action, args)
|
|
log("Running Perforce cmd: %s" % cmd, LogSeverity.INFO)
|
|
|
|
if os.system(cmd) != 0:
|
|
log("Failed to successfully run P4 command: %s" % cmd, LogSeverity.ERROR)
|
|
return False
|
|
|
|
return True
|
|
|
|
# *** HELPER FUNCTIONS (END) ***
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|