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/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py

709 lines
29 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
"""
# -------------------------------------------------------------------------
"""<DCCsi>.config
Generate dynamic and synethetic environment contest and settings
using dynaconf (dynamic configuration and settings)
This config.py synthetic env can be overriden or extended with a local .env
See: example.env.tmp (copy and rename to .env)
To do: ensure that we can stack/layer the dynamic env to work with O3DE projects
"""
# built in's
import os
import sys
import site
import re
import logging as _logging
# 3rdParty (possibly) py3 ships with pathlib, 2.7 does not
# import pathlib
# our framework for dcc tools need to run in apps like Maya that may still be
# on py27 so we need to import and use after some boostrapping
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
_O3DE_RUNNING=None
try:
import azlmbr
_O3DE_RUNNING=True
except:
_O3DE_RUNNING=False
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
def attach_debugger():
_DCCSI_GDEBUG = True
os.environ["DYNACONF_DCCSI_GDEBUG"] = str(_DCCSI_GDEBUG)
_DCCSI_DEV_MODE = True
os.environ["DYNACONF_DCCSI_DEV_MODE"] = str(_DCCSI_DEV_MODE)
from azpy.test.entry_test import connect_wing
_debugger = connect_wing()
return _debugger
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# global scope
_MODULENAME = __name__
if _MODULENAME is '__main__':
_MODULENAME = 'DCCsi.config'
#os.environ['PYTHONINSPECT'] = 'True'
_MODULE_PATH = os.path.abspath(__file__)
# we don't have access yet to the DCCsi Lib\site-packages
# (1) this will give us import access to azpy (always?)
_DCCSI_PATH = os.getenv('DCCSI_PATH',
os.path.abspath(os.path.dirname(_MODULE_PATH)))
# ^ we assume this config is in the root of the DCCsi
# if it's not, be sure to set envar 'DCCSI_PATH' to ensure it
site.addsitedir(_DCCSI_PATH) # must be done for azpy
# now we have azpy api access
import azpy
from azpy.env_bool import env_bool
from azpy.constants import ENVAR_DCCSI_GDEBUG
from azpy.constants import ENVAR_DCCSI_DEV_MODE
from azpy.constants import ENVAR_DCCSI_LOGLEVEL
# set up global space, logging etc.
# set these true if you want them set globally for debugging
_DCCSI_GDEBUG = env_bool(ENVAR_DCCSI_GDEBUG, False)
_DCCSI_DEV_MODE = env_bool(ENVAR_DCCSI_DEV_MODE, False)
_DCCSI_LOGLEVEL = int(env_bool(ENVAR_DCCSI_LOGLEVEL, int(20)))
if _DCCSI_GDEBUG:
_DCCSI_LOGLEVEL = int(10)
# early attach WingIDE debugger (can refactor to include other IDEs later)
# requires externally enabling via ENVAR
if _DCCSI_DEV_MODE:
_debugger = attach_debugger()
# to do: ^ this should be replaced with full featured azpy.dev.util
# that supports additional debuggers (pycharm, vscode, etc.)
# set up module logging
for handler in _logging.root.handlers[:]:
_logging.root.removeHandler(handler)
_LOGGER = azpy.initialize_logger(_MODULENAME,
log_to_file=_DCCSI_GDEBUG,
default_log_level=_DCCSI_LOGLEVEL)
_LOGGER.debug('Initializing: {0}.'.format({_MODULENAME}))
_LOGGER.info('site.addsitedir({})'.format(_DCCSI_PATH))
_LOGGER.debug('_DCCSI_GDEBUG: {}'.format(_DCCSI_GDEBUG))
_LOGGER.debug('_DCCSI_DEV_MODE: {}'.format(_DCCSI_DEV_MODE))
_LOGGER.debug('_DCCSI_LOGLEVEL: {}'.format(_DCCSI_LOGLEVEL))
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# this will give us import access to additional modules we provide with DCCsi
_DCCSI_PYTHON_LIB_PATH = azpy.config_utils.bootstrap_dccsi_py_libs(_DCCSI_PATH)
# Now we should be able to just carry on with pth lib and dynaconf
from dynaconf import Dynaconf
try:
import pathlib
except:
import pathlib2 as pathlib
from pathlib import Path
_DCCSI_PATH = Path(_DCCSI_PATH) # pathify
_DCCSI_PYTHON_PATH = Path(_DCCSI_PATH,'3rdParty','Python')
_DCCSI_PYTHON_LIB_PATH = Path(_DCCSI_PYTHON_LIB_PATH)
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# start locally prepping known default values for dyanmic environment settings
_O3DE_DCCSI_PATH = os.environ['PATH']
os.environ["DYNACONF_PATH"] = _O3DE_DCCSI_PATH
# this will retreive the O3DE engine root
_O3DE_DEV = azpy.config_utils.get_o3de_engine_root()
# set up dynamic config envars
os.environ["DYNACONF_O3DE_DEV"] = str(_O3DE_DEV.resolve())
from azpy.constants import TAG_DIR_O3DE_BUILD_FOLDER
_O3DE_BUILD_FOLDER = TAG_DIR_O3DE_BUILD_FOLDER
os.environ["DYNACONF_O3DE_BUILD_FOLDER"] = str(_O3DE_BUILD_FOLDER)
_O3DE_BUILD_PATH = Path(_O3DE_DEV, TAG_DIR_O3DE_BUILD_FOLDER)
os.environ["DYNACONF_O3DE_BUILD_PATH"] = str(_O3DE_BUILD_PATH.resolve())
from azpy.constants import STR_O3DE_BIN_PATH
_O3DE_BIN_PATH = Path(STR_O3DE_BIN_PATH.format(_O3DE_BUILD_PATH))
os.environ["DYNACONF_O3DE_BIN_PATH"] = str(_O3DE_BIN_PATH.resolve())
# this in most cases will return the project folder
# if it returns a matching engine folder then we don't know the project folder
_O3DE_PROJECT_PATH = azpy.config_utils.get_o3de_project_path()
os.environ["DYNACONF_O3DE_PROJECT_PATH"] = str(_O3DE_PROJECT_PATH.resolve())
# special, a home for stashing PYTHONPATHs into managed settings
_O3DE_PYTHONPATH = list()
_O3DE_PYTHONPATH.append(_DCCSI_PATH)
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
def init_o3de_pyside2(dccsi_path=_DCCSI_PATH,
engine_bin=_O3DE_BIN_PATH):
"""Initialize the DCCsi Qt/PySide dynamic env and settings
sets access to lumberyards Qt dlls and PySide"""
_DCCSI_PATH = Path(dccsi_path)
_O3DE_BIN_PATH = Path(engine_bin)
if not _O3DE_BIN_PATH.exists():
raise Exception('_O3DE_BIN_PATH does NOT exist: {0}'.format(_O3DE_BIN_PATH))
else:
pass
# python config
_DCCSI_PYTHON_PATH = Path(_DCCSI_PATH,'3rdParty','Python')
os.environ["DYNACONF_DCCSI_PYTHON_PATH"] = str(_DCCSI_PYTHON_PATH.resolve())
# # allows to retreive from settings.QTFORPYTHON_PATH
# from azpy.constants import STR_QTFORPYTHON_PATH # a path string constructor
# QTFORPYTHON_PATH = Path(STR_QTFORPYTHON_PATH.format(O3DE_DEV)).resolve()
# os.environ["DYNACONF_QTFORPYTHON_PATH"] = str(QTFORPYTHON_PATH)
# site.addsitedir(str(QTFORPYTHON_PATH)) # PYTHONPATH
QT_PLUGIN_PATH = Path.joinpath(_O3DE_BIN_PATH,'EditorPlugins')
os.environ["DYNACONF_QT_PLUGIN_PATH"] = str(QT_PLUGIN_PATH.resolve())
os.environ['PATH'] = QT_PLUGIN_PATH.as_posix() + os.pathsep + os.environ['PATH']
QT_QPA_PLATFORM_PLUGIN_PATH = Path.joinpath(QT_PLUGIN_PATH, 'platforms')
os.environ["DYNACONF_QT_QPA_PLATFORM_PLUGIN_PATH"] = str(QT_QPA_PLATFORM_PLUGIN_PATH.resolve())
# if the line below is removed external standalone apps can't load PySide2
os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = str(QT_QPA_PLATFORM_PLUGIN_PATH.resolve())
# ^^ bypass trying to set only with DYNACONF environment
os.environ['PATH'] = QT_QPA_PLATFORM_PLUGIN_PATH.as_posix() + os.pathsep + os.environ['PATH']
# ^^ this particular env only works correctly if put on the PATH in this manner
# add Qt binaries to the Windows path to handle findings DLL file dependencies
if sys.platform.startswith('win'):
_LOGGER.info('~ Qt/PySide2 bootstrapped PATH for Windows.')
else:
_LOGGER.warning('~ Not tested on Non-Windows platforms.')
# To Do: figure out how to test and/or modify to work
try:
import PySide2
_LOGGER.info('~ SUCCESS: import PySide2')
_LOGGER.debug(PySide2)
status = True
except ImportError as e:
_LOGGER.error('~ FAILURE: import PySide2')
status = False
raise(e)
try:
import shiboken2
_LOGGER.info('~ SUCCESS: import shiboken2')
_LOGGER.debug(shiboken2)
status = True
except ImportError as e:
_LOGGER.error('~ FAILURE: import shiboken2')
status = False
raise(e)
# set up the pyside2-tools (pyside2uic)
# to do: move path construction string to constants and build off of SDK
# have not done that yet as I really want to get legal approval and
# add this to the QtForPython Gem
# please pass this in current code reviews
_DCCSI_PYSIDE2_TOOLS = Path(_DCCSI_PYTHON_PATH,'pyside2-tools')
if _DCCSI_PYSIDE2_TOOLS.exists():
os.environ["DYNACONF_DCCSI_PYSIDE2_TOOLS"] = str(_DCCSI_PYSIDE2_TOOLS.resolve())
os.environ['PATH'] = _DCCSI_PYSIDE2_TOOLS.as_posix() + os.pathsep + os.environ['PATH']
site.addsitedir(_DCCSI_PYSIDE2_TOOLS)
_O3DE_PYTHONPATH.append(_DCCSI_PYSIDE2_TOOLS.resolve())
_LOGGER.info('~ PySide2-Tools bootstrapped PATH for Windows.')
try:
import pyside2uic
_LOGGER.info('~ SUCCESS: import pyside2uic')
_LOGGER.debug(shiboken2)
status = True
except ImportError as e:
_LOGGER.error('~ FAILURE: import pyside2uic')
status = False
raise(e)
else:
_LOGGER.warning('~ No PySide2 Tools: {}'.format(_DCCSI_PYSIDE2_TOOLS.resolve))
_O3DE_DCCSI_PATH = os.environ['PATH']
os.environ["DYNACONF_PATH"] = _O3DE_DCCSI_PATH
try:
_DCCSI_PYTHONPATH = os.environ['PYTHONPATH']
os.environ["DYNACONF_PYTHONPATH"] = _DCCSI_PYTHONPATH
except:
pass
from dynaconf import settings
_LOGGER.info('~ config.init_o3de_pyside() ... DONE')
if status:
return settings
else:
return None
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
def test_pyside2():
"""Convenience method to test Qt / PySide2 access"""
# now test
_LOGGER.info('~ Testing Qt / PySide2')
try:
from PySide2.QtWidgets import QApplication, QPushButton
app = QApplication(sys.argv)
hello = QPushButton("~ O3DE DCCsi PySide2 Test!")
hello.resize(200, 60)
hello.show()
except Exception as e:
_LOGGER.error('~ FAILURE: Qt / PySide2')
status = False
raise(e)
_LOGGER.info('~ SUCCESS: .test_pyside2()')
sys.exit(app.exec_())
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
def init_o3de_core(engine_path=_O3DE_DEV,
build_folder=_O3DE_BUILD_FOLDER,
project_name=None,
project_path=_O3DE_PROJECT_PATH):
"""Initialize the DCCsi Core dynamic env and settings"""
# `envvar_prefix` = export envvars with `export DYNACONF_FOO=bar`.
# `settings_files` = Load this files in the order.
# here we are modifying or adding to the dynamic config settings on import
settings = Dynaconf(envvar_prefix='DYNACONF',
settings_files=['settings.json',
'dev.settings.json',
'user.settings.json',
'.secrets.json'])
# global settings
os.environ["DYNACONF_DCCSI_OS_FOLDER"] = azpy.config_utils.get_os()
os.environ["DYNACONF_DCCSI_GDEBUG"] = str(_DCCSI_GDEBUG)
os.environ["DYNACONF_DCCSI_DEV_MODE"] = str(_DCCSI_DEV_MODE)
os.environ['DYNACONF_DCCSI_LOGLEVEL'] = str(_DCCSI_LOGLEVEL)
os.environ["DYNACONF_DCCSI_PATH"] = str(_DCCSI_PATH.resolve())
os.environ['PATH'] = _DCCSI_PATH.as_posix() + os.pathsep + os.environ['PATH']
# we already defaulted to discovering these two early because of importance
#os.environ["DYNACONF_O3DE_DEV"] = str(_O3DE_DEV.resolve())
#os.environ["DYNACONF_O3DE_PROJECT_PATH"] = str(_O3DE_PROJECT_PATH)
# we also already added them to DYNACONF_
# this in an explicit pass in
if project_path:
_project_path = Path(project_path)
try:
_project_path.exists()
_O3DE_PROJECT_PATH = _project_path
os.environ["DYNACONF_O3DE_PROJECT_PATH"] = str(_O3DE_PROJECT_PATH.resolve())
except FileExistsError as e:
_LOGGER.error('~ The project path specified does not appear to exist!')
_LOGGER.warning('~ project_path: {}'.format(project_path))
_LOGGER.warning('~ fallback to engine root: {}'.format())
project_path = _O3DE_DEV
os.environ["DYNACONF_O3DE_PROJECT_PATH"] = str(_O3DE_DEV.resolve())
# we can pull the O3DE_PROJECT (name) from the project path
if not project_name:
project_name = Path(_O3DE_PROJECT_PATH).name
os.environ["DYNACONF_O3DE_PROJECT"] = str(project_name)
# To Do: there might be a project namespace in the project.json?
# -- O3DE build -- set up \bin\path (for Qt dll access)
os.environ["DYNACONF_O3DE_BUILD_FOLDER"] = str(build_folder)
_O3DE_BUILD_PATH = Path(_O3DE_DEV, build_folder)
os.environ["DYNACONF_O3DE_BUILD_PATH"] = str(_O3DE_BUILD_PATH.resolve())
_O3DE_BIN_PATH = Path(STR_O3DE_BIN_PATH.format(_O3DE_BUILD_PATH))
os.environ["DYNACONF_O3DE_BIN_PATH"] = str(_O3DE_BIN_PATH.resolve())
# hard check
if not _O3DE_BIN_PATH.exists():
raise Exception('O3DE_BIN_PATH does NOT exist: {0}'.format(_O3DE_BIN_PATH))
else:
# adding to sys.path apparently doesn't work for .dll locations like Qt
os.environ['PATH'] = _O3DE_BIN_PATH.as_posix() + os.pathsep + os.environ['PATH']
# --
from azpy.constants import TAG_DIR_DCCSI_TOOLS
_DCCSI_TOOLS_PATH = Path(_DCCSI_PATH, TAG_DIR_DCCSI_TOOLS)
os.environ["DYNACONF_DCCSI_TOOLS_PATH"] = str(_DCCSI_TOOLS_PATH.resolve())
from azpy.constants import TAG_DCCSI_NICKNAME
from azpy.constants import PATH_DCCSI_LOG_PATH
_DCCSI_LOG_PATH = Path(PATH_DCCSI_LOG_PATH.format(O3DE_PROJECT_PATH=project_path,
TAG_DCCSI_NICKNAME=TAG_DCCSI_NICKNAME))
os.environ["DYNACONF_DCCSI_LOG_PATH"] = str(_DCCSI_LOG_PATH)
from azpy.constants import TAG_DIR_REGISTRY, TAG_DCCSI_CONFIG
_DCCSI_CONFIG_PATH = Path(project_path, TAG_DIR_REGISTRY, TAG_DCCSI_CONFIG)
os.environ["DYNACONF_DCCSI_CONFIG_PATH"] = str(_DCCSI_CONFIG_PATH.resolve())
from azpy.constants import TAG_DIR_DCCSI_TOOLS
_DCCSIG_TOOLS_PATH = Path.joinpath(_DCCSI_PATH, TAG_DIR_DCCSI_TOOLS)
os.environ["DYNACONF_DCCSIG_TOOLS_PATH"] = str(_DCCSIG_TOOLS_PATH.resolve())
_O3DE_DCCSI_PATH = os.environ['PATH']
os.environ["DYNACONF_PATH"] = _O3DE_DCCSI_PATH
from dynaconf import settings
_LOGGER.info('~ config.init_o3de_core() ... DONE')
return settings
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
def init_o3de_python(engine_path=_O3DE_DEV,
engine_bin=_O3DE_BIN_PATH,
dccsi_path=_DCCSI_PATH):
# pathify
_O3DE_DEV = Path(engine_path)
_O3DE_BIN_PATH = Path(engine_bin)
_DCCSI_PATH = Path(dccsi_path)
# python config
_DCCSI_PYTHON_PATH = Path(_DCCSI_PATH,'3rdParty','Python')
os.environ["DYNACONF_DCCSI_PYTHON_PATH"] = str(_DCCSI_PYTHON_PATH.resolve())
_DCCSI_PYTHON_LIB_PATH = azpy.config_utils.bootstrap_dccsi_py_libs(_DCCSI_PATH)
os.environ["DYNACONF_DCCSI_PYTHON_LIB_PATH"] = str(_DCCSI_PYTHON_LIB_PATH.resolve())
os.environ['PATH'] = _DCCSI_PYTHON_LIB_PATH.as_posix() + os.pathsep + os.environ['PATH']
site.addsitedir(_DCCSI_PYTHON_LIB_PATH)
_O3DE_PYTHONPATH.append(_DCCSI_PYTHON_LIB_PATH.resolve())
site.addsitedir(_O3DE_BIN_PATH)
_O3DE_PYTHONPATH.append(_O3DE_BIN_PATH.resolve())
_O3DE_PY_EXE = Path(sys.executable)
_DCCSI_PY_IDE = Path(_O3DE_PY_EXE)
os.environ["DYNACONF_DCCSI_PY_IDE"] = str(_DCCSI_PY_IDE.resolve())
_O3DE_PYTHONHOME = Path(_O3DE_PY_EXE.parents[0])
os.environ["DYNACONF_O3DE_PYTHONHOME"] = str(_O3DE_PYTHONHOME.resolve())
os.environ['PATH'] = _O3DE_PYTHONHOME.as_posix() + os.pathsep + os.environ['PATH']
_LOGGER.info('~ O3DE_PYTHONHOME - is now the folder containing O3DE python executable')
_O3DE_PYTHON_INSTALL = Path(_O3DE_DEV, 'python')
os.environ["DYNACONF_O3DE_PYTHON_INSTALL"] = str(_O3DE_PYTHON_INSTALL.resolve())
os.environ['PATH'] = _O3DE_PYTHON_INSTALL.as_posix() + os.pathsep + os.environ['PATH']
if sys.platform.startswith('win'):
_DCCSI_PY_BASE = Path(_O3DE_PYTHON_INSTALL, 'python.cmd')
elif sys.platform == "linux":
_DCCSI_PY_BASE = Path(_O3DE_PYTHON_INSTALL, 'python.sh')
elif sys.platform == "darwin":
_DCCSI_PY_BASE = Path(_O3DE_PYTHON_INSTALL, 'python.sh')
else:
_DCCSI_PY_BASE = None
if _DCCSI_PY_BASE:
os.environ["DYNACONF_DCCSI_PY_BASE"] = str(_DCCSI_PY_BASE.resolve())
_O3DE_DCCSI_PATH = os.environ['PATH']
os.environ["DYNACONF_PATH"] = _O3DE_DCCSI_PATH
try:
_DCCSI_PYTHONPATH = os.environ['PYTHONPATH']
os.environ["DYNACONF_PYTHONPATH"] = _DCCSI_PYTHONPATH
except:
pass
from dynaconf import settings
_LOGGER.info('~ config.init_o3de_python() ... DONE')
return settings
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# settings.setenv() # doing this will add the additional DYNACONF_ envars
def get_config_settings(engine_path=_O3DE_DEV,
build_folder=_O3DE_BUILD_FOLDER,
project_name=None,
project_path=_O3DE_PROJECT_PATH,
enable_o3de_python=None,
enable_o3de_pyside2=None,
set_env=True):
"""Convenience method to initialize and retreive settings directly from module."""
settings = init_o3de_core(engine_path,
build_folder,
project_name,
project_path)
if enable_o3de_python:
settings = init_o3de_python(settings.O3DE_DEV,
settings.O3DE_BIN_PATH,
settings.DCCSI_PATH)
# These should ONLY be set for O3DE and non-DCC environments
# They will most likely cause other Qt/PySide DCC apps to fail
# or hopefully they can be overridden for DCC envionments
# that provide their own Qt dlls and Pyside2
# _LOGGER.info('QTFORPYTHON_PATH: {}'.format(settings.QTFORPYTHON_PATH))
# _LOGGER.info('QT_PLUGIN_PATH: {}'.format(settings.QT_PLUGIN_PATH))
# assume our standalone python tools wants this access?
# it's safe to do this for dev and from ide
if enable_o3de_pyside2:
settings = init_o3de_pyside2(settings.DCCSI_PATH,
settings.O3DE_BIN_PATH)
# now standalone we can validate the config. env, settings.
from dynaconf import settings
if set_env:
settings.setenv()
return settings
# --- END -----------------------------------------------------------------
###########################################################################
# Main Code Block, runs this script as main (testing)
# -------------------------------------------------------------------------
if __name__ == '__main__':
"""Run this file as a standalone cli script"""
_MODULENAME = __name__
if _MODULENAME is '__main__':
_MODULENAME = 'DCCsi.config'
from azpy.constants import STR_CROSSBAR
while 0: # temp internal debug flag
_DCCSI_GDEBUG = True
break
# overide logger for standalone to be more verbose and log to file
_LOGGER = azpy.initialize_logger(_MODULENAME,
log_to_file=_DCCSI_GDEBUG,
default_log_level=_DCCSI_LOGLEVEL)
# happy print
_LOGGER.info(STR_CROSSBAR)
_LOGGER.info('~ constants.py ... Running script as __main__')
_LOGGER.info(STR_CROSSBAR)
# go ahead and run the rest of the configuration
# parse the command line args
import argparse
parser = argparse.ArgumentParser(
description='O3DE DCCsi Dynamic Config (dynaconf)',
epilog="Attempts to determine O3DE project if -pp not set")
parser.add_argument('-gd', '--global-debug',
type=bool,
required=False,
help='Enables global debug flag.')
parser.add_argument('-dm', '--developer-mode',
type=bool,
required=False,
help='Enables dev mode for early auto attaching debugger.')
parser.add_argument('-ep', '--engine-path',
type=pathlib.Path,
required=False,
help='The path to the o3de engine.')
parser.add_argument('-bf', '--build-folder',
type=str,
required=False,
help='The name (tag) of the o3de build folder, example build or windows_vs2019.')
parser.add_argument('-pp', '--project-path',
type=pathlib.Path,
required=False,
help='The path to the project.')
parser.add_argument('-pn', '--project-name',
type=str,
required=False,
help='The name of the project.')
parser.add_argument('-py', '--enable-python',
type=bool,
required=False,
help='Enables O3DE python access.')
parser.add_argument('-qt', '--enable-qt',
type=bool,
required=False,
help='Enables O3DE Qt\PySide2 access.')
parser.add_argument('-sd', '--set-debugger',
type=str,
required=False,
help='Default debugger: WING, others: PYCHARM, VSCODE (not yet implemented).')
parser.add_argument('-pc', '--project-config',
type=bool,
required=False,
help='Enables reading the projects registry\dccsiconfiguration.setreg.')
parser.add_argument('-es', '--export-settings',
type=pathlib.Path,
required=False,
help='Writes managed settings to specified path.')
parser.add_argument('-ec', '--export-configuration',
type=bool,
required=False,
help='writes settings as a O3DE registry\dccsiconfiguration.setreg.')
parser.add_argument('-tp', '--test-pyside2',
type=bool,
required=False,
help='Runs Qt/PySide2 tests and reports.')
args = parser.parse_args()
# easy overrides
if args.global_debug:
_DCCSI_GDEBUG = True
os.environ["DYNACONF_DCCSI_GDEBUG"] = str(_DCCSI_GDEBUG)
if args.developer_mode:
attach_debugger() # attempts to start debugger
if args.set_debugger:
_LOGGER.info('Setting and switching debugger type from WingIDE not implemented.')
# To Do: implement debugger plugin pattern
# need to do a little plumbing
if not args.engine_path:
args.engine_path=_O3DE_DEV
if not args.build_folder:
from azpy.constants import TAG_DIR_O3DE_BUILD_FOLDER
args.build_folder = TAG_DIR_O3DE_BUILD_FOLDER
if not args.project_path:
args.project_path=_O3DE_PROJECT_PATH
if _DCCSI_GDEBUG:
args.enable_python = True
args.enable_qt = True
# now standalone we can validate the config. env, settings.
settings = get_config_settings(engine_path=args.engine_path,
build_folder=args.build_folder,
project_name=args.project_name,
project_path=args.project_path,
enable_o3de_python=args.enable_python,
enable_o3de_pyside2=args.enable_qt)
## CORE
_LOGGER.info(STR_CROSSBAR)
# not using fstrings in this module because it might run in py2.7 (maya)
_LOGGER.info('DCCSI_GDEBUG: {}'.format(settings.DCCSI_GDEBUG))
_LOGGER.info('DCCSI_DEV_MODE: {}'.format(settings.DCCSI_DEV_MODE))
_LOGGER.info('DCCSI_LOGLEVEL: {}'.format(settings.DCCSI_LOGLEVEL))
_LOGGER.info('DCCSI_OS_FOLDER: {}'.format(settings.DCCSI_OS_FOLDER))
_LOGGER.info('O3DE_DEV: {}'.format(settings.O3DE_DEV))
_LOGGER.info('O3DE_O3DE_BUILD_FOLDER: {}'.format(settings.O3DE_BUILD_PATH))
_LOGGER.info('O3DE_BUILD_PATH: {}'.format(settings.O3DE_BUILD_PATH))
_LOGGER.info('O3DE_BIN_PATH: {}'.format(settings.O3DE_BIN_PATH))
_LOGGER.info('O3DE_PROJECT: {}'.format(settings.O3DE_PROJECT))
_LOGGER.info('O3DE_PROJECT_PATH: {}'.format(settings.O3DE_PROJECT_PATH))
_LOGGER.info('DCCSI_PATH: {}'.format(settings.DCCSI_PATH))
_LOGGER.info('DCCSI_LOG_PATH: {}'.format(settings.DCCSI_LOG_PATH))
_LOGGER.info('DCCSI_CONFIG_PATH: {}'.format(settings.DCCSI_CONFIG_PATH))
if settings.O3DE_DCCSI_ENV_TEST:
_LOGGER.info('O3DE_DCCSI_ENV_TEST: {}'.format(settings.O3DE_DCCSI_ENV_TEST))
_LOGGER.info(STR_CROSSBAR)
_LOGGER.info('')
if args.enable_python:
_LOGGER.info(STR_CROSSBAR)
_LOGGER.info('DCCSI_PYTHON_PATH'.format(settings.DCCSI_PYTHON_PATH))
_LOGGER.info('DCCSI_PYTHON_LIB_PATH: {}'.format(settings.DCCSI_PYTHON_LIB_PATH))
_LOGGER.info('DCCSI_PY_IDE'.format(settings.DCCSI_PY_IDE))
_LOGGER.info('O3DE_PYTHONHOME'.format(settings.O3DE_PYTHONHOME))
_LOGGER.info('O3DE_PYTHON_INSTALL'.format(settings.O3DE_PYTHON_INSTALL))
_LOGGER.info('DCCSI_PY_BASE: {}'.format(settings.DCCSI_PY_BASE))
_LOGGER.info(STR_CROSSBAR)
_LOGGER.info('')
else:
_LOGGER.info('Tip: add arg --enable-python to extend the environment with O3DE python access')
if args.enable_qt:
_LOGGER.info(STR_CROSSBAR)
# _LOGGER.info('QTFORPYTHON_PATH: {}'.format(settings.QTFORPYTHON_PATH))
_LOGGER.info('QT_PLUGIN_PATH: {}'.format(settings.QT_PLUGIN_PATH))
_LOGGER.info('QT_QPA_PLATFORM_PLUGIN_PATH: {}'.format(settings.QT_QPA_PLATFORM_PLUGIN_PATH))
_LOGGER.info('DCCSI_PYSIDE2_TOOLS: {}'.format(settings.DCCSI_PYSIDE2_TOOLS))
_LOGGER.info(STR_CROSSBAR)
_LOGGER.info('')
else:
_LOGGER.info('Tip: add arg --enable-qt to extend the environment with O3DE Qt/PySide2 support')
settings.setenv() # doing this will add/set the additional DYNACONF_ envars
if _DCCSI_GDEBUG or args.export_settings:
# to do: need to add malformed json validation to <dccsi>\settings.json
# this can cause a bad error that is deep and hard to debug
# writting settings
from dynaconf import loaders
from dynaconf.utils.boxing import DynaBox
_settings_dict = settings.as_dict()
# default temp filename
_settings_file = Path('settings_export.json.tmp')
# writes to a file, the format is inferred by extension
# can be .yaml, .toml, .ini, .json, .py
#loaders.write(_settings_file, DynaBox(data).to_dict(), merge=False, env='development')
#loaders.write(_settings_file, DynaBox(data).to_dict())
# we want to possibly modify or stash our settings into a o3de .setreg
from box import Box
_settings_box = Box(_settings_dict)
_LOGGER.info('Pretty print, _settings_box: {}'.format(_settings_file))
_LOGGER.info(str(_settings_box.to_json(sort_keys=True,
indent=4)))
# writes settings box
_settings_box.to_json(filename=_settings_file.as_posix(),
sort_keys=True,
indent=4)
if _DCCSI_GDEBUG or args.test_pyside2:
test_pyside2() # test PySide2 access with a pop-up button
try:
import pyside2uic
except ImportError as e:
_LOGGER.warning("Could not import 'pyside2uic'")
_LOGGER.warning("Refer to: '< local DCCsi >\3rdParty\Python\README.txt'")
_LOGGER.error(e)
# return
sys.exit()
# --- END -----------------------------------------------------------------