From 9f9b8f70b45007234c3961e2e25978912e7c0348 Mon Sep 17 00:00:00 2001 From: Vincent Liu <5900509+onecent1101@users.noreply.github.com> Date: Wed, 28 Apr 2021 11:28:23 -0700 Subject: [PATCH] [LYN-3149] Update AWSCore Editor menu to invoke resource mapping tool through engine python environment (#318) ## Details After migrating to engine python environment, there is no extra step required to launch resource mapping tool in editor. 1. This change is to migrate the editor tool launching process to engine python environment. 2. Add messagebox to show errors while using the tool 3. Note - as Qt binaries are not well organized in build directory, so separate out *AWSCore.ResourceMappintTool* target to group Qt binaries into independent build sub folder to solve the issue (temporarily, fix can be tracked by https://jira.agscollab.com/browse/LYN-2669, once fix is done, we can just remove this individual target) ## Testing Runs AWSCore.Editor.Tests ``` [----------] Global test environment tear-down [==========] 8 tests from 4 test cases ran. (161 ms total) [ PASSED ] 8 tests. ``` --- Gems/AWSCore/Code/CMakeLists.txt | 20 ++- .../Private/Editor/UI/AWSCoreEditorMenu.h | 21 +-- .../UI/AWSCoreResourceMappingToolAction.h | 42 ++++++ .../Source/Editor/UI/AWSCoreEditorMenu.cpp | 112 +++++++-------- .../UI/AWSCoreResourceMappingToolAction.cpp | 134 ++++++++++++++++++ .../AWSCoreEditorSystemComponentTest.cpp | 3 +- .../Tests/Editor/AWSCoreEditorManagerTest.cpp | 4 +- .../Tests/Editor/UI/AWSCoreEditorMenuTest.cpp | 7 +- .../AWSCoreResourceMappingToolActionTest.cpp | 57 ++++++++ .../Code/Tools/ResourceMappingTool/README.md | 128 ++++++++--------- .../resource_mapping_tool.cmd | 24 ---- .../resource_mapping_tool.py | 2 +- Gems/AWSCore/Code/awscore_editor_files.cmake | 2 + .../Code/awscore_editor_tests_files.cmake | 1 + .../awscore_resourcemappingtool_files.cmake | 15 ++ 15 files changed, 400 insertions(+), 172 deletions(-) create mode 100644 Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h create mode 100644 Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp create mode 100644 Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreResourceMappingToolActionTest.cpp delete mode 100644 Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.cmd create mode 100644 Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index cfb646710e..468530be31 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -70,7 +70,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_target( NAME AWSCore.Editor MODULE NAMESPACE Gem - OUTPUT_SUBDIRECTORY AWSCoreEditorPlugins FILES_CMAKE awscore_editor_shared_files.cmake INCLUDE_DIRECTORIES @@ -85,6 +84,25 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) Gem::AWSCore.Static Gem::AWSCore.Editor.Static ) + + ly_add_target( + NAME AWSCore.ResourceMappintTool MODULE + NAMESPACE Gem + OUTPUT_SUBDIRECTORY AWSCoreEditorQtBin + FILES_CMAKE + awscore_resourcemappingtool_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Include/Private + PUBLIC + Include/Public + BUILD_DEPENDENCIES + PRIVATE + 3rdParty::Qt::Core + 3rdParty::Qt::Widgets + AZ::AzToolsFramework + ) + ly_add_dependencies(AWSCore.Editor AWSCore.ResourceMappintTool) endif() ################################################################################ diff --git a/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreEditorMenu.h b/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreEditorMenu.h index 3994379df9..19f241e368 100644 --- a/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreEditorMenu.h +++ b/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreEditorMenu.h @@ -18,6 +18,11 @@ #include +namespace AzFramework +{ + class ProcessWatcher; +} + namespace AWSCore { class AWSCoreEditorMenu @@ -25,7 +30,11 @@ namespace AWSCore , AWSCoreEditorRequestBus::Handler { public: - static constexpr const char ResourceMappingToolPath[] = "Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.cmd"; + static constexpr const char AWSResourceMappingToolReadMeWarningText[] = + "Failed to launch Resource Mapping Tool, please follow README to setup tool before using it."; + static constexpr const char AWSResourceMappingToolIsRunningText[] = "Resource Mapping Tool is running..."; + static constexpr const char AWSResourceMappingToolLogWarningText[] = + "Failed to launch Resource Mapping Tool, please check logs for details."; static constexpr const char AWSResourceMappingToolActionText[] = "AWS Resource Mapping Tool..."; static constexpr const char CredentialConfigurationActionText[] = "Credential Configuration"; static constexpr const char CredentialConfigurationUrl[] = "https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/credentials.html"; @@ -40,23 +49,17 @@ namespace AWSCore ~AWSCoreEditorMenu(); private: - void InitializeEngineRootFolder(); void InitializeResourceMappingToolAction(); void InitializeAWSDocActions(); void InitializeAWSFeatureGemActions(); - void StartResourceMappingProcess(); - // AWSCoreEditorRequestBus interface implementation void SetAWSClientAuthEnabled() override; void SetAWSMetricsEnabled() override; void SetAWSFeatureActionsEnabled(const AZStd::string actionText); - AZStd::string m_engineRootFolder; - - AZStd::mutex m_resourceMappingToolMutex; - bool m_resourceMappintToolIsRunning; - AZStd::thread m_resourceMappingToolThread; + // To improve experience, use process watcher to keep track of ongoing tool process + AZStd::unique_ptr m_resourceMappingToolWatcher; }; } // namespace AWSCore diff --git a/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h b/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h new file mode 100644 index 0000000000..c7391fcfc9 --- /dev/null +++ b/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h @@ -0,0 +1,42 @@ +/* + * 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. + * + */ +#pragma once + +#include + +#include + +namespace AWSCore +{ + class AWSCoreResourceMappingToolAction + : public QAction + { + public: + static constexpr const char ResourceMappingToolDirectoryPath[] = "Gems/AWSCore/Code/Tools/ResourceMappingTool"; + static constexpr const char EngineWindowsPythonEntryScriptPath[] = "python/python.cmd"; + + AWSCoreResourceMappingToolAction(const QString& text); + + AZStd::string GetToolLaunchCommand() const; + AZStd::string GetToolLogPath() const; + AZStd::string GetToolReadMePath() const; + + private: + bool m_isDebug; + AZStd::string m_enginePythonEntryPath; + AZStd::string m_toolScriptPath; + AZStd::string m_toolQtBinDirectoryPath; + + AZStd::string m_toolLogPath; + AZStd::string m_toolReadMePath; + }; +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreEditorMenu.cpp b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreEditorMenu.cpp index 62ead9ba4a..754cc32751 100644 --- a/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreEditorMenu.cpp +++ b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreEditorMenu.cpp @@ -13,17 +13,20 @@ #include #include #include +#include #include #include #include +#include #include +#include #include #include #include +#include #include -#include #include #include @@ -31,15 +34,9 @@ namespace AWSCore { AWSCoreEditorMenu::AWSCoreEditorMenu(const QString& text) : QMenu(text) - , m_engineRootFolder("") - , m_resourceMappintToolIsRunning(false) + , m_resourceMappingToolWatcher(nullptr) { - InitializeEngineRootFolder(); - -#ifdef AWSCORE_EDITOR_RESOURCE_MAPPING_TOOL_ENABLED InitializeResourceMappingToolAction(); - this->addSeparator(); -#endif InitializeAWSDocActions(); this->addSeparator(); InitializeAWSFeatureGemActions(); @@ -50,46 +47,58 @@ namespace AWSCore AWSCoreEditorMenu::~AWSCoreEditorMenu() { AWSCoreEditorRequestBus::Handler::BusDisconnect(); - - if (m_resourceMappingToolThread.joinable()) + if (m_resourceMappingToolWatcher) { - m_resourceMappingToolThread.join(); - } - } - - void AWSCoreEditorMenu::InitializeEngineRootFolder() - { - auto engineRootFolder = AZ::IO::FileIOBase::GetInstance()->GetAlias("@engroot@"); - if (!engineRootFolder) - { - AZ_Error("AWSCoreEditorMenu", false, "Failed to initialize engine root folder path."); - } - else - { - m_engineRootFolder = engineRootFolder; + if (m_resourceMappingToolWatcher->IsProcessRunning()) + { + m_resourceMappingToolWatcher->TerminateProcess(AZ::u32(-1)); + } + m_resourceMappingToolWatcher.reset(); } + this->clear(); } void AWSCoreEditorMenu::InitializeResourceMappingToolAction() { - QAction* resourceMappingAction = new QAction(QObject::tr(AWSResourceMappingToolActionText)); - QObject::connect(resourceMappingAction, &QAction::triggered, this, [this]() { - AZStd::lock_guard lockGuard{m_resourceMappingToolMutex}; - if (!m_resourceMappintToolIsRunning) - { - m_resourceMappintToolIsRunning = true; - if (m_resourceMappingToolThread.joinable()) +#ifdef AWSCORE_EDITOR_RESOURCE_MAPPING_TOOL_ENABLED + AWSCoreResourceMappingToolAction* resourceMappingTool = + new AWSCoreResourceMappingToolAction(QObject::tr(AWSResourceMappingToolActionText)); + QObject::connect(resourceMappingTool, &QAction::triggered, this, + [resourceMappingTool, this]() { + AZStd::string launchCommand = resourceMappingTool->GetToolLaunchCommand(); + if (launchCommand.empty()) { - m_resourceMappingToolThread.join(); + AZStd::string resourceMappingToolReadMePath = resourceMappingTool->GetToolReadMePath(); + AZStd::string message = AZStd::string::format(AWSResourceMappingToolReadMeWarningText, resourceMappingToolReadMePath.c_str()); + QMessageBox::warning(QApplication::activeWindow(), "Warning", message.c_str(), QMessageBox::Ok); + return; + } + if (m_resourceMappingToolWatcher && m_resourceMappingToolWatcher->IsProcessRunning()) + { + QMessageBox::information(QApplication::activeWindow(), "Info", AWSResourceMappingToolIsRunningText, QMessageBox::Ok); + return; + } + if (m_resourceMappingToolWatcher) + { + m_resourceMappingToolWatcher.reset(); + } + + AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo; + processLaunchInfo.m_commandlineParameters = launchCommand; + processLaunchInfo.m_showWindow = false; + m_resourceMappingToolWatcher = AZStd::unique_ptr( + AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE)); + + if (!m_resourceMappingToolWatcher || !m_resourceMappingToolWatcher->IsProcessRunning()) + { + AZStd::string resourceMappingToolLogPath = resourceMappingTool->GetToolLogPath(); + AZStd::string message = AZStd::string::format(AWSResourceMappingToolLogWarningText, resourceMappingToolLogPath.c_str()); + QMessageBox::warning(QApplication::activeWindow(), "Warning", message.c_str(), QMessageBox::Ok); } - m_resourceMappingToolThread = AZStd::thread(AZStd::bind(&AWSCoreEditorMenu::StartResourceMappingProcess, this)); - } - else - { - AZ_Warning("AWSCoreEditorMenu", false, "Resource Mapping Tool is already running..."); - } }); - this->addAction(resourceMappingAction); + this->addAction(resourceMappingTool); + this->addSeparator(); +#endif } void AWSCoreEditorMenu::InitializeAWSDocActions() @@ -124,31 +133,6 @@ namespace AWSCore this->addAction(metrics); } - void AWSCoreEditorMenu::StartResourceMappingProcess() - { - AZStd::string toolScriptPath = AZStd::string::format("%s/%s", m_engineRootFolder.c_str(), ResourceMappingToolPath); - AzFramework::StringFunc::Path::Normalize(toolScriptPath); - QProcess resourceMappingToolProcess; - resourceMappingToolProcess.setProgram("cmd.exe"); - resourceMappingToolProcess.setArguments({"/C", toolScriptPath.c_str()}); - - resourceMappingToolProcess.start(); - while (!resourceMappingToolProcess.waitForFinished()) - { - if (resourceMappingToolProcess.state() != QProcess::Running) - { - break; - } - } - if (resourceMappingToolProcess.exitCode() != 0) - { - AZ_Error("AWSCoreEditorMenu", false, - "Failed to launch Resource Mapping Tool, please follow README to setup tool before using it."); - } - AZStd::lock_guard lockGuard{m_resourceMappingToolMutex}; - m_resourceMappintToolIsRunning = false; - } - void AWSCoreEditorMenu::SetAWSClientAuthEnabled() { SetAWSFeatureActionsEnabled(AWSClientAuthActionText); diff --git a/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp new file mode 100644 index 0000000000..fb46a8a700 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp @@ -0,0 +1,134 @@ +/* + * 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 +#include +#include + +#include + +namespace AWSCore +{ + AWSCoreResourceMappingToolAction::AWSCoreResourceMappingToolAction(const QString& text) + : QAction(text) + , m_isDebug(false) + , m_enginePythonEntryPath("") + , m_toolScriptPath("") + , m_toolQtBinDirectoryPath("") + , m_toolLogPath("") + , m_toolReadMePath("") + { + auto engineRootPath = AZ::IO::FileIOBase::GetInstance()->GetAlias("@engroot@"); + if (!engineRootPath) + { + AZ_Error("AWSCoreEditor", false, "Failed to determine engine root path."); + } + else + { + m_enginePythonEntryPath = AZStd::string::format("%s/%s", engineRootPath, EngineWindowsPythonEntryScriptPath); + AzFramework::StringFunc::Path::Normalize(m_enginePythonEntryPath); + if (!AZ::IO::SystemFile::Exists(m_enginePythonEntryPath.c_str())) + { + AZ_Error("AWSCoreEditor", false, "Failed to find engine python entry at %s.", m_enginePythonEntryPath.c_str()); + m_enginePythonEntryPath.clear(); + } + + m_toolScriptPath = AZStd::string::format("%s/%s/resource_mapping_tool.py", engineRootPath, ResourceMappingToolDirectoryPath); + AzFramework::StringFunc::Path::Normalize(m_toolScriptPath); + if (!AZ::IO::SystemFile::Exists(m_toolScriptPath.c_str())) + { + AZ_Error("AWSCoreEditor", false, "Failed to find ResourceMappingTool python script at %s.", m_toolScriptPath.c_str()); + m_toolScriptPath.clear(); + } + + m_toolLogPath = AZStd::string::format("%s/%s/resource_mapping_tool.log", engineRootPath, ResourceMappingToolDirectoryPath); + AzFramework::StringFunc::Path::Normalize(m_toolLogPath); + if (!AZ::IO::SystemFile::Exists(m_toolLogPath.c_str())) + { + AZ_Error("AWSCoreEditor", false, "Failed to find ResourceMappingTool log file at %s.", m_toolLogPath.c_str()); + m_toolLogPath.clear(); + } + + m_toolReadMePath = AZStd::string::format("%s/%s/README.md", engineRootPath, ResourceMappingToolDirectoryPath); + AzFramework::StringFunc::Path::Normalize(m_toolReadMePath); + if (!AZ::IO::SystemFile::Exists(m_toolReadMePath.c_str())) + { + AZ_Error("AWSCoreEditor", false, "Failed to find ResourceMappingTool README file at %s.", m_toolReadMePath.c_str()); + m_toolReadMePath.clear(); + } + + char executablePath[AZ_MAX_PATH_LEN]; + auto result = AZ::Utils::GetExecutablePath(executablePath, AZ_MAX_PATH_LEN); + if (result.m_pathStored != AZ::Utils::ExecutablePathResult::Success) + { + AZ_Error("AWSCoreEditor", false, "Failed to find engine executable path."); + } + else + { + if (result.m_pathIncludesFilename) + { + // Remove the file name if it exists, and keep the parent folder only + char* lastSeparatorAddress = strrchr(executablePath, AZ_CORRECT_FILESYSTEM_SEPARATOR); + if (lastSeparatorAddress) + { + *lastSeparatorAddress = '\0'; + } + } + } + + AZStd::string binDirectoryPath(executablePath); + auto lastSeparator = binDirectoryPath.find_last_of(AZ_CORRECT_FILESYSTEM_SEPARATOR); + if (lastSeparator != AZStd::string::npos) + { + m_isDebug = binDirectoryPath.substr(lastSeparator).contains("debug"); + } + + m_toolQtBinDirectoryPath = AZStd::string::format("%s/%s", binDirectoryPath.c_str(), "AWSCoreEditorQtBin"); + AzFramework::StringFunc::Path::Normalize(m_toolQtBinDirectoryPath); + if (!AZ::IO::SystemFile::Exists(m_toolQtBinDirectoryPath.c_str())) + { + AZ_Error("AWSCoreEditor", false, "Failed to find ResourceMappingTool Qt binaries at %s.", m_toolQtBinDirectoryPath.c_str()); + m_toolQtBinDirectoryPath.clear(); + } + } + } + + AZStd::string AWSCoreResourceMappingToolAction::GetToolLaunchCommand() const + { + if (m_enginePythonEntryPath.empty() || m_toolScriptPath.empty() || m_toolQtBinDirectoryPath.empty()) + { + return ""; + } + if (m_isDebug) + { + return AZStd::string::format( + "%s debug %s --binaries_path %s --debug", + m_enginePythonEntryPath.c_str(), m_toolScriptPath.c_str(), m_toolQtBinDirectoryPath.c_str()); + } + else + { + return AZStd::string::format( + "%s %s --binaries_path %s", + m_enginePythonEntryPath.c_str(), m_toolScriptPath.c_str(), m_toolQtBinDirectoryPath.c_str()); + } + } + + AZStd::string AWSCoreResourceMappingToolAction::GetToolLogPath() const + { + return m_toolLogPath; + } + + AZStd::string AWSCoreResourceMappingToolAction::GetToolReadMePath() const + { + return m_toolReadMePath; + } +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Tests/AWSCoreEditorSystemComponentTest.cpp b/Gems/AWSCore/Code/Tests/AWSCoreEditorSystemComponentTest.cpp index 6d0484c11a..e9c249f1c8 100644 --- a/Gems/AWSCore/Code/Tests/AWSCoreEditorSystemComponentTest.cpp +++ b/Gems/AWSCore/Code/Tests/AWSCoreEditorSystemComponentTest.cpp @@ -36,7 +36,6 @@ class AWSCoreEditorSystemComponentTest AWSCoreEditorUIFixture::SetUp(); AWSCoreFixture::SetUp(); - m_localFileIO->SetAlias("@engroot@", "dummy engine root"); m_serializeContext = AZStd::make_unique(); m_serializeContext->CreateEditContext(); m_behaviorContext = AZStd::make_unique(); @@ -46,7 +45,9 @@ class AWSCoreEditorSystemComponentTest m_entity = aznew AZ::Entity(); m_coreEditorSystemsComponent.reset(m_entity->CreateComponent()); + AZ_TEST_START_TRACE_SUPPRESSION; m_entity->Init(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above have thrown an AZ_Error m_entity->Activate(); } diff --git a/Gems/AWSCore/Code/Tests/Editor/AWSCoreEditorManagerTest.cpp b/Gems/AWSCore/Code/Tests/Editor/AWSCoreEditorManagerTest.cpp index 007fef46df..84efabc0f6 100644 --- a/Gems/AWSCore/Code/Tests/Editor/AWSCoreEditorManagerTest.cpp +++ b/Gems/AWSCore/Code/Tests/Editor/AWSCoreEditorManagerTest.cpp @@ -27,8 +27,6 @@ class AWSCoreEditorManagerTest { AWSCoreEditorUIFixture::SetUp(); AWSCoreFixture::SetUp(); - - m_localFileIO->SetAlias("@engroot@", "dummy engine root"); } void TearDown() override @@ -40,6 +38,8 @@ class AWSCoreEditorManagerTest TEST_F(AWSCoreEditorManagerTest, AWSCoreEditorManager_Constructor_HaveExpectedUIResourcesCreated) { + AZ_TEST_START_TRACE_SUPPRESSION; AWSCoreEditorManager testManager; + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above have thrown an AZ_Error EXPECT_TRUE(testManager.GetAWSCoreEditorMenu()); } diff --git a/Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreEditorMenuTest.cpp b/Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreEditorMenuTest.cpp index 01622a5a92..7a578d2bbe 100644 --- a/Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreEditorMenuTest.cpp +++ b/Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreEditorMenuTest.cpp @@ -35,8 +35,6 @@ class AWSCoreEditorMenuTest { AWSCoreEditorUIFixture::SetUp(); AWSCoreFixture::SetUp(); - - m_localFileIO->SetAlias("@engroot@", "dummy engine root"); } void TearDown() override @@ -48,7 +46,6 @@ class AWSCoreEditorMenuTest TEST_F(AWSCoreEditorMenuTest, AWSCoreEditorMenu_NoEngineRootFolder_ExpectOneError) { - m_localFileIO->ClearAlias("@engroot@"); AZ_TEST_START_TRACE_SUPPRESSION; AWSCoreEditorMenu testMenu("dummy title"); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above have thrown an AZ_Error @@ -56,7 +53,9 @@ TEST_F(AWSCoreEditorMenuTest, AWSCoreEditorMenu_NoEngineRootFolder_ExpectOneErro TEST_F(AWSCoreEditorMenuTest, AWSCoreEditorMenu_GetAllActions_GetExpectedNumberOfActions) { + AZ_TEST_START_TRACE_SUPPRESSION; AWSCoreEditorMenu testMenu("dummy title"); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above have thrown an AZ_Error QList actualActions = testMenu.actions(); #ifdef AWSCORE_EDITOR_RESOURCE_MAPPING_TOOL_ENABLED @@ -68,7 +67,9 @@ TEST_F(AWSCoreEditorMenuTest, AWSCoreEditorMenu_GetAllActions_GetExpectedNumberO TEST_F(AWSCoreEditorMenuTest, AWSCoreEditorMenu_BroadcastFeatureGemsAreEnabled_CorrespondingActionsAreEnabled) { + AZ_TEST_START_TRACE_SUPPRESSION; AWSCoreEditorMenu testMenu("dummy title"); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above have thrown an AZ_Error AWSCoreEditorRequestBus::Broadcast(&AWSCoreEditorRequests::SetAWSClientAuthEnabled); AWSCoreEditorRequestBus::Broadcast(&AWSCoreEditorRequests::SetAWSMetricsEnabled); diff --git a/Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreResourceMappingToolActionTest.cpp b/Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreResourceMappingToolActionTest.cpp new file mode 100644 index 0000000000..7efe77bc01 --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/UI/AWSCoreResourceMappingToolActionTest.cpp @@ -0,0 +1,57 @@ +/* + * 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 + +#include +#include +#include + +#include + +using namespace AWSCore; + +class AWSCoreResourceMappingToolActionTest + : public AWSCoreFixture + , public AWSCoreEditorUIFixture +{ + void SetUp() override + { + AWSCoreEditorUIFixture::SetUp(); + AWSCoreFixture::SetUp(); + m_localFileIO->SetAlias("@engroot@", "dummy engine root"); + } + + void TearDown() override + { + AWSCoreFixture::TearDown(); + AWSCoreEditorUIFixture::TearDown(); + } +}; + +TEST_F(AWSCoreResourceMappingToolActionTest, AWSCoreResourceMappingToolAction_NoEngineRootFolder_ExpectOneError) +{ + m_localFileIO->ClearAlias("@engroot@"); + AZ_TEST_START_TRACE_SUPPRESSION; + AWSCoreResourceMappingToolAction testAction("dummy title"); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above have thrown an AZ_Error +} + +TEST_F(AWSCoreResourceMappingToolActionTest, AWSCoreResourceMappingToolAction_UnableToFindExpectedFileOrFolder_ExpectFiveErrorsAndEmptyResult) +{ + AZ_TEST_START_TRACE_SUPPRESSION; + AWSCoreResourceMappingToolAction testAction("dummy title"); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + EXPECT_TRUE(testAction.GetToolLaunchCommand() == ""); + EXPECT_TRUE(testAction.GetToolLogPath() == ""); + EXPECT_TRUE(testAction.GetToolReadMePath() == ""); +} diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md b/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md index d90f78465b..78a8856288 100644 --- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md +++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md @@ -3,45 +3,44 @@ ## Setup aws config and credential Resource mapping tool is using boto3 to interact with aws services: - * Follow boto3 + * Read boto3 [Configuration](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) to setup default aws region. - * Follow boto3 + * Read boto3 [Credentials](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html) to setup default profile or credential keys. Or follow **AWS CLI** configuration which can be reused by boto3 lib: * Follow [Quick configuration with aws configure](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config) -**In Progress** - Override default aws profile in resource mapping tool - ## Python Environment Setup Options -### 1. Engine python environment -In order to use engine python environment, it requires to link Qt binaries for this tool. +### 1. Engine python environment (Including Editor) +1. In order to use engine python environment, it requires to link Qt binaries for this tool. Follow cmake instructions to configure your project, for example: + ``` + $ cmake -B -S . -G "Visual Studio 16 2019" -DLY_3RDPARTY_PATH= -DLY_PROJECTS= + ``` -``` -$ cmake -B -S . -G "Visual Studio 16 2019" -DLY_3RDPARTY_PATH= -DLY_PROJECTS= -``` +2. At this point, double check engine python environment gets setup under */python/runtime* directory -Build project with **AWSCore.Editor** target to generate required Qt binaries. -(Or use **Editor** target) +3. Build project with **AWSCore.Editor** (or **AWSCore.ResourceMappintTool**, or **Editor**) target to generate required Qt binaries. + ``` + $ cmake --build --target AWSCore.Editor --config -j + ``` -``` -$ cmake --build --target AWSCore.Editor --config -j -``` - -Launch resource mapping tool under engine root folder: - -#### Windows -##### release mode -``` -$ python\python.cmd Gems\AWSCore\Code\Tools\ResourceMappingTool\resource_mapping_tool.py --binaries_path \bin\profile\AWSCoreEditorPlugins -``` -##### debug mode -``` -$ python\python.cmd debug Gems\AWSCore\Code\Tools\ResourceMappingTool\resource_mapping_tool.py --binaries_path \bin\debug\AWSCoreEditorPlugins -``` +4. At this point, double check Qt binaries gets generated under */bin//AWSCoreEditorQtBin* directory +5. Launch resource mapping tool under engine root folder: + * Windows + * release mode + ``` + $ python\python.cmd Gems\AWSCore\Code\Tools\ResourceMappingTool\resource_mapping_tool.py --binaries_path \bin\profile\AWSCoreEditorQtBin + ``` + * debug mode + ``` + $ python\python.cmd debug Gems\AWSCore\Code\Tools\ResourceMappingTool\resource_mapping_tool.py --binaries_path \bin\debug\AWSCoreEditorQtBin + ``` +* Note - Editor is integrated with the same engine python environment to launch Resource Mapping Tool. If it is failed to launch the tool +in Editor, please follow above steps to make sure expected scripts/binaries are present. ### 2. Python virtual environment This project is set up like a standard Python project. The initialization @@ -51,47 +50,42 @@ directory. To create the virtualenv it assumes that there is a `python3` package. If for any reason the automatic creation of the virtualenv fails, you can create the virtualenv manually. -To manually create a virtualenv on MacOS and Linux: +1. To manually create a virtualenv: + * Windows + ``` + $ python -m venv .env + ``` + * Mac or Linux + ``` + $ python3 -m venv .env + ``` -``` -$ python -m venv .env -``` +2. Once the virtualenv is created, you can use the following step to activate your virtualenv: + * Windows + ``` + % .env\Scripts\activate.bat + ``` + * Mac or Linux + ``` + $ source .env/bin/activate + ``` -Once the virtualenv is created, you can use the following step to activate your virtualenv. +3. Once the virtualenv is activated, you can install the required dependencies: + * Windows + ``` + $ pip install -r requirements.txt + ``` + * Mac or Linux + ``` + $ pip3 install -r requirements.txt + ``` -``` -$ source .env/bin/activate -``` - -If you are a Windows platform, you would activate the virtualenv like this: - -``` -% .env\Scripts\activate.bat -``` - -Once the virtualenv is activated, you can install the required dependencies. - -``` -$ pip install -r requirements.txt -``` - -#### 2.1 Launch Options -##### 2.1.1 Launch Resource Mapping Tool from python directly -At this point you can launch tool like other standard python project. - -``` -$ python resource_mapping_tool.py -``` - -##### 2.1.2 Launch Resource Mapping Tool from batch script/Editor -Update `resource_mapping_tool.cmd` with your virtualenv full path. - - * **VIRTUALENV_PATH**: Fill this variable with your virtualenv full path. - -Then you can launch the resource mapping tool by running the batch script directly. - -``` -$ resource_mapping_tool.cmd -``` - -Or you can launch the resource mapping tool from menu action Cloud services/AWS Resource Mapping Tool... +4. At this point you can launch tool like other standard python project. + * Windows + ``` + $ python resource_mapping_tool.py + ``` + * Mac or Linux + ``` + $ python3 resource_mapping_tool.py + ``` diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.cmd b/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.cmd deleted file mode 100644 index be2f308de7..0000000000 --- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.cmd +++ /dev/null @@ -1,24 +0,0 @@ -@ECHO OFF -REM -REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -REM its licensors. -REM -REM For complete copyright and license terms please see the LICENSE at the root of this -REM distribution (the "License"). All use of this software is governed by the License, -REM or, if provided, by the license below or the license accompanying this file. Do not -REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -REM -REM Original file Copyright Crytek GMBH or its affiliates, used under license. -REM - -SETLOCAL -SET CMD_DIR=%~dp0 -SET CMD_DIR=%CMD_DIR:~0,-1% - -SET VIRTUALENV_PATH= -SET RESOURCE_MAPPING_DIR=%CMD_DIR% -SET LOCAL_PYTHONPATH=%VIRTUALENV_PATH%\Scripts\python.exe - -%LOCAL_PYTHONPATH% %RESOURCE_MAPPING_DIR%\resource_mapping_tool.py %* && exit 0 -exit 1 diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py index b067105ce3..90e702b997 100755 --- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py +++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py @@ -19,7 +19,7 @@ from utils import file_utils # arguments setup argument_parser: ArgumentParser = ArgumentParser() argument_parser.add_argument('--binaries_path', help='Path to QT Binaries necessary for PySide.') -argument_parser.add_argument('--debug', action='store_true', help='Execute on debug mode.') +argument_parser.add_argument('--debug', action='store_true', help='Execute on debug mode to enable DEBUG logging level') arguments: Namespace = argument_parser.parse_args() # logging setup diff --git a/Gems/AWSCore/Code/awscore_editor_files.cmake b/Gems/AWSCore/Code/awscore_editor_files.cmake index b8b9fbbc11..652f0455e1 100644 --- a/Gems/AWSCore/Code/awscore_editor_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_files.cmake @@ -13,7 +13,9 @@ set(FILES Include/Private/AWSCoreEditorSystemComponent.h Include/Private/Editor/AWSCoreEditorManager.h Include/Private/Editor/UI/AWSCoreEditorMenu.h + Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h Source/AWSCoreEditorSystemComponent.cpp Source/Editor/AWSCoreEditorManager.cpp Source/Editor/UI/AWSCoreEditorMenu.cpp + Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp ) diff --git a/Gems/AWSCore/Code/awscore_editor_tests_files.cmake b/Gems/AWSCore/Code/awscore_editor_tests_files.cmake index 60852746fb..ff89b6b5bd 100644 --- a/Gems/AWSCore/Code/awscore_editor_tests_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_tests_files.cmake @@ -13,6 +13,7 @@ set(FILES Tests/AWSCoreEditorSystemComponentTest.cpp Tests/Editor/UI/AWSCoreEditorMenuTest.cpp Tests/Editor/UI/AWSCoreEditorUIFixture.h + Tests/Editor/UI/AWSCoreResourceMappingToolActionTest.cpp Tests/Editor/AWSCoreEditorManagerTest.cpp Tests/Editor/AWSCoreEditorTest.cpp ) diff --git a/Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake b/Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake new file mode 100644 index 0000000000..b67c50e955 --- /dev/null +++ b/Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake @@ -0,0 +1,15 @@ +# +# 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(FILES + Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h + Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp +)