From 4bea8cf67cf502c2beab6ab56c86fbddda3713d9 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Fri, 26 Sep 2014 21:08:25 +0100 Subject: [PATCH] Implemented loot_get_masterlist_revision. --- src/api/api.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++-- src/api/api.h | 3 ++- src/backend/game.cpp | 9 ++++---- src/backend/game.h | 4 ++-- src/backend/git.cpp | 18 ++++++++++------ src/gui/handler.cpp | 20 +++++++++++++---- 6 files changed, 84 insertions(+), 21 deletions(-) diff --git a/src/api/api.cpp b/src/api/api.cpp index c0fc03fa..ca7c9d24 100644 --- a/src/api/api.cpp +++ b/src/api/api.cpp @@ -97,13 +97,17 @@ struct _loot_db_int : public loot::Game { extMessageArray(nullptr), extMessageArraySize(0), extStringArray(nullptr), - extStringArraySize(0) { + extStringArraySize(0), + extRevisionID(nullptr), + extRevisionDate(nullptr) { this->SetDetails("", "", "", "", gamePath, "").Init(); } ~_loot_db_int() { delete[] extAddedTagIds; delete[] extRemovedTagIds; + delete[] extRevisionID; + delete[] extRevisionDate; if (extTagMap != nullptr) { for (size_t i = 0; i < bashTagMap.size(); i++) @@ -134,6 +138,9 @@ struct _loot_db_int : public loot::Game { char ** extStringArray; size_t extStringArraySize; + char * extRevisionID; + char * extRevisionDate; + unsigned int * extAddedTagIds; unsigned int * extRemovedTagIds; @@ -447,10 +454,20 @@ LOOT_API unsigned int loot_update_masterlist(loot_db db, if (db == nullptr || masterlistPath == nullptr || remoteURL == nullptr || remoteBranch == nullptr || updated == nullptr) return c_error(loot_error_invalid_args, "Null pointer passed."); + *updated = false; + + try { + loot::Masterlist masterlist; + } + catch (loot::error &e) { + return c_error(e); + } + return loot_ok; } -LOOT_API unsigned int loot_get_masterlist_revision(const char * const masterlistPath, +LOOT_API unsigned int loot_get_masterlist_revision(loot_db db, + const char * const masterlistPath, const bool getShortID, char ** const revisionID, char ** const revisionDate, @@ -458,6 +475,36 @@ LOOT_API unsigned int loot_get_masterlist_revision(const char * const masterlist if (masterlistPath == nullptr || revisionID == nullptr || revisionDate == nullptr || isModified == nullptr) return c_error(loot_error_invalid_args, "Null pointer passed."); + *revisionID = nullptr; + *revisionDate = nullptr; + *isModified = false; + + bool edited = false; + try { + loot::Masterlist masterlist; + std::string id = masterlist.GetRevision(masterlistPath, getShortID); + std::string date = masterlist.GetDate(masterlistPath); + + if (boost::ends_with(id, " (edited)")) { + id = id.substr(0, id.length() - 9); + date = date.substr(0, date.length() - 9); + edited = true; + } + + db->extRevisionID = ToNewCString(id); + db->extRevisionDate = ToNewCString(date); + } + catch (loot::error &e) { + return c_error(e); + } + catch (std::bad_alloc& e) { + return c_error(loot_error_no_mem, e.what()); + } + + *revisionID = db->extRevisionID; + *revisionDate = db->extRevisionDate; + *isModified = edited; + return loot_ok; } diff --git a/src/api/api.h b/src/api/api.h index df3f1867..76eb9c2d 100644 --- a/src/api/api.h +++ b/src/api/api.h @@ -482,7 +482,8 @@ extern "C" * the revision given. * @returns A return code. */ - LOOT_API unsigned int loot_get_masterlist_revision(const char * const masterlistPath, + LOOT_API unsigned int loot_get_masterlist_revision(loot_db db, + const char * const masterlistPath, const bool getShortID, char ** const revisionID, char ** const revisionDate, diff --git a/src/backend/game.cpp b/src/backend/game.cpp index 0c418c88..52f8c6fa 100644 --- a/src/backend/game.cpp +++ b/src/backend/game.cpp @@ -266,16 +266,16 @@ namespace loot { } } - std::string Masterlist::GetRevision(const boost::filesystem::path& path) { - if (revision.empty()) - GetGitInfo(path); + std::string Masterlist::GetRevision(const boost::filesystem::path& path, bool shortID) { + if (revision.empty() || (shortID && revision.length() == 40) || (!shortID && revision.length() < 40)) + GetGitInfo(path, shortID); return revision; } std::string Masterlist::GetDate(const boost::filesystem::path& path) { if (date.empty()) - GetGitInfo(path); + GetGitInfo(path, true); return date; } @@ -695,7 +695,6 @@ namespace loot { } void Game::SetLoadOrder(const std::list& loadOrder) const { - size_t pluginArrSize = loadOrder.size(); char ** pluginArr = new char*[pluginArrSize]; int i = 0; diff --git a/src/backend/game.h b/src/backend/game.h index 30329d34..591707dc 100644 --- a/src/backend/game.h +++ b/src/backend/game.h @@ -86,11 +86,11 @@ namespace loot { bool Load(Game& game, const unsigned int language); //Handles update with load fallback. bool Update(Game& game, const unsigned int language); - std::string GetRevision(const boost::filesystem::path& path); + std::string GetRevision(const boost::filesystem::path& path, bool shortID); std::string GetDate(const boost::filesystem::path& path); private: - void GetGitInfo(const boost::filesystem::path& path); + void GetGitInfo(const boost::filesystem::path& path, bool shortID); std::string revision; std::string date; diff --git a/src/backend/git.cpp b/src/backend/git.cpp index 054cd764..77f49531 100644 --- a/src/backend/git.cpp +++ b/src/backend/git.cpp @@ -150,14 +150,12 @@ namespace loot { return 0; } - void Masterlist::GetGitInfo(const boost::filesystem::path& path) { + void Masterlist::GetGitInfo(const boost::filesystem::path& path, bool shortID) { if (!isRepository(path.parent_path())) { - revision = "Unknown: Git repository missing"; - date = "Unknown: Git repository missing"; + throw error(error::git_error, "Unknown: Git repository missing"); } else if (!fs::exists(path)) { - revision = "N/A: No masterlist present"; - date = "N/A: No masterlist present"; + throw error(error::git_error, "N/A: No masterlist present"); } else { // Perform a git diff, then iterate the deltas to see if one exists for masterlist.yaml. @@ -184,8 +182,14 @@ namespace loot { git.call(git_revparse_single(&git.obj, git.repo, "HEAD")); BOOST_LOG_TRIVIAL(trace) << "Generating hex string for Git object ID."; - git.call(git_object_short_id(&git.buf, git.obj)); - revision = git.buf.ptr; + if (shortID) { + git.call(git_object_short_id(&git.buf, git.obj)); + revision = git.buf.ptr; + } + else { + char c_rev[GIT_OID_HEXSZ + 1]; + revision = git_oid_tostr(c_rev, GIT_OID_HEXSZ + 1, git_object_id(git.obj)); + } BOOST_LOG_TRIVIAL(trace) << "Getting date for Git object."; const git_oid * oid = git_object_id(git.obj); diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index b29b9375..c2650242 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -654,8 +654,14 @@ namespace loot { if (isFirstLoad) { // Store the masterlist revision and date. - gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath()); - gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); + try { + gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath(), true); + gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); + } + catch (error &e) { + gameNode["masterlist"]["revision"] = e.what(); + gameNode["masterlist"]["date"] = e.what(); + } } // Now store plugin data. @@ -801,8 +807,14 @@ namespace loot { YAML::Node gameNode; // Store the masterlist revision and date. - gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath()); - gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); + try { + gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath(), true); + gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); + } + catch (error &e) { + gameNode["masterlist"]["revision"] = e.what(); + gameNode["masterlist"]["date"] = e.what(); + } for (const auto& pluginPair : g_app_state.CurrentGame().plugins) { Plugin mlistPlugin(pluginPair.second);