You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Tools/SerializeContextAnalyzer/SerializeContextAnalyzer.py

122 lines
4.7 KiB
Python

########################################################################################
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
########################################################################################
import argparse
import getopt
import jinja2
import json
import string
import os
# Creates the folder at the given path is it doesn't already exist.
def CreateOutputFolder(path):
folderPath = os.path.dirname(path)
if not os.path.exists(folderPath):
try:
os.mkdir(folderPath)
except OSError:
print "Failed to create path '{0}'".format(folderPath)
return False
return True
# Function to check if a type is derived from one of the provided classes.
def IsDerivedFrom(context, classInfo, derivedType):
bases = classInfo.get('Bases', [])
for base in bases:
baseUuid = base.get('Uuid')
if baseUuid is not None:
if baseUuid == derivedType:
return True
else:
baseClassInfo = context.get(baseUuid)
if baseClassInfo is not None:
if IsDerivedFrom(context, baseClassInfo, derivedType):
return True
return False
# A Jinja2 filter function that filters any type that's not one of the provided types.
def FilterByBase(context, type):
result = {}
for uuid, classInfo in context.items():
if uuid == type or IsDerivedFrom(context, classInfo, type):
result[uuid] = classInfo
return result
def ParseAdditionalArguments(dict, arguments):
currentArg = None
for arg in arguments:
if arg[:2] == '--' or arg[:1] == '-':
if currentArg is not None:
dict[currentArg] = True
if arg[:2] == '--':
currentArg = arg[2:]
elif arg[:1] == '-':
currentArg = arg[1:]
else:
if currentArg is not None:
dict[currentArg] = arg
currentArg = None
if currentArg is not None:
dict[currentArg] = True
# Convert the json formatted Serialize Context through the provided Jinja2 template.
def Convert(source, output, template, split, additionalArgs):
with open(source) as jsonFile:
data = json.load(jsonFile)
jinjaEnvironment = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(template)), trim_blocks=True, lstrip_blocks=True)
jinjaEnvironment.filters['FilterByBase'] = FilterByBase
renderer = jinjaEnvironment.get_template(os.path.basename(template))
path, extension = os.path.splitext(output);
file = os.path.basename(path)
data['Config'] = {}
data['Config']['Document'] = file
ParseAdditionalArguments(data['Config'], additionalArgs)
print "Template arguments: {}".format(data['Config'])
if split:
for c in string.ascii_lowercase:
data['Config']['Filter'] = c
outputFilePath = "{0} {1}{2}".format(path, c, extension)
rendering = renderer.render(data)
with open(outputFilePath, 'w') as outputFile:
outputFile.write(rendering)
else:
rendering = renderer.render(data)
with open(output, 'w') as outputFile:
outputFile.write(rendering)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Takes a json-formatted dump of the Serialize Context and runs it through the provided Jinja2 templates.')
parser.add_argument('--source', help='Path to the json file containing the output of the SerializeContext.', required=True)
parser.add_argument('--output', help='Path to the file to write the converted result to.', required=True)
parser.add_argument('--template', help='Path to the Jinja2 template to use for the conversion.', required=True)
parser.add_argument('--split', help='Only include entries that start with this letter.', action='store_true')
args, remainingArgs = parser.parse_known_args()
sourcePath = args.source
if not os.path.isabs(sourcePath):
sourcePath = os.path.abspath(sourcePath)
outputPath = args.output
if not os.path.isabs(outputPath):
outputPath = os.path.abspath(outputPath)
templatePath = args.template
if not os.path.isabs(templatePath):
templatePath = os.path.abspath(templatePath)
if CreateOutputFolder(outputPath):
print 'Converting from "{0}" to "{1}" using template "{2}".'.format(sourcePath, outputPath, templatePath)
Convert(sourcePath, outputPath, templatePath, args.split, remainingArgs)