[LYN-2514] Extending pythin bindings to adapt CLI changes for the gem catalog

* Added ExecuteWithLockErrorHandling() which returns an outcome with the actual error we get from python so that we can expose that to the UI.
* Added cmake pybind.
* Get gems now calling get_all_gems and alphabetically sorting the result.
* Added get enabled gems function which first gets the cmake enabled gems file path from the project path and then the list of gem names that are enabled.
* Some changes to the enable and disable gem functions.
main
Benjamin Jillich 5 years ago
parent 7b6226a8aa
commit ede8daaece

@ -283,6 +283,7 @@ namespace O3DE::ProjectManager
AZ_Warning("ProjectManagerWindow", result != -1, "Append to sys path failed"); AZ_Warning("ProjectManagerWindow", result != -1, "Append to sys path failed");
// import required modules // import required modules
m_cmake = pybind11::module::import("o3de.cmake");
m_register = pybind11::module::import("o3de.register"); m_register = pybind11::module::import("o3de.register");
m_manifest = pybind11::module::import("o3de.manifest"); m_manifest = pybind11::module::import("o3de.manifest");
m_engineTemplate = pybind11::module::import("o3de.engine_template"); m_engineTemplate = pybind11::module::import("o3de.engine_template");
@ -311,7 +312,7 @@ namespace O3DE::ProjectManager
return !PyErr_Occurred(); return !PyErr_Occurred();
} }
bool PythonBindings::ExecuteWithLock(AZStd::function<void()> executionCallback) AZ::Outcome<void, AZStd::string> PythonBindings::ExecuteWithLockErrorHandling(AZStd::function<void()> executionCallback)
{ {
AZStd::lock_guard<decltype(m_lock)> lock(m_lock); AZStd::lock_guard<decltype(m_lock)> lock(m_lock);
pybind11::gil_scoped_release release; pybind11::gil_scoped_release release;
@ -320,15 +321,20 @@ namespace O3DE::ProjectManager
try try
{ {
executionCallback(); executionCallback();
return true; return AZ::Success();
} }
catch ([[maybe_unused]] const std::exception& e) catch ([[maybe_unused]] const std::exception& e)
{ {
AZ_Warning("PythonBindings", false, "Python exception %s", e.what()); AZ_Warning("PythonBindings", false, "Python exception %s", e.what());
return false; return AZ::Failure<AZStd::string>(e.what());
} }
} }
bool PythonBindings::ExecuteWithLock(AZStd::function<void()> executionCallback)
{
return ExecuteWithLockErrorHandling(executionCallback).IsSuccess();
}
AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo() AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo()
{ {
EngineInfo engineInfo; EngineInfo engineInfo;
@ -419,7 +425,7 @@ namespace O3DE::ProjectManager
return result; return result;
} }
AZ::Outcome<GemInfo> PythonBindings::GetGem(const QString& path) AZ::Outcome<GemInfo> PythonBindings::GetGemInfo(const QString& path)
{ {
GemInfo gemInfo = GemInfoFromPath(pybind11::str(path.toStdString())); GemInfo gemInfo = GemInfoFromPath(pybind11::str(path.toStdString()));
if (gemInfo.IsValid()) if (gemInfo.IsValid())
@ -432,32 +438,59 @@ namespace O3DE::ProjectManager
} }
} }
AZ::Outcome<QVector<GemInfo>> PythonBindings::GetGems() AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetAllGemInfos(const QString& projectPath)
{ {
QVector<GemInfo> gems; QVector<GemInfo> gems;
bool result = ExecuteWithLock([&] { auto result = ExecuteWithLockErrorHandling([&]
// external gems
for (auto path : m_manifest.attr("get_gems")())
{ {
gems.push_back(GemInfoFromPath(path)); pybind11::str pyProjectPath = projectPath.toStdString();
} for (auto path : m_manifest.attr("get_all_gems")(pyProjectPath))
{
gems.push_back(GemInfoFromPath(path));
}
});
if (!result.IsSuccess())
{
return AZ::Failure<AZStd::string>(result.GetError().c_str());
}
// gems from the engine std::sort(gems.begin(), gems.end());
for (auto path : m_manifest.attr("get_engine_gems")()) return AZ::Success(AZStd::move(gems));
{ }
gems.push_back(GemInfoFromPath(path));
}
});
if (!result) AZ::Outcome<QVector<AZStd::string>, AZStd::string> PythonBindings::GetEnabledGemNames(const QString& projectPath)
{
// Retrieve the path to the cmake file that lists the enabled gems.
pybind11::str enabledGemsFilename;
auto result = ExecuteWithLockErrorHandling([&]
{
const pybind11::str pyProjectPath = projectPath.toStdString();
enabledGemsFilename = m_cmake.attr("get_enabled_gem_cmake_file")(
pybind11::none(), // project_name
pyProjectPath); // project_path
});
if (!result.IsSuccess())
{ {
return AZ::Failure(); return AZ::Failure<AZStd::string>(result.GetError().c_str());
} }
else
// Retrieve the actual list of names from the cmake file.
QVector<AZStd::string> gemNames;
result = ExecuteWithLockErrorHandling([&]
{
const auto pyGemNames = m_cmake.attr("get_enabled_gems")(enabledGemsFilename);
for (auto gemName : pyGemNames)
{
gemNames.push_back(Py_To_String(gemName));
}
});
if (!result.IsSuccess())
{ {
return AZ::Success(AZStd::move(gems)); return AZ::Failure<AZStd::string>(result.GetError().c_str());
} }
return AZ::Success(AZStd::move(gemNames));
} }
bool PythonBindings::AddProject(const QString& path) bool PythonBindings::AddProject(const QString& path)
@ -637,38 +670,36 @@ namespace O3DE::ProjectManager
} }
} }
bool PythonBindings::AddGemToProject(const QString& gemPath, const QString& projectPath) AZ::Outcome<void, AZStd::string> PythonBindings::AddGemToProject(const QString& gemPath, const QString& projectPath)
{ {
bool result = ExecuteWithLock([&] { return ExecuteWithLockErrorHandling([&]
pybind11::str pyGemPath = gemPath.toStdString(); {
pybind11::str pyProjectPath = projectPath.toStdString(); pybind11::str pyGemPath = gemPath.toStdString();
pybind11::str pyProjectPath = projectPath.toStdString();
m_enableGemProject.attr("enable_gem_in_project")(
pybind11::none(), // gem_name m_enableGemProject.attr("enable_gem_in_project")(
pyGemPath, pybind11::none(), // gem name not needed as path is provided
pybind11::none(), // project_name pyGemPath,
pyProjectPath pybind11::none(), // project name not needed as path is provided
); pyProjectPath
}); );
});
return result;
} }
bool PythonBindings::RemoveGemFromProject(const QString& gemPath, const QString& projectPath) AZ::Outcome<void, AZStd::string> PythonBindings::RemoveGemFromProject(const QString& gemPath, const QString& projectPath)
{ {
bool result = ExecuteWithLock([&] { return ExecuteWithLockErrorHandling([&]
pybind11::str pyGemPath = gemPath.toStdString(); {
pybind11::str pyProjectPath = projectPath.toStdString(); pybind11::str pyGemPath = gemPath.toStdString();
pybind11::str pyProjectPath = projectPath.toStdString();
m_disableGemProject.attr("disable_gem_in_project")(
pybind11::none(), // gem_name m_disableGemProject.attr("disable_gem_in_project")(
pyGemPath, pybind11::none(), // gem name not needed as path is provided
pybind11::none(), // project_name pyGemPath,
pyProjectPath pybind11::none(), // project name not needed as path is provided
); pyProjectPath
}); );
});
return result;
} }
bool PythonBindings::UpdateProject([[maybe_unused]] const ProjectInfo& projectInfo) bool PythonBindings::UpdateProject([[maybe_unused]] const ProjectInfo& projectInfo)

