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 +)