Merge pull request #34 from aws-lumberyard-dev/ly-as-sdk/Engine-Gem-Tracking

Implemented the RFC for tracking external_subdirectory dependencies in the engine.json
This commit is contained in:
lumberyard-employee-dm
2021-05-25 11:44:56 -05:00
committed by GitHub
70 changed files with 4646 additions and 5962 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ __pycache__
AssetProcessorTemp/**
[Bb]uild/**
[Cc]ache/
install/
/install/
Editor/EditorEventLog.xml
Editor/EditorLayout.xml
**/*egg-info/**
+16 -25
View File
@@ -25,10 +25,6 @@ include(cmake/LySet.cmake)
include(cmake/Version.cmake)
include(cmake/OutputDirectory.cmake)
# Set the engine_path and engine_json
set(o3de_engine_path ${CMAKE_CURRENT_LIST_DIR})
set(o3de_engine_json ${o3de_engine_path}/engine.json)
if(NOT PROJECT_NAME)
project(O3DE
LANGUAGES C CXX
@@ -36,21 +32,6 @@ if(NOT PROJECT_NAME)
)
endif()
################################################################################
# Resolve this engines name and restricted path
################################################################################
include(cmake/o3de_manifest.cmake)
o3de_engine_name(${o3de_engine_json} o3de_engine_name)
o3de_restricted_path(${o3de_engine_json} o3de_engine_restricted_path)
message(STATUS "O3DE Engine Name: ${o3de_engine_name}")
message(STATUS "O3DE Engine Path: ${o3de_engine_path}")
if(o3de_engine_restricted_path)
message(STATUS "O3DE Engine Restricted Path: ${o3de_engine_restricted_path}")
endif()
# add the engines cmake folder to the CMAKE_MODULE_PATH
list(APPEND CMAKE_MODULE_PATH "${o3de_engine_path}/cmake")
################################################################################
# Initialize
################################################################################
@@ -72,11 +53,22 @@ include(cmake/Monolithic.cmake)
include(cmake/SettingsRegistry.cmake)
include(cmake/TestImpactFramework/LYTestImpactFramework.cmake)
include(cmake/CMakeFiles.cmake)
include(cmake/O3DEJson.cmake)
################################################################################
# Subdirectory processing
################################################################################
function(add_engine_json_external_subdirectories)
read_json_external_subdirs(external_subdis ${LY_ROOT_FOLDER}/engine.json)
foreach(external_subdir ${external_subdis})
file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER})
list(APPEND engine_external_subdirs ${real_external_subdir})
endforeach()
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${engine_external_subdirs})
endfunction()
# Add the projects first so the Launcher can find them
include(cmake/Projects.cmake)
@@ -92,12 +84,11 @@ if(NOT INSTALLED_ENGINE)
add_subdirectory(Tools/RemoteConsole/ly_remote_console/tests/)
endif()
# Add any engine restricted platforms as external subdirs
o3de_add_engine_restricted_platform_external_subdirs()
# Add external subdirectories listed in the manifest. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra
# Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra
# external subdirectories
list(APPEND LY_EXTERNAL_SUBDIRS ${o3de_engine_external_subdirectories})
add_engine_json_external_subdirectories()
get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs})
# Loop over the additional external subdirectories and invoke add_subdirectory on them
foreach(external_directory ${LY_EXTERNAL_SUBDIRS})
@@ -111,7 +102,7 @@ if(NOT INSTALLED_ENGINE)
string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash)
# Use the last directory as the suffix path to use for the Binary Directory
get_filename_component(directory_name ${external_directory} NAME)
add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/${directory_name}-${full_directory_hash})
add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash})
endforeach()
else()
@@ -25,7 +25,7 @@ namespace O3DE::ProjectManager
bool GemInfo::IsValid() const
{
return !m_path.isEmpty() && !m_uuid.IsNull();
return !m_path.isEmpty();
}
} // namespace O3DE::ProjectManager
@@ -43,7 +43,6 @@ namespace O3DE::ProjectManager
QString m_path;
QString m_name;
QString m_displayName;
AZ::Uuid m_uuid;
QString m_creator;
bool m_isAdded = false; //! Is the gem currently added and enabled in the project?
QString m_summary;
@@ -112,7 +112,7 @@ namespace O3DE::ProjectManager
AZ_Warning("ProjectManagerWindow", result != -1, "Append to sys path failed");
// import required modules
m_registration = pybind11::module::import("o3de.registration");
m_registration = pybind11::module::import("o3de.manifest");
return result == 0 && !PyErr_Occurred();
} catch ([[maybe_unused]] const std::exception& e)
@@ -227,14 +227,13 @@ namespace O3DE::ProjectManager
GemInfo gemInfo;
gemInfo.m_path = Py_To_String(path);
auto data = m_registration.attr("get_gem_data")(pybind11::none(), path);
auto data = m_registration.attr("get_gem_json_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(data))
{
try
{
// required
gemInfo.m_name = Py_To_String(data["Name"]);
gemInfo.m_uuid = AZ::Uuid(Py_To_String(data["Uuid"]));
gemInfo.m_name = Py_To_String(data["gem_name"]);
// optional
gemInfo.m_displayName = Py_To_String_Optional(data, "DisplayName", gemInfo.m_name);
@@ -270,7 +269,7 @@ namespace O3DE::ProjectManager
ProjectInfo projectInfo;
projectInfo.m_path = Py_To_String(path);
auto projectData = m_registration.attr("get_project_data")(pybind11::none(), path);
auto projectData = m_registration.attr("get_project_json_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(projectData))
{
try
@@ -327,7 +326,7 @@ namespace O3DE::ProjectManager
ProjectTemplateInfo templateInfo;
templateInfo.m_path = Py_To_String(path);
auto data = m_registration.attr("get_template_data")(pybind11::none(), path);
auto data = m_registration.attr("get_template_json_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(data))
{
try
@@ -0,0 +1,10 @@
{
"gem_name": "ImageProcessingAtom",
"display_name": "Atom Image Processing",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "AtomShader",
"display_name": "Atom Shader Builder",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_Bootstrap",
"display_name": "Atom Bootstrap",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_Component_DebugCamera",
"display_name": "Atom Debug Camera Component",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_Feature_Common",
"display_name": "Atom Feature Common",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_RHI_DX12",
"display_name": "Atom RHI DX12",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_RHI_Metal",
"display_name": "Atom RHI Metal",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_RHI_Null",
"display_name": "Atom RHI Null",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_RHI_Vulkan",
"display_name": "Atom RHI Vulkan",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_RHI",
"display_name": "Atom RHI",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_RPI",
"display_name": "Atom API",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
@@ -0,0 +1,10 @@
{
"gem_name": "AtomToolsFramework",
"display_name": "Atom Tools Framework",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+3 -1
View File
@@ -1,3 +1,5 @@
{
"gem_name": "Atom"
"gem_name": "Atom",
"display_name": "Atom",
"summary": "Next-Gen Rendering Package for the O3DE engine"
}
@@ -0,0 +1,10 @@
{
"gem_name": "Atom_AtomBridge",
"display_name": "Atom Bridge",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "AtomFont",
"display_name": "Atom Font",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
@@ -0,0 +1,10 @@
{
"gem_name": "AtomImGuiTools",
"display_name": "Atom ImGui",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
@@ -9,4 +9,4 @@
"AtomLyIntegration",
"AtomViewportDisplayInfo"
]
}
}
@@ -0,0 +1,10 @@
{
"gem_name": "CommonFeaturesAtom",
"display_name": "Common Features Atom",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
@@ -0,0 +1,10 @@
{
"gem_name": "EMotionFX_Atom",
"display_name": "EMotionFX Atom",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+10
View File
@@ -0,0 +1,10 @@
{
"gem_name": "ImguiAtom",
"display_name": "Imgui Atom",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
@@ -0,0 +1,10 @@
{
"gem_name": "DccScriptingInterface",
"display_name": "Atom Dcc Scripting Interface",
"summary": "",
"canonical_tags": [
"Gem"
],
"user_tags": [
]
}
+3 -1
View File
@@ -1,3 +1,5 @@
{
"gem_name": "AtomLyIntegration"
"gem_name": "AtomLyIntegration",
"display_name": "Atom O3DE Integration",
"summary": "Collection of module targets for integrating Atom with the O3DE engine"
}
+1 -1
View File
@@ -11,7 +11,7 @@
set(o3de_gem_path ${CMAKE_CURRENT_LIST_DIR})
set(o3de_gem_json ${o3de_gem_path}/gem.json)
o3de_gem_name(${o3de_gem_json} o3de_gem_name)
o3de_read_json_key(o3de_gem_name ${o3de_gem_json} "gem_name")
o3de_restricted_path(${o3de_gem_json} o3de_gem_restricted_path)
# Currently we are in the DefaultProjectSource folder: ${CMAKE_CURRENT_LIST_DIR}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"template_name": "DefaultGem",
"restricted": "o3de",
"restricted_name": "o3de",
"restricted_platform_relative_path": "Templates",
"origin": "The primary repo for DefaultGem goes here: i.e. http://www.mydomain.com",
"license": "What license DefaultGem uses goes here: i.e. https://opensource.org/licenses/MIT",
@@ -46,98 +46,3 @@ else()
add_subdirectory(Code)
endif()
# #! Adds the --project-path argument to the VS IDE debugger command arguments
# function(add_vs_debugger_arguments)
# # Inject the project root into the --project-path argument into the Visual Studio Debugger arguments by defaults
# list(APPEND app_targets ${Name}.GameLauncher ${Name}.ServerLauncher)
# list(APPEND app_targets AssetBuilder AssetProcessor AssetProcessorBatch Editor)
# foreach(app_target IN LISTS app_targets)
# if (TARGET ${app_target})
# set_property(TARGET ${app_target} APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${CMAKE_CURRENT_LIST_DIR}\"")
# endif()
# endforeach()
# endfunction()
# set(o3de_project_path ${CMAKE_CURRENT_LIST_DIR})
# set(o3de_project_json ${o3de_project_path}/project.json)
# if(NOT PROJECT_NAME)
# cmake_minimum_required(VERSION 3.19)
# project(${Name}
# LANGUAGES C CXX
# VERSION 1.0.0.0
# )
# # set this project as the only project
# set(LY_PROJECTS ${CMAKE_CURRENT_LIST_DIR})
# # o3de manifest
# include(o3de_manifest.cmake)
# ################################################################################
# # Set the engine_path and resolve this engines restricted path if it has one
# ################################################################################
# o3de_engine_path(${o3de_project_json} o3de_engine_path)
# o3de_project_name(${o3de_project_json} o3de_project_name)
# o3de_restricted_path(${o3de_project_json} o3de_project_restricted_path)
# message(STATUS "O3DE Project Name: ${o3de_project_name}")
# message(STATUS "O3DE Project Path: ${o3de_project_path}")
# if(o3de_project_restricted_path)
# message(STATUS "O3DE Project Restricted Path: ${o3de_project_restricted_path}")
# endif()
# # add the engines cmake folder to the CMAKE_MODULE_PATH
# list(APPEND CMAKE_MODULE_PATH "${o3de_engine_path}/cmake")
# # add subdirectory on the engine path for this project
# #add_subdirectory(${o3de_engine_path} o3de)
# find_package(o3de REQUIRED)
# o3de_initialize()
# # add this --project-path arguments to visual studio debugger
# add_vs_debugger_arguments()
# else()
# ######################################################
# # the engine is calling add sub_directory() on us
# ######################################################
# o3de_project_name(${o3de_project_json} o3de_project_name)
# o3de_restricted_path(${o3de_project_json} o3de_project_restricted_path)
# # Currently we are in the folder: ${CMAKE_CURRENT_LIST_DIR}
# # Get the platform specific folder ${pal_dir} for the folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}
# # Note: ly_get_list_relative_pal_filename will take care of the details for us, as this may be a restricted platform
# # in which case it will see if that platform is present here or in the restricted folder.
# # i.e. It could here: TestDP/Platform/<platorm_name> or
# # <restricted_folder>/<platform_name>/TestDP
# ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_project_restricted_path} ${o3de_project_path} ${o3de_project_name})
# # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the
# # project cmake for this platform.
# include(${pal_dir}/${PAL_PLATFORM_NAME_LOWERCASE}_project.cmake)
# # Add the project_name to global LY_PROJECTS_TARGET_NAME property
# set_property(GLOBAL APPEND PROPERTY LY_PROJECTS_TARGET_NAME ${o3de_project_name})
# add_subdirectory(Code)
# endif()
@@ -0,0 +1,14 @@
{
"gem_name": "${Name}",
"origin": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com",
"license": "What license ${Name} uses goes here: i.e. https://opensource.org/licenses/MIT",
"display_name": "${Name}",
"summary": "A short description of ${Name}.",
"canonical_tags": [
"Gem"
],
"user_tags": [
"${Name}"
],
"icon_path": "preview.png"
}
+7 -1
View File
@@ -1,6 +1,6 @@
{
"template_name": "DefaultProject",
"restricted": "o3de",
"restricted_name": "o3de",
"restricted_platform_relative_path": "Templates",
"origin": "The primary repo for DefaultProject goes here: i.e. http://www.mydomain.com",
"license": "What license DefaultProject uses goes here: i.e. https://opensource.org/licenses/MIT",
@@ -48,6 +48,12 @@
"isTemplated": true,
"isOptional": false
},
{
"file": "Code/gem.json",
"origin": "Code/gem.json",
"isTemplated": true,
"isOptional": true
},
{
"file": "Code/Include/${Name}/${Name}Bus.h",
"origin": "Code/Include/${Name}/${Name}Bus.h",
-52
View File
@@ -1,52 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
# This file is copied during engine registration. Edits to this file will be lost next
# time a registration happens.
include_guard()
# Read the engine name from the project_json file
file(READ ${CMAKE_CURRENT_LIST_DIR}/project.json project_json)
string(JSON LY_ENGINE_NAME_TO_USE ERROR_VARIABLE json_error GET ${project_json} engine)
if(json_error)
message(FATAL_ERROR "Unable to read key 'engine' from 'project.json', error: ${json_error}")
endif()
# Read the list of paths from ~.o3de/o3de_manifest.json
file(TO_CMAKE_PATH "$ENV{USERPROFILE}" home_directory) # Windows
if((NOT home_directory) OR (NOT EXISTS ${home_directory}))
file(TO_CMAKE_PATH "$ENV{HOME}" home_directory)# Unix
endif()
if (NOT home_directory)
message(FATAL_ERROR "Cannot find user home directory, the o3de manifest cannot be found")
endif()
# Set manifest path to path in the user home directory
set(manifest_path ${home_directory}/.o3de/o3de_manifest.json)
if(EXISTS ${manifest_path})
file(READ ${manifest_path} manifest_json)
string(JSON engines_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines)
if(json_error)
message(FATAL_ERROR "Unable to read key 'engines' from '${manifest_path}', error: ${json_error}")
endif()
math(EXPR engines_count "${engines_count}-1")
foreach(engine_path_index RANGE ${engines_count})
string(JSON engine_path ERROR_VARIABLE json_error GET ${manifest_json} engines ${engine_path_index})
if(${json_error})
message(FATAL_ERROR "Unable to read engines[${engine_path_index}] '${manifest_path}', error: ${json_error}")
endif()
if(engine_path)
list(APPEND CMAKE_MODULE_PATH "${engine_path}/cmake")
endif()
endforeach()
endif()
+47
View File
@@ -0,0 +1,47 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
# This file is copied during engine registration. Edits to this file will be lost next
# time a registration happens.
include_guard()
set(LY_EXTERNAL_SUBDIRS "" CACHE STRING "List of subdirectories to recurse into when running cmake against the engine's CMakeLists.txt")
#! read_engine_external_subdirs
# Read the external subdirectories from the engine.json file
# External subdirectories are any folders with CMakeLists.txt in them
# This could be regular subdirectories, Gems(contains an additional gem.json),
# Restricted folders(contains an additional restricted.json), etc...
# \arg:output_external_subdirs name of output variable to store external subdirectories into
function(read_engine_external_subdirs output_external_subdirs)
file(READ ${LY_ROOT_FOLDER}/engine.json engine_json_data)
string(JSON external_subdirs_count ERROR_VARIABLE engine_json_error
LENGTH ${engine_json_data} "external_subdirectories")
if(engine_json_error)
message(FATAL_ERROR "Error querying number of elements in JSON array \"external_subdirectories\": ${engine_json_error}")
endif()
if(external_subdirs_count GREATER 0)
math(EXPR external_subdir_range "${external_subdirs_count}-1")
# Convert the paths the relative paths to absolute paths using the engine root
# as the base directory
foreach(external_subdir_index RANGE ${external_subdir_range})
string(JSON external_subdir ERROR_VARIABLE engine_json_error
GET ${engine_json_data} "external_subdirectories" "${external_subdir_index}")
if(engine_json_error)
message(FATAL_ERROR "Error reading field at index ${external_subdir_index} in \"external_subdirectories\" JSON array: ${engine_json_error}")
endif()
file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${CMAKE_SOURCE_DIR})
list(APPEND external_subdirs ${real_external_subdir})
endforeach()
endif()
set(${output_external_subdirs} ${external_subdirs} PARENT_SCOPE)
endfunction()
+55
View File
@@ -0,0 +1,55 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
include_guard()
set(LY_EXTERNAL_SUBDIRS "" CACHE STRING "List of subdirectories to recurse into when running cmake against the engine's CMakeLists.txt")
#! read_json_external_subdirs
# Read the "external_subdirectories" array from a *.json file
# External subdirectories are any folders with CMakeLists.txt in them
# This could be regular subdirectories, Gems(contains an additional gem.json),
# Restricted folders(contains an additional restricted.json), etc...
#
# \arg:output_external_subdirs name of output variable to store external subdirectories into
# \arg:input_json_path path to the *.json file to load and read the external subdirectories from
# \return: external subdirectories as is from the json file.
function(read_json_external_subdirs output_external_subdirs input_json_path)
file(READ ${input_json_path} manifest_json_data)
string(JSON external_subdirs_count ERROR_VARIABLE manifest_json_error
LENGTH ${manifest_json_data} "external_subdirectories")
if(manifest_json_error)
# There is "external_subdirectories" key, so theire are no subdirectories to read
return()
endif()
if(external_subdirs_count GREATER 0)
math(EXPR external_subdir_range "${external_subdirs_count}-1")
foreach(external_subdir_index RANGE ${external_subdir_range})
string(JSON external_subdir ERROR_VARIABLE manifest_json_error
GET ${manifest_json_data} "external_subdirectories" "${external_subdir_index}")
if(manifest_json_error)
message(FATAL_ERROR "Error reading field at index ${external_subdir_index} in \"external_subdirectories\" JSON array: ${manifest_json_error}")
endif()
list(APPEND external_subdirs ${external_subdir})
endforeach()
endif()
set(${output_external_subdirs} ${external_subdirs} PARENT_SCOPE)
endfunction()
function(o3de_read_json_key output_value input_json_path key)
file(READ ${input_json_path} manifest_json_data)
string(JSON value ERROR_VARIABLE manifest_json_error GET ${manifest_json_data} ${key})
if(manifest_json_error)
message(FATAL_ERROR "Error reading field at key ${key} in file \"${input_json_path}\" : ${manifest_json_error}")
endif()
set(${output_value} ${value} PARENT_SCOPE)
endfunction()
+106 -30
View File
@@ -22,7 +22,105 @@ file(GLOB detection_files "cmake/Platform/*/PALDetection_*.cmake")
foreach(detection_file ${detection_files})
include(${detection_file})
endforeach()
file(GLOB detection_files ${o3de_engine_restricted_path}/*/cmake/PALDetection_*.cmake)
#! o3de_restricted_id: Reads the "restricted" key from the o3de manifest
#
# \arg:o3de_json_file name of the o3de json file to read the "restricted_name" key from
# \arg:restricted returns the restricted association element from an o3de json, otherwise engine 'o3de' is assumed
# \arg:o3de_json_file name of the o3de json file
function(o3de_restricted_id o3de_json_file restricted)
file(READ ${o3de_json_file} json_data)
string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} "restricted_name")
if(json_error)
message(WARNING "Unable to read restricted from '${o3de_json_file}', error: ${json_error}")
endif()
if(restricted_entry)
set(${restricted} ${restricted_entry} PARENT_SCOPE)
endif()
endfunction()
#! o3de_find_restricted_folder:
#
# \arg:restricted_path returns the path of the o3de restricted folder with name restricted_name
# \arg:restricted_name name of the restricted
function(o3de_find_restricted_folder restricted_name restricted_path)
# Read the restricted path from engine.json if one EXISTS
file(READ ${LY_ROOT_FOLDER}/engine.json engine_json_data)
string(JSON restricted_subdirs_count ERROR_VARIABLE engine_json_error LENGTH ${engine_json_data} "restricted")
if(restricted_subdirs_count GREATER 0)
string(JSON restricted_subdir ERROR_VARIABLE engine_json_error GET ${engine_json_data} "restricted" "0")
set(${restricted_path} ${restricted_subdir} PARENT_SCOPE)
return()
endif()
file(TO_CMAKE_PATH "$ENV{USERPROFILE}" home_directory) # Windows
if(NOT EXISTS ${home_directory})
file(TO_CMAKE_PATH "$ENV{HOME}" home_directory) # Unix
if (NOT EXISTS ${home_directory})
return()
endif()
endif()
# Examine the o3de manifest file for the list of restricted directories
set(o3de_manifest_path ${home_directory}/.o3de/o3de_manifest.json)
if(EXISTS ${o3de_manifest_path})
file(READ ${o3de_manifest_path} o3de_manifest_json_data)
string(JSON restricted_subdirs_count ERROR_VARIABLE engine_json_error LENGTH ${o3de_manifest_json_data} "restricted")
if(restricted_subdirs_count GREATER 0)
math(EXPR restricted_subdirs_range "${restricted_subdirs_count}-1")
foreach(restricted_subdir_index RANGE ${restricted_subdirs_range})
string(JSON restricted_subdir ERROR_VARIABLE engine_json_error GET ${o3de_manifest_json_data} "restricted" "${restricted_subdir_index}")
list(APPEND restricted_subdirs ${restricted_subdir})
endforeach()
endif()
endif()
# Iterate over the restricted directories from the manifest file
foreach(restricted_entry ${restricted_subdirs})
set(restricted_json_file ${restricted_entry}/restricted.json)
file(READ ${restricted_json_file} restricted_json)
string(JSON this_restricted_name ERROR_VARIABLE json_error GET ${restricted_json} "restricted_name")
if(json_error)
message(WARNING "Unable to read restricted_name from '${restricted_json_file}', error: ${json_error}")
else()
if(this_restricted_name STREQUAL restricted_name)
set(${restricted_path} ${restricted_entry} PARENT_SCOPE)
return()
endif()
endif()
endforeach()
endfunction()
#! o3de_restricted_path:
#
# \arg:o3de_json_file json file to read restricted id from
# \arg:restricted_name name of the restricted object
function(o3de_restricted_path o3de_json_file restricted_path)
o3de_restricted_id(${o3de_json_file} restricted_name)
if(restricted_name)
o3de_find_restricted_folder(${restricted_name} restricted_folder)
if(restricted_folder)
set(${restricted_path} ${restricted_folder} PARENT_SCOPE)
endif()
endif()
endfunction()
#! read_engine_restricted_path: Locates the restricted path within the engine from a json file
#
# \arg:output_restricted_path returns the path of the o3de restricted folder with name restricted_name
function(read_engine_restricted_path output_restricted_path)
# Set manifest path to path in the user home directory
set(manifest_path ${LY_ROOT_FOLDER}/engine.json)
if(EXISTS ${manifest_path})
o3de_restricted_path(${manifest_path} output_restricted_path)
endif()
endfunction()
read_engine_restricted_path(O3DE_ENGINE_RESTRICTED_PATH)
file(GLOB detection_files ${O3DE_ENGINE_RESTRICTED_PATH}/*/cmake/PALDetection_*.cmake)
foreach(detection_file ${detection_files})
include(${detection_file})
endforeach()
@@ -37,8 +135,8 @@ ly_set(PAL_HOST_PLATFORM_NAME_LOWERCASE ${PAL_HOST_PLATFORM_NAME_LOWERCASE})
set(PAL_RESTRICTED_PLATFORMS)
string(LENGTH ${o3de_engine_restricted_path} engine_restricted_length)
file(GLOB pal_restricted_files ${o3de_engine_restricted_path}/*/cmake/PAL_*.cmake)
string(LENGTH "${O3DE_ENGINE_RESTRICTED_PATH}" engine_restricted_length)
file(GLOB pal_restricted_files ${O3DE_ENGINE_RESTRICTED_PATH}/*/cmake/PAL_*.cmake)
foreach(pal_restricted_file ${pal_restricted_files})
string(FIND ${pal_restricted_file} "/cmake/PAL" end)
if(${end} GREATER -1)
@@ -109,18 +207,18 @@ function(ly_get_absolute_pal_filename out_name in_name)
else()
# The user has not supplied any path so we must assume it is the o3de engine restricted and o3de engine path
# if the file is not in the o3de engine path then we cannot determine a PAL file for it
file(RELATIVE_PATH relative_path ${o3de_engine_path} ${full_name})
file(RELATIVE_PATH relative_path ${LY_ROOT_FOLDER} ${full_name})
if (NOT (IS_ABSOLUTE relative_path OR relative_path MATCHES [[^(\.\./)+(.*)]]))
if (NOT EXISTS ${full_name})
string(REGEX MATCH "${o3de_engine_path}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name})
string(REGEX MATCH "${LY_ROOT_FOLDER}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name})
if(NOT CMAKE_MATCH_1)
string(REGEX MATCH "${o3de_engine_path}/Platform/([^/]*)/?(.*)$" match ${full_name})
set(full_name ${o3de_engine_restricted_path}/${CMAKE_MATCH_1})
string(REGEX MATCH "${LY_ROOT_FOLDER}/Platform/([^/]*)/?(.*)$" match ${full_name})
set(full_name ${O3DE_ENGINE_RESTRICTED_PATH}/${CMAKE_MATCH_1})
if(CMAKE_MATCH_2)
string(APPEND full_name "/" ${CMAKE_MATCH_2})
endif()
elseif("${CMAKE_MATCH_2}" IN_LIST PAL_RESTRICTED_PLATFORMS)
set(full_name ${o3de_engine_restricted_path}/${CMAKE_MATCH_2}/${CMAKE_MATCH_1})
set(full_name ${O3DE_ENGINE_RESTRICTED_PATH}/${CMAKE_MATCH_2}/${CMAKE_MATCH_1})
if(CMAKE_MATCH_3)
string(APPEND full_name "/" ${CMAKE_MATCH_3})
endif()
@@ -149,25 +247,3 @@ set(LY_DISABLE_TEST_MODULES FALSE CACHE BOOL "Option to forcibly disable the inc
if(LY_DISABLE_TEST_MODULES)
ly_set(PAL_TRAIT_BUILD_TESTS_SUPPORTED FALSE)
endif()
################################################################################
# Add each restricted platform in the engines restricted folder
# If the enabled restricted platform does not have a folder add one.
# If the restricted platform folder does not have a CMakeLists.txt, create one
# so the add_subdirectory on the external folder does not fail.
################################################################################
function(o3de_add_engine_restricted_platform_external_subdirs)
foreach(restricted_platform ${PAL_RESTRICTED_PLATFORMS})
if(restricted_platform IN_LIST enabled_platforms)
set(o3de_engine_restricted_platform_folder ${o3de_engine_restricted_path}/${restricted_platform})
if(NOT EXISTS ${o3de_engine_restricted_platform_folder})
file(MAKE_DIRECTORY ${o3de_engine_restricted_platform_folder})
endif()
set(o3de_engine_restricted_platform_folder_cmakelists ${o3de_engine_restricted_platform_folder}/CMakeLists.txt)
if(NOT EXISTS ${o3de_engine_restricted_platform_folder_cmakelists})
file(TOUCH ${o3de_engine_restricted_platform_folder_cmakelists})
endif()
list(APPEND LY_EXTERNAL_SUBDIRS ${o3de_engine_restricted_platform_folder})
endif()
endforeach()
endfunction()
@@ -224,6 +224,16 @@ function(ly_setup_cmake_install)
REGEX "Platform\/.*\/BuiltInPackages_.*\.cmake" EXCLUDE
)
# Transform the LY_EXTERNAL_SUBDIRS list into a json array
set(LY_INSTALL_EXTERNAL_SUBDIRS "[]")
set(external_subdir_index "0")
foreach(external_subdir ${LY_EXTERNAL_SUBDIRS})
math(EXPR external_subdir_index "${external_subdir_index} + 1")
file(RELATIVE_PATH engine_rel_external_subdir ${LY_ROOT_FOLDER} ${external_subdir})
string(JSON LY_INSTALL_EXTERNAL_SUBDIRS ERROR_VARIABLE external_subdir_error SET ${LY_INSTALL_EXTERNAL_SUBDIRS}
${external_subdir_index} "\"${engine_rel_external_subdir}\"")
endforeach()
configure_file(${LY_ROOT_FOLDER}/cmake/install/engine.json.in ${CMAKE_CURRENT_BINARY_DIR}/cmake/engine.json @ONLY)
install(
+27 -12
View File
@@ -105,6 +105,7 @@ function(ly_add_project_dependencies)
)
endfunction()
#template for generating the project build_path setreg
set(project_build_path_template [[
{
@@ -120,7 +121,6 @@ set(project_build_path_template [[
}]]
)
#! ly_generate_project_build_path_setreg: Generates a .setreg file that contains an absolute path to the ${CMAKE_BINARY_DIR}
# This allows locate the directory where the project it's binaries are built to be located within the engine.
# Which are the shared libraries and launcher executables
@@ -136,18 +136,32 @@ set(project_build_path_template [[
# can only run on the host platform
# \arg:project_real_path Full path to the o3de project directory
function(ly_generate_project_build_path_setreg project_real_path)
# The build path isn't needed on non-monolithic platforms
# Nor on any non-host platforms
if (LY_MONOLITHIC_GAME OR NOT PAL_TRAIT_BUILD_HOST_TOOLS)
return()
endif()
# The build path isn't needed on non-monolithic platforms
# Nor on any non-host platforms
if (LY_MONOLITHIC_GAME OR NOT PAL_TRAIT_BUILD_HOST_TOOLS)
return()
endif()
# Set the project_bin_path to the ${CMAKE_BINARY_DIR} to provide the configure template
# with the project build directory
set(project_bin_path ${CMAKE_BINARY_DIR})
string(CONFIGURE ${project_build_path_template} project_build_path_setreg_content @ONLY)
set(project_user_build_path_setreg_file ${project_real_path}/user/Registry/Platform/${PAL_PLATFORM_NAME}/build_path.setreg)
file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content})
# Set the project_bin_path to the ${CMAKE_BINARY_DIR} to provide the configure template
# with the project build directory
set(project_bin_path ${CMAKE_BINARY_DIR})
string(CONFIGURE ${project_build_path_template} project_build_path_setreg_content @ONLY)
set(project_user_build_path_setreg_file ${project_real_path}/user/Registry/Platform/${PAL_PLATFORM_NAME}/build_path.setreg)
file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content})
endfunction()
function(add_project_json_external_subdirectories project_path)
set(project_json_path ${project_path}/project.json)
if(EXISTS ${project_json_path})
read_json_external_subdirs(external_subdirs ${project_path}/project.json)
foreach(external_subdir ${external_subdirs})
file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${project_path})
list(APPEND project_external_subdirs ${real_external_subdir})
endforeach()
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${project_external_subdirs})
endif()
endfunction()
# Add the projects here so the above function is found
@@ -163,5 +177,6 @@ foreach(project ${LY_PROJECTS})
list(APPEND LY_PROJECTS_FOLDER_NAME ${project_folder_name})
add_subdirectory(${project} "${project_folder_name}-${full_directory_hash}")
ly_generate_project_build_path_setreg(${full_directory_path})
add_project_json_external_subdirectories(${full_directory_path})
endforeach()
ly_set(LY_PROJECTS_FOLDER_NAME ${LY_PROJECTS_FOLDER_NAME})
+36 -17
View File
@@ -31,7 +31,7 @@ set(gem_module_template [[
"@stripped_gem_target@":
{
"Modules":["$<TARGET_FILE_NAME:@gem_target@>"],
"SourcePaths":["@gem_relative_source_dir@"]
"SourcePaths":["@gem_module_root_relative_to_engine_root@"]
}]]
)
@@ -85,6 +85,36 @@ function(ly_get_gem_load_dependencies ly_GEM_LOAD_DEPENDENCIES ly_TARGET)
set(${ly_GEM_LOAD_DEPENDENCIES} ${all_gem_load_dependencies} PARENT_SCOPE)
endfunction()
#!ly_get_gem_module_root: Uses the supplied gem_target to lookup the nearest gem.json file above the SOURCE_DIR
#
# \arg:gem_target(TARGET) - Target to look upwards from using its SOURCE_DIR property
function(ly_get_gem_module_root output_gem_module_root gem_target)
unset(gem_module_roots)
get_property(gem_source_dir TARGET ${gem_target} PROPERTY SOURCE_DIR)
if(gem_source_dir)
set(candidate_gem_dir ${gem_source_dir})
# Locate the root of the gem by finding the gem.json location
while(NOT EXISTS ${candidate_gem_dir}/gem.json)
get_filename_component(parent_dir ${candidate_gem_dir} DIRECTORY)
if (${parent_dir} STREQUAL ${candidate_gem_dir})
message(WARNING "Did not find a gem.json while processing GEM_MODULE target ${gem_target}!")
break()
endif()
set(candidate_gem_dir ${parent_dir})
endwhile()
endif()
if (EXISTS ${candidate_gem_dir}/gem.json)
set(gem_source_dir ${candidate_gem_dir})
endif()
# Set the gem module root output directory to the location with the gem.json file within it or
# the supplied gem_target SOURCE_DIR location if no gem.json file was found
set(${output_gem_module_root} ${gem_source_dir} PARENT_SCOPE)
endfunction()
#! ly_delayed_generate_settings_registry: Generates a .setreg file for each target with dependencies
# added to it via ly_add_target_dependencies
# The generated file contains the file to the each dependent targets
@@ -102,17 +132,17 @@ function(ly_delayed_generate_settings_registry)
# Retrieve the target name from the back of the list
list(POP_BACK prefix_target_list target)
# Retreives the prefix if available from the remaining element of the list
# Retrieves the prefix if available from the remaining element of the list
list(POP_BACK prefix_target_list prefix)
# Get the gem dependencies for the given project and target combination
get_property(gem_dependencies GLOBAL PROPERTY LY_DELAYED_LOAD_"${prefix_target}")
list(REMOVE_DUPLICATES gem_dependencies) # Strip out any duplicate gem targets
set(all_gem_dependencies ${gem_dependencies})
unset(all_gem_dependencies)
foreach(gem_target ${gem_dependencies})
ly_get_gem_load_dependencies(gem_load_gem_dependencies ${gem_target})
list(APPEND all_gem_dependencies ${gem_load_gem_dependencies})
list(APPEND all_gem_dependencies ${gem_load_gem_dependencies} ${gem_target})
endforeach()
list(REMOVE_DUPLICATES all_gem_dependencies)
@@ -123,20 +153,9 @@ function(ly_delayed_generate_settings_registry)
if (NOT TARGET ${gem_target})
message(FATAL_ERROR "Dependency ${gem_target} from ${target} does not exist")
endif()
get_property(gem_relative_source_dir TARGET ${gem_target} PROPERTY SOURCE_DIR)
if(gem_relative_source_dir)
# Most gems SOURCE dir is nested in the path, we need to find the path where an 'Assets' or 'Code' folder resides
while(NOT EXISTS ${gem_relative_source_dir}/Assets AND NOT EXISTS ${gem_relative_source_dir}/Code)
get_filename_component(parent_dir ${gem_relative_source_dir} DIRECTORY)
if (${parent_dir} STREQUAL ${gem_relative_source_dir})
message(FATAL_ERROR "Did not find a Gem source dir while processing target ${gem_target}!")
endif()
set(gem_relative_source_dir ${parent_dir})
endwhile()
file(TO_CMAKE_PATH ${LY_ROOT_FOLDER} ly_root_folder_cmake)
file(RELATIVE_PATH gem_relative_source_dir ${ly_root_folder_cmake} ${gem_relative_source_dir})
endif()
ly_get_gem_module_root(gem_module_root ${gem_target})
file(RELATIVE_PATH gem_module_root_relative_to_engine_root ${LY_ROOT_FOLDER} ${gem_module_root})
# Strip target namespace from gem targets before configuring them into the json template
ly_strip_target_namespace(TARGET ${gem_target} OUTPUT_VARIABLE stripped_gem_target)
+4 -1
View File
@@ -17,16 +17,19 @@ set(FILES
Configurations.cmake
Dependencies.cmake
Deployment.cmake
EngineFinder.cmake
EngineJson.cmake
FileUtil.cmake
Findo3de.cmake
GeneralSettings.cmake
Install.cmake
LyAutoGen.cmake
LYPackage_S3Downloader.cmake
LySet.cmake
LYTestWrappers.cmake
LYPython.cmake
LYWrappers.cmake
Monolithic.cmake
OutputDirectory.cmake
Packaging.cmake
PAL.cmake
PALTools.cmake
+5 -2
View File
@@ -1,8 +1,11 @@
{
"engine_name": "@LY_VERSION_ENGINE_NAME@",
"restricted": "o3de",
"restricted_name": "o3de",
"FileVersion": 1,
"O3DEVersion": "@LY_VERSION_STRING@",
"O3DECopyrightYear": @LY_VERSION_COPYRIGHT_YEAR@,
"O3DEBuildNumber": @LY_VERSION_BUILD_NUMBER@
"O3DEBuildNumber": @LY_VERSION_BUILD_NUMBER@,
"external_subdirectories": @LY_INSTALL_EXTERNAL_SUBDIRS@,
"projects": [@LY_INSTALL_PROJECTS@],
"templates": [@LY_INSTALL_TEMPLATES@]
}
-970
View File
@@ -1,970 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
# Set the user home directory
set(O3DE_HOME_PATH "" CACHE PATH "Override the user home to this path")
if(O3DE_HOME_PATH)
set(home_directory ${O3DE_HOME_PATH})
elseif(CMAKE_HOST_WIN32)
file(TO_CMAKE_PATH "$ENV{USERPROFILE}" home_directory)
else()
file(TO_CMAKE_PATH "$ENV{HOME}" home_directory)
endif()
if (NOT home_directory)
message(FATAL_ERROR "Cannot find user home directory, without the user home directory the o3de manifest cannot be found")
endif()
# Optionally delete the home directory
if(O3DE_DELETE_HOME_PATH)
if(EXISTS ${home_directory}/.o3de)
message(STATUS "Deleting ${home_directory}/.o3de")
file(REMOVE_RECURSE ${home_directory}/.o3de)
else()
message(STATUS "Home path ${home_directory}/.o3de doesnt exist.")
endif()
endif()
########################################################################################################################
# If O3DE_REGISTER_ENGINE_PATH variable is set on the commandline this will allow registration of anything using
# O3DE_REGISTER_ENGINE_PATH o3de script. This is handy for situations like build servers which download the code and
# are expected to build without the need for someone to register o3de objects like this engine by manually typing it in.
# If O3DE_REGISTER_THIS_ENGINE=TRUE is set on the commandline when O3DE_REGISTER_ENGINE_PATH is also set this will call:
# O3DE_REGISTER_ENGINE_PATH/scripts>o3de register --this-engine --override-home-folder <home_directory>
# Note: register --this-engine will automatically register anything it finds in known folders, so if you put your
# o3de objects like projects/gems/templates/restricted/etc... in known folders for those types they will get registered
# automatically. Known folders for types are your .o3de/Projects and .o3de/Gems etc. So if I wanted my project to be
# registered and built by this build server I could simply put them in those known folders on the build server and they
# would get registered automatically by this call.
# OR
# I could put them on the commandline as well. This would be the way if the o3de objects we need to regiater are NOT
# in known folders or you do not intend to call with O3DE_REGISTER_THIS_ENGINE=TRUE Ex.
# -DO3DE_REGISTER_ENGINE_PATH=C:\this\engine
# -DO3DE_REGISTER_PROJECT_PATHS=C:\ThisGame;C:\ThatGame
# -DO3DE_REGISTER_GEM_PATHS=C:\ThisGem;C:\ThatGem;C:\And\Some\Other\Gem
# -DO3DE_REGISTER_RESTRICTED_PATHS=C:\this\engine\Restricted;C:\ThisGame\Restricted;C:\ThisGem\Restricted
########################################################################################################################
if(O3DE_REGISTER_ENGINE_PATH)
if(O3DE_REGISTER_THIS_ENGINE)
if(CMAKE_HOST_WIN32)
execute_process(
COMMAND cmd /c ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.bat register --this-engine --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_this_engine_cmd_result
)
else()
execute_process(
COMMAND sh ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.sh register --this-engine --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_this_engine_cmd_result
)
endif()
if(o3de_register_this_engine_cmd_result)
message(FATAL_ERROR "An error occured trying to register --this-engine: ${o3de_register_this_engine_cmd_result}")
else()
message(STATUS "Engine ${O3DE_REGISTER_ENGINE_PATH} registration successfull.")
endif()
endif()
if(O3DE_REGISTER_RESTRICTED_PATHS)
foreach(restricted_path ${O3DE_REGISTER_RESTRICTED_PATHS})
if(CMAKE_HOST_WIN32)
execute_process(
COMMAND cmd /c ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.bat register --restricted-path ${restricted_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_restricted_cmd_result
)
else()
execute_process(
COMMAND sh ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.sh register --restricted-path ${restricted_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_restricted_cmd_result
)
endif()
if(o3de_register_restricted_cmd_result)
message(FATAL_ERROR "An error occured trying to ${O3DE_REGISTER_ENGINE_PATH}/scripts>o3de register --restricted-path ${restricted_path} --override-home-folder ${home_directory}: ${o3de_register_restricted_cmd_result}")
else()
message(STATUS "Restricted ${restricted_path} registration successfull.")
endif()
endforeach()
endif()
if(O3DE_REGISTER_PROJECT_PATHS)
foreach(project_path ${O3DE_REGISTER_PROJECT_PATHS})
if(CMAKE_HOST_WIN32)
execute_process(
COMMAND cmd /c ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.bat register --project-path ${project_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_project_cmd_result
)
else()
execute_process(
COMMAND sh ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.sh register --project-path ${project_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_project_cmd_result
)
endif()
if(o3de_register_project_cmd_result)
message(FATAL_ERROR "An error occured trying to ${O3DE_REGISTER_ENGINE_PATH}/scripts>o3de register --project-path ${project_path} --override-home-folder ${home_directory}")
else()
message(STATUS "Project ${project_path} registration successfull.")
endif()
endforeach()
endif()
if(O3DE_REGISTER_GEM_PATHS)
foreach(gem_path ${O3DE_REGISTER_GEM_PATHS})
if(CMAKE_HOST_WIN32)
execute_process(
COMMAND cmd /c ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.bat register --gem-path ${gem_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_gem_cmd_result
)
else()
execute_process(
COMMAND sh ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.sh register --gem-path ${gem_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_gem_cmd_result
)
endif()
if(o3de_register_gem_cmd_result)
message(FATAL_ERROR "An error occured trying to ${O3DE_REGISTER_ENGINE_PATH}/scripts>o3de register --gem-path ${gem_path} --override-home-folder ${home_directory}")
else()
message(STATUS "Gem ${gem_path} registration successfull.")
endif()
endforeach()
endif()
if(O3DE_REGISTER_TEMPLATE_PATHS)
foreach(template_path ${O3DE_REGISTER_TEMPLATE_PATHS})
if(CMAKE_HOST_WIN32)
execute_process(
COMMAND cmd /c ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.bat register --template-path ${template_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_template_cmd_result
)
else()
execute_process(
COMMAND sh ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.sh register --template-path ${template_path} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_template_cmd_result
)
endif()
if(o3de_register_template_cmd_result)
message(FATAL_ERROR "An error occured trying to ${O3DE_REGISTER_ENGINE_PATH}/scripts>o3de register --template-path ${template_path} --override-home-folder ${home_directory}")
else()
message(STATUS "Template ${template_path} registration successfull.")
endif()
endforeach()
endif()
if(O3DE_REGISTER_REPO_URIS)
foreach(repo_uri ${O3DE_REGISTER_REPO_URIS})
if(CMAKE_HOST_WIN32)
execute_process(
COMMAND cmd /c ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.bat register --repo-uri ${repo_uri} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_repo_cmd_result
)
else()
execute_process(
COMMAND sh ${O3DE_REGISTER_ENGINE_PATH}/scripts/o3de.sh register --repo-uri ${repo_uri} --override-home-folder ${home_directory}
RESULT_VARIABLE o3de_register_repo_cmd_result
)
endif()
if(o3de_register_repo_cmd_result)
message(FATAL_ERROR "An error occured trying to ${O3DE_REGISTER_ENGINE_PATH}/scripts>o3de register --repo-uri ${repo_uri} --override-home-folder ${home_directory}")
else()
message(STATUS "Repo ${repo_uri} registration successfull.")
endif()
endforeach()
endif()
endif()
################################################################################
# o3de manifest
################################################################################
# Set manifest json path to the <home_directory>/.o3de/o3de_manifest.json
set(o3de_manifest_json_path ${home_directory}/.o3de/o3de_manifest.json)
if(NOT EXISTS ${o3de_manifest_json_path})
message(FATAL_ERROR "${o3de_manifest_json_path} not found. You must o3de register --this-engine.")
endif()
file(READ ${o3de_manifest_json_path} manifest_json_data)
################################################################################
# o3de manifest name
################################################################################
string(JSON o3de_manifest_name ERROR_VARIABLE json_error GET ${manifest_json_data} o3de_manifest_name)
if(json_error)
message(FATAL_ERROR "Unable to read repo_name from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
################################################################################
# o3de origin
################################################################################
string(JSON o3de_origin ERROR_VARIABLE json_error GET ${manifest_json_data} origin)
if(json_error)
message(FATAL_ERROR "Unable to read origin from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
################################################################################
# o3de default engines folder
################################################################################
string(JSON o3de_default_engines_folder ERROR_VARIABLE json_error GET ${manifest_json_data} default_engines_folder)
if(json_error)
message(FATAL_ERROR "Unable to read default_engines_folder from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
################################################################################
# o3de default projects folder
################################################################################
string(JSON o3de_default_projects_folder ERROR_VARIABLE json_error GET ${manifest_json_data} default_projects_folder)
if(json_error)
message(FATAL_ERROR "Unable to read default_projects_folder from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
################################################################################
# o3de default gems folder
################################################################################
string(JSON o3de_default_gems_folder ERROR_VARIABLE json_error GET ${manifest_json_data} default_gems_folder)
if(json_error)
message(FATAL_ERROR "Unable to read default_gems_folder from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
################################################################################
# o3de default templates folder
################################################################################
string(JSON o3de_default_templates_folder ERROR_VARIABLE json_error GET ${manifest_json_data} default_templates_folder)
if(json_error)
message(FATAL_ERROR "Unable to read default_templates_folder from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
################################################################################
# o3de default restricted folder
################################################################################
string(JSON o3de_default_restricted_folder ERROR_VARIABLE json_error GET ${manifest_json_data} default_restricted_folder)
if(json_error)
message(FATAL_ERROR "Unable to read default_restricted_folder from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
################################################################################
# o3de projects
################################################################################
string(JSON o3de_projects_count ERROR_VARIABLE json_error LENGTH ${manifest_json_data} projects)
if(json_error)
message(FATAL_ERROR "Unable to read key 'projects' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_projects_count} GREATER 0)
math(EXPR o3de_projects_count "${o3de_projects_count}-1")
foreach(projects_index RANGE ${o3de_projects_count})
string(JSON projects_path ERROR_VARIABLE json_error GET ${manifest_json_data} projects ${projects_index})
if(json_error)
message(FATAL_ERROR "Unable to read projects[${projects_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_projects ${projects_path})
list(APPEND o3de_global_projects ${projects_path})
endforeach()
endif()
################################################################################
# o3de gems
################################################################################
string(JSON o3de_gems_count ERROR_VARIABLE json_error LENGTH ${manifest_json_data} gems)
if(json_error)
message(FATAL_ERROR "Unable to read key 'gems' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_gems_count} GREATER 0)
math(EXPR o3de_gems_count "${o3de_gems_count}-1")
foreach(gems_index RANGE ${o3de_gems_count})
string(JSON gems_path ERROR_VARIABLE json_error GET ${manifest_json_data} gems ${gems_index})
if(json_error)
message(FATAL_ERROR "Unable to read gems[${gems_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_gems ${gems_path})
list(APPEND o3de_global_gems ${gems_path})
endforeach()
endif()
################################################################################
# o3de templates
################################################################################
string(JSON o3de_templates_count ERROR_VARIABLE json_error LENGTH ${manifest_json_data} templates)
if(json_error)
message(FATAL_ERROR "Unable to read key 'templates' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_templates_count} GREATER 0)
math(EXPR o3de_templates_count "${o3de_templates_count}-1")
foreach(templates_index RANGE ${o3de_templates_count})
string(JSON templates_path ERROR_VARIABLE json_error GET ${manifest_json_data} templates ${templates_index})
if(json_error)
message(FATAL_ERROR "Unable to read templates[${templates_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_templates ${templates_path})
list(APPEND o3de_global_templates ${templates_path})
endforeach()
endif()
################################################################################
# o3de repos
################################################################################
string(JSON o3de_repos_count ERROR_VARIABLE json_error LENGTH ${manifest_json_data} repos)
if(json_error)
message(FATAL_ERROR "Unable to read key 'repos' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_repos_count} GREATER 0)
math(EXPR o3de_repos_count "${o3de_repos_count}-1")
foreach(repos_index RANGE ${o3de_repos_count})
string(JSON repo_uri ERROR_VARIABLE json_error GET ${manifest_json_data} repos ${repos_index})
if(json_error)
message(FATAL_ERROR "Unable to read repos[${repos_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_repos ${repo_uri})
list(APPEND o3de_global_repos ${repo_uri})
endforeach()
endif()
################################################################################
# o3de restricted
################################################################################
string(JSON o3de_restricted_count ERROR_VARIABLE json_error LENGTH ${manifest_json_data} restricted)
if(json_error)
message(FATAL_ERROR "Unable to read key 'restricted' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_restricted_count} GREATER 0)
math(EXPR o3de_restricted_count "${o3de_restricted_count}-1")
foreach(restricted_index RANGE ${o3de_restricted_count})
string(JSON restricted_path ERROR_VARIABLE json_error GET ${manifest_json_data} restricted ${restricted_index})
if(json_error)
message(FATAL_ERROR "Unable to read restricted[${restricted_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_restricted ${restricted_path})
list(APPEND o3de_global_restricted ${restricted_path})
endforeach()
endif()
################################################################################
# o3de engines
################################################################################
string(JSON o3de_engines_count ERROR_VARIABLE json_error LENGTH ${manifest_json_data} engines)
if(json_error)
message(FATAL_ERROR "Unable to read key 'engines' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_engines_count} GREATER 0)
math(EXPR o3de_engines_count "${o3de_engines_count}-1")
# Either the engine_path and engine_json are set in which case the user is configuring from the engine
# or project_path and project_json are set in which case the user is configuring from the project.
# We need to know which engine_path the user is using so if the project_json is set then we need
# to read the project_json and disambiguate the engine_path.
if(NOT o3de_engine_path)
if(NOT o3de_project_json)
message(FATAL_ERROR "Neither o3de_engine_path nor o3de_project_json defined. Cannot determine engine!")
endif()
# get the name of the engine this project uses
file(READ ${o3de_project_json} project_json_data)
string(JSON project_engine_name ERROR_VARIABLE json_error GET ${project_json_data} engine)
if(json_error)
message(FATAL_ERROR "Unable to read 'engine' from '${o3de_project_json}', error: ${json_error}")
endif()
# search each engine in order from the manifest to find the matching engine name
foreach(engines_index RANGE ${o3de_engines_count})
string(JSON engine_data ERROR_VARIABLE json_error GET ${manifest_json_data} engines ${engines_index})
if(json_error)
message(FATAL_ERROR "Unable to read engines[${engines_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
# get this engines path
string(JSON this_engine_path ERROR_VARIABLE json_error GET ${engine_data} path)
if(json_error)
message(FATAL_ERROR "Unable to read engine path from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
# add this engine to the engines list
list(APPEND o3de_engines ${this_engine_path})
# use path to get the engine.json
set(this_engine_json ${this_engine_path}/engine.json)
# read the name of this engine
file(READ ${this_engine_json} this_engine_json_data)
string(JSON this_engine_name ERROR_VARIABLE json_error GET ${this_engine_json_data} engine_name)
if(json_error)
message(FATAL_ERROR "Unable to read engine_name from '${this_engine_json}', error: ${json_error}")
endif()
# see if this engines name is the same as the one this projects should use
if(${this_engine_name} STREQUAL ${project_engine_name})
message(STATUS "Found engine: '${project_engine_name}' at ${this_engine_path}")
set(o3de_engine_path ${this_engine_path})
break()
endif()
endforeach()
endif()
endif()
#we should have an engine_path at this point
if(NOT o3de_engine_path)
message(FATAL_ERROR "o3de_engine_path not defined. Cannot determine engine!")
endif()
# now that we have an engine_path read in that engines o3de resources
if(${o3de_engines_count} GREATER -1)
foreach(engines_index RANGE ${o3de_engines_count})
string(JSON engine_data ERROR_VARIABLE json_error GET ${manifest_json_data} engines ${engines_index})
if(json_error)
message(FATAL_ERROR "Unable to read engines[${engines_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
# get this engines path
string(JSON this_engine_path ERROR_VARIABLE json_error GET ${engine_data} path)
if(json_error)
message(FATAL_ERROR "Unable to read engine path from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_engine_path} STREQUAL ${this_engine_path})
################################################################################
# o3de engine projects
################################################################################
string(JSON o3de_engine_projects_count ERROR_VARIABLE json_error LENGTH ${engine_data} projects)
if(json_error)
message(FATAL_ERROR "Unable to read key 'projects' from '${engine_data}', error: ${json_error}")
endif()
if(${o3de_engine_projects_count} GREATER 0)
math(EXPR o3de_engine_projects_count "${o3de_engine_projects_count}-1")
foreach(engine_projects_index RANGE ${o3de_engine_projects_count})
string(JSON engine_projects_path ERROR_VARIABLE json_error GET ${engine_data} projects ${engine_projects_index})
if(json_error)
message(FATAL_ERROR "Unable to read engine projects[${projects_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_projects ${engine_projects_path})
list(APPEND o3de_engine_projects ${engine_projects_path})
endforeach()
endif()
################################################################################
# o3de engine gems
################################################################################
string(JSON o3de_engine_gems_count ERROR_VARIABLE json_error LENGTH ${engine_data} gems)
if(json_error)
message(FATAL_ERROR "Unable to read key 'gems' from '${engine_data}', error: ${json_error}")
endif()
if(${o3de_engine_gems_count} GREATER 0)
math(EXPR o3de_engine_gems_count "${o3de_engine_gems_count}-1")
foreach(engine_gems_index RANGE ${o3de_engine_gems_count})
string(JSON engine_gems_path ERROR_VARIABLE json_error GET ${engine_data} gems ${engine_gems_index})
if(json_error)
message(FATAL_ERROR "Unable to read engine gems[${gems_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_gems ${engine_gems_path})
list(APPEND o3de_engine_gems ${engine_gems_path})
endforeach()
endif()
################################################################################
# o3de engine templates
################################################################################
string(JSON o3de_engine_templates_count ERROR_VARIABLE json_error LENGTH ${engine_data} templates)
if(json_error)
message(FATAL_ERROR "Unable to read key 'templates' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_engine_gems_count} GREATER 0)
math(EXPR o3de_engine_templates_count "${o3de_engine_templates_count}-1")
foreach(engine_templates_index RANGE ${o3de_engine_templates_count})
string(JSON engine_templates_path ERROR_VARIABLE json_error GET ${engine_data} templates ${engine_templates_index})
if(json_error)
message(FATAL_ERROR "Unable to read engine templates[${templates_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_templates ${engine_templates_path})
list(APPEND o3de_engine_templates ${engine_templates_path})
endforeach()
endif()
################################################################################
# o3de engine restricted
################################################################################
string(JSON o3de_engine_restricted_count ERROR_VARIABLE json_error LENGTH ${engine_data} restricted)
if(json_error)
message(FATAL_ERROR "Unable to read key 'restricted' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_engine_restricted_count} GREATER 0)
math(EXPR o3de_engine_restricted_count "${o3de_engine_restricted_count}-1")
foreach(engine_restricted_index RANGE ${o3de_engine_restricted_count})
string(JSON engine_restricted_path ERROR_VARIABLE json_error GET ${engine_data} restricted ${engine_restricted_index})
if(json_error)
message(FATAL_ERROR "Unable to read engine restricted[${engine_restricted_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_restricted ${engine_restricted_path})
list(APPEND o3de_engine_restricted ${engine_restricted_path})
endforeach()
endif()
################################################################################
# o3de engine external_subdirectories
################################################################################
string(JSON o3de_external_subdirectories_count ERROR_VARIABLE json_error LENGTH ${engine_data} external_subdirectories)
if(json_error)
message(FATAL_ERROR "Unable to read key 'external_subdirectories' from '${o3de_manifest_json_path}', error: ${json_error}")
endif()
if(${o3de_external_subdirectories_count} GREATER 0)
math(EXPR o3de_external_subdirectories_count "${o3de_external_subdirectories_count}-1")
foreach(external_subdirectories_index RANGE ${o3de_external_subdirectories_count})
string(JSON external_subdirectories_path ERROR_VARIABLE json_error GET ${engine_data} external_subdirectories ${external_subdirectories_index})
if(json_error)
message(FATAL_ERROR "Unable to read engine external_subdirectories[${gems_index}] '${o3de_manifest_json_path}', error: ${json_error}")
endif()
list(APPEND o3de_engine_external_subdirectories ${external_subdirectories_path})
endforeach()
endif()
break()
endif()
endforeach()
endif()
################################################################################
#! o3de_engine_id:
#
# \arg:engine returns the engine association element from an o3de json
# \arg:o3de_json_file name of the o3de json file
################################################################################
function(o3de_engine_id o3de_json_file engine)
file(READ ${o3de_json_file} json_data)
string(JSON engine_entry ERROR_VARIABLE json_error GET ${json_data} engine)
if(json_error)
message(WARNING "Unable to read engine from '${o3de_json_file}', error: ${json_error}")
message(WARNING "Setting engine to engine default 'o3de'")
set(engine_entry "o3de")
endif()
if(engine_entry)
set(${engine} ${engine_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_project_id:
#
# \arg:project returns the project association element from an o3de json
# \arg:o3de_json_file name of the o3de json file
################################################################################
function(o3de_project_id o3de_json_file project)
file(READ ${o3de_json_file} json_data)
string(JSON project_entry ERROR_VARIABLE json_error GET ${json_data} project)
if(json_error)
message(FATAL_ERROR "Unable to read project from '${o3de_json_file}', error: ${json_error}")
endif()
if(project_entry)
set(${project} ${project_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_gem_id:
#
# \arg:gem returns the gem association element from an o3de json
# \arg:o3de_json_file name of the o3de json file
################################################################################
function(o3de_gem_id o3de_json_file gem)
file(READ ${o3de_json_file} json_data)
string(JSON gem_entry ERROR_VARIABLE json_error GET ${json_data} gem)
if(json_error)
message(FATAL_ERROR "Unable to read gem from '${o3de_json_file}', error: ${json_error}")
endif()
if(gem_entry)
set(${gem} ${gem_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_template_id:
#
# \arg:template returns the template association element from an o3de json
# \arg:o3de_json_file name of the o3de json file
################################################################################
function(o3de_template_id o3de_json_file template)
file(READ ${o3de_json_file} json_data)
string(JSON template_entry ERROR_VARIABLE json_error GET ${json_data} template)
if(json_error)
message(FATAL_ERROR "Unable to read template from '${o3de_json_file}', error: ${json_error}")
endif()
if(template_entry)
set(${template} ${template_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_repo_id:
#
# \arg:repo returns the repo association element from an o3de json
# \arg:o3de_json_file name of the o3de json file
################################################################################
function(o3de_repo_id o3de_json_file repo)
file(READ ${o3de_json_file} json_data)
string(JSON repo_entry ERROR_VARIABLE json_error GET ${json_data} repo)
if(json_error)
message(FATAL_ERROR "Unable to read repo from '${o3de_json_file}', error: ${json_error}")
endif()
if(repo_entry)
set(${repo} ${repo_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_restricted_id:
#
# \arg:restricted returns the restricted association element from an o3de json, otherwise engine 'o3de' is assumed
# \arg:o3de_json_file name of the o3de json file
################################################################################
function(o3de_restricted_id o3de_json_file restricted)
file(READ ${o3de_json_file} json_data)
string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} restricted)
if(json_error)
message(WARNING "Unable to read restricted from '${o3de_json_file}', error: ${json_error}")
message(WARNING "Setting restricted to engine default 'o3de'")
set(restricted_entry "o3de")
endif()
if(restricted_entry)
set(${restricted} ${restricted_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_find_engine_folder:
#
# \arg:engine_path returns the path of the o3de engine folder with name engine_name
# \arg:engine_name name of the engine
################################################################################
function(o3de_find_engine_folder engine_name engine_path)
foreach(engine_entry ${o3de_engines})
set(engine_json_file ${engine_entry}/engine.json)
file(READ ${engine_json_file} engine_json)
string(JSON this_engine_name ERROR_VARIABLE json_error GET ${engine_json} engine_name)
if(json_error)
message(WARNING "Unable to read engine_name from '${engine_json_file}', error: ${json_error}")
else()
if(this_engine_name STREQUAL engine_name)
set(${engine_path} ${engine_entry} PARENT_SCOPE)
return()
endif()
endif()
endforeach()
message(FATAL_ERROR "Unable to find repo_name: '${engine_name}'")
endfunction()
################################################################################
#! o3de_find_project_folder:
#
# \arg:project_path returns the path of the o3de project folder with name project_name
# \arg:project_name name of the project
################################################################################
function(o3de_find_project_folder project_name project_path)
foreach(project_entry ${o3de_projects})
set(project_json_file ${project_entry}/project.json)
file(READ ${project_json_file} project_json)
string(JSON this_project_name ERROR_VARIABLE json_error GET ${project_json} project_name)
if(json_error)
message(WARNING "Unable to read project_name from '${project_json_file}', error: ${json_error}")
else()
if(this_project_name STREQUAL project_name)
set(${project_path} ${project_entry} PARENT_SCOPE)
return()
endif()
endif()
endforeach()
message(FATAL_ERROR "Unable to find project_name: '${project_name}'")
endfunction()
################################################################################
#! o3de_find_gem_folder:
#
# \arg:gem_path returns the path of the o3de gem folder with name gem_name
# \arg:gem_name name of the gem
################################################################################
function(o3de_find_gem_folder gem_name gem_path)
foreach(gem_entry ${o3de_gems})
set(gem_json_file ${gem_entry}/gem.json)
file(READ ${gem_json_file} gem_json)
string(JSON this_gem_name ERROR_VARIABLE json_error GET ${gem_json} gem_name)
if(json_error)
message(WARNING "Unable to read gem_name from '${gem_json_file}', error: ${json_error}")
else()
if(this_gem_name STREQUAL gem_name)
set(${gem_path} ${gem_entry} PARENT_SCOPE)
return()
endif()
endif()
endforeach()
message(FATAL_ERROR "Unable to find gem_name: '${gem_name}'")
endfunction()
################################################################################
#! o3de_find_template_folder:
#
# \arg:template_path returns the path of the o3de template folder with name template_name
# \arg:template_name name of the template
################################################################################
function(o3de_find_template_folder template_name template_path)
foreach(template_entry ${o3de_templates})
set(template_json_file ${template_entry}/template.json)
file(READ ${template_json_file} template_json)
string(JSON this_template_name ERROR_VARIABLE json_error GET ${template_json} template_name)
if(json_error)
message(WARNING "Unable to read template_name from '${template_json_file}', error: ${json_error}")
else()
if(this_template_name STREQUAL template_name)
set(${template_path} ${template_entry} PARENT_SCOPE)
return()
endif()
endif()
endforeach()
message(FATAL_ERROR "Unable to find template_name: '${template_name}'")
endfunction()
################################################################################
#! o3de_find_repo_folder:
#
# \arg:repo_path returns the path of the o3de repo folder with name repo_name
# \arg:repo_name name of the repo
################################################################################
function(o3de_find_repo_folder repo_name repo_path)
foreach(repo_entry ${o3de_repos})
set(repo_json_file ${repo_entry}/repo.json)
file(READ ${repo_json_file} repo_json)
string(JSON this_repo_name ERROR_VARIABLE json_error GET ${repo_json} repo_name)
if(json_error)
message(WARNING "Unable to read repo_name from '${repo_json_file}', error: ${json_error}")
else()
if(this_repo_name STREQUAL repo_name)
set(${repo_path} ${repo_entry} PARENT_SCOPE)
return()
endif()
endif()
endforeach()
message(FATAL_ERROR "Unable to find repo_name: '${repo_name}'")
endfunction()
################################################################################
#! o3de_find_restricted_folder:
#
# \arg:restricted_path returns the path of the o3de restricted folder with name restricted_name
# \arg:restricted_name name of the restricted
################################################################################
function(o3de_find_restricted_folder restricted_name restricted_path)
foreach(restricted_entry ${o3de_restricted})
set(restricted_json_file ${restricted_entry}/restricted.json)
file(READ ${restricted_json_file} restricted_json)
string(JSON this_restricted_name ERROR_VARIABLE json_error GET ${restricted_json} restricted_name)
if(json_error)
message(WARNING "Unable to read restricted_name from '${restricted_json_file}', error: ${json_error}")
else()
if(this_restricted_name STREQUAL restricted_name)
set(${restricted_path} ${restricted_entry} PARENT_SCOPE)
return()
endif()
endif()
endforeach()
message(FATAL_ERROR "Unable to find restricted_name: '${restricted_name}'")
endfunction()
################################################################################
#! o3de_engine_name:
#
# \arg:engine returns the engine_name element from an engine.json
# \arg:o3de_engine_json_file name of the o3de json file
################################################################################
function(o3de_engine_name o3de_engine_json_file engine)
file(READ ${o3de_engine_json_file} json_data)
string(JSON engine_entry ERROR_VARIABLE json_error GET ${json_data} engine_name)
if(json_error)
message(FATAL_ERROR "Unable to read engine_name from '${o3de_json_file}', error: ${json_error}")
endif()
if(engine_entry)
set(${engine} ${engine_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_project_name:
#
# \arg:project returns the project_name element from an project.json
# \arg:o3de_project_json_file name of the o3de json file
################################################################################
function(o3de_project_name o3de_project_json_file project)
file(READ ${o3de_project_json_file} json_data)
string(JSON project_entry ERROR_VARIABLE json_error GET ${json_data} project_name)
if(json_error)
message(FATAL_ERROR "Unable to read project_name from '${o3de_json_file}', error: ${json_error}")
endif()
if(project_entry)
set(${project} ${project_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_gem_name:
#
# \arg:gem returns the gem_name element from an gem.json
# \arg:o3de_gem_json_file name of the o3de json file
################################################################################
function(o3de_gem_name o3de_gem_json_file gem)
file(READ ${o3de_gem_json_file} json_data)
string(JSON gem_entry ERROR_VARIABLE json_error GET ${json_data} gem_name)
if(json_error)
message(FATAL_ERROR "Unable to read gem_name from '${o3de_json_file}', error: ${json_error}")
endif()
if(gem_entry)
set(${gem} ${gem_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_template_name:
#
# \arg:template returns the template_name element from an template json
# \arg:o3de_template_json_file name of the o3de json file
################################################################################
function(o3de_template_name o3de_template_json_file template)
file(READ ${o3de_template_json_file} json_data)
string(JSON template_entry ERROR_VARIABLE json_error GET ${json_data} template_name)
if(json_error)
message(FATAL_ERROR "Unable to read template_name from '${o3de_json_file}', error: ${json_error}")
endif()
if(template_entry)
set(${template} ${template_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_repo_name:
#
# \arg:repo returns the repo_name element from an repo.json or o3de_manifest.json
# \arg:o3de_repo_json_file name of the o3de json file
################################################################################
function(o3de_repo_name o3de_repo_json_file repo)
file(READ ${o3de_repo_json_file} json_data)
string(JSON repo_entry ERROR_VARIABLE json_error GET ${json_data} repo_name)
if(json_error)
message(FATAL_ERROR "Unable to read repo_name from '${o3de_json_file}', error: ${json_error}")
endif()
if(repo_entry)
set(${repo} ${repo_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_restricted_name:
#
# \arg:restricted returns the restricted association element from an o3de json
# \arg:o3de_json_file name of the o3de json file
################################################################################
function(o3de_restricted_name o3de_json_file restricted)
file(READ ${o3de_json_file} json_data)
string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} restricted_name)
if(json_error)
message(WARNING "FATAL_ERROR to read restricted_name from '${o3de_json_file}', error: ${json_error}")
endif()
if(restricted_entry)
set(${restricted} ${restricted_entry} PARENT_SCOPE)
endif()
endfunction()
################################################################################
#! o3de_engine_path:
#
# \arg:engine_path returns the path of the o3de engine folder with name engine_name
# \arg:engine_name name of the engine
################################################################################
function(o3de_engine_path o3de_json_file engine_path)
o3de_engine_id(${o3de_json_file} engine_name)
if(engine_name)
o3de_find_engine_folder(${engine_name} engine_folder)
if(engine_folder)
set(${engine_path} ${engine_folder} PARENT_SCOPE)
endif()
endif()
endfunction()
################################################################################
#! o3de_project_path:
#
# \arg:project_path returns the path of the o3de project folder with name project_name
# \arg:project_name name of the project
################################################################################
function(o3de_project_path o3de_json_file project_path)
o3de_project_id(${o3de_json_file} project_name)
if(project_name)
o3de_find_project_folder(${project_name} project_folder)
if(project_folder)
set(${project_path} ${project_folder} PARENT_SCOPE)
endif()
endif()
endfunction()
################################################################################
#! o3de_template_path:
#
# \arg:template_path returns the path of the o3de template folder with name template_name
# \arg:template_name name of the template
################################################################################
function(o3de_template_path o3de_json_file template_path)
o3de_template_id(${o3de_json_file} template_name)
if(template_name)
o3de_find_template_folder(${template_name} template_folder)
if(template_folder)
set(${template_path} ${template_folder} PARENT_SCOPE)
endif()
endif()
endfunction()
################################################################################
#! o3de_repo_path:
#
# \arg:repo_path returns the path of the o3de repo folder with name repo_name
# \arg:repo_name name of the repo
################################################################################
function(o3de_repo_path o3de_json_file repo_path)
o3de_repo_id(${o3de_json_file} repo_name)
if(repo_name)
o3de_find_repo_folder(${repo_name} repo_folder)
if(repo_folder)
set(${repo_path} ${repo_folder} PARENT_SCOPE)
endif()
endif()
endfunction()
################################################################################
#! o3de_restricted_path:
#
# \arg:restricted_path returns the path of the o3de restricted folder with name restricted_name
# \arg:restricted_name name of the restricted
################################################################################
function(o3de_restricted_path o3de_json_file restricted_path)
o3de_restricted_id(${o3de_json_file} restricted_name)
if(restricted_name)
o3de_find_restricted_folder(${restricted_name} restricted_folder)
if(restricted_folder)
set(${restricted_path} ${restricted_folder} PARENT_SCOPE)
endif()
endif()
endfunction()
+92 -2
View File
@@ -1,8 +1,98 @@
{
"engine_name": "o3de",
"restricted": "o3de",
"restricted_name": "o3de",
"FileVersion": 1,
"O3DEVersion": "0.0.0.0",
"O3DECopyrightYear": 2021,
"O3DEBuildNumber": 0
"O3DEBuildNumber": 0,
"external_subdirectories": [
"Gems/Achievements",
"Gems/AssetMemoryAnalyzer",
"Gems/AssetValidation",
"Gems/Atom",
"Gems/AtomContent",
"Gems/AtomLyIntegration",
"Gems/AtomTressFX",
"Gems/AudioEngineWwise",
"Gems/AudioSystem",
"Gems/AutomatedLauncherTesting",
"Gems/AWSClientAuth",
"Gems/AWSCore",
"Gems/AWSMetrics",
"Gems/Blast",
"Gems/Camera",
"Gems/CameraFramework",
"Gems/CertificateManager",
"Gems/CrashReporting",
"Gems/CustomAssetExample",
"Gems/DebugDraw",
"Gems/DevTextures",
"Gems/EditorPythonBindings",
"Gems/EMotionFX",
"Gems/ExpressionEvaluation",
"Gems/FastNoise",
"Gems/GameState",
"Gems/GameStateSamples",
"Gems/Gestures",
"Gems/GradientSignal",
"Gems/GraphCanvas",
"Gems/GraphModel",
"Gems/HttpRequestor",
"Gems/ImGui",
"Gems/InAppPurchases",
"Gems/LandscapeCanvas",
"Gems/LmbrCentral",
"Gems/LocalUser",
"Gems/LyShine",
"Gems/LyShineExamples",
"Gems/Maestro",
"Gems/MessagePopup",
"Gems/Metastream",
"Gems/Microphone",
"Gems/Multiplayer",
"Gems/MultiplayerCompression",
"Gems/NvCloth",
"Gems/PBSreferenceMaterials",
"Gems/PhysicsEntities",
"Gems/PhysX",
"Gems/PhysXDebug",
"Gems/PhysXSamples",
"Gems/Prefab",
"Gems/Presence",
"Gems/PrimitiveAssets",
"Gems/PythonAssetBuilder",
"Gems/QtForPython",
"Gems/RADTelemetry",
"Gems/SaveData",
"Gems/SceneLoggingExample",
"Gems/SceneProcessing",
"Gems/ScriptCanvas",
"Gems/ScriptCanvasDeveloper",
"Gems/ScriptCanvasPhysics",
"Gems/ScriptCanvasTesting",
"Gems/ScriptedEntityTweener",
"Gems/ScriptEvents",
"Gems/SliceFavorites",
"Gems/StartingPointCamera",
"Gems/StartingPointInput",
"Gems/StartingPointMovement",
"Gems/SurfaceData",
"Gems/TestAssetBuilder",
"Gems/TextureAtlas",
"Gems/TickBusOrderViewer",
"Gems/Twitch",
"Gems/UIBasics",
"Gems/Vegetation",
"Gems/Vegetation_Gem_Assets",
"Gems/VideoPlaybackFramework",
"Gems/VirtualGamepad",
"Gems/WhiteBox"
],
"projects": [
"AutomatedTesting"
],
"templates": [
"Templates/DefaultGem",
"Templates/DefaultProject"
]
}
@@ -35,7 +35,7 @@
"PARAMETERS": {
"CONFIGURATION":"debug",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
@@ -60,7 +60,7 @@
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
@@ -76,7 +76,7 @@
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
@@ -93,7 +93,7 @@
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\windows_vs2019",
"CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"AssetProcessorBatch",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -112,7 +112,7 @@
"PARAMETERS": {
"CONFIGURATION":"release",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
@@ -128,7 +128,7 @@
"PARAMETERS": {
"CONFIGURATION":"release",
"OUTPUT_DIRECTORY":"build\\mono_android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
+11 -11
View File
@@ -37,7 +37,7 @@
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
@@ -53,7 +53,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
@@ -66,7 +66,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
@@ -80,7 +80,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all",
"CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest"
@@ -92,7 +92,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all",
"CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest"
@@ -108,7 +108,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"ASSET_PROCESSOR_BINARY": "bin/profile/AssetProcessorBatch",
@@ -122,7 +122,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"ASSET_PROCESSOR_BINARY": "bin/profile/AssetProcessorBatch",
@@ -140,7 +140,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_periodic",
"CTEST_OPTIONS": "-L \"(SUITE_periodic)\""
@@ -156,7 +156,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_benchmark",
"CTEST_OPTIONS": "-L \"(SUITE_benchmark)\""
@@ -172,7 +172,7 @@
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
@@ -187,7 +187,7 @@
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/mono_linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
+8 -8
View File
@@ -37,7 +37,7 @@
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
@@ -51,7 +51,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
@@ -66,7 +66,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
@@ -81,7 +81,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"ASSET_PROCESSOR_BINARY": "bin/profile/AssetProcessorBatch",
@@ -99,7 +99,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_periodic",
"CTEST_OPTIONS": "-L \"(SUITE_periodic)\""
@@ -115,7 +115,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_benchmark",
"CTEST_OPTIONS": "-L \"(SUITE_benchmark)\""
@@ -131,7 +131,7 @@
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
@@ -146,7 +146,7 @@
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/mono_mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
@@ -87,7 +87,7 @@
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_BUILD_WITH_INCREMENTAL_LINKING_DEBUG=FALSE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_BUILD_WITH_INCREMENTAL_LINKING_DEBUG=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
@@ -101,7 +101,7 @@
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_BUILD_WITH_INCREMENTAL_LINKING_DEBUG=FALSE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_BUILD_WITH_INCREMENTAL_LINKING_DEBUG=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -119,7 +119,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
@@ -135,7 +135,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
@@ -150,7 +150,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -171,7 +171,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -190,7 +190,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -209,7 +209,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_periodic",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -231,7 +231,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_sandbox",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -250,7 +250,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_benchmark",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
@@ -269,7 +269,7 @@
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
@@ -285,7 +285,7 @@
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build\\mono_windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
@@ -300,7 +300,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_DISABLE_TEST_MODULES=TRUE -DCMAKE_INSTALL_PREFIX=install -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_DISABLE_TEST_MODULES=TRUE -DCMAKE_INSTALL_PREFIX=install",
"CMAKE_LY_PROJECTS": "",
"CMAKE_TARGET": "INSTALL",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
@@ -4,7 +4,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "windows_vs2017",
"CMAKE_OPTIONS": "-G \"Visual Studio 15 2017\" -A x64 -T host=x64 -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G \"Visual Studio 15 2017\" -A x64 -T host=x64 -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AtomTest;AtomSampleViewer",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m:4 /p:CL_MPCount=!HALF_PROCESSORS! /nologo"
@@ -15,7 +15,7 @@
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"windows_vs2019",
"CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AtomTest;AtomSampleViewer",
"CMAKE_TARGET":"ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
+4 -4
View File
@@ -27,7 +27,7 @@
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
@@ -44,7 +44,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
@@ -60,7 +60,7 @@
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
@@ -94,7 +94,7 @@
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
+57 -19
View File
@@ -13,27 +13,65 @@ import argparse
import pathlib
import sys
# As o3de.py shares the same name as the o3de package attempting to use a regular
# from o3de import <module> line tries to import from the current o3de.py script and not the package
# So the current script directory is removed from the sys.path temporary
SCRIPT_DIR_REMOVED = False
SCRIPT_DIR = pathlib.Path(__file__).parent.resolve()
if str(SCRIPT_DIR) in sys.path:
SCRIPT_DIR_REMOVED = True
sys.path.remove(str(SCRIPT_DIR))
from o3de import engine_template
from o3de import global_project
from o3de import registration
if SCRIPT_DIR_REMOVED:
sys.path.insert(0, str(SCRIPT_DIR))
def add_args(parser, subparsers) -> None:
global_project.add_args(parser, subparsers)
engine_template.add_args(parser, subparsers)
registration.add_args(parser, subparsers)
"""
add_args is called to add expected parser arguments and subparsers arguments to each command such that it can be
invoked by o3de.py
Ex o3de.py can invoke the register downloadable commands by importing register,
call add_args and execute: python o3de.py register --gem-path "C:/TestGem"
:param parser: the caller instantiates a parser and passes it in here
:param subparsers: the caller instantiates subparsers and passes it in here
"""
# As o3de.py shares the same name as the o3de package attempting to use a regular
# from o3de import <module> line tries to import from the current o3de.py script and not the package
# So the current script directory is removed from the sys.path temporary
script_dir_removed = False
script_abs_dir_removed = False
script_dir = pathlib.Path(__file__).parent
script_abs_dir = pathlib.Path(__file__).parent.resolve()
while str(script_dir) in sys.path:
script_dir_removed = True
sys.path.remove(str(script_dir))
while str(script_abs_dir) in sys.path:
script_abs_dir_removed = True
# Remove the absolute path to the script_dir as well
sys.path.remove(str(script_abs_dir.resolve()))
from o3de import engine_template, global_project, register, print_registration, get_registration, download, \
add_gem_project, remove_gem_project, sha256
if script_abs_dir_removed:
sys.path.insert(0, str(script_abs_dir))
if script_dir_removed:
sys.path.insert(0, str(script_dir))
# global_project
global_project.add_args(subparsers)
# engine templaate
engine_template.add_args(subparsers)
# register
register.add_args(subparsers)
# show
print_registration.add_args(subparsers)
# get-registered
get_registration.add_args(subparsers)
# download
download.add_args(subparsers)
# add a gem to a project
add_gem_project.add_args(subparsers)
# remove a gem from a project
remove_gem_project.add_args(subparsers)
# sha256
sha256.add_args(subparsers)
if __name__ == "__main__":
+342
View File
@@ -0,0 +1,342 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
"""
Contains command to add a gem to a project's cmake scripts
"""
import argparse
import json
import logging
import os
import pathlib
import sys
from o3de import cmake, manifest, validation
logger = logging.getLogger()
logging.basicConfig()
def add_gem_dependency(cmake_file: str or pathlib.Path,
gem_target: str) -> int:
"""
adds a gem dependency to a cmake file
:param cmake_file: path to the cmake file
:param gem_target: name of the cmake target
:return: 0 for success or non 0 failure code
"""
if not os.path.isfile(cmake_file):
logger.error(f'Failed to locate cmake file {cmake_file}')
return 1
# on a line by basis, see if there already is Gem::{gem_name}
# find the first occurrence of a gem, copy its formatting and replace
# the gem name with the new one and append it
# if the gem is already present fail
t_data = []
added = False
with open(cmake_file, 'r') as s:
for line in s:
if f'Gem::{gem_target}' in line:
logger.warning(f'{gem_target} is already a gem dependency.')
return 0
if not added and r'Gem::' in line:
new_gem = ' ' * line.find(r'Gem::') + f'Gem::{gem_target}\n'
t_data.append(new_gem)
added = True
t_data.append(line)
# if we didn't add it the set gem dependencies could be empty so
# add a new gem, if empty the correct format is 1 tab=4spaces
if not added:
index = 0
for line in t_data:
index = index + 1
if r'set(GEM_DEPENDENCIES' in line:
t_data.insert(index, f' Gem::{gem_target}\n')
added = True
break
# if we didn't add it then it's not here, add a whole new one
if not added:
t_data.append('\n')
t_data.append('set(GEM_DEPENDENCIES\n')
t_data.append(f' Gem::{gem_target}\n')
t_data.append(')\n')
# write the cmake
os.unlink(cmake_file)
with open(cmake_file, 'w') as s:
s.writelines(t_data)
return 0
def add_gem_to_project(gem_name: str = None,
gem_path: str or pathlib.Path = None,
gem_target: str = None,
project_name: str = None,
project_path: str or pathlib.Path = None,
dependencies_file: str or pathlib.Path = None,
runtime_dependency: bool = False,
tool_dependency: bool = False,
server_dependency: bool = False,
platforms: str = 'Common',
add_to_cmake: bool = True) -> int:
"""
add a gem to a project
:param gem_name: name of the gem to add
:param gem_path: path to the gem to add
:param gem_target: the name of the cmake gem module
:param project_name: name of to the project to add the gem to
:param project_path: path to the project to add the gem to
:param dependencies_file: if this dependency goes/is in a specific file
:param runtime_dependency: bool to specify this is a runtime gem for the game
:param tool_dependency: bool to specify this is a tool gem for the editor
:param server_dependency: bool to specify this is a server gem for the server
:param platforms: str to specify common or which specific platforms
:param add_to_cmake: bool to specify that this gem should be added to cmake
:return: 0 for success or non 0 failure code
"""
# we need either a project name or path
if not project_name and not project_path:
logger.error(f'Must either specify a Project path or Project Name.')
return 1
# if project name resolve it into a path
if project_name and not project_path:
project_path = manifest.get_registered(project_name=project_name)
project_path = pathlib.Path(project_path).resolve()
if not project_path.is_dir():
logger.error(f'Project path {project_path} is not a folder.')
return 1
# get the engine name this project is associated with
# and resolve that engines path
project_json = project_path / 'project.json'
if not validation.valid_o3de_project_json(project_json):
logger.error(f'Project json {project_json} is not valid.')
return 1
with project_json.open('r') as s:
try:
project_json_data = json.load(s)
except json.JSONDecodeError as e:
logger.error(f'Error loading Project json {project_json}: {str(e)}')
return 1
else:
try:
engine_name = project_json_data['engine']
except KeyError as e:
logger.error(f'Project json {project_json} "engine" not found: {str(e)}')
return 1
else:
engine_path = manifest.get_registered(engine_name=engine_name)
if not engine_path:
logger.error(f'Engine {engine_name} is not registered.')
return 1
# we need either a gem name or path
if not gem_name and not gem_path:
logger.error(f'Must either specify a Gem path or Gem Name.')
return 1
# if gem name resolve it into a path
if gem_name and not gem_path:
gem_path = manifest.get_registered(gem_name=gem_name)
gem_path = pathlib.Path(gem_path).resolve()
# make sure this gem already exists if we're adding. We can always remove a gem.
if not gem_path.is_dir():
logger.error(f'Gem Path {gem_path} does not exist.')
return 1
# if add to cmake, make sure the gem.json exists and valid before we proceed
if add_to_cmake:
gem_json = gem_path / 'gem.json'
if not gem_json.is_file():
logger.error(f'Gem json {gem_json} is not present.')
return 1
if not validation.valid_o3de_gem_json(gem_json):
logger.error(f'Gem json {gem_json} is not valid.')
return 1
# find all available modules in this gem_path
modules = cmake.get_gem_targets(gem_path=gem_path)
if len(modules) == 0:
logger.error(f'No gem modules found under {gem_path}.')
return 1
# if the gem has no modules and the user has specified a target fail
if gem_target and not modules:
logger.error(f'Gem has no targets, but gem target {gem_target} was specified.')
return 1
# if the gem target is not in the modules
if gem_target not in modules:
logger.error(f'Gem target not in gem modules: {modules}')
return 1
if gem_target:
# if the user has not specified either we will assume they meant the most common which is runtime
if not runtime_dependency and not tool_dependency and not server_dependency and not dependencies_file:
logger.warning("Dependency type not specified: Assuming '--runtime-dependency'")
runtime_dependency = True
ret_val = 0
# if the user has specified the dependencies file then ignore the runtime_dependency and tool_dependency flags
if dependencies_file:
dependencies_file = pathlib.Path(dependencies_file).resolve()
# make sure this is a project has a dependencies_file
if not dependencies_file.is_file():
logger.error(f'Dependencies file {dependencies_file} is not present.')
return 1
# add the dependency
ret_val = add_gem_dependency(dependencies_file, gem_target)
else:
if ',' in platforms:
platforms = platforms.split(',')
else:
platforms = [platforms]
for platform in platforms:
if runtime_dependency:
# make sure this is a project has a runtime_dependencies.cmake file
project_runtime_dependencies_file = pathlib.Path(
cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='runtime',
platform=platform)).resolve()
if not project_runtime_dependencies_file.is_file():
logger.error(f'Runtime dependencies file {project_runtime_dependencies_file} is not present.')
return 1
# add the dependency
ret_val = add_gem_dependency(project_runtime_dependencies_file, gem_target)
if (ret_val == 0) and tool_dependency:
# make sure this is a project has a tool_dependencies.cmake file
project_tool_dependencies_file = pathlib.Path(
cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='tool',
platform=platform)).resolve()
if not project_tool_dependencies_file.is_file():
logger.error(f'Tool dependencies file {project_tool_dependencies_file} is not present.')
return 1
# add the dependency
ret_val = add_gem_dependency(project_tool_dependencies_file, gem_target)
if (ret_val == 0) and server_dependency:
# make sure this is a project has a tool_dependencies.cmake file
project_server_dependencies_file = pathlib.Path(
cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='server',
platform=platform)).resolve()
if not project_server_dependencies_file.is_file():
logger.error(f'Server dependencies file {project_server_dependencies_file} is not present.')
return 1
# add the dependency
ret_val = add_gem_dependency(project_server_dependencies_file, gem_target)
return ret_val
def _run_add_gem_to_project(args: argparse) -> int:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
return add_gem_to_project(args.gem_name,
args.gem_path,
args.gem_target,
args.project_name,
args.project_path,
args.dependencies_file,
args.runtime_dependency,
args.tool_dependency,
args.server_dependency,
args.platforms,
args.add_to_cmake)
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python add_gem_project.py --project-path "D:/TestProject" --gem-path "D:/TestGem"
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-pp', '--project-path', type=str, required=False,
help='The path to the project.')
group.add_argument('-pn', '--project-name', type=str, required=False,
help='The name of the project.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-gp', '--gem-path', type=str, required=False,
help='The path to the gem.')
group.add_argument('-gn', '--gem-name', type=str, required=False,
help='The name of the gem.')
parser.add_argument('-gt', '--gem-target', type=str, required=False,
help='The cmake target name to add. If not specified it will assume gem_name')
parser.add_argument('-df', '--dependencies-file', type=str, required=False,
help='The cmake dependencies file in which the gem dependencies are specified.'
'If not specified it will assume ')
parser.add_argument('-rd', '--runtime-dependency', action='store_true', required=False,
default=False,
help='Optional toggle if this gem should be added as a runtime dependency')
parser.add_argument('-td', '--tool-dependency', action='store_true', required=False,
default=False,
help='Optional toggle if this gem should be added as a tool dependency')
parser.add_argument('-sd', '--server-dependency', action='store_true', required=False,
default=False,
help='Optional toggle if this gem should be added as a server dependency')
parser.add_argument('-pl', '--platforms', type=str, required=False,
default='Common',
help='Optional list of platforms this gem should be added to.'
' Ex. --platforms Mac,Windows,Linux')
parser.add_argument('-a', '--add-to-cmake', type=bool, required=False,
default=True,
help='Automatically call add-gem-to-cmake.')
parser.add_argument('-ohf', '--override-home-folder', type=str, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.set_defaults(func=_run_add_gem_to_project)
def add_args(subparsers) -> None:
"""
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py add-gem-to-project --project-path "D:/TestProject" --gem-path "D:/TestGem"
:param subparsers: the caller instantiates subparsers and passes it in here
"""
add_gem_project_subparser = subparsers.add_parser('add-gem-to-project')
add_parser_args(add_gem_project_subparser)
def main():
"""
Runs add_gem_project.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()
# add subparsers
# add args to the parser
add_parser_args(the_parser)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
sys.exit(ret)
if __name__ == "__main__":
main()
+234
View File
@@ -0,0 +1,234 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
"""
Contains methods for query CMake gem target information
"""
import logging
import os
import pathlib
from o3de import manifest
logger = logging.getLogger()
logging.basicConfig()
def get_project_runtime_gem_targets(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
return get_gem_targets_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='runtime', platform=platform))
def get_project_tool_gem_targets(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
return get_gem_targets_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='tool', platform=platform))
def get_project_server_gem_targets(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
return get_gem_targets_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='server', platform=platform))
def get_project_gem_targets(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
runtime_gems = get_gem_targets_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='runtime', platform=platform))
tool_gems = get_gem_targets_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='tool', platform=platform))
server_gems = get_gem_targets_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='server', platform=platform))
return runtime_gems.union(tool_gems.union(server_gems))
def get_gem_targets_from_cmake_file(cmake_file: str or pathlib.Path) -> set:
"""
Gets a list of declared gem targets dependencies of a cmake file
:param cmake_file: path to the cmake file
:return: set of gem targets found
"""
cmake_file = pathlib.Path(cmake_file).resolve()
if not cmake_file.is_file():
logger.error(f'Failed to locate cmake file {cmake_file}')
return set()
gem_target_set = set()
with cmake_file.open('r') as s:
for line in s:
gem_name = line.split('Gem::')
if len(gem_name) > 1:
# Only take the name as everything leading up to the first '.' if found
# Gem naming conventions will have GemName.Editor, GemName.Server, and GemName
# as different targets of the GemName Gem
gem_target_set.add(gem_name[1].replace('\n', ''))
return gem_target_set
def get_project_runtime_gem_names(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
return get_gem_names_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='runtime', platform=platform))
def get_project_tool_gem_names(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
return get_gem_names_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='tool', platform=platform))
def get_project_server_gem_names(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
return get_gem_names_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='server', platform=platform))
def get_project_gem_names(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
runtime_gem_names = get_gem_names_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='runtime', platform=platform))
tool_gem_names = get_gem_names_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='tool', platform=platform))
server_gem_names = get_gem_names_from_cmake_file(get_dependencies_cmake_file(project_path=project_path, dependency_type='server', platform=platform))
return runtime_gem_names.union(tool_gem_names.union(server_gem_names))
def get_gem_names_from_cmake_file(cmake_file: str or pathlib.Path) -> set:
"""
Gets a list of declared gem dependencies of a cmake file
:param cmake_file: path to the cmake file
:return: set of gems found
"""
cmake_file = pathlib.Path(cmake_file).resolve()
if not cmake_file.is_file():
logger.error(f'Failed to locate cmake file {cmake_file}')
return set()
gem_set = set()
with cmake_file.open('r') as s:
for line in s:
gem_name = line.split('Gem::')
if len(gem_name) > 1:
# Only take the name as everything leading up to the first '.' if found
# Gem naming conventions will have GemName.Editor, GemName.Server, and GemName
# as different targets of the GemName Gem
gem_set.add(gem_name[1].split('.')[0].replace('\n', ''))
return gem_set
def get_project_runtime_gem_paths(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
gem_names = get_project_runtime_gem_names(project_path, platform)
gem_paths = set()
for gem_name in gem_names:
gem_paths.add(manifest.get_registered(gem_name=gem_name))
return gem_paths
def get_project_tool_gem_paths(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
gem_names = get_project_tool_gem_names(project_path, platform)
gem_paths = set()
for gem_name in gem_names:
gem_paths.add(manifest.get_registered(gem_name=gem_name))
return gem_paths
def get_project_server_gem_paths(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
gem_names = get_project_server_gem_names(project_path, platform)
gem_paths = set()
for gem_name in gem_names:
gem_paths.add(manifest.get_registered(gem_name=gem_name))
return gem_paths
def get_project_gem_paths(project_path: str or pathlib.Path,
platform: str = 'Common') -> set:
gem_names = get_project_gem_names(project_path, platform)
gem_paths = set()
for gem_name in gem_names:
gem_paths.add(manifest.get_registered(gem_name=gem_name))
return gem_paths
def get_dependencies_cmake_file(project_name: str = None,
project_path: str or pathlib.Path = None,
dependency_type: str = 'runtime',
platform: str = 'Common') -> str or None:
"""
get the standard cmake file name for a particular type of dependency
:param gem_name: name of the gem, resolves gem_path
:param gem_path: path of the gem
:return: list of gem targets
"""
if not project_name and not project_path:
logger.error(f'Must supply either a Project Name or Project Path.')
return None
if project_name and not project_path:
project_path = manifest.get_registered(project_name=project_name)
project_path = pathlib.Path(project_path).resolve()
if platform == 'Common':
dependencies_file = f'{dependency_type}_dependencies.cmake'
dependencies_file_path = project_path / 'Gem/Code' / dependencies_file
if dependencies_file_path.is_file():
return dependencies_file_path
return project_path / 'Code' / dependencies_file
else:
dependencies_file = f'{platform.lower()}_{dependency_type}_dependencies.cmake'
dependencies_file_path = project_path / 'Gem/Code/Platform' / platform / dependencies_file
if dependencies_file_path.is_file():
return dependencies_file_path
return project_path / 'Code/Platform' / platform / dependencies_file
def get_all_gem_targets() -> list:
modules = []
for gem_path in manifest.get_all_gems():
this_gems_targets = get_gem_targets(gem_path=gem_path)
modules.extend(this_gems_targets)
return modules
def get_gem_targets(gem_name: str = None,
gem_path: str or pathlib.Path = None) -> list:
"""
Finds gem targets in a gem
:param gem_name: name of the gem, resolves gem_path
:param gem_path: path of the gem
:return: list of gem targets
"""
if not gem_name and not gem_path:
return []
if gem_name and not gem_path:
gem_path = manifest.get_registered(gem_name=gem_name)
if not gem_path:
return []
gem_path = pathlib.Path(gem_path).resolve()
gem_json = gem_path / 'gem.json'
if not validation.valid_o3de_gem_json(gem_json):
return []
module_identifiers = [
'MODULE',
'GEM_MODULE',
'${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}'
]
modules = []
for root, dirs, files in os.walk(gem_path):
for file in files:
if file == 'CMakeLists.txt':
with open(os.path.join(root, file), 'r') as s:
for line in s:
trimmed = line.lstrip()
if trimmed.startswith('NAME '):
trimmed = trimmed.rstrip(' \n')
split_trimmed = trimmed.split(' ')
if len(split_trimmed) == 3 and split_trimmed[2] in module_identifiers:
modules.append(split_trimmed[1])
return modules
+241
View File
@@ -0,0 +1,241 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
"""
Implements functionality for downloading o3de objecs either locally or from a URI
"""
import argparse
import hashlib
import json
import logging
import pathlib
import shutil
import sys
import urllib.parse
import urllib.request
from o3de import manifest, repo, utils, validation
logger = logging.getLogger()
logging.basicConfig()
def unzip_manifest_json_data(download_zip_path: pathlib.Path, zip_file_name: str) -> dict:
json_data = {}
with zipfile.ZipFile(download_zip_path, 'r') as zip_data:
with zip_data.open(zip_file_name) as manifest_json_file:
try:
json_data = json.load(manifest_json_file)
except json.JSONDecodeError as e:
logger.error(f'UnZip exception:{str(e)}')
return json_data
def validate_downloaded_zip_sha256(download_uri_json_data: dict, download_zip_path: pathlib.Path,
manifest_json_name) -> int:
# if the engine.json has a sha256 check it against a sha256 of the zip
try:
sha256A = download_uri_json_data['sha256']
except KeyError as e:
logger.warn(f'SECURITY WARNING: The advertised o3de object you downloaded has no "sha256"!!! Be VERY careful!!!'
f' We cannot verify this is the actually the advertised object!!!')
else:
sha256B = hashlib.sha256(download_zip_path.open('rb').read()).hexdigest()
if sha256A != sha256B:
logger.error(f'SECURITY VIOLATION: Downloaded zip sha256 {sha256B} does not match'
f' the advertised "sha256":{sha256A} in the f{manifest_json_name}. Deleting unzipped files!!!')
shutil.rmtree(dest_path)
return 1
manifest_json_data = unzip_manifest_json_data(download_zip_path, manifest_json_name)
# remove the sha256 if present in the advertised downloadable manifest json
# then compare it to the json in the zip, they should now be identical
try:
del download_uri_json_data['sha256']
except KeyError as e:
pass
sha256A = hashlib.sha256(json.dumps(download_uri_json_data, indent=4).encode('utf8')).hexdigest()
with unzipped_manifest_json.open('r') as s:
try:
unzipped_manifest_json_data = json.load(s)
except json.JSONDecodeError as e:
logger.error(f'Failed to read manifest json {unzipped_manifest_json}. Unable to confirm this'
f' is the same template that was advertised.')
return 1
sha256B = hashlib.sha256(json.dumps(unzipped_manifest_json_data, indent=4).encode('utf8')).hexdigest()
if sha256A != sha256B:
logger.error(f'SECURITY VIOLATION: Downloaded manifest json does not match'
f' the advertised manifest json. Deleting unzipped files!!!')
shutil.rmtree(dest_path)
return 1
return 0
def get_downloadable(engine_name: str = None,
project_name: str = None,
gem_name: str = None,
template_name: str = None,
restricted_name: str = None) -> dict or None:
json_data = manifest.load_o3de_manifest()
try:
o3de_object_uris = json_data['repos']
except KeyError as key_err:
logger.error(f'Unable to load repos from o3de manifest: {str(key_err)}')
return None
manifest_json = 'repo.json'
search_func = lambda: repo.search_repo(manifest_json, engine_name, project_name, gem_name, template_name)
return repo.search_o3de_object(manifest_json, o3de_object_uris, search_func)
def download_o3de_object(object_name: str, default_folder_name: str, dest_path: str or pathlib.Path,
object_type: str, downloadable_kwarg_key) -> int:
if not dest_path:
dest_path = manifest.get_registered(default_folder=default_folder_name)
if not dest_path:
logger.error(f'Destination path not cannot be empty.')
return 1
dest_path = pathlib.Path(dest_path).resolve()
dest_path.mkdir(exist_ok=True)
download_path = manifest.get_o3de_download_folder() / default_folder_name / object_name
download_path.mkdir(exist_ok=True)
download_zip_path = download_path / f'{object_type}.zip'
downloadable_object_data = get_downloadable(**{downloadable_kwarg_key : object_name})
if not downloadable_object_data:
logger.error(f'Downloadable o3de object {object_name} not found.')
return 1
origin = downloadable_json_data['origin']
url = f'{origin}/object_type.zip'
parsed_uri = urllib.parse.urlparse(url)
download_zip_result = utils.download_zip_file(parsed_uri, download_zip_path)
if download_zip_result != 0:
return download_zip_result
return validate_downloaded_zip_sha256(downloadable_object_data, download_zip_path)
def download_engine(engine_name: str,
dest_path: str or pathlib.Path) -> int:
return download_o3de_object(engine_name, 'engines', dest_path, 'engine', 'engine_name')
def download_project(project_name: str,
dest_path: str or pathlib.Path) -> int:
return download_o3de_object(project_name, 'projects', dest_path, 'project', 'project_name')
def download_gem(gem_name: str,
dest_path: str or pathlib.Path) -> int:
return download_o3de_object(gem_name, 'gems', dest_path, 'gem', 'gem_name')
def download_template(template_name: str,
dest_path: str or pathlib.Path) -> int:
return download_o3de_object(template_name, 'templates', dest_path, 'template', 'template_name')
def download_restricted(restricted_name: str,
dest_path: str or pathlib.Path) -> int:
return download_o3de_object(restricted_name, 'restricted', dest_path, 'restricted', 'restricted_name')
def _run_download(args: argparse) -> int:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
if args.engine_name:
return download_engine(args.engine_name,
args.dest_path)
elif args.project_name:
return download_project(args.project_name,
args.dest_path)
elif args.gem_nanme:
return download_gem(args.gem_name,
args.dest_path)
elif args.template_name:
return download_template(args.template_name,
args.dest_path)
return 1
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python download.py --engine-name "o3de"
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-e', '--engine-name', type=str, required=False,
help='Downloadable engine name.')
group.add_argument('-p', '--project-name', type=str, required=False,
help='Downloadable project name.')
group.add_argument('-g', '--gem-name', type=str, required=False,
help='Downloadable gem name.')
group.add_argument('-t', '--template-name', type=str, required=False,
help='Downloadable template name.')
parser.add_argument('-dp', '--dest-path', type=str, required=False,
default=None,
help='Optional destination folder to download into.'
' i.e. download --project-name "AstomSamplerViewer" --dest-path "C:/projects"'
' will result in C:/projects/AtomSampleViewer'
' If blank will download to default object type folder')
parser.add_argument('-ohf', '--override-home-folder', type=str, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.set_defaults(func=_run_download)
def add_args(subparsers) -> None:
"""
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py download --engine-name "o3de"
:param subparsers: the caller instantiates subparsers and passes it in here
"""
download_subparser = subparsers.add_parser('download')
add_parser_args(download_subparser)
def main():
"""
Runs download.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()
# add subparsers
# add args to the parser
add_parser_args(the_parser)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
sys.exit(ret)
if __name__ == "__main__":
main()
+137 -163
View File
@@ -21,7 +21,7 @@ import uuid
import re
from o3de import utils, registration
from o3de import manifest, validation, utils
logger = logging.getLogger()
logging.basicConfig()
@@ -79,7 +79,7 @@ restricted_platforms = {
}
template_file_name = 'template.json'
this_script_parent = os.path.dirname(os.path.realpath(__file__))
def _transform(s_data: str,
replacements: list,
@@ -321,7 +321,7 @@ def _instantiate_template(template_json_data: dict,
platform_json = f'{template_restricted_platform_path_rel}/{template_file_name}'.replace('//', '/')
if os.path.isfile(platform_json):
if not registration.valid_o3de_template_json(platform_json):
if not validation.valid_o3de_template_json(platform_json):
logger.error(f'Template json {platform_json} is invalid.')
return 1
@@ -329,7 +329,7 @@ def _instantiate_template(template_json_data: dict,
with open(platform_json, 'r') as s:
try:
json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Failed to load {platform_json}: ' + str(e))
return 1
else:
@@ -403,11 +403,11 @@ def create_template(source_path: str,
template_path = source_name
template_path = template_path.replace('\\', '/')
if not os.path.isabs(template_path):
default_templates_folder = registration.get_registered(default_folder='templates')
default_templates_folder = manifest.get_registered(default_folder='templates')
template_path = f'{default_templates_folder}/{template_path}'
logger.info(f'Template path not a full path. Using default templates folder {template_path}')
if os.path.isdir(template_path):
logger.error(f'Template path {template_path} is already exists.')
logger.error(f'Template path {template_path} already exists.')
return 1
# template name is now the last component of the template_path
@@ -419,28 +419,28 @@ def create_template(source_path: str,
return 1
if source_restricted_name and not source_restricted_path:
source_restricted_path = registration.get_registered(restricted_name=source_restricted_name)
source_restricted_path = manifest.get_registered(restricted_name=source_restricted_name)
# source_restricted_path
if source_restricted_path:
source_restricted_path = source_restricted_path.replace('\\', '/')
if not os.path.isabs(source_restricted_path):
engine_json = f'{registration.get_this_engine_path()}/engine.json'
if not registration.valid_o3de_engine_json(engine_json):
engine_json = f'{manifest.get_this_engine_path()}/engine.json'
if not validation.valid_o3de_engine_json(engine_json):
logger.error(f"Engine json {engine_json} is not valid.")
return 1
with open(engine_json) as s:
try:
engine_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f"Failed to read engine json {engine_json}: {str(e)}")
return 1
try:
engine_restricted = engine_json_data['restricted']
except Exception as e:
engine_restricted = engine_json_data['restricted_name']
except KeyError as e:
logger.error(f"Engine json {engine_json} restricted not found.")
return 1
engine_restricted_folder = registration.get_registered(restricted_name=engine_restricted)
engine_restricted_folder = manifest.get_registered(restricted_name=engine_restricted)
new_source_restricted_path = f'{engine_restricted_folder}/{source_restricted_path}'
logger.info(f'Source restricted path {source_restricted_path} not a full path. We must assume this engines'
f' restricted folder {new_source_restricted_path}')
@@ -449,7 +449,7 @@ def create_template(source_path: str,
return 1
if template_restricted_name and not template_restricted_path:
template_restricted_path = registration.get_registered(restricted_name=template_restricted_name)
template_restricted_path = manifest.get_registered(restricted_name=template_restricted_name)
if not template_restricted_name:
template_restricted_name = template_name
@@ -458,7 +458,7 @@ def create_template(source_path: str,
if template_restricted_path:
template_restricted_path = template_restricted_path.replace('\\', '/')
if not os.path.isabs(template_restricted_path):
default_templates_restricted_folder = registration.get_registered(restricted_name='templates')
default_templates_restricted_folder = manifest.get_registered(restricted_name='templates')
new_template_restricted_path = f'{default_templates_restricted_folder}/{template_restricted_path}'
logger.info(f'Template restricted path {template_restricted_path} not a full path. We must assume the'
f' default templates restricted folder {new_template_restricted_path}')
@@ -466,21 +466,21 @@ def create_template(source_path: str,
if os.path.isdir(template_restricted_path):
# see if this is already a restricted path, if it is get the "restricted_name" from the restricted json
# so we can set "restricted" to it for this template
# so we can set "restricted_name" to it for this template
restricted_json = f'{template_restricted_path}/restricted.json'
if os.path.isfile(restricted_json):
if not registration.valid_o3de_restricted_json(restricted_json):
if not validation.valid_o3de_restricted_json(restricted_json):
logger.error(f'{restricted_json} is not valid.')
return 1
with open(restricted_json, 'r') as s:
try:
restricted_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Failed to load {restricted_json}: ' + str(e))
return 1
try:
template_restricted_name = restricted_json_data['restricted_name']
except Exception as e:
except KeyError as e:
logger.error(f'Failed to read restricted_name from {restricted_json}')
return 1
else:
@@ -928,7 +928,7 @@ def create_template(source_path: str,
json_data.update({'user_tags': [f"{template_name}"]})
json_data.update({'icon_path': "preview.png"})
if template_restricted_path:
json_data.update({'restricted': template_restricted_name})
json_data.update({'restricted_name': template_restricted_name})
if template_restricted_platform_relative_path != '':
json_data.update({'template_restricted_platform_relative_path': template_restricted_platform_relative_path})
json_data.update({'copyFiles': copy_files})
@@ -943,8 +943,7 @@ def create_template(source_path: str,
s.write(json.dumps(json_data, indent=4))
# copy the default preview.png
this_script_parent = os.path.dirname(os.path.realpath(__file__))
preview_png_src = f'{this_script_parent}/preview.png'
preview_png_src = f'{this_script_parent}/resources/preview.png'
preview_png_dst = f'{template_path}/Template/preview.png'
if not os.path.isfile(preview_png_dst):
shutil.copy(preview_png_src, preview_png_dst)
@@ -1048,7 +1047,7 @@ def create_from_template(destination_path: str,
return 1
if template_name:
template_path = registration.get_registered(template_name=template_name)
template_path = manifest.get_registered(template_name=template_name)
if not os.path.isdir(template_path):
logger.error(f'Could not find the template {template_name}=>{template_path}')
@@ -1059,7 +1058,7 @@ def create_from_template(destination_path: str,
# the template.json should be in the template_path, make sure it's there a nd valid
template_json = f'{template_path}/template.json'
if not registration.valid_o3de_template_json(template_json):
if not validation.valid_o3de_template_json(template_json):
logger.error(f'Template json {template_path} is invalid.')
return 1
@@ -1067,14 +1066,14 @@ def create_from_template(destination_path: str,
with open(template_json) as s:
try:
template_json_data = json.load(s)
except Exception as e:
except KeyError as e:
logger.error(f'Could read template json {template_json}: {str(e)}.')
return 1
# read template name from the json
try:
template_name = template_json_data['template_name']
except Exception as e:
except KeyError as e:
logger.error(f'Could not read "template_name" from template json {template_json}: {str(e)}.')
return 1
@@ -1082,57 +1081,57 @@ def create_from_template(destination_path: str,
# see if the template itself specifies a restricted name
if not template_restricted_name and not template_restricted_path:
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".')
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".')
else:
template_restricted_name = template_json_restricted_name
# if no restricted name or path we continue on as if there is no template restricted files.
if template_restricted_name or template_restricted_path:
# If the user specified a --template-restricted-name we need to check that against the templates
# 'restricted' if it has one and see if they match. If they match then we don't have a problem.
# 'restricted_name' if it has one and see if they match. If they match then we don't have a problem.
# If they don't then we error out. If supplied but not present in the template we warn and use it.
# If not supplied we set what's in the template. If not supplied and not in the template we continue
# on as if there is no template restricted files.
if template_restricted_name:
# The user specified a --template-restricted-name
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".'
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".'
f' Using supplied {template_restricted_name}')
else:
if template_json_restricted_name != template_restricted_name:
logger.error(
f'The supplied --template-restricted-name {template_restricted_name} does not match the'
f' templates "restricted". Either the the --template-restricted-name is incorrect or the'
f' templates "restricted" is wrong. Note that since this template specifies "restricted" as'
f' templates "restricted_name". Either the the --template-restricted-name is incorrect or the'
f' templates "restricted_name" is wrong. Note that since this template specifies "restricted_name" as'
f' {template_json_restricted_name}, --template-restricted-name need not be supplied.')
template_restricted_path = registration.get_registered(restricted_name=template_restricted_name)
template_restricted_path = manifest.get_registered(restricted_name=template_restricted_name)
else:
# The user has supplied the --template-restricted-path, see if that matches the template specifies.
# If it does then we do not have a problem. If it doesn't match then error out. If not specified
# in the template then warn and use the --template-restricted-path
template_restricted_path = template_restricted_path.replace('\\', '/')
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".'
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".'
f' Using supplied {template_restricted_path}')
else:
template_json_restricted_path = registration.get_registered(
template_json_restricted_path = manifest.get_registered(
restricted_name=template_json_restricted_name)
if template_json_restricted_path != template_restricted_path:
logger.error(
f'The supplied --template-restricted-path {template_restricted_path} does not match the'
f' templates "restricted" {template_restricted_name} => {template_json_restricted_path}.'
f' templates "restricted_name" {template_restricted_name} => {template_json_restricted_path}.'
f' Either the the supplied --template-restricted-path is incorrect or the templates'
f' "restricted" is wrong. Note that since this template specifies "restricted" as'
f' "restricted_name" is wrong. Note that since this template specifies "restricted_name" as'
f' {template_json_restricted_name} --template-restricted-path need not be supplied'
f' and {template_json_restricted_path} will be used.')
return 1
@@ -1154,7 +1153,7 @@ def create_from_template(destination_path: str,
try:
template_json_restricted_platform_relative_path = template_json_data[
'restricted_platform_relative_path']
except Exception as e:
except KeyError as e:
# the template json doesn't have a 'restricted_platform_relative_path' element warn and use it
logger.info(f'The template does not specify a "restricted_platform_relative_path".'
f' Using {template_restricted_platform_relative_path}')
@@ -1175,7 +1174,7 @@ def create_from_template(destination_path: str,
try:
template_restricted_platform_relative_path = template_json_data[
'restricted_platform_relative_path']
except Exception as e:
except KeyError as e:
# The template json doesn't have a 'restricted_platform_relative_path' element, set empty string.
template_restricted_platform_relative_path = ''
@@ -1203,19 +1202,19 @@ def create_from_template(destination_path: str,
# destination restricted name
if destination_restricted_name:
destination_restricted_path = registration.get_registered(restricted_name=destination_restricted_name)
destination_restricted_path = manifest.get_registered(restricted_name=destination_restricted_name)
# destination restricted path
elif destination_restricted_path:
destination_restricted_path = destination_restricted_path.replace('\\', '/')
if os.path.isabs(destination_restricted_path):
restricted_default_path = registration.get_registered(default='restricted')
restricted_default_path = manifest.get_registered(default='restricted')
new_destination_restricted_path = f'{restricted_default_path}/{destination_restricted_path}'
logger.info(f'{destination_restricted_path} is not a full path, making it relative'
f' to default restricted path = {new_destination_restricted_path}')
destination_restricted_path = new_destination_restricted_path
elif template_restricted_path:
restricted_default_path = registration.get_registered(default='restricted')
restricted_default_path = manifest.get_registered(default='restricted')
logger.info(f'--destination-restricted-path is not specified, using default restricted path / destination name'
f' = {restricted_default_path}')
destination_restricted_path = restricted_default_path
@@ -1337,7 +1336,7 @@ def create_project(project_path: str,
template_name = 'DefaultProject'
if template_name and not template_path:
template_path = registration.get_registered(template_name=template_name)
template_path = manifest.get_registered(template_name=template_name)
if not os.path.isdir(template_path):
logger.error(f'Could not find the template {template_name}=>{template_path}')
@@ -1348,7 +1347,7 @@ def create_project(project_path: str,
# the template.json should be in the template_path, make sure it's there and valid
template_json = f'{template_path}/template.json'
if not registration.valid_o3de_template_json(template_json):
if not validation.valid_o3de_template_json(template_json):
logger.error(f'Template json {template_path} is not valid.')
return 1
@@ -1356,14 +1355,14 @@ def create_project(project_path: str,
with open(template_json) as s:
try:
template_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Could read template json {template_json}: {str(e)}.')
return 1
# read template name from the json
try:
template_name = template_json_data['template_name']
except Exception as e:
except KeyError as e:
logger.error(f'Could not read "template_name" from template json {template_json}: {str(e)}.')
return 1
@@ -1371,57 +1370,57 @@ def create_project(project_path: str,
# see if the template itself specifies a restricted name
if not template_restricted_name and not template_restricted_path:
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".')
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".')
else:
template_restricted_name = template_json_restricted_name
# if no restricted name or path we continue on as if there is no template restricted files.
if template_restricted_name or template_restricted_path:
# If the user specified a --template-restricted-name we need to check that against the templates
# 'restricted' if it has one and see if they match. If they match then we don't have a problem.
# 'restricted_name' if it has one and see if they match. If they match then we don't have a problem.
# If they don't then we error out. If supplied but not present in the template we warn and use it.
# If not supplied we set what's in the template. If not supplied and not in the template we continue
# on as if there is no template restricted files.
if template_restricted_name and not template_restricted_path:
# The user specified a --template-restricted-name
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".'
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".'
f' Using supplied {template_restricted_name}')
else:
if template_json_restricted_name != template_restricted_name:
logger.error(
f'The supplied --template-restricted-name {template_restricted_name} does not match the'
f' templates "restricted". Either the the --template-restricted-name is incorrect or the'
f' templates "restricted" is wrong. Note that since this template specifies "restricted" as'
f' templates "restricted_name". Either the the --template-restricted-name is incorrect or the'
f' templates "restricted_name" is wrong. Note that since this template specifies "restricted_name" as'
f' {template_json_restricted_name}, --template-restricted-name need not be supplied.')
template_restricted_path = registration.get_registered(restricted_name=template_restricted_name)
template_restricted_path = manifest.get_registered(restricted_name=template_restricted_name)
else:
# The user has supplied the --template-restricted-path, see if that matches the template specifies.
# If it does then we do not have a problem. If it doesn't match then error out. If not specified
# in the template then warn and use the --template-restricted-path
template_restricted_path = template_restricted_path.replace('\\', '/')
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".'
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".'
f' Using supplied {template_restricted_path}')
else:
template_json_restricted_path = registration.get_registered(
template_json_restricted_path = manifest.get_registered(
restricted_name=template_json_restricted_name)
if template_json_restricted_path != template_restricted_path:
logger.error(
f'The supplied --template-restricted-path {template_restricted_path} does not match the'
f' templates "restricted" {template_restricted_name} => {template_json_restricted_path}.'
f' templates "restricted_name" {template_restricted_name} => {template_json_restricted_path}.'
f' Either the the supplied --template-restricted-path is incorrect or the templates'
f' "restricted" is wrong. Note that since this template specifies "restricted" as'
f' "restricted_name" is wrong. Note that since this template specifies "restricted_name" as'
f' {template_json_restricted_name} --template-restricted-path need not be supplied'
f' and {template_json_restricted_path} will be used.')
return 1
@@ -1442,7 +1441,7 @@ def create_project(project_path: str,
try:
template_json_restricted_platform_relative_path = template_json_data[
'restricted_platform_relative_path']
except Exception as e:
except KeyError as e:
# the template json doesn't have a 'restricted_platform_relative_path' element warn and use it
logger.info(f'The template does not specify a "restricted_platform_relative_path".'
f' Using {template_restricted_platform_relative_path}')
@@ -1463,7 +1462,7 @@ def create_project(project_path: str,
try:
template_restricted_platform_relative_path = template_json_data[
'restricted_platform_relative_path']
except Exception as e:
except KeyError as e:
# The template json doesn't have a 'restricted_platform_relative_path' element, set empty string.
template_restricted_platform_relative_path = ''
if not template_restricted_platform_relative_path:
@@ -1475,7 +1474,7 @@ def create_project(project_path: str,
return 1
project_path = project_path.replace('\\', '/')
if not os.path.isabs(project_path):
default_projects_folder = registration.get_registered(default_folder='projects')
default_projects_folder = manifest.get_registered(default_folder='projects')
new_project_path = f'{default_projects_folder}/{project_path}'
logger.info(f'Project Path {project_path} is not a full path, we must assume its relative'
f' to default projects path = {new_project_path}')
@@ -1496,19 +1495,19 @@ def create_project(project_path: str,
# project restricted name
if project_restricted_name and not project_restricted_path:
project_restricted_path = registration.get_registered(restricted_name=project_restricted_name)
project_restricted_path = manifest.get_registered(restricted_name=project_restricted_name)
# project restricted path
elif project_restricted_path:
project_restricted_path = project_restricted_path.replace('\\', '/')
if not os.path.isabs(project_restricted_path):
default_projects_restricted_folder = registration.get_registered(restricted_name='projects')
default_projects_restricted_folder = manifest.get_registered(restricted_name='projects')
new_project_restricted_path = f'{default_projects_restricted_folder}/{project_restricted_path}'
logger.info(f'Project restricted path {project_restricted_path} is not a full path, we must assume its'
f' relative to default projects restricted path = {new_project_restricted_path}')
project_restricted_path = new_project_restricted_path
elif template_restricted_path:
project_restricted_default_path = registration.get_registered(restricted_name='projects')
project_restricted_default_path = manifest.get_registered(restricted_name='projects')
logger.info(f'--project-restricted-path is not specified, using default project restricted path / project name'
f' = {project_restricted_default_path}')
project_restricted_path = project_restricted_default_path
@@ -1585,7 +1584,7 @@ def create_project(project_path: str,
# read the restricted_name from the projects restricted.json
restricted_json = f"{project_restricted_path}/restricted.json".replace('//', '/')
if os.path.isfile(restricted_json):
if not registration.valid_o3de_restricted_json(restricted_json):
if not validation.valid_o3de_restricted_json(restricted_json):
logger.error(f'Restricted json {restricted_json} is not valid.')
return 1
else:
@@ -1597,35 +1596,35 @@ def create_project(project_path: str,
with open(restricted_json, 'r') as s:
try:
restricted_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Failed to load restricted json {restricted_json}.')
return 1
try:
restricted_name = restricted_json_data["restricted_name"]
except Exception as e:
except KeyError as e:
logger.error(f'Failed to read "restricted_name" from restricted json {restricted_json}.')
return 1
# set the "restricted": "restricted_name" element of the project.json
# set the "restricted_name": "restricted_name" element of the project.json
project_json = f"{project_path}/project.json".replace('//', '/')
if not registration.valid_o3de_project_json(project_json):
if not validation.valid_o3de_project_json(project_json):
logger.error(f'Project json {project_json} is not valid.')
return 1
with open(project_json, 'r') as s:
try:
project_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Failed to load project json {project_json}.')
return 1
project_json_data.update({"restricted": restricted_name})
project_json_data.update({"restricted_name": restricted_name})
os.unlink(project_json)
with open(project_json, 'w') as s:
try:
s.write(json.dumps(project_json_data, indent=4))
except Exception as e:
except OSError as e:
logger.error(f'Failed to write project json {project_json}.')
return 1
@@ -1653,43 +1652,20 @@ def create_project(project_path: str,
d.write('# {END_LICENSE}\n')
# set the "engine" element of the project.json
engine_json = f'{registration.get_this_engine_path()}/engine.json'
if not registration.valid_o3de_engine_json(engine_json):
logger.error(f"Engine json {engine_json} is not valid.")
engine_json_data = manifest.get_engine_json_data(engine_path=manifest.get_this_engine_path())
try:
engine_name = engine_json_data['engine_name']
except KeyError as e:
logger.error(f"engine_name for this engine not found in engine.json.")
return 1
with open(engine_json) as s:
try:
engine_json_data = json.load(s)
except Exception as e:
logger.error(f"Failed to read engine json {engine_json}: {str(e)}")
return 1
try:
engine_name = engine_json_data['engine_name']
except Exception as e:
logger.error(f"Engine json {engine_json} engine_name not found.")
return 1
project_json = f"{project_path}/project.json".replace('//', '/')
if not registration.valid_o3de_project_json(project_json):
logger.error(f'Project json {project_json} is not valid.')
return 1
with open(project_json, 'r') as s:
try:
project_json_data = json.load(s)
except Exception as e:
logger.error(f'Failed to load project json {project_json}.')
return 1
project_json_data = manifest.get_project_json_data(project_path=project_path)
project_json_data.update({"engine": engine_name})
os.unlink(project_json)
with open(project_json, 'w') as s:
try:
s.write(json.dumps(project_json_data, indent=4))
except Exception as e:
logger.error(f'Failed to write project json {project_json}.')
except OSError as e:
logger.error(f'Failed to write project json at {project_path}.')
return 1
return 0
@@ -1753,7 +1729,7 @@ def create_gem(gem_path: str,
template_name = 'DefaultGem'
if template_name and not template_path:
template_path = registration.get_registered(template_name=template_name)
template_path = manifest.get_registered(template_name=template_name)
if not os.path.isdir(template_path):
logger.error(f'Could not find the template {template_name}=>{template_path}')
@@ -1764,7 +1740,7 @@ def create_gem(gem_path: str,
# the template.json should be in the template_path, make sure it's there and valid
template_json = f'{template_path}/template.json'
if not registration.valid_o3de_template_json(template_json):
if not validation.valid_o3de_template_json(template_json):
logger.error(f'Template json {template_path} is not valid.')
return 1
@@ -1772,14 +1748,14 @@ def create_gem(gem_path: str,
with open(template_json) as s:
try:
template_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Could read template json {template_json}: {str(e)}.')
return 1
# read template name from the json
try:
template_name = template_json_data['template_name']
except Exception as e:
except KeyError as e:
logger.error(f'Could not read "template_name" from template json {template_json}: {str(e)}.')
return 1
@@ -1787,56 +1763,56 @@ def create_gem(gem_path: str,
# see if the template itself specifies a restricted name
if not template_restricted_name and not template_restricted_path:
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".')
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".')
else:
template_restricted_name = template_json_restricted_name
# if no restricted name or path we continue on as if there is no template restricted files.
if template_restricted_name or template_restricted_path:
# if the user specified a --template-restricted-name we need to check that against the templates 'restricted'
# if the user specified a --template-restricted-name we need to check that against the templates 'restricted_name'
# if it has one and see if they match. If they match then we don't have a problem. If they don't then we error
# out. If supplied but not present in the template we warn and use it. If not supplied we set what's in the
# template. If not supplied and not in the template we continue on as if there is no template restricted files.
if template_restricted_name and not template_restricted_path:
# The user specified a --template-restricted-name
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".'
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".'
f' Using supplied {template_restricted_name}')
else:
if template_json_restricted_name != template_restricted_name:
logger.error(
f'The supplied --template-restricted-name {template_restricted_name} does not match the'
f' templates "restricted". Either the the --template-restricted-name is incorrect or the'
f' templates "restricted" is wrong. Note that since this template specifies "restricted" as'
f' templates "restricted_name". Either the the --template-restricted-name is incorrect or the'
f' templates "restricted_name" is wrong. Note that since this template specifies "restricted_name" as'
f' {template_json_restricted_name}, --template-restricted-name need not be supplied.')
template_restricted_path = registration.get_registered(restricted_name=template_restricted_name)
template_restricted_path = manifest.get_registered(restricted_name=template_restricted_name)
else:
# The user has supplied the --template-restricted-path, see if that matches the template specifies.
# If it does then we do not have a problem. If it doesn't match then error out. If not specified
# in the template then warn and use the --template-restricted-path
template_restricted_path = template_restricted_path.replace('\\', '/')
try:
template_json_restricted_name = template_json_data['restricted']
except Exception as e:
# the template json doesn't have a 'restricted' element warn and use it
logger.info(f'The template does not specify a "restricted".'
template_json_restricted_name = template_json_data['restricted_name']
except KeyError as e:
# the template json doesn't have a 'restricted_name' element warn and use it
logger.info(f'The template does not specify a "restricted_name".'
f' Using supplied {template_restricted_path}')
else:
template_json_restricted_path = registration.get_registered(
template_json_restricted_path = manifest.get_registered(
restricted_name=template_json_restricted_name)
if template_json_restricted_path != template_restricted_path:
logger.error(
f'The supplied --template-restricted-path {template_restricted_path} does not match the'
f' templates "restricted" {template_restricted_name} => {template_json_restricted_path}.'
f' templates "restricted_name" {template_restricted_name} => {template_json_restricted_path}.'
f' Either the the supplied --template-restricted-path is incorrect or the templates'
f' "restricted" is wrong. Note that since this template specifies "restricted" as'
f' "restricted_name" is wrong. Note that since this template specifies "restricted_name" as'
f' {template_json_restricted_name} --template-restricted-path need not be supplied'
f' and {template_json_restricted_path} will be used.')
return 1
@@ -1856,7 +1832,7 @@ def create_gem(gem_path: str,
try:
template_json_restricted_platform_relative_path = template_json_data[
'restricted_platform_relative_path']
except Exception as e:
except KeyError as e:
# the template json doesn't have a 'restricted_platform_relative_path' element warn and use it
logger.info(f'The template does not specify a "restricted_platform_relative_path".'
f' Using {template_restricted_platform_relative_path}')
@@ -1877,7 +1853,7 @@ def create_gem(gem_path: str,
try:
template_restricted_platform_relative_path = template_json_data[
'restricted_platform_relative_path']
except Exception as e:
except KeyError as e:
# The template json doesn't have a 'restricted_platform_relative_path' element, set empty string.
template_restricted_platform_relative_path = ''
if not template_restricted_platform_relative_path:
@@ -1889,7 +1865,7 @@ def create_gem(gem_path: str,
return 1
gem_path = gem_path.replace('\\', '/')
if not os.path.isabs(gem_path):
default_gems_folder = registration.get_registered(default_folder='gems')
default_gems_folder = manifest.get_registered(default_folder='gems')
new_gem_path = f'{default_gems_folder}/{gem_path}'
logger.info(f'Gem Path {gem_path} is not a full path, we must assume its relative'
f' to default gems path = {new_gem_path}')
@@ -1910,19 +1886,19 @@ def create_gem(gem_path: str,
# gem restricted name
if gem_restricted_name and not gem_restricted_path:
gem_restricted_path = registration.get_registered(restricted_name=gem_restricted_name)
gem_restricted_path = manifest.get_registered(restricted_name=gem_restricted_name)
# gem restricted path
elif gem_restricted_path:
gem_restricted_path = gem_restricted_path.replace('\\', '/')
if not os.path.isabs(gem_restricted_path):
default_gems_restricted_folder = registration.get_registered(restricted_name='gems')
default_gems_restricted_folder = manifest.get_registered(restricted_name='gems')
new_gem_restricted_path = f'{default_gems_restricted_folder}/{gem_restricted_path}'
logger.info(f'Gem restricted path {gem_restricted_path} is not a full path, we must assume its'
f' relative to default gems restricted path = {new_gem_restricted_path}')
gem_restricted_path = new_gem_restricted_path
elif template_restricted_path:
gem_restricted_default_path = registration.get_registered(restricted_name='gems')
gem_restricted_default_path = manifest.get_registered(restricted_name='gems')
logger.info(f'--gem-restricted-path is not specified, using default gem restricted path / gem name'
f' = {gem_restricted_default_path}')
gem_restricted_path = gem_restricted_default_path
@@ -1999,7 +1975,7 @@ def create_gem(gem_path: str,
# read the restricted_name from the gems restricted.json
restricted_json = f"{gem_restricted_path}/restricted.json".replace('//', '/')
if os.path.isfile(restricted_json):
if not registration.valid_o3de_restricted_json(restricted_json):
if not validation.valid_o3de_restricted_json(restricted_json):
logger.error(f'Restricted json {restricted_json} is not valid.')
return 1
else:
@@ -2011,35 +1987,35 @@ def create_gem(gem_path: str,
with open(restricted_json, 'r') as s:
try:
restricted_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Failed to load restricted json {restricted_json}.')
return 1
try:
restricted_name = restricted_json_data["restricted_name"]
except Exception as e:
except KeyError as e:
logger.error(f'Failed to read "restricted_name" from restricted json {restricted_json}.')
return 1
# set the "restricted": "restricted_name" element of the gem.json
# set the "restricted_name": "restricted_name" element of the gem.json
gem_json = f"{gem_path}/gem.json".replace('//', '/')
if not registration.valid_o3de_gem_json(gem_json):
if not validation.valid_o3de_gem_json(gem_json):
logger.error(f'Gem json {gem_json} is not valid.')
return 1
with open(gem_json, 'r') as s:
try:
gem_json_data = json.load(s)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Failed to load gem json {gem_json}.')
return 1
gem_json_data.update({"restricted": restricted_name})
gem_json_data.update({"restricted_name": restricted_name})
os.unlink(gem_json)
with open(gem_json, 'w') as s:
try:
s.write(json.dumps(gem_json_data, indent=4))
except Exception as e:
except OSError as e:
logger.error(f'Failed to write project json {gem_json}.')
return 1
@@ -2133,15 +2109,14 @@ def _run_create_gem(args: argparse) -> int:
args.module_id)
def add_args(parser, subparsers) -> None:
def add_args(subparsers) -> None:
"""
add_args is called to add expected parser arguments and subparsers arguments to each command such that it can be
invoked locally or aggregated by a central python file.
Ex. Directly run from this file alone with: python engine_template.py create_gem --gem-path TestGem
Ex. Directly run from this file alone with: python engine_template.py create-gem --gem-path TestGem
OR
o3de.py can aggregate commands by importing engine_template,
call add_args and execute: python o3de.py create_gem --gem-path TestGem
:param parser: the caller instantiates a parser and passes it in here
call add_args and execute: python o3de.py create-gem --gem-path TestGem
:param subparsers: the caller instantiates subparsers and passes it in here
"""
# turn a directory into a template
@@ -2151,7 +2126,7 @@ def add_args(parser, subparsers) -> None:
create_template_subparser.add_argument('-tp', '--template-path', type=str, required=False,
help='The path to the template to create, can be absolute or relative'
' to default templates path')
group = create_template_subparser.add_mutually_exclusive_group(required=True)
group = create_template_subparser.add_mutually_exclusive_group(required=False)
group.add_argument('-srp', '--source-restricted-path', type=str, required=False,
default=None,
help='The path to the source restricted folder.')
@@ -2160,7 +2135,7 @@ def add_args(parser, subparsers) -> None:
help='The name of the source restricted folder. If supplied this will resolve'
' the --source-restricted-path.')
group = create_template_subparser.add_mutually_exclusive_group(required=True)
group = create_template_subparser.add_mutually_exclusive_group(required=False)
group.add_argument('-trp', '--template-restricted-path', type=str, required=False,
default=None,
help='The path to the templates restricted folder.')
@@ -2461,13 +2436,12 @@ if __name__ == "__main__":
the_subparsers = the_parser.add_subparsers(help='sub-command help', dest='command', required=True)
# add args to the parser
add_args(the_parser, the_subparsers)
add_args(the_subparsers)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
+96
View File
@@ -0,0 +1,96 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import pathlib
import sys
from o3de import manifest
def _run_get_registered(args: argparse) -> str or pathlib.Path:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
return manifest.get_registered(args.engine_name,
args.project_name,
args.gem_name,
args.template_name,
args.default_folder,
args.repo_name,
args.restricted_name)
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python get_registration.py --engine-name "o3de"
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-en', '--engine-name', type=str, required=False,
help='Engine name.')
group.add_argument('-pn', '--project-name', type=str, required=False,
help='Project name.')
group.add_argument('-gn', '--gem-name', type=str, required=False,
help='Gem name.')
group.add_argument('-tn', '--template-name', type=str, required=False,
help='Template name.')
group.add_argument('-df', '--default-folder', type=str, required=False,
choices=['engines', 'projects', 'gems', 'templates', 'restricted'],
help='The default folders for o3de.')
group.add_argument('-rn', '--repo-name', type=str, required=False,
help='Repo name.')
group.add_argument('-rsn', '--restricted-name', type=str, required=False,
help='Restricted name.')
parser.add_argument('-ohf', '--override-home-folder', type=str, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.set_defaults(func=_run_get_registered)
def add_args(subparsers) -> None:
"""
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py get-registered --engine-name "o3de"
:param subparsers: the caller instantiates subparsers and passes it in here
"""
get_registered_subparser = subparsers.add_parser('get-registered')
add_parser_args(get_registered_subparser)
def main():
"""
Runs get_registration.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()
# add subparsers
# add args to the parser
add_parser_args(the_parser)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
sys.exit(ret)
if __name__ == "__main__":
main()
+13 -14
View File
@@ -16,7 +16,7 @@ import sys
import re
import pathlib
import json
from o3de import registration
from o3de import manifest
logger = logging.getLogger()
logging.basicConfig()
@@ -39,7 +39,7 @@ def set_global_project(project_name: str or None,
return 1
if project_name and not project_path:
project_path = registration.get_registered(project_name=project_name)
project_path = manifest.get_registered(project_name=project_name)
if not project_path:
logger.error(f'Project Path {project_path} has not been registered.')
@@ -47,22 +47,22 @@ def set_global_project(project_name: str or None,
project_path = pathlib.Path(project_path).resolve()
bootstrap_setreg_file = registration.get_o3de_registry_folder() / 'bootstrap.setreg'
bootstrap_setreg_file = manifest.get_o3de_registry_folder() / 'bootstrap.setreg'
if bootstrap_setreg_file.is_file():
with bootstrap_setreg_file.open('r') as f:
try:
json_data = json.load(f)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Bootstrap.setreg failed to load: {str(e)}')
else:
try:
json_data["Amazon"]["AzCore"]["Bootstrap"]["project_path"] = project_path
except Exception as e:
except KeyError as e:
logger.error(f'Bootstrap.setreg failed to load: {str(e)}')
else:
try:
os.unlink(bootstrap_setreg_file)
except Exception as e:
except OSError as e:
logger.error(f'Failed to unlink bootstrap file {bootstrap_setreg_file}: {str(e)}')
return 1
else:
@@ -80,7 +80,7 @@ def get_global_project() -> pathlib.Path or None:
get what the current project set is
:return: project_path or None on failure
"""
bootstrap_setreg_file = registration.get_o3de_registry_folder() / 'bootstrap.setreg'
bootstrap_setreg_file = manifest.get_o3de_registry_folder() / 'bootstrap.setreg'
if not bootstrap_setreg_file.is_file():
logger.error(f'Bootstrap.setreg file {bootstrap_setreg_file} does not exist.')
return None
@@ -88,12 +88,12 @@ def get_global_project() -> pathlib.Path or None:
with bootstrap_setreg_file.open('r') as f:
try:
json_data = json.load(f)
except Exception as e:
except json.JSONDecodeError as e:
logger.error(f'Bootstrap.setreg failed to load: {str(e)}')
else:
try:
project_path = json_data["Amazon"]["AzCore"]["Bootstrap"]["project_path"]
except Exception as e:
except KeyError as e:
logger.error(f'Bootstrap.setreg cannot find Amazon:AzCore:Bootstrap:project_path: {str(e)}')
else:
return pathlib.Path(project_path).resolve()
@@ -101,7 +101,7 @@ def get_global_project() -> pathlib.Path or None:
def _run_get_global_project(args: argparse) -> int:
if args.override_home_folder:
registration.override_home_folder = args.override_home_folder
manifest.override_home_folder = args.override_home_folder
project_path = get_global_project()
if project_path:
@@ -112,13 +112,13 @@ def _run_get_global_project(args: argparse) -> int:
def _run_set_global_project(args: argparse) -> int:
if args.override_home_folder:
registration.override_home_folder = args.override_home_folder
manifest.override_home_folder = args.override_home_folder
return set_global_project(args.project_name,
args.project_path)
def add_args(parser, subparsers) -> None:
def add_args(subparsers) -> None:
"""
add_args is called to add expected parser arguments and subparsers arguments to each command such that it can be
invoked locally or aggregated by a central python file.
@@ -126,7 +126,6 @@ def add_args(parser, subparsers) -> None:
OR
o3de.py can aggregate commands by importing global_project, call add_args and
execute: python o3de.py set_global_project --project-path C:/TestProject
:param parser: the caller instantiates a parser and passes it in here
:param subparsers: the caller instantiates subparsers and passes it in here
"""
get_global_project_subparser = subparsers.add_parser('get-global-project')
@@ -156,7 +155,7 @@ if __name__ == "__main__":
the_subparsers = the_parser.add_subparsers(help='sub-command help', dest='command', required=True)
# add args to the parser
add_args(the_parser, the_subparsers)
add_args(the_subparsers)
# parse args
the_args = the_parser.parse_args()
+638
View File
@@ -0,0 +1,638 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
"""
Contains functions for data from json files such as the o3de_manifests.json, engine.json, project.json, etc...
"""
import json
import logging
import os
import pathlib
from o3de import validation
logger = logging.getLogger()
logging.basicConfig()
# Directory methods
override_home_folder = None
def get_this_engine_path() -> pathlib.Path:
return pathlib.Path(os.path.realpath(__file__)).parents[3].resolve()
def get_home_folder() -> pathlib.Path:
if override_home_folder:
return pathlib.Path(override_home_folder).resolve()
else:
return pathlib.Path(os.path.expanduser("~")).resolve()
def get_o3de_folder() -> pathlib.Path:
o3de_folder = get_home_folder() / '.o3de'
o3de_folder.mkdir(parents=True, exist_ok=True)
return o3de_folder
def get_o3de_registry_folder() -> pathlib.Path:
registry_folder = get_o3de_folder() / 'Registry'
registry_folder.mkdir(parents=True, exist_ok=True)
return registry_folder
def get_o3de_cache_folder() -> pathlib.Path:
cache_folder = get_o3de_folder() / 'Cache'
cache_folder.mkdir(parents=True, exist_ok=True)
return cache_folder
def get_o3de_download_folder() -> pathlib.Path:
download_folder = get_o3de_folder() / 'Download'
download_folder.mkdir(parents=True, exist_ok=True)
return download_folder
def get_o3de_engines_folder() -> pathlib.Path:
engines_folder = get_o3de_folder() / 'Engines'
engines_folder.mkdir(parents=True, exist_ok=True)
return engines_folder
def get_o3de_projects_folder() -> pathlib.Path:
projects_folder = get_o3de_folder() / 'Projects'
projects_folder.mkdir(parents=True, exist_ok=True)
return projects_folder
def get_o3de_gems_folder() -> pathlib.Path:
gems_folder = get_o3de_folder() / 'Gems'
gems_folder.mkdir(parents=True, exist_ok=True)
return gems_folder
def get_o3de_templates_folder() -> pathlib.Path:
templates_folder = get_o3de_folder() / 'Templates'
templates_folder.mkdir(parents=True, exist_ok=True)
return templates_folder
def get_o3de_restricted_folder() -> pathlib.Path:
restricted_folder = get_o3de_folder() / 'Restricted'
restricted_folder.mkdir(parents=True, exist_ok=True)
return restricted_folder
def get_o3de_logs_folder() -> pathlib.Path:
logs_folder = get_o3de_folder() / 'Logs'
logs_folder.mkdir(parents=True, exist_ok=True)
return logs_folder
# o3de manifest file methods
def get_o3de_manifest() -> pathlib.Path:
manifest_path = get_o3de_folder() / 'o3de_manifest.json'
if not manifest_path.is_file():
username = os.path.split(get_home_folder())[-1]
o3de_folder = get_o3de_folder()
default_registry_folder = get_o3de_registry_folder()
default_cache_folder = get_o3de_cache_folder()
default_downloads_folder = get_o3de_download_folder()
default_logs_folder = get_o3de_logs_folder()
default_engines_folder = get_o3de_engines_folder()
default_projects_folder = get_o3de_projects_folder()
default_gems_folder = get_o3de_gems_folder()
default_templates_folder = get_o3de_templates_folder()
default_restricted_folder = get_o3de_restricted_folder()
default_projects_restricted_folder = default_projects_folder / 'Restricted'
default_projects_restricted_folder.mkdir(parents=True, exist_ok=True)
default_gems_restricted_folder = default_gems_folder / 'Restricted'
default_gems_restricted_folder.mkdir(parents=True, exist_ok=True)
default_templates_restricted_folder = default_templates_folder / 'Restricted'
default_templates_restricted_folder.mkdir(parents=True, exist_ok=True)
json_data = {}
json_data.update({'o3de_manifest_name': f'{username}'})
json_data.update({'origin': o3de_folder.as_posix()})
json_data.update({'default_engines_folder': default_engines_folder.as_posix()})
json_data.update({'default_projects_folder': default_projects_folder.as_posix()})
json_data.update({'default_gems_folder': default_gems_folder.as_posix()})
json_data.update({'default_templates_folder': default_templates_folder.as_posix()})
json_data.update({'default_restricted_folder': default_restricted_folder.as_posix()})
json_data.update({'projects': []})
json_data.update({'external_subdirectories': []})
json_data.update({'templates': []})
json_data.update({'restricted': []})
json_data.update({'repos': []})
json_data.update({'engines': []})
default_restricted_folder_json = default_restricted_folder / 'restricted.json'
if not default_restricted_folder_json.is_file():
with default_restricted_folder_json.open('w') as s:
restricted_json_data = {}
restricted_json_data.update({'restricted_name': 'o3de'})
s.write(json.dumps(restricted_json_data, indent=4))
json_data.update({'default_restricted_folder': default_restricted_folder.as_posix()})
default_projects_restricted_folder_json = default_projects_restricted_folder / 'restricted.json'
if not default_projects_restricted_folder_json.is_file():
with default_projects_restricted_folder_json.open('w') as s:
restricted_json_data = {}
restricted_json_data.update({'restricted_name': 'projects'})
s.write(json.dumps(restricted_json_data, indent=4))
default_gems_restricted_folder_json = default_gems_restricted_folder / 'restricted.json'
if not default_gems_restricted_folder_json.is_file():
with default_gems_restricted_folder_json.open('w') as s:
restricted_json_data = {}
restricted_json_data.update({'restricted_name': 'gems'})
s.write(json.dumps(restricted_json_data, indent=4))
default_templates_restricted_folder_json = default_templates_restricted_folder / 'restricted.json'
if not default_templates_restricted_folder_json.is_file():
with default_templates_restricted_folder_json.open('w') as s:
restricted_json_data = {}
restricted_json_data.update({'restricted_name': 'templates'})
s.write(json.dumps(restricted_json_data, indent=4))
with manifest_path.open('w') as s:
s.write(json.dumps(json_data, indent=4))
return manifest_path
def load_o3de_manifest(manifest_path: pathlib.Path = None) -> dict:
"""
Loads supplied manifest file or ~/.o3de/o3de_manifest.json if None
:param manifest_path: optional path to manifest file to load
"""
if not manifest_path:
manifest_path = get_o3de_manifest()
with manifest_path.open('r') as f:
try:
json_data = json.load(f)
except json.JSONDecodeError as e:
logger.error(f'Manifest json failed to load: {str(e)}')
return {}
else:
return json_data
def save_o3de_manifest(json_data: dict, manifest_path: pathlib.Path = None) -> None:
"""
Save the json dictionary to the supplied manifest file or ~/.o3de/o3de_manifest.json if None
:param json_data: dictionary to save in json format at the file path
:param manifest_path: optional path to manifest file to save
"""
if not manifest_path:
manifest_path = get_o3de_manifest()
with manifest_path.open('w') as s:
try:
s.write(json.dumps(json_data, indent=4))
except OSError as e:
logger.error(f'Manifest json failed to save: {str(e)}')
# Data query methods
def get_this_engine() -> dict:
json_data = load_o3de_manifest()
engine_data = find_engine_data(json_data)
return engine_data
def get_engines() -> list:
json_data = load_o3de_manifest()
return json_data['engines']
def get_projects() -> list:
json_data = load_o3de_manifest()
return json_data['projects']
def get_gems() -> list:
def is_gem_subdirectory(subdir):
return (pathlib.Path(subdir) / 'gem.json').exists()
external_subdirs = get_external_subdirectories()
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_templates() -> list:
json_data = load_o3de_manifest()
return json_data['templates']
def get_restricted() -> list:
json_data = load_o3de_manifest()
return json_data['restricted']
def get_external_subdirectories() -> list:
json_data = load_o3de_manifest()
return json_data['external_subdirectories']
def get_repos() -> list:
json_data = load_o3de_manifest()
return json_data['repos']
# engine.json queries
def get_engine_projects() -> list:
engine_path = get_this_engine_path()
engine_object = get_engine_json_data(engine_path=engine_path)
return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(),
engine_object['projects'])) if 'projects' in engine_object else []
def get_engine_gems() -> list:
def is_gem_subdirectory(subdir):
return (pathlib.Path(subdir) / 'gem.json').exists()
external_subdirs = get_engine_external_subdirectories()
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_engine_templates() -> list:
engine_path = get_this_engine_path()
engine_object = get_engine_json_data(engine_path=engine_path)
return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(),
engine_object['templates']))
def get_engine_restricted() -> list:
engine_path = get_this_engine_path()
engine_object = get_engine_json_data(engine_path=engine_path)
return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(),
engine_object['restricted'])) if 'restricted' in engine_object else []
def get_engine_external_subdirectories() -> list:
engine_path = get_this_engine_path()
engine_object = get_engine_json_data(engine_path=engine_path)
return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(),
engine_object['external_subdirectories'])) if 'external_subdirectories' in engine_object else []
# project.json queries
def get_project_gems(project_path: pathlib.Path) -> list:
def is_gem_subdirectory(subdir):
return (pathlib.Path(subdir) / 'gem.json').exists()
external_subdirs = get_project_external_subdirectories()
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_project_external_subdirectories(project_path: pathlib.Path) -> list:
project_object = get_project_json_data(project_path=project_path)
return list(map(lambda rel_path: (pathlib.Path(project_path) / rel_path).as_posix(),
project_object['external_subdirectories'])) if 'external_subdirectories' in project_object else []
def get_all_projects() -> list:
engine_projects = get_engine_projects()
projects_data = get_projects()
projects_data.extend(engine_projects)
return projects_data
def get_all_gems() -> list:
engine_gems = get_engine_gems()
gems_data = get_gems()
gems_data.extend(engine_gems)
return gems_data
def get_all_templates() -> list:
engine_templates = get_engine_templates()
templates_data = get_templates()
templates_data.extend(engine_templates)
return templates_data
def get_all_restricted() -> list:
engine_restricted = get_engine_restricted()
restricted_data = get_restricted()
restricted_data.extend(engine_restricted)
return restricted_data
def find_engine_data(json_data: dict,
engine_path: str or pathlib.Path = None) -> dict or None:
if not engine_path:
engine_path = get_this_engine_path()
engine_path = pathlib.Path(engine_path).resolve()
for engine_object in json_data['engines']:
engine_object_path = pathlib.Path(engine_object['path']).resolve()
if engine_path == engine_object_path:
return engine_object
return None
def get_engine_json_data(engine_name: str = None,
engine_path: str or pathlib.Path = None) -> dict or None:
if not engine_name and not engine_path:
logger.error('Must specify either a Engine name or Engine Path.')
return None
if engine_name and not engine_path:
engine_path = get_registered(engine_name=engine_name)
if not engine_path:
logger.error(f'Engine Path {engine_path} has not been registered.')
return None
engine_path = pathlib.Path(engine_path).resolve()
engine_json = engine_path / 'engine.json'
if not engine_json.is_file():
logger.error(f'Engine json {engine_json} is not present.')
return None
if not validation.valid_o3de_engine_json(engine_json):
logger.error(f'Engine json {engine_json} is not valid.')
return None
with engine_json.open('r') as f:
try:
engine_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{engine_json} failed to load: {str(e)}')
else:
return engine_json_data
return None
def get_project_json_data(project_name: str = None,
project_path: str or pathlib.Path = None) -> dict or None:
if not project_name and not project_path:
logger.error('Must specify either a Project name or Project Path.')
return None
if project_name and not project_path:
project_path = get_registered(project_name=project_name)
if not project_path:
logger.error(f'Project Path {project_path} has not been registered.')
return None
project_path = pathlib.Path(project_path).resolve()
project_json = project_path / 'project.json'
if not project_json.is_file():
logger.error(f'Project json {project_json} is not present.')
return None
if not validation.valid_o3de_project_json(project_json):
logger.error(f'Project json {project_json} is not valid.')
return None
with project_json.open('r') as f:
try:
project_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{project_json} failed to load: {str(e)}')
else:
return project_json_data
return None
def get_gem_json_data(gem_name: str = None,
gem_path: str or pathlib.Path = None) -> dict or None:
if not gem_name and not gem_path:
logger.error('Must specify either a Gem name or Gem Path.')
return None
if gem_name and not gem_path:
gem_path = get_registered(gem_name=gem_name)
if not gem_path:
logger.error(f'Gem Path {gem_path} has not been registered.')
return None
gem_path = pathlib.Path(gem_path).resolve()
gem_json = gem_path / 'gem.json'
if not gem_json.is_file():
logger.error(f'Gem json {gem_json} is not present.')
return None
if not validation.valid_o3de_gem_json(gem_json):
logger.error(f'Gem json {gem_json} is not valid.')
return None
with gem_json.open('r') as f:
try:
gem_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{gem_json} failed to load: {str(e)}')
else:
return gem_json_data
return None
def get_template_json_data(template_name: str = None,
template_path: str or pathlib.Path = None) -> dict or None:
if not template_name and not template_path:
logger.error('Must specify either a Template name or Template Path.')
return None
if template_name and not template_path:
template_path = get_registered(template_name=template_name)
if not template_path:
logger.error(f'Template Path {template_path} has not been registered.')
return None
template_path = pathlib.Path(template_path).resolve()
template_json = template_path / 'template.json'
if not template_json.is_file():
logger.error(f'Template json {template_json} is not present.')
return None
if not validation.valid_o3de_template_json(template_json):
logger.error(f'Template json {template_json} is not valid.')
return None
with template_json.open('r') as f:
try:
template_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{template_json} failed to load: {str(e)}')
else:
return template_json_data
return None
def get_restricted_data(restricted_name: str = None,
restricted_path: str or pathlib.Path = None) -> dict or None:
if not restricted_name and not restricted_path:
logger.error('Must specify either a Restricted name or Restricted Path.')
return None
if restricted_name and not restricted_path:
restricted_path = get_registered(restricted_name=restricted_name)
if not restricted_path:
logger.error(f'Restricted Path {restricted_path} has not been registered.')
return None
restricted_path = pathlib.Path(restricted_path).resolve()
restricted_json = restricted_path / 'restricted.json'
if not restricted_json.is_file():
logger.error(f'Restricted json {restricted_json} is not present.')
return None
if not validation.valid_o3de_restricted_json(restricted_json):
logger.error(f'Restricted json {restricted_json} is not valid.')
return None
with restricted_json.open('r') as f:
try:
restricted_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{restricted_json} failed to load: {str(e)}')
else:
return restricted_json_data
return None
def get_registered(engine_name: str = None,
project_name: str = None,
gem_name: str = None,
template_name: str = None,
default_folder: str = None,
repo_name: str = None,
restricted_name: str = None) -> pathlib.Path or None:
json_data = load_o3de_manifest()
# check global first then this engine
if isinstance(engine_name, str):
for engine in json_data['engines']:
engine_path = pathlib.Path(engine['path']).resolve()
engine_json = engine_path / 'engine.json'
with engine_json.open('r') as f:
try:
engine_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{engine_json} failed to load: {str(e)}')
else:
this_engines_name = engine_json_data['engine_name']
if this_engines_name == engine_name:
return engine_path
elif isinstance(project_name, str):
enging_projects = get_engine_projects()
projects = json_data['projects'].copy()
projects.extend(engine_object['projects'])
for project_path in projects:
project_path = pathlib.Path(project_path).resolve()
project_json = project_path / 'project.json'
with project_json.open('r') as f:
try:
project_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{project_json} failed to load: {str(e)}')
else:
this_projects_name = project_json_data['project_name']
if this_projects_name == project_name:
return project_path
elif isinstance(gem_name, str):
engine_gems = get_engine_gems()
gems = json_data['gems'].copy()
gems.extend(engine_gems)
for gem_path in gems:
gem_path = pathlib.Path(gem_path).resolve()
gem_json = gem_path / 'gem.json'
with gem_json.open('r') as f:
try:
gem_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{gem_json} failed to load: {str(e)}')
else:
this_gems_name = gem_json_data['gem_name']
if this_gems_name == gem_name:
return gem_path
elif isinstance(template_name, str):
engine_templates = get_engine_templates()
templates = json_data['templates'].copy()
templates.extend(engine_templates)
for template_path in templates:
template_path = pathlib.Path(template_path).resolve()
template_json = template_path / 'template.json'
with template_json.open('r') as f:
try:
template_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{template_path} failed to load: {str(e)}')
else:
this_templates_name = template_json_data['template_name']
if this_templates_name == template_name:
return template_path
elif isinstance(restricted_name, str):
engine_restricted = get_engine_restricted()
restricted = json_data['restricted'].copy()
restricted.extend(engine_restricted)
for restricted_path in restricted:
restricted_path = pathlib.Path(restricted_path).resolve()
restricted_json = restricted_path / 'restricted.json'
with restricted_json.open('r') as f:
try:
restricted_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{restricted_json} failed to load: {str(e)}')
else:
this_restricted_name = restricted_json_data['restricted_name']
if this_restricted_name == restricted_name:
return restricted_path
elif isinstance(default_folder, str):
if default_folder == 'engines':
default_engines_folder = pathlib.Path(json_data['default_engines_folder']).resolve()
return default_engines_folder
elif default_folder == 'projects':
default_projects_folder = pathlib.Path(json_data['default_projects_folder']).resolve()
return default_projects_folder
elif default_folder == 'gems':
default_gems_folder = pathlib.Path(json_data['default_gems_folder']).resolve()
return default_gems_folder
elif default_folder == 'templates':
default_templates_folder = pathlib.Path(json_data['default_templates_folder']).resolve()
return default_templates_folder
elif default_folder == 'restricted':
default_restricted_folder = pathlib.Path(json_data['default_restricted_folder']).resolve()
return default_restricted_folder
elif isinstance(repo_name, str):
cache_folder = get_o3de_cache_folder()
for repo_uri in json_data['repos']:
repo_uri = pathlib.Path(repo_uri).resolve()
repo_sha256 = hashlib.sha256(repo_uri.encode())
cache_file = cache_folder / str(repo_sha256.hexdigest() + '.json')
if cache_file.is_file():
repo = pathlib.Path(cache_file).resolve()
with repo.open('r') as f:
try:
repo_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{cache_file} failed to load: {str(e)}')
else:
this_repos_name = repo_json_data['repo_name']
if this_repos_name == repo_name:
return repo_uri
return None
+490
View File
@@ -0,0 +1,490 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import json
import hashlib
import logging
import sys
import urllib.parse
from o3de import manifest, validation
logger = logging.getLogger()
logging.basicConfig()
def print_this_engine(verbose: int) -> None:
engine_data = manifest.get_this_engine()
print(json.dumps(engine_data, indent=4))
if verbose > 0:
print_engines_data(engine_data)
def print_engines(verbose: int) -> None:
engines_data = manifest.get_engines()
print(json.dumps(engines_data, indent=4))
if verbose > 0:
print_engines_data(engines_data)
def print_projects(verbose: int) -> None:
projects_data = manifest.get_projects()
print(json.dumps(projects_data, indent=4))
if verbose > 0:
print_projects_data(projects_data)
def print_gems(verbose: int) -> None:
gems_data = manifest.get_gems()
print(json.dumps(gems_data, indent=4))
if verbose > 0:
print_gems_data(gems_data)
def print_templates(verbose: int) -> None:
templates_data = manifest.get_templates()
print(json.dumps(templates_data, indent=4))
if verbose > 0:
print_templates_data(templates_data)
def print_restricted(verbose: int) -> None:
restricted_data = manifest.get_restricted()
print(json.dumps(restricted_data, indent=4))
if verbose > 0:
print_restricted_data(restricted_data)
def print_engine_projects(verbose: int) -> None:
engine_projects_data = manifest.get_engine_projects()
print(json.dumps(engine_projects_data, indent=4))
if verbose > 0:
print_projects_data(engine_projects_data)
def print_engine_gems(verbose: int) -> None:
engine_gems_data = manifest.get_engine_gems()
print(json.dumps(engine_gems_data, indent=4))
if verbose > 0:
print_gems_data(engine_gems_data)
def print_engine_templates(verbose: int) -> None:
engine_templates_data = manifest.get_engine_templates()
print(json.dumps(engine_templates_data, indent=4))
if verbose > 0:
print_templates_data(engine_templates_data)
def print_engine_restricted(verbose: int) -> None:
engine_restricted_data = manifest.get_engine_restricted()
print(json.dumps(engine_restricted_data, indent=4))
if verbose > 0:
print_restricted_data(engine_restricted_data)
def print_engine_external_subdirectories(verbose: int) -> None:
external_subdirs_data = manifest.get_engine_external_subdirectories()
print(json.dumps(external_subdirs_data, indent=4))
def print_all_projects(verbose: int) -> None:
all_projects_data = manifest.get_all_projects()
print(json.dumps(all_projects_data, indent=4))
if verbose > 0:
print_projects_data(all_projects_data)
def print_all_gems(verbose: int) -> None:
all_gems_data = manifest.get_all_gems()
print(json.dumps(all_gems_data, indent=4))
if verbose > 0:
print_gems_data(all_gems_data)
def print_all_templates(verbose: int) -> None:
all_templates_data = manifest.get_all_templates()
print(json.dumps(all_templates_data, indent=4))
if verbose > 0:
print_templates_data(all_templates_data)
def print_all_restricted(verbose: int) -> None:
all_restricted_data = manifest.get_all_restricted()
print(json.dumps(all_restricted_data, indent=4))
if verbose > 0:
print_restricted_data(all_restricted_data)
def print_engines_data(engines_data: dict) -> None:
print('\n')
print("Engines================================================")
for engine_object in engines_data:
# if it's not local it should be in the cache
engine_uri = engine_object['path']
parsed_uri = urllib.parse.urlparse(engine_uri)
if parsed_uri.scheme == 'http' or \
parsed_uri.scheme == 'https' or \
parsed_uri.scheme == 'ftp' or \
parsed_uri.scheme == 'ftps':
repo_sha256 = hashlib.sha256(engine_uri.encode())
cache_folder = manifest.get_o3de_cache_folder()
engine = cache_folder / str(repo_sha256.hexdigest() + '.json')
print(f'{engine_uri}/engine.json cached as:')
else:
engine_json = pathlib.Path(engine_uri).resolve() / 'engine.json'
with engine_json.open('r') as f:
try:
engine_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{engine_json} failed to load: {str(e)}')
else:
print(engine_json)
print(json.dumps(engine_json_data, indent=4))
print('\n')
def print_projects_data(projects_data: dict) -> None:
print('\n')
print("Projects================================================")
for project_uri in projects_data:
# if it's not local it should be in the cache
parsed_uri = urllib.parse.urlparse(project_uri)
if parsed_uri.scheme == 'http' or \
parsed_uri.scheme == 'https' or \
parsed_uri.scheme == 'ftp' or \
parsed_uri.scheme == 'ftps':
repo_sha256 = hashlib.sha256(project_uri.encode())
cache_folder = manifest.get_o3de_cache_folder()
project_json = cache_folder / str(repo_sha256.hexdigest() + '.json')
else:
project_json = pathlib.Path(project_uri).resolve() / 'project.json'
with project_json.open('r') as f:
try:
project_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{project_json} failed to load: {str(e)}')
else:
print(project_json)
print(json.dumps(project_json_data, indent=4))
print('\n')
def print_gems_data(gems_data: dict) -> None:
print('\n')
print("Gems================================================")
for gem_uri in gems_data:
# if it's not local it should be in the cache
parsed_uri = urllib.parse.urlparse(gem_uri)
if parsed_uri.scheme == 'http' or \
parsed_uri.scheme == 'https' or \
parsed_uri.scheme == 'ftp' or \
parsed_uri.scheme == 'ftps':
repo_sha256 = hashlib.sha256(gem_uri.encode())
cache_folder = manifest.get_o3de_cache_folder()
gem_json = cache_folder / str(repo_sha256.hexdigest() + '.json')
else:
gem_json = pathlib.Path(gem_uri).resolve() / 'gem.json'
with gem_json.open('r') as f:
try:
gem_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{gem_json} failed to load: {str(e)}')
else:
print(gem_json)
print(json.dumps(gem_json_data, indent=4))
print('\n')
def print_templates_data(templates_data: dict) -> None:
print('\n')
print("Templates================================================")
for template_uri in templates_data:
# if it's not local it should be in the cache
parsed_uri = urllib.parse.urlparse(template_uri)
if parsed_uri.scheme == 'http' or \
parsed_uri.scheme == 'https' or \
parsed_uri.scheme == 'ftp' or \
parsed_uri.scheme == 'ftps':
repo_sha256 = hashlib.sha256(template_uri.encode())
cache_folder = manifest.get_o3de_cache_folder()
template_json = cache_folder / str(repo_sha256.hexdigest() + '.json')
else:
template_json = pathlib.Path(template_uri).resolve() / 'template.json'
with template_json.open('r') as f:
try:
template_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{template_json} failed to load: {str(e)}')
else:
print(template_json)
print(json.dumps(template_json_data, indent=4))
print('\n')
def print_repos_data(repos_data: dict) -> None:
print('\n')
print("Repos================================================")
cache_folder = manifest.get_o3de_cache_folder()
for repo_uri in repos_data:
repo_sha256 = hashlib.sha256(repo_uri.encode())
cache_file = cache_folder / str(repo_sha256.hexdigest() + '.json')
if validation.valid_o3de_repo_json(cache_file):
with cache_file.open('r') as s:
try:
repo_json_data = json.load(s)
except json.JSONDecodeError as e:
logger.warn(f'{cache_file} failed to load: {str(e)}')
else:
print(f'{repo_uri}/repo.json cached as:')
print(cache_file)
print(json.dumps(repo_json_data, indent=4))
print('\n')
def print_restricted_data(restricted_data: dict) -> None:
print('\n')
print("Restricted================================================")
for restricted_path in restricted_data:
restricted_json = pathlib.Path(restricted_path).resolve() / 'restricted.json'
with restricted_json.open('r') as f:
try:
restricted_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{restricted_json} failed to load: {str(e)}')
else:
print(restricted_json)
print(json.dumps(restricted_json_data, indent=4))
print('\n')
def register_show_repos(verbose: int) -> None:
repos_data = get_repos()
print(json.dumps(repos_data, indent=4))
if verbose > 0:
print_repos_data(repos_data)
def register_show(verbose: int) -> None:
json_data = manifest.load_o3de_manifest()
print(f"{manifest.get_o3de_manifest()}:")
print(json.dumps(json_data, indent=4))
if verbose > 0:
print_engines_data(manifest.get_engines())
print_projects_data(manifest.get_all_projects())
print_gems_data(manifest.get_gems())
print_templates_data(manifest.get_all_templates())
print_restricted_data(manifest.get_all_restricted())
print_repos_data(manifest.get_repos())
def _run_register_show(args: argparse) -> int:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
if args.this_engine:
print_this_engine(args.verbose)
return 0
elif args.engines:
print_engines(args.verbose)
return 0
elif args.projects:
print_projects(args.verbose)
return 0
elif args.gems:
print_gems(args.verbose)
return 0
elif args.templates:
print_templates(args.verbose)
return 0
elif args.repos:
register_show_repos(args.verbose)
return 0
elif args.restricted:
print_restricted(args.verbose)
return 0
elif args.engine_projects:
print_engine_projects(args.verbose)
return 0
elif args.engine_gems:
print_engine_gems(args.verbose)
return 0
elif args.engine_templates:
print_engine_templates(args.verbose)
return 0
elif args.engine_restricted:
print_engine_restricted(args.verbose)
return 0
elif args.engine_external_subdirectories:
print_engine_external_subdirectories(args.verbose)
return 0
elif args.all_projects:
print_all_projects(args.verbose)
return 0
elif args.all_gems:
print_all_gems(args.verbose)
return 0
elif args.all_templates:
print_all_templates(args.verbose)
return 0
elif args.all_restricted:
print_all_restricted(args.verbose)
return 0
elif args.downloadables:
print_downloadables(args.verbose)
return 0
if args.downloadable_engines:
print_downloadable_engines(args.verbose)
return 0
elif args.downloadable_projects:
print_downloadable_projects(args.verbose)
return 0
elif args.downloadable_gems:
print_downloadable_gems(args.verbose)
return 0
elif args.downloadable_templates:
print_downloadable_templates(args.verbose)
return 0
else:
register_show(args.verbose)
return 0
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python print_registration.py --engine-projects
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('-te', '--this-engine', action='store_true', required=False,
default=False,
help='Just the local engines.')
group.add_argument('-e', '--engines', action='store_true', required=False,
default=False,
help='Just the local engines.')
group.add_argument('-p', '--projects', action='store_true', required=False,
default=False,
help='Just the local projects.')
group.add_argument('-g', '--gems', action='store_true', required=False,
default=False,
help='Just the local gems.')
group.add_argument('-t', '--templates', action='store_true', required=False,
default=False,
help='Just the local templates.')
group.add_argument('-r', '--repos', action='store_true', required=False,
default=False,
help='Just the local repos. Ignores repos.')
group.add_argument('-rs', '--restricted', action='store_true', required=False,
default=False,
help='The local restricted folders.')
group.add_argument('-ep', '--engine-projects', action='store_true', required=False,
default=False,
help='Just the local projects. Ignores repos.')
group.add_argument('-eg', '--engine-gems', action='store_true', required=False,
default=False,
help='Just the local gems. Ignores repos')
group.add_argument('-et', '--engine-templates', action='store_true', required=False,
default=False,
help='Just the local templates. Ignores repos.')
group.add_argument('-ers', '--engine-restricted', action='store_true', required=False,
default=False,
help='The restricted folders.')
group.add_argument('-x', '--engine-external-subdirectories', action='store_true', required=False,
default=False,
help='The external subdirectories.')
group.add_argument('-ap', '--all-projects', action='store_true', required=False,
default=False,
help='Just the local projects. Ignores repos.')
group.add_argument('-ag', '--all-gems', action='store_true', required=False,
default=False,
help='Just the local gems. Ignores repos')
group.add_argument('-at', '--all-templates', action='store_true', required=False,
default=False,
help='Just the local templates. Ignores repos.')
group.add_argument('-ars', '--all-restricted', action='store_true', required=False,
default=False,
help='The restricted folders.')
group.add_argument('-d', '--downloadables', action='store_true', required=False,
default=False,
help='Combine all repos into a single list of resources.')
group.add_argument('-de', '--downloadable-engines', action='store_true', required=False,
default=False,
help='Combine all repos engines into a single list of resources.')
group.add_argument('-dp', '--downloadable-projects', action='store_true', required=False,
default=False,
help='Combine all repos projects into a single list of resources.')
group.add_argument('-dg', '--downloadable-gems', action='store_true', required=False,
default=False,
help='Combine all repos gems into a single list of resources.')
group.add_argument('-dt', '--downloadable-templates', action='store_true', required=False,
default=False,
help='Combine all repos templates into a single list of resources.')
parser.add_argument('-v', '--verbose', action='count', required=False,
default=0,
help='How verbose do you want the output to be.')
parser.add_argument('-ohf', '--override-home-folder', type=str, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.set_defaults(func=_run_register_show)
def add_args(subparsers) -> None:
"""
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py register-show --engine-projects
:param subparsers: the caller instantiates subparsers and passes it in here
"""
register_show_subparser = subparsers.add_parser('register-show')
add_parser_args(register_show_subparser)
def main():
"""
Runs print_registration.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()
# add subparsers
# add args to the parser
add_parser_args(the_parser)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
sys.exit(ret)
if __name__ == "__main__":
main()
+868
View File
@@ -0,0 +1,868 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
"""
This file contains all the code that has to do with registering engines, projects, gems and templates
"""
import argparse
import hashlib
import logging
import json
import os
import pathlib
import shutil
import sys
import urllib.parse
import urllib.request
from o3de import get_registration, manifest, repo, utils, validation
logger = logging.getLogger()
logging.basicConfig()
def register_shipped_engine_o3de_objects(force: bool = False) -> int:
engine_path = manifest.get_this_engine_path()
ret_val = 0
# register anything in the users default folders globally
error_code = register_all_engines_in_folder(manifest.get_registered(default_folder='engines'), force=force)
if error_code:
ret_val = error_code
error_code = register_all_projects_in_folder(manifest.get_registered(default_folder='projects'))
if error_code:
ret_val = error_code
error_code = register_all_gems_in_folder(manifest.get_registered(default_folder='gems'))
if error_code:
ret_val = error_code
error_code = register_all_templates_in_folder(manifest.get_registered(default_folder='templates'))
if error_code:
ret_val = error_code
error_code = register_all_restricted_in_folder(manifest.get_registered(default_folder='restricted'))
if error_code:
ret_val = error_code
error_code = register_all_restricted_in_folder(manifest.get_registered(default_folder='projects'))
if error_code:
ret_val = error_code
error_code = register_all_restricted_in_folder(manifest.get_registered(default_folder='gems'))
if error_code:
ret_val = error_code
error_code = register_all_restricted_in_folder(manifest.get_registered(default_folder='templates'))
if error_code:
ret_val = error_code
return ret_val
def register_all_in_folder(folder_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None,
exclude: list = None) -> int:
if not folder_path:
logger.error(f'Folder path cannot be empty.')
return 1
folder_path = pathlib.Path(folder_path).resolve()
if not folder_path.is_dir():
logger.error(f'Folder path is not dir.')
return 1
engines_set = set()
projects_set = set()
gems_set = set()
templates_set = set()
restricted_set = set()
repo_set = set()
ret_val = 0
for root, dirs, files in os.walk(folder_path):
if root in exclude:
continue
for name in files:
if name == 'engine.json':
engines_set.add(root)
elif name == 'project.json':
projects_set.add(root)
elif name == 'gem.json':
gems_set.add(root)
elif name == 'template.json':
templates_set.add(root)
elif name == 'restricted.json':
restricted_set.add(root)
elif name == 'repo.json':
repo_set.add(root)
for engine in sorted(engines_set, reverse=True):
error_code = register(engine_path=engine, remove=remove)
if error_code:
ret_val = error_code
for project in sorted(projects_set, reverse=True):
error_code = register(engine_path=engine_path, project_path=project, remove=remove)
if error_code:
ret_val = error_code
for gem in sorted(gems_set, reverse=True):
error_code = register(engine_path=engine_path, gem_path=gem, remove=remove)
if error_code:
ret_val = error_code
for template in sorted(templates_set, reverse=True):
error_code = register(engine_path=engine_path, template_path=template, remove=remove)
if error_code:
ret_val = error_code
for restricted in sorted(restricted_set, reverse=True):
error_code = register(engine_path=engine_path, restricted_path=restricted, remove=remove)
if error_code:
ret_val = error_code
for repo in sorted(repo_set, reverse=True):
error_code = register(engine_path=engine_path, repo_uri=repo, remove=remove)
if error_code:
ret_val = error_code
return ret_val
def register_all_o3de_objects_of_type_in_folder(o3de_object_path: str or pathlib.Path,
o3de_object_type: str,
remove: bool,
force: bool,
**register_kwargs) -> int:
if not o3de_object_path:
logger.error(f'Engines path cannot be empty.')
return 1
o3de_object_path = pathlib.Path(o3de_object_path).resolve()
if not o3de_object_path.is_dir():
logger.error(f'Engines path is not dir.')
return 1
o3de_object_type_set = set()
register_path_kwarg = f'{o3de_object_type}_path' if o3de_object_type != 'repo' else f'{o3de_object_type}_uri'
ret_val = 0
for root, dirs, files in os.walk(o3de_object_path):
if f'{o3de_object_type}.json' in files:
o3de_object_type_set.add(root)
# Stop iteration of any subdirectories
# Nested o3de objects of the same type aren't supported(i.e an engine cannot be inside of a engine).
dirs[:] = []
for o3de_object_type_root in sorted(o3de_object_type_set, reverse=True):
error_code = register(**{register_path_kwarg: o3de_object_type_root},
remove=remove, force=force, **register_kwargs)
if error_code:
ret_val = error_code
return ret_val
def register_all_engines_in_folder(engines_path: str or pathlib.Path,
remove: bool = False,
force: bool = False) -> int:
return register_all_o3de_objects_of_type_in_folder(engines_path, 'engine', remove, force)
def register_all_projects_in_folder(projects_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None) -> int:
return register_all_o3de_objects_of_type_in_folder(projects_path, 'project', remove, False, engine_path=engine_path)
def register_all_gems_in_folder(gems_path: str or pathlib.Path,
remove: bool = False,
engine_path: pathlib.Path = None,
project_path: pathlib.Path = None) -> int:
return register_all_o3de_objects_of_type_in_folder(gems_path, 'gem', remove, False, engine_path=engine_path)
def register_all_templates_in_folder(templates_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None) -> int:
return register_all_o3de_objects_of_type_in_folder(templates_path, 'template', remove, False, engine_path=engine_path)
def register_all_restricted_in_folder(restricted_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None) -> int:
return register_all_o3de_objects_of_type_in_folder(restricted_path, 'restricted', remove, False, engine_path=engine_path)
def register_all_repos_in_folder(repos_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None) -> int:
return register_all_o3de_objects_of_type_in_folder(repos_path, 'repo', remove, force, engine_path=engine_path)
def remove_engine_name_to_path(json_data: dict,
engine_path: pathlib.Path) -> int:
"""
Remove the engine at the specified path if it exist in the o3de manifest
:param json_data in-memory json view of the o3de_manifest.json data
:param engine_path path to engine to remove from the manifest data
returns 0 to indicate no issues has occurred with removal
"""
if engine_path.is_dir() and validation.valid_o3de_engine_json(engine_path):
engine_json_data = manifest.get_engine_json_data(engine_path=engine_path)
if 'engine_name' in engine_json_data and 'engines_path' in json_data:
engine_name = engine_json_data['engine_name']
try:
del json_data['engines_path'][engine_name]
except KeyError:
# Attempting to remove a non-existent engine_name is fine
pass
return 0
def add_engine_name_to_path(json_data: dict, engine_path: pathlib.Path, force: bool):
# Add an engine path JSON object which maps the "engine_name" -> "engine_path"
engine_json_data = manifest.get_engine_json_data(engine_path=engine_path)
if not engine_json_data:
logger.error(f'Unable to retrieve json data from engine.json at path {engine_path.as_posix()}')
return 1
engines_path_json = json_data.setdefault('engines_path', {})
if 'engine_name' not in engine_json_data:
logger.error(f'engine.json at path {engine_path.as_posix()} is missing "engine_name" key')
return 1
engine_name = engine_json_data['engine_name']
if not force and engine_name in engines_path_json and \
pathlib.PurePath(engines_path_json[engine_name]) != engine_path:
logger.error(
f'Attempting to register existing engine "{engine_name}" with a new path of {engine_path.as_posix()}.'
f' The current path is {pathlib.Path(engines_path_json[engine_name]).as_posix()}.'
f' To force registration of a new engine path, specify the -f/--force option.')
return 1
engines_path_json[engine_name] = engine_path.as_posix()
return 0
def register_engine_path(json_data: dict,
engine_path: str or pathlib.Path,
remove: bool = False,
force: bool = False) -> int:
if not engine_path:
logger.error(f'Engine path cannot be empty.')
return 1
engine_path = pathlib.Path(engine_path).resolve()
for engine_object in json_data.get('engines', {}):
engine_object_path = pathlib.Path(engine_object['path']).resolve()
if engine_object_path == engine_path:
json_data['engines'].remove(engine_object)
if remove:
return remove_engine_name_to_path(json_data, engine_path)
if not engine_path.is_dir():
logger.error(f'Engine path {engine_path} does not exist.')
return 1
engine_json = engine_path / 'engine.json'
if not validation.valid_o3de_engine_json(engine_json):
logger.error(f'Engine json {engine_json} is not valid.')
return 1
engine_object = {}
engine_object.update({'path': engine_path.as_posix()})
json_data.setdefault('engines', []).insert(0, engine_object)
return add_engine_name_to_path(json_data, engine_path, force)
def register_o3de_object_path(json_data: dict,
o3de_object_path: str or pathlib.Path,
o3de_object_key: str,
o3de_json_filename: str,
validation_func: callable,
remove: bool = False,
engine_path: pathlib.Path = None,
project_path: pathlib.Path = None) -> int:
# save_path variable is used to save the changes to the store the path to the file to save
# if the registration is for the project or engine
save_path = None
if not o3de_object_path:
logger.error(f'o3de object path cannot be empty.')
return 1
o3de_object_path = pathlib.Path(o3de_object_path).resolve()
if engine_path and project_path:
logger.error(f'Both a project path: {project_path} and engine path: {engine_path} has been supplied.'
'A subdirectory can only be registered to either the engine path or project in one command')
manifest_data = None
if engine_path:
manifest_data = manifest.get_engine_json_data(json_data, engine_path)
if not manifest_data:
logger.error(f'Cannot load engine.json data at path {engine_path}')
return 1
save_path = engine_path / 'engine.json'
elif project_path:
manifest_data = manifest.get_project_json_data(json_data, project_path)
if not manifest_data:
logger.error(f'Cannot load project.json data at path {project_path}')
return 1
save_path = project_path / 'project.json'
else:
manifest_data = json_data
paths_to_remove = [o3de_object_path]
if save_path:
try:
paths_to_remove.append(o3de_object_path.relative_to(save_path.parent))
except ValueError:
pass # It is OK relative path cannot be formed
manifest_data[o3de_object_key] = list(filter(lambda p: pathlib.Path(p) not in paths_to_remove,
manifest_data.setdefault(o3de_object_key, [])))
if remove:
if save_path:
manifest.save_o3de_manifest(manifest_data, save_path)
return 0
if not o3de_object_path.is_dir():
logger.error(f'o3de object path {o3de_object_path} does not exist.')
return 1
manifest_json_path = o3de_object_path / o3de_json_filename
if validation_func and not validation_func(manifest_json_path):
logger.error(f'o3de json {manifest_json_path} is not valid.')
return 1
# if there is a save path make it relative the directory containing o3de object json file
if save_path:
try:
o3de_object_path = o3de_object_path.relative_to(save_path.parent)
except ValueError:
pass # It is OK relative path cannot be formed
manifest_data[o3de_object_key].insert(0, o3de_object_path.as_posix())
if save_path:
manifest.save_o3de_manifest(manifest_data, save_path)
return 0
def register_external_subdirectory(json_data: dict,
external_subdir_path: str or pathlib.Path,
remove: bool = False,
engine_path: pathlib.Path = None,
project_path: pathlib.Path = None) -> int:
"""
:return An integer return code indicating whether registration or removal of the external subdirectory
completed successfully
"""
return register_o3de_object_path(json_data, external_subdir_path, 'external_subdirectories', '', None, remove,
engine_path, project_path)
def register_gem_path(json_data: dict,
gem_path: str or pathlib.Path,
remove: bool = False,
engine_path: pathlib.Path = None,
project_path: pathlib.Path = None) -> int:
return register_o3de_object_path(json_data, gem_path, 'external_subdirectories', 'gem.json',
validation.valid_o3de_gem_json, remove, engine_path, project_path)
def register_project_path(json_data: dict,
project_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None) -> int:
result = register_o3de_object_path(json_data, project_path, 'projects', 'project.json',
validation.valid_o3de_project_json, remove, engine_path, None)
if result != 0:
return result
# registering a project has the additional step of setting the project.json 'engine' field
this_engine_json = manifest.get_engine_json_data(engine_path=manifest.get_this_engine_path())
if not this_engine_json:
return 1
project_json_data = manifest.get_project_json_data(project_path=project_path)
if not project_json_data:
return 1
update_project_json = False
try:
update_project_json = project_json_data['engine'] != this_engine_json['engine_name']
except KeyError as e:
update_project_json = True
if update_project_json:
project_json_data['engine'] = this_engine_json['engine_name']
utils.backup_file(project_json)
with project_json.open('w') as s:
try:
s.write(json.dumps(project_json_data, indent=4))
except OSError as e:
logger.error(f'Project json failed to save: {str(e)}')
return 1
return 0
def register_template_path(json_data: dict,
template_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None) -> int:
return register_o3de_object_path(json_data, template_path, 'templates', 'template.json',
validation.valid_o3de_template_json, remove, engine_path, None)
def register_restricted_path(json_data: dict,
restricted_path: str or pathlib.Path,
remove: bool = False,
engine_path: str or pathlib.Path = None) -> int:
return register_o3de_object_path(json_data, restricted_path, 'restricted', 'restricted.json',
validation.valid_o3de_restricted_json, remove, engine_path, None)
def register_repo(json_data: dict,
repo_uri: str or pathlib.Path,
remove: bool = False) -> int:
if not repo_uri:
logger.error(f'Repo URI cannot be empty.')
return 1
url = f'{repo_uri}/repo.json'
parsed_uri = urllib.parse.urlparse(url)
if parsed_uri.scheme in ['http', 'https', 'ftp', 'ftps']:
while repo_uri in json_data['repos']:
json_data['repos'].remove(repo_uri)
else:
repo_uri = pathlib.Path(repo_uri).resolve()
while repo_uri.as_posix() in json_data['repos']:
json_data['repos'].remove(repo_uri.as_posix())
if remove:
logger.warn(f'Removing repo uri {repo_uri}.')
return 0
repo_sha256 = hashlib.sha256(url.encode())
cache_file = manifest.get_o3de_cache_folder() / str(repo_sha256.hexdigest() + '.json')
result = utils.download_file(url, cache_file)
if result == 0:
json_data['repos'].insert(0, repo_uri.as_posix())
result = repo.process_add_o3de_repo(cache_file, repo_set)
return result
def register_default_o3de_object_folder(json_data: dict,
default_o3de_object_folder: str or pathlib.Path,
o3de_object_key: str) -> int:
# make sure the path exists
default_o3de_object_folder = pathlib.Path(default_o3de_object_folder).resolve()
if not default_o3de_object_folder.is_dir():
logger.error(f'Default o3de object folder {default_o3de_object_folder} does not exist.')
return 1
json_data[o3de_object_key] = default_o3de_object_folder.as_posix()
return 0
def register_default_engines_folder(json_data: dict,
default_engines_folder: str or pathlib.Path,
remove: bool = False) -> int:
return register_default_o3de_object_folder(json_data,
manifest.get_o3de_engines_folder() if remove else default_engines_folder,
'default_engines_folder', remove)
def register_default_projects_folder(json_data: dict,
default_projects_folder: str or pathlib.Path,
remove: bool = False) -> int:
return register_default_o3de_object_folder(json_data,
manifest.get_o3de_projects_folder() if remove else default_projects_folder,
'default_projects_folder', remove)
def register_default_gems_folder(json_data: dict,
default_gems_folder: str or pathlib.Path,
remove: bool = False) -> int:
return register_default_o3de_object_folder(json_data,
manifest.get_o3de_gems_folder() if remove else default_gems_folder,
'default_gems_folder', remove)
def register_default_templates_folder(json_data: dict,
default_templates_folder: str or pathlib.Path,
remove: bool = False) -> int:
return register_default_o3de_object_folder(json_data,
manifest.get_o3de_templates_folder() if remove else default_templates_folder,
'default_templates_folder', remove)
def register_default_restricted_folder(json_data: dict,
default_restricted_folder: str or pathlib.Path,
reset_to_default: bool = False) -> int:
return register_default_o3de_object_folder(json_data,
manifest.get_o3de_restricted_folder() if remove else default_restricted_folder,
'default_restricted_folder', remove)
def register(engine_path: str or pathlib.Path = None,
project_path: str or pathlib.Path = None,
gem_path: str or pathlib.Path = None,
external_subdir_path: str or pathlib.Path = None,
template_path: str or pathlib.Path = None,
restricted_path: str or pathlib.Path = None,
repo_uri: str or pathlib.Path = None,
default_engines_folder: str or pathlib.Path = None,
default_projects_folder: str or pathlib.Path = None,
default_gems_folder: str or pathlib.Path = None,
default_templates_folder: str or pathlib.Path = None,
default_restricted_folder: str or pathlib.Path = None,
external_subdir_engine_path: pathlib.Path = None,
external_subdir_project_path: pathlib.Path = None,
remove: bool = False,
force: bool = False
) -> int:
"""
Adds/Updates entries to the ~/.o3de/o3de_manifest.json
:param engine_path: if engine folder is supplied the path will be added to the engine if it can, if not global
:param project_path: project folder
:param gem_path: gem folder
:param external_subdir_path: external subdirectory
:param template_path: template folder
:param restricted_path: restricted folder
:param repo_uri: repo uri
:param default_engines_folder: default engines folder
:param default_projects_folder: default projects folder
:param default_gems_folder: default gems folder
:param default_templates_folder: default templates folder
:param default_restricted_folder: default restricted code folder
:param external_subdir_engine_path: Path to the engine to use when registering an external subdirectory.
The registration occurs in the engine.json file in this case
:param external_subdir_engine_path: Path to the project to use when registering an external subdirectory.
The registrations occurs in the project.json in this case
:param remove: add/remove the entries
:param force: force update of the engine_path for specified "engine_name" from the engine.json file
:return: 0 for success or non 0 failure code
"""
json_data = manifest.load_o3de_manifest()
result = 0
# do anything that could require a engine context first
if isinstance(project_path, str) or isinstance(project_path, pathlib.PurePath):
if not project_path:
logger.error(f'Project path cannot be empty.')
return 1
result = register_project_path(json_data, project_path, remove, engine_path)
elif isinstance(gem_path, str) or isinstance(gem_path, pathlib.PurePath):
if not gem_path:
logger.error(f'Gem path cannot be empty.')
return 1
result = register_gem_path(json_data, gem_path, remove,
external_subdir_engine_path, external_subdir_project_path)
elif isinstance(external_subdir_path, str) or isinstance(external_subdir_path, pathlib.PurePath):
if not external_subdir_path:
logger.error(f'External Subdirectory path is None.')
return 1
result = register_external_subdirectory(json_data, external_subdir_path, remove,
external_subdir_engine_path, external_subdir_project_path)
elif isinstance(template_path, str) or isinstance(template_path, pathlib.PurePath):
if not template_path:
logger.error(f'Template path cannot be empty.')
return 1
result = register_template_path(json_data, template_path, remove, engine_path)
elif isinstance(restricted_path, str) or isinstance(restricted_path, pathlib.PurePath):
if not restricted_path:
logger.error(f'Restricted path cannot be empty.')
return 1
result = register_restricted_path(json_data, restricted_path, remove, engine_path)
elif isinstance(repo_uri, str) or isinstance(repo_uri, pathlib.PurePath):
if not repo_uri:
logger.error(f'Repo URI cannot be empty.')
return 1
result = register_repo(json_data, repo_uri, remove)
elif isinstance(default_engines_folder, str) or isinstance(default_engines_folder, pathlib.PurePath):
result = register_default_engines_folder(json_data, default_engines_folder, remove)
elif isinstance(default_projects_folder, str) or isinstance(default_projects_folder, pathlib.PurePath):
result = register_default_projects_folder(json_data, default_projects_folder, remove)
elif isinstance(default_gems_folder, str) or isinstance(default_gems_folder, pathlib.PurePath):
result = register_default_gems_folder(json_data, default_gems_folder, remove)
elif isinstance(default_templates_folder, str) or isinstance(default_templates_folder, pathlib.PurePath):
result = register_default_templates_folder(json_data, default_templates_folder, remove)
elif isinstance(default_restricted_folder, str) or isinstance(default_restricted_folder, pathlib.PurePath):
result = register_default_restricted_folder(json_data, default_restricted_folder, remove)
# engine is done LAST
# Now that everything that could have an engine context is done, if the engine is supplied that means this is
# registering the engine itself
elif isinstance(engine_path, str) or isinstance(engine_path, pathlib.PurePath):
if not engine_path:
logger.error(f'Engine path cannot be empty.')
return 1
result = register_engine_path(json_data, engine_path, remove, force)
if not result:
manifest.save_o3de_manifest(json_data)
return result
def remove_invalid_o3de_objects() -> None:
json_data = manifest.load_o3de_manifest()
for engine_object in json_data['engines']:
engine_path = engine_object['path']
if not validation.valid_o3de_engine_json(pathlib.Path(engine_path).resolve() / 'engine.json'):
logger.warn(f"Engine path {engine_path} is invalid.")
register(engine_path=engine_path, remove=True)
for project in json_data['projects']:
if not validation.valid_o3de_project_json(pathlib.Path(project).resolve() / 'project.json'):
logger.warn(f"Project path {project} is invalid.")
register(project_path=project, remove=True)
for gem in json_data['gems']:
if not validation.valid_o3de_gem_json(pathlib.Path(gem).resolve() / 'gem.json'):
logger.warn(f"Gem path {gem} is invalid.")
register(gem_path=gem, remove=True)
for external in json_data['external_subdirectories']:
external = pathlib.Path(external).resolve()
if not external.is_dir():
logger.warn(f"External subdirectory {external} is invalid.")
register(engine_path=engine_path, external_subdir_path=external, remove=True)
for template in json_data['templates']:
if not validation.valid_o3de_template_json(pathlib.Path(template).resolve() / 'template.json'):
logger.warn(f"Template path {template} is invalid.")
register(template_path=template, remove=True)
for restricted in json_data['restricted']:
if not validation.valid_o3de_restricted_json(pathlib.Path(restricted).resolve() / 'restricted.json'):
logger.warn(f"Restricted path {restricted} is invalid.")
register(restricted_path=restricted, remove=True)
default_engines_folder = pathlib.Path(json_data['default_engines_folder']).resolve()
if not default_engines_folder.is_dir():
new_default_engines_folder = manifest.get_o3de_folder() / 'Engines'
new_default_engines_folder.mkdir(parents=True, exist_ok=True)
logger.warn(
f"Default engines folder {default_engines_folder} is invalid. Set default {new_default_engines_folder}")
register(default_engines_folder=new_default_engines_folder.as_posix())
default_projects_folder = pathlib.Path(json_data['default_projects_folder']).resolve()
if not default_projects_folder.is_dir():
new_default_projects_folder = manifest.get_o3de_folder() / 'Projects'
new_default_projects_folder.mkdir(parents=True, exist_ok=True)
logger.warn(
f"Default projects folder {default_projects_folder} is invalid. Set default {new_default_projects_folder}")
register(default_projects_folder=new_default_projects_folder.as_posix())
default_gems_folder = pathlib.Path(json_data['default_gems_folder']).resolve()
if not default_gems_folder.is_dir():
new_default_gems_folder = manifest.get_o3de_folder() / 'Gems'
new_default_gems_folder.mkdir(parents=True, exist_ok=True)
logger.warn(f"Default gems folder {default_gems_folder} is invalid."
f" Set default {new_default_gems_folder}")
register(default_gems_folder=new_default_gems_folder.as_posix())
default_templates_folder = pathlib.Path(json_data['default_templates_folder']).resolve()
if not default_templates_folder.is_dir():
new_default_templates_folder = manifest.get_o3de_folder() / 'Templates'
new_default_templates_folder.mkdir(parents=True, exist_ok=True)
logger.warn(
f"Default templates folder {default_templates_folder} is invalid."
f" Set default {new_default_templates_folder}")
register(default_templates_folder=new_default_templates_folder.as_posix())
default_restricted_folder = pathlib.Path(json_data['default_restricted_folder']).resolve()
if not default_restricted_folder.is_dir():
default_restricted_folder = manifest.get_o3de_folder() / 'Restricted'
default_restricted_folder.mkdir(parents=True, exist_ok=True)
logger.warn(
f"Default restricted folder {default_restricted_folder} is invalid."
f" Set default {default_restricted_folder}")
register(default_restricted_folder=default_restricted_folder.as_posix())
def _run_register(args: argparse) -> int:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
if args.update:
remove_invalid_o3de_objects()
return repo.refresh_repos()
elif args.this_engine:
ret_val = register(engine_path=manifest.get_this_engine_path(), force=args.force)
error_code = register_shipped_engine_o3de_objects(force=args.force)
if error_code:
ret_val = error_code
return ret_val
elif args.all_engines_path:
return register_all_engines_in_folder(args.all_engines_path, args.remove, args.force)
elif args.all_projects_path:
return register_all_projects_in_folder(args.all_projects_path, args.remove)
elif args.all_gems_path:
return register_all_gems_in_folder(args.all_gems_path, args.remove)
elif args.all_templates_path:
return register_all_templates_in_folder(args.all_templates_path, args.remove)
elif args.all_restricted_path:
return register_all_restricted_in_folder(args.all_restricted_path, args.remove)
elif args.all_repo_uri:
return register_all_repos_in_folder(args.all_restricted_path, args.remove)
else:
return register(engine_path=args.engine_path,
project_path=args.project_path,
gem_path=args.gem_path,
external_subdir_path=args.external_subdirectory,
template_path=args.template_path,
restricted_path=args.restricted_path,
repo_uri=args.repo_uri,
default_engines_folder=args.default_engines_folder,
default_projects_folder=args.default_projects_folder,
default_gems_folder=args.default_gems_folder,
default_templates_folder=args.default_templates_folder,
default_restricted_folder=args.default_restricted_folder,
external_subdir_engine_path=args.external_subdirectory_engine_path,
external_subdir_project_path=args.external_subdirectory_project_path,
remove=args.remove,
force=args.force)
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python register.py --engine-path "C:/o3de"
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--this-engine', action='store_true', required=False,
default=False,
help='Registers the engine this script is running from.')
group.add_argument('-ep', '--engine-path', type=str, required=False,
help='Engine path to register/remove.')
group.add_argument('-pp', '--project-path', type=str, required=False,
help='Project path to register/remove.')
group.add_argument('-gp', '--gem-path', type=str, required=False,
help='Gem path to register/remove.')
group.add_argument('-es', '--external-subdirectory', type=str, required=False,
help='External subdirectory path to register/remove.')
group.add_argument('-tp', '--template-path', type=str, required=False,
help='Template path to register/remove.')
group.add_argument('-rp', '--restricted-path', type=str, required=False,
help='A restricted folder to register/remove.')
group.add_argument('-ru', '--repo-uri', type=str, required=False,
help='A repo uri to register/remove.')
group.add_argument('-aep', '--all-engines-path', type=str, required=False,
help='All engines under this folder to register/remove.')
group.add_argument('-app', '--all-projects-path', type=str, required=False,
help='All projects under this folder to register/remove.')
group.add_argument('-agp', '--all-gems-path', type=str, required=False,
help='All gems under this folder to register/remove.')
group.add_argument('-atp', '--all-templates-path', type=str, required=False,
help='All templates under this folder to register/remove.')
group.add_argument('-arp', '--all-restricted-path', type=str, required=False,
help='All templates under this folder to register/remove.')
group.add_argument('-aru', '--all-repo-uri', type=str, required=False,
help='All repos under this folder to register/remove.')
group.add_argument('-def', '--default-engines-folder', type=str, required=False,
help='The default engines folder to register/remove.')
group.add_argument('-dpf', '--default-projects-folder', type=str, required=False,
help='The default projects folder to register/remove.')
group.add_argument('-dgf', '--default-gems-folder', type=str, required=False,
help='The default gems folder to register/remove.')
group.add_argument('-dtf', '--default-templates-folder', type=str, required=False,
help='The default templates folder to register/remove.')
group.add_argument('-drf', '--default-restricted-folder', type=str, required=False,
help='The default restricted folder to register/remove.')
group.add_argument('-u', '--update', action='store_true', required=False,
default=False,
help='Refresh the repo cache.')
parser.add_argument('-ohf', '--override-home-folder', type=str, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.add_argument('-r', '--remove', action='store_true', required=False,
default=False,
help='Remove entry.')
parser.add_argument('-f', '--force', action='store_true', default=False,
help='For the update of the registration field being modified.')
external_subdir_group = parser.add_argument_group(title='external-subdirectory',
description='path arguments to use with the --external-subdirectory option')
external_subdir_path_group = external_subdir_group.add_mutually_exclusive_group()
external_subdir_path_group.add_argument('-esep', '--external-subdirectory-engine-path', type=pathlib.Path,
help='If supplied, registers the external subdirectory with the engine.json at' \
' the engine-path location')
external_subdir_path_group.add_argument('-espp', '--external-subdirectory-project-path', type=pathlib.Path)
parser.set_defaults(func=_run_register)
def add_args(subparsers) -> None:
"""
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py register --engine-path "C:/o3de"
:param subparsers: the caller instantiates subparsers and passes it in here
"""
register_subparser = subparsers.add_parser('register')
add_parser_args(register_subparser)
def main():
"""
Runs register.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()
# add subparsers
# add args to the parser
add_parser_args(the_parser)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
sys.exit(ret)
if __name__ == "__main__":
main()
File diff suppressed because it is too large Load Diff
+296
View File
@@ -0,0 +1,296 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
"""
Contains methods for removing a gem target from a project
"""
import argparse
import logging
import os
import pathlib
import sys
from o3de import cmake
logger = logging.getLogger()
logging.basicConfig()
def remove_gem_dependency(cmake_file: str or pathlib.Path,
gem_target: str) -> int:
"""
removes a gem dependency from a cmake file
:param cmake_file: path to the cmake file
:param gem_target: cmake target name
:return: 0 for success or non 0 failure code
"""
if not os.path.isfile(cmake_file):
logger.error(f'Failed to locate cmake file {cmake_file}')
return 1
# on a line by basis, remove any line with Gem::{gem_name}
t_data = []
# Remove the gem from the cmake_dependencies file by skipping the gem name entry
removed = False
with open(cmake_file, 'r') as s:
for line in s:
if f'Gem::{gem_target}' in line:
removed = True
else:
t_data.append(line)
if not removed:
logger.error(f'Failed to remove Gem::{gem_target} from cmake file {cmake_file}')
return 1
# write the cmake
os.unlink(cmake_file)
with open(cmake_file, 'w') as s:
s.writelines(t_data)
return 0
def remove_gem_from_project(gem_name: str = None,
gem_path: str or pathlib.Path = None,
gem_target: str = None,
project_name: str = None,
project_path: str or pathlib.Path = None,
dependencies_file: str or pathlib.Path = None,
runtime_dependency: bool = False,
tool_dependency: bool = False,
server_dependency: bool = False,
platforms: str = 'Common',
remove_from_cmake: bool = False) -> int:
"""
remove a gem from a project
:param gem_name: name of the gem to add
:param gem_path: path to the gem to add
:param gem_target: the name of teh cmake gem module
:param project_name: name of the project to add the gem to
:param project_path: path to the project to add the gem to
:param dependencies_file: if this dependency goes/is in a specific file
:param runtime_dependency: bool to specify this is a runtime gem for the game
:param tool_dependency: bool to specify this is a tool gem for the editor
:param server_dependency: bool to specify this is a server gem for the server
:param platforms: str to specify common or which specific platforms
:param remove_from_cmake: bool to specify that this gem should be removed from cmake
:return: 0 for success or non 0 failure code
"""
# we need either a project name or path
if not project_name and not project_path:
logger.error(f'Must either specify a Project path or Project Name.')
return 1
# if project name resolve it into a path
if project_name and not project_path:
project_path = manifest.get_registered(project_name=project_name)
project_path = pathlib.Path(project_path).resolve()
if not project_path.is_dir():
logger.error(f'Project path {project_path} is not a folder.')
return 1
# We need either a gem name or path
if not gem_name and not gem_path:
logger.error(f'Must either specify a Gem path or Gem Name.')
return 1
# if gem name resolve it into a path
if gem_name and not gem_path:
gem_path = manifest.get_registered(gem_name=gem_name)
gem_path = pathlib.Path(gem_path).resolve()
# make sure this gem already exists if we're adding. We can always remove a gem.
if not gem_path.is_dir():
logger.error(f'Gem Path {gem_path} does not exist.')
return 1
# find all available modules in this gem_path
modules = cmake.get_gem_targets(gem_path=gem_path)
if len(modules) == 0:
logger.error(f'No gem modules found.')
return 1
# if the user has not set a specific gem target remove all of them
# if gem target not specified, see if there is only 1 module
if not gem_target:
if len(modules) == 1:
gem_target = modules[0]
else:
logger.error(f'Gem target not specified: {modules}')
return 1
elif gem_target not in modules:
logger.error(f'Gem target not in gem modules: {modules}')
return 1
# if the user has not specified either we will assume they meant the most common which is runtime
if not runtime_dependency and not tool_dependency and not server_dependency and not dependencies_file:
logger.warning("Dependency type not specified: Assuming '--runtime-dependency'")
runtime_dependency = True
# when removing we will try to do as much as possible even with failures so ret_val will be the last error code
ret_val = 0
# if the user has specified the dependencies file then ignore the runtime_dependency and tool_dependency flags
if dependencies_file:
dependencies_file = pathlib.Path(dependencies_file).resolve()
# make sure this is a project has a dependencies_file
if not dependencies_file.is_file():
logger.error(f'Dependencies file {dependencies_file} is not present.')
return 1
# remove the dependency
error_code = remove_gem_dependency(dependencies_file, gem_target)
if error_code:
ret_val = error_code
else:
if ',' in platforms:
platforms = platforms.split(',')
else:
platforms = [platforms]
for platform in platforms:
if runtime_dependency:
# make sure this is a project has a runtime_dependencies.cmake file
project_runtime_dependencies_file = pathlib.Path(
cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='runtime',
platform=platform)).resolve()
if not project_runtime_dependencies_file.is_file():
logger.error(f'Runtime dependencies file {project_runtime_dependencies_file} is not present.')
else:
# remove the dependency
error_code = remove_gem_dependency(project_runtime_dependencies_file, gem_target)
if error_code:
ret_val = error_code
if tool_dependency:
# make sure this is a project has a tool_dependencies.cmake file
project_tool_dependencies_file = pathlib.Path(
cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='tool',
platform=platform)).resolve()
if not project_tool_dependencies_file.is_file():
logger.error(f'Tool dependencies file {project_tool_dependencies_file} is not present.')
else:
# remove the dependency
error_code = remove_gem_dependency(project_tool_dependencies_file, gem_target)
if error_code:
ret_val = error_code
if server_dependency:
# make sure this is a project has a tool_dependencies.cmake file
project_server_dependencies_file = pathlib.Path(
cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='server',
platform=platform)).resolve()
if not project_server_dependencies_file.is_file():
logger.error(f'Server dependencies file {project_server_dependencies_file} is not present.')
else:
# remove the dependency
error_code = remove_gem_dependency(project_server_dependencies_file, gem_target)
if error_code:
ret_val = error_code
return ret_val
def _run_remove_gem_from_project(args: argparse) -> int:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
return remove_gem_from_project(args.gem_name,
args.gem_path,
args.gem_target,
args.project_path,
args.project_name,
args.dependencies_file,
args.runtime_dependency,
args.tool_dependency,
args.server_dependency,
args.platforms,
args.remove_from_cmake)
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python remove_gem_project.py --project-path D:/Test --gem-name Atom
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-pp', '--project-path', type=str, required=False,
help='The path to the project.')
group.add_argument('-pn', '--project-name', type=str, required=False,
help='The name of the project.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-gp', '--gem-path', type=str, required=False,
help='The path to the gem.')
group.add_argument('-gn', '--gem-name', type=str, required=False,
help='The name of the gem.')
parser.add_argument('-gt', '--gem-target', type=str, required=False,
help='The cmake target name to add. If not specified it will assume gem_name')
parser.add_argument('-df', '--dependencies-file', type=str, required=False,
help='The cmake dependencies file in which the gem dependencies are specified.'
'If not specified it will assume ')
parser.add_argument('-rd', '--runtime-dependency', action='store_true', required=False,
default=False,
help='Optional toggle if this gem should be removed as a runtime dependency')
parser.add_argument('-td', '--tool-dependency', action='store_true', required=False,
default=False,
help='Optional toggle if this gem should be removed as a server dependency')
parser.add_argument('-sd', '--server-dependency', action='store_true', required=False,
default=False,
help='Optional toggle if this gem should be removed as a server dependency')
parser.add_argument('-pl', '--platforms', type=str, required=False,
default='Common',
help='Optional list of platforms this gem should be removed from'
' Ex. --platforms Mac,Windows,Linux')
parser.add_argument('-ohf', '--override-home-folder', type=str, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.set_defaults(func=_run_remove_gem_from_project)
def add_args(subparsers) -> None:
"""
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py remove-gem-from-project --project-path D:/Test --gem-name Atom
:param subparsers: the caller instantiates subparsers and passes it in here
"""
remove_gem_project_subparser = subparsers.add_parser('remove-gem-from-project')
add_parser_args(remove_gem_project_subparser)
def main():
"""
Runs remove_gem_project.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()
# add subparsers
# add args to the parser
add_parser_args(the_parser)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
sys.exit(ret)
if __name__ == "__main__":
main()
+160
View File
@@ -0,0 +1,160 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import json
import logging
import pathlib
import shutil
import urllib.parse
import urllib.request
from o3de import manifest, utils, validation
logger = logging.getLogger()
logging.basicConfig()
def process_add_o3de_repo(file_name: str or pathlib.Path,
repo_set: set) -> int:
file_name = pathlib.Path(file_name).resolve()
if not validation.valid_o3de_repo_json(file_name):
return 1
cache_folder = manifest.get_o3de_cache_folder()
with file_name.open('r') as f:
try:
repo_data = json.load(f)
except json.JSONDecodeError as e:
logger.error(f'{file_name} failed to load: {str(e)}')
return 1
for o3de_object_uris, manifest_json in [(repo_data['engines'], 'engine.json'),
(repo_data['projects'], 'project.json'),
(repo_data['gems'], 'gem.json'),
(repo_data['template'], 'template.json'),
(repo_data['restricted'], 'restricted.json')]:
for o3de_object_uri in o3de_object_uris:
manifest_json_uri = f'{o3de_object_uri}/{manifest_json}'
manifest_json_sha256 = hashlib.sha256(manifest_json_uri.encode())
cache_file = cache_folder / str(manifest_json_sha256.hexdigest() + '.json')
if not cache_file.is_file():
parsed_uri = urllib.parse.urlparse(manifest_json_uri)
download_file_result = utils.download_file(parsed_uri, cache_file)
if download_file_result != 0:
return download_file_result
repo_set |= repo_data['repos']
return 0
def refresh_repos() -> int:
json_data = manifest.load_o3de_manifest()
# clear the cache
cache_folder = manifest.get_o3de_cache_folder()
shutil.rmtree(cache_folder)
cache_folder = manifest.get_o3de_cache_folder() # will recreate it
result = 0
# set will stop circular references
repo_set = set()
for repo_uri in json_data['repos']:
if repo_uri not in repo_set:
repo_set.add(repo_uri)
repo_uri = f'{repo_uri}/repo.json'
repo_sha256 = hashlib.sha256(repo_uri.encode())
cache_file = cache_folder / str(repo_sha256.hexdigest() + '.json')
if not cache_file.is_file():
parsed_uri = urllib.parse.urlparse(repo_uri)
download_file_result = utils.download_file(parsed_uri, cache_file)
if download_file_result != 0:
return download_file_result
if not validation.valid_o3de_repo_json(cache_file):
logger.error(f'Repo json {repo_uri} is not valid.')
cache_file.unlink()
return 1
last_failure = process_add_o3de_repo(cache_file, repo_set)
if last_failure:
result = last_failure
return result
def search_repo(repo_json_data: dict,
engine_name: str = None,
project_name: str = None,
gem_name: str = None,
template_name: str = None,
restricted_name: str = None) -> dict or None:
if isinstance(engine_name, str) or isinstance(engine_name, pathlib.PurePath):
o3de_object_uris = repo_json_data['engines']
manifest_json = 'engine.json'
json_key = 'engine_name'
search_func = lambda: None if manifest_json_data.get(json_key, '') == engine_name else manifest_json_data
elif isinstance(project_name, str) or isinstance(project_name, pathlib.PurePath):
o3de_object_uris = repo_json_data['projects']
manifest_json = 'project.json'
json_key = 'project_name'
search_func = lambda: None if manifest_json_data.get(json_key, '') == project_name else manifest_json_data
elif isinstance(gem_name, str) or isinstance(gem_name, pathlib.PurePath):
o3de_object_uris = repo_json_data['gems']
manifest_json = 'gem.json'
json_key = 'gem_name'
search_func = lambda: None if manifest_json_data.get(json_key, '') == gem_name else manifest_json_data
elif isinstance(template_name, str) or isinstance(template_name, pathlib.PurePath):
o3de_object_uris = repo_json_data['template']
manifest_json = 'template.json'
json_key = 'template_name'
search_func = lambda: None if manifest_json_data.get(json_key, '') == template_name_name else manifest_json_data
elif isinstance(restricted_name, str) or isinstance(restricted_name, pathlib.PurePath):
o3de_object_uris = repo_json_data['restricted']
manifest_json = 'restricted.json'
json_key = 'restricted_name'
search_func = lambda: None if manifest_json_data.get(json_key, '') == restricted_name else manifest_json_data
else:
return None
o3de_object = search_o3de_object(manifest_json, o3de_object_uris, search_func)
if o3de_object:
return o3de_object
# recurse into the repos object to search for the o3de object
o3de_object_uris = repo_json_data['repos']
manifest_json = 'repo.json'
search_func = lambda: search_repo(manifest_json, engine_name, project_name, gem_name, template_name)
return search_o3de_object(manifest_json, o3de_object_uris, search_func)
def search_o3de_object(manifest_json, o3de_object_uris, search_func):
# Search for the o3de object based on the supplied object name in the current repo
cache_folder = manifest.get_o3de_cache_folder()
for o3de_object_uri in o3de_object_uris:
manifest_json_uri = f'{o3de_object_uri}/{manifest_json}'
manifest_json_sha256 = hashlib.sha256(manifest_json_uri.encode())
cache_file = cache_folder / str(manifest_json_sha256.hexdigest() + '.json')
if cache_file.is_file():
with cache_file.open('r') as f:
try:
manifest_json_data = json.load(f)
except json.JSONDecodeError as e:
logger.warn(f'{cache_file} failed to load: {str(e)}')
else:
result_json_data = search_func()
if result_json_data:
return result_json_data
return None
+117
View File
@@ -0,0 +1,117 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import json
import logging
import hashlib
import pathlib
import sys
from o3de import utils
logger = logging.getLogger()
logging.basicConfig()
def sha256(file_path: str or pathlib.Path,
json_path: str or pathlib.Path = None) -> int:
if not file_path:
logger.error(f'File path cannot be empty.')
return 1
file_path = pathlib.Path(file_path).resolve()
if not file_path.is_file():
logger.error(f'File path {file_path} does not exist.')
return 1
if json_path:
json_path = pathlib.Path(json_path).resolve()
if not json_path.is_file():
logger.error(f'Json path {json_path} does not exist.')
return 1
sha256 = hashlib.sha256(file_path.open('rb').read()).hexdigest()
if json_path:
with json_path.open('r') as s:
try:
json_data = json.load(s)
except json.JSONDecodeError as e:
logger.error(f'Failed to read Json path {json_path}: {str(e)}')
return 1
json_data.update({"sha256": sha256})
utils.backup_file(json_path)
with json_path.open('w') as s:
try:
s.write(json.dumps(json_data, indent=4))
except OSError as e:
logger.error(f'Failed to write Json path {json_path}: {str(e)}')
return 1
else:
print(sha256)
return 0
def _run_sha256(args: argparse) -> int:
return sha256(args.file_path,
args.json_path)
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python sha256.py --file-path "C:/TestGem"
:param parser: the caller passes an argparse parser like instance to this method
"""
parser.add_argument('-f', '--file-path', type=str, required=True,
help='The path to the file you want to sha256.')
parser.add_argument('-j', '--json-path', type=str, required=False,
help='optional path to an o3de json file to add the "sha256" element to.')
parser.set_defaults(func=_run_sha256)
def add_args(subparsers) -> None:
"""
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py sha256 --file-path "C:/TestGem"
:param subparsers: the caller instantiates subparsers and passes it in here
"""
sha256_subparser = subparsers.add_parser('sha256')
add_parser_args(sha256_subparser)
def main():
"""
Runs sha256.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()
# add subparsers
# add args to the parser
add_parser_args(the_parser)
# parse args
the_args = the_parser.parse_args()
# run
ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1
# return
sys.exit(ret)
if __name__ == "__main__":
main()
+66 -1
View File
@@ -13,7 +13,9 @@ This file contains utility functions
"""
import uuid
import pathlib
import shutil
import urllib.request
def validate_identifier(identifier: str) -> bool:
"""
@@ -45,3 +47,66 @@ def validate_uuid4(uuid_string: str) -> bool:
except ValueError:
return False
return str(val) == uuid_string
def backup_file(file_name: str or pathlib.Path) -> None:
index = 0
renamed = False
while not renamed:
backup_file_name = pathlib.Path(str(file_name) + '.bak' + str(index)).resolve()
index += 1
if not backup_file_name.is_file():
file_name = pathlib.Path(file_name).resolve()
file_name.rename(backup_file_name)
if backup_file_name.is_file():
renamed = True
def backup_folder(folder: str or pathlib.Path) -> None:
index = 0
renamed = False
while not renamed:
backup_folder_name = pathlib.Path(str(folder) + '.bak' + str(index)).resolve()
index += 1
if not backup_folder_name.is_dir():
folder = pathlib.Path(folder).resolve()
folder.rename(backup_folder_name)
if backup_folder_name.is_dir():
renamed = True
def download_file(parsed_uri, download_path: pathlib.Path) -> int:
"""
:param parsed_uri: uniform resource identifier to zip file to download
:param download_path: location path on disk to download file
"""
if download_path.is_file():
logger.warn(f'File already downloaded to {download_path}.')
elif parsed_uri.scheme in ['http', 'https', 'ftp', 'ftps']:
with urllib.request.urlopen(url) as s:
with download_path.open('wb') as f:
shutil.copyfileobj(s, f)
else:
origin_file = pathlib.Path(url).resolve()
if not origin_file.is_file():
return 1
shutil.copy(origin_file, download_path)
return 0
def download_zip_file(parsed_uri, download_zip_path: pathlib.Path) -> int:
"""
:param parsed_uri: uniform resource identifier to zip file to download
:param download_zip_path: path to output zip file
"""
download_file_result = download_file(parsed_uri, download_zip_path)
if download_file_result != 0:
return download_file_result
if not zipfile.is_zipfile(download_zip_path):
logger.error(f"File zip {download_zip_path} is invalid.")
download_zip_path.unlink()
return 1
return 0
+102
View File
@@ -0,0 +1,102 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
"""
This file validating o3de object json files
"""
import json
import pathlib
def valid_o3de_json_dict(json_data: dict, key: str) -> bool:
return key in json_data
def valid_o3de_repo_json(file_name: str or pathlib.Path) -> bool:
file_name = pathlib.Path(file_name).resolve()
if not file_name.is_file():
return False
with file_name.open('r') as f:
try:
json_data = json.load(f)
test = json_data['repo_name']
test = json_data['origin']
except (json.JSONDecodeError, KeyError) as e:
return False
return True
def valid_o3de_engine_json(file_name: str or pathlib.Path) -> bool:
file_name = pathlib.Path(file_name).resolve()
if not file_name.is_file():
return False
with file_name.open('r') as f:
try:
json_data = json.load(f)
test = json_data['engine_name']
except (json.JSONDecodeError, KeyError) as e:
return False
return True
def valid_o3de_project_json(file_name: str or pathlib.Path) -> bool:
file_name = pathlib.Path(file_name).resolve()
if not file_name.is_file():
return False
with file_name.open('r') as f:
try:
json_data = json.load(f)
test = json_data['project_name']
except (json.JSONDecodeError, KeyError) as e:
return False
return True
def valid_o3de_gem_json(file_name: str or pathlib.Path) -> bool:
file_name = pathlib.Path(file_name).resolve()
if not file_name.is_file():
return False
with file_name.open('r') as f:
try:
json_data = json.load(f)
test = json_data['gem_name']
except (json.JSONDecodeError, KeyError) as e:
return False
return True
def valid_o3de_template_json(file_name: str or pathlib.Path) -> bool:
file_name = pathlib.Path(file_name).resolve()
if not file_name.is_file():
return False
with file_name.open('r') as f:
try:
json_data = json.load(f)
test = json_data['template_name']
except (json.JSONDecodeError, KeyError) as e:
return False
return True
def valid_o3de_restricted_json(file_name: str or pathlib.Path) -> bool:
file_name = pathlib.Path(file_name).resolve()
if not file_name.is_file():
return False
with file_name.open('r') as f:
try:
json_data = json.load(f)
test = json_data['restricted_name']
except (json.JSONDecodeError, KeyError) as e:
return False
return True
+1 -1
View File
@@ -16,7 +16,7 @@ endif()
# Add a test to test out the o3de package `o3de.py register` command
ly_add_pytest(
NAME o3de_register
PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_registration.py
PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_register.py
TEST_SUITE smoke
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
)
@@ -12,7 +12,7 @@
import os
import pytest
from . import add_remove_gem
from o3de import add_gem_project
TEST_WITHOUT_NO_GEM_CONTENT = """
# {BEGIN_LICENSE}
@@ -105,7 +105,7 @@ def test_add_gem_dependency(tmpdir, contents, gem, expected_result, runtime_pres
with open(runtime_dependencies_cmake_file, 'a') as s:
s.write(contents)
result = add_remove_gem.add_gem_dependency(runtime_dependencies_cmake_file, gem)
result = add_gem_project.add_gem_dependency(runtime_dependencies_cmake_file, gem)
if expect_failure:
assert result != 0
+117
View File
@@ -0,0 +1,117 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import json
import logging
import pytest
import pathlib
from unittest.mock import patch
from o3de import register
string_manifest_data = '{}'
@pytest.mark.parametrize(
"engine_path, engine_name, force, expected_result", [
pytest.param(pathlib.PurePath('D:/o3de/o3de'), "o3de", False, 0),
# Same engine_name and path should result in valid registration
pytest.param(pathlib.PurePath('D:/o3de/o3de'), "o3de", False, 0),
# Same engine_name and but different path should fail
pytest.param(pathlib.PurePath('D:/o3de/engine-path'), "o3de", False, 1),
# New engine_name should result in valid registration
pytest.param(pathlib.PurePath('D:/o3de/engine-path'), "o3de-other", False, 0),
# Same engine_name and but different path with --force should result in valid registration
pytest.param(pathlib.PurePath('F:/Open3DEngine'), "o3de", True, 0),
]
)
def test_register_engine_path(engine_path, engine_name, force, expected_result):
parser = argparse.ArgumentParser()
# Register the registration script subparsers with the current argument parser
register.add_parser_args(parser)
arg_list = ['--engine-path', str(engine_path)]
if force:
arg_list += ['--force']
args = parser.parse_args(arg_list)
def load_manifest_from_string() -> dict:
try:
manifest_json = json.loads(string_manifest_data)
except json.JSONDecodeError as err:
logging.error("Error decoding Json from Manifest file")
else:
return manifest_json
def save_manifest_to_string(manifest_json: dict) -> None:
global string_manifest_data
string_manifest_data = json.dumps(manifest_json)
engine_json_data = {'engine_name': engine_name}
with patch('o3de.manifest.load_o3de_manifest', side_effect=load_manifest_from_string) as load_manifest_mock, \
patch('o3de.manifest.save_o3de_manifest', side_effect=save_manifest_to_string) as save_manifest_mock, \
patch('o3de.manifest.get_engine_json_data', return_value=engine_json_data) as engine_paths_mock, \
patch('o3de.validation.valid_o3de_engine_json', return_value=True) as valid_engine_mock, \
patch('pathlib.Path.is_dir', return_value=True) as pathlib_is_dir_mock:
result = register._run_register(args)
assert result == expected_result
@pytest.fixture(scope='class')
def init_manifest_data(request):
class ManifestData:
def __init__(self):
self.json_string = json.dumps({'default_engines_folder': '',
'default_projects_folder': '', 'default_gems_folder': '',
'default_templates_folder': '', 'default_restricted_folder': ''})
request.cls.manifest_data = ManifestData()
@pytest.mark.usefixtures('init_manifest_data')
class TestRegisterThisEngine:
@pytest.mark.parametrize(
"engine_path, engine_name, force, expected_result", [
pytest.param(pathlib.PurePath('D:/o3de/o3de'), "o3de", False, 0),
pytest.param(pathlib.PurePath('F:/Open3DEngine'), "o3de", False, 1),
pytest.param(pathlib.PurePath('F:/Open3DEngine'), "o3de", True, 0)
]
)
def test_register_this_engine(self, engine_path, engine_name, force, expected_result):
parser = argparse.ArgumentParser()
# Register the registration script subparsers with the current argument parser
register.add_parser_args(parser)
arg_list = ['--this-engine']
if force:
arg_list += ['--force']
args = parser.parse_args(arg_list)
def load_manifest_from_string() -> dict:
try:
manifest_json = json.loads(self.manifest_data.json_string)
except json.JSONDecodeError as err:
logging.error("Error decoding Json from Manifest file")
else:
return manifest_json
def save_manifest_to_string(manifest_json: dict) -> None:
self.manifest_data.json_string = json.dumps(manifest_json)
engine_json_data = {'engine_name': engine_name}
with patch('o3de.manifest.load_o3de_manifest', side_effect=load_manifest_from_string) as load_manifest_mock, \
patch('o3de.manifest.save_o3de_manifest', side_effect=save_manifest_to_string) as save_manifest_mock, \
patch('o3de.manifest.get_engine_json_data', return_value=engine_json_data) as engine_paths_mock, \
patch('o3de.manifest.get_this_engine_path', return_value=engine_path) as engine_paths_mock, \
patch('o3de.validation.valid_o3de_engine_json', return_value=True) as valid_engine_mock, \
patch('pathlib.Path.is_dir', return_value=True) as pathlib_is_dir_mock:
result = register._run_register(args)
assert result == expected_result
@@ -1,66 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import json
import logging
import pytest
import pathlib
from unittest.mock import patch
from .. import registration
string_manifest_data = '{}'
@pytest.mark.parametrize(
"engine_path, engine_name, force, expected_result", [
pytest.param(pathlib.PurePath('D:/o3de/o3de'), "o3de", False, 0),
# Same engine_name and path should result in valid registration
pytest.param(pathlib.PurePath('D:/o3de/o3de'), "o3de", False, 0),
# Same engine_name and but different path should fail
pytest.param(pathlib.PurePath('D:/o3de/engine-path'), "o3de", False, 1),
# New engine_name should result in valid registration
pytest.param(pathlib.PurePath('D:/o3de/engine-path'), "o3de-other", False, 0),
# Same engine_name and but different path with --force should result in valid registration
pytest.param(pathlib.PurePath('F:/Open3DEngine'), "o3de", True, 0),
]
)
def test_register_engine_path(engine_path, engine_name, force, expected_result):
parser = argparse.ArgumentParser()
subparser = parser.add_subparsers(help='sub-command help')
# Register the registration script subparsers with the current argument parser
registration.add_args(parser, subparser)
arg_list = ['register', '--engine-path', str(engine_path)]
if force:
arg_list += ['--force']
args = parser.parse_args(arg_list)
def load_manifest_from_string() -> dict:
try:
manifest_json = json.loads(string_manifest_data)
except json.JSONDecodeError as err:
logging.error("Error decoding Json from Manifest file")
else:
return manifest_json
def save_manifest_to_string(manifest_json: dict) -> None:
global string_manifest_data
string_manifest_data = json.dumps(manifest_json)
engine_json_data = {'engine_name': engine_name}
with patch('o3de.registration.load_o3de_manifest', side_effect=load_manifest_from_string) as load_manifest_mock, \
patch('o3de.registration.save_o3de_manifest', side_effect=save_manifest_to_string) as save_manifest_mock, \
patch('o3de.registration.get_engine_data', return_value=engine_json_data) as engine_paths_mock, \
patch('o3de.registration.valid_o3de_engine_json', return_value=True) as valid_engine_mock, \
patch('pathlib.Path.is_dir', return_value=True) as pathlib_is_dir_mock:
result = registration._run_register(args)
assert result == expected_result