@ -39,8 +39,9 @@ namespace O3DE::ProjectManager
bool SetEngineInfo(const EngineInfo& engineInfo) override; bool SetEngineInfo(const EngineInfo& engineInfo) override;
// Gem // Gem
AZ::Outcome<GemInfo> GetGem(const QString& path) override; AZ::Outcome<GemInfo> GetGemInfo(const QString& path) override;
AZ::Outcome<QVector<GemInfo>> GetGems() override; AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemInfos(const QString& projectPath) override;
AZ::Outcome<QVector<AZStd::string>, AZStd::string> GetEnabledGemNames(const QString& projectPath) override;
// Project // Project
AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo) override; AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo) override;
@ -49,8 +50,8 @@ namespace O3DE::ProjectManager
bool AddProject(const QString& path) override; bool AddProject(const QString& path) override;
bool RemoveProject(const QString& path) override; bool RemoveProject(const QString& path) override;
bool UpdateProject(const ProjectInfo& projectInfo) override; bool UpdateProject(const ProjectInfo& projectInfo) override;
bool AddGemToProject(const QString& gemPath, const QString& projectPath) override; AZ::Outcome<void, AZStd::string> AddGemToProject(const QString& gemPath, const QString& projectPath) override;
bool RemoveGemFromProject(const QString& gemPath, const QString& projectPath) override; AZ::Outcome<void, AZStd::string> RemoveGemFromProject(const QString& gemPath, const QString& projectPath) override;
// ProjectTemplate // ProjectTemplate
AZ::Outcome<QVector<ProjectTemplateInfo>> GetProjectTemplates() override; AZ::Outcome<QVector<ProjectTemplateInfo>> GetProjectTemplates() override;
@ -58,6 +59,7 @@ namespace O3DE::ProjectManager
private: private:
AZ_DISABLE_COPY_MOVE(PythonBindings); AZ_DISABLE_COPY_MOVE(PythonBindings);
AZ::Outcome<void, AZStd::string> ExecuteWithLockErrorHandling(AZStd::function<void()> executionCallback);
bool ExecuteWithLock(AZStd::function<void()> executionCallback); bool ExecuteWithLock(AZStd::function<void()> executionCallback);
GemInfo GemInfoFromPath(pybind11::handle path); GemInfo GemInfoFromPath(pybind11::handle path);
ProjectInfo ProjectInfoFromPath(pybind11::handle path); ProjectInfo ProjectInfoFromPath(pybind11::handle path);
@ -68,6 +70,7 @@ namespace O3DE::ProjectManager
AZ::IO::FixedMaxPath m_enginePath; AZ::IO::FixedMaxPath m_enginePath;
pybind11::handle m_engineTemplate; pybind11::handle m_engineTemplate;
AZStd::recursive_mutex m_lock; AZStd::recursive_mutex m_lock;
pybind11::handle m_cmake;
pybind11::handle m_register; pybind11::handle m_register;
pybind11::handle m_manifest; pybind11::handle m_manifest;
pybind11::handle m_enableGemProject; pybind11::handle m_enableGemProject;

@ -57,13 +57,21 @@ namespace O3DE::ProjectManager
* @param path the absolute path to the Gem * @param path the absolute path to the Gem
* @return an outcome with GemInfo on success * @return an outcome with GemInfo on success
*/ */
virtual AZ::Outcome<GemInfo> GetGem(const QString& path) = 0; virtual AZ::Outcome<GemInfo> GetGemInfo(const QString& path) = 0;
/** /**
* Get info about all known Gems * Get all available gem infos. This concatenates gems registered by the engine and the project.
* @return an outcome with GemInfos on success * @param path The absolute path to the project.
* @return A list of gem infos.
*/ */
virtual AZ::Outcome<QVector<GemInfo>> GetGems() = 0; virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemInfos(const QString& projectPath) = 0;
/**
* Get a list of all enabled gem names for a given project.
* @param[in] projectPath Absolute file path to the project.
* @return A list of gem names of all the enabled gems for a given project or a error message on failure.
*/
virtual AZ::Outcome<QVector<AZStd::string>, AZStd::string> GetEnabledGemNames(const QString& projectPath) = 0;
// Projects // Projects
@ -114,17 +122,17 @@ namespace O3DE::ProjectManager
* Add a gem to a project * Add a gem to a project
* @param gemPath the absolute path to the gem * @param gemPath the absolute path to the gem
* @param projectPath the absolute path to the project * @param projectPath the absolute path to the project
* @return true on success, false on failure * @return An outcome with the success flag as well as an error message in case of a failure.
*/ */
virtual bool AddGemToProject(const QString& gemPath, const QString& projectPath) = 0; virtual AZ::Outcome<void, AZStd::string> AddGemToProject(const QString& gemPath, const QString& projectPath) = 0;
/** /**
* Remove gem to a project * Remove gem to a project
* @param gemPath the absolute path to the gem * @param gemPath the absolute path to the gem
* @param projectPath the absolute path to the project * @param projectPath the absolute path to the project
* @return true on success, false on failure * @return An outcome with the success flag as well as an error message in case of a failure.
*/ */
virtual bool RemoveGemFromProject(const QString& gemPath, const QString& projectPath) = 0; virtual AZ::Outcome<void, AZStd::string> RemoveGemFromProject(const QString& gemPath, const QString& projectPath) = 0;
// Project Templates // Project Templates

Loading…
Cancel
Save