diff --git a/hyprpm/src/core/DataState.cpp b/hyprpm/src/core/DataState.cpp index a7f9a7ae..61ad336f 100644 --- a/hyprpm/src/core/DataState.cpp +++ b/hyprpm/src/core/DataState.cpp @@ -45,7 +45,8 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) { {"repository", toml::table{ {"name", repo.name}, {"hash", repo.hash}, - {"url", repo.url} + {"url", repo.url}, + {"rev", repo.rev} }} }; for (auto& p : repo.plugins) { @@ -178,12 +179,14 @@ std::vector DataState::getAllRepositories() { const auto NAME = STATE["repository"]["name"].value_or(""); const auto URL = STATE["repository"]["url"].value_or(""); + const auto REV = STATE["repository"]["rev"].value_or(""); const auto HASH = STATE["repository"]["hash"].value_or(""); SPluginRepository repo; repo.hash = HASH; repo.name = NAME; repo.url = URL; + repo.rev = REV; for (const auto& [key, val] : STATE) { if (key == "repository") diff --git a/hyprpm/src/core/Plugin.hpp b/hyprpm/src/core/Plugin.hpp index a69478d1..e66031c9 100644 --- a/hyprpm/src/core/Plugin.hpp +++ b/hyprpm/src/core/Plugin.hpp @@ -12,6 +12,7 @@ struct SPlugin { struct SPluginRepository { std::string url; + std::string rev; std::string name; std::vector plugins; std::string hash; diff --git a/hyprpm/src/core/PluginManager.cpp b/hyprpm/src/core/PluginManager.cpp index 4b026090..725e6a93 100644 --- a/hyprpm/src/core/PluginManager.cpp +++ b/hyprpm/src/core/PluginManager.cpp @@ -77,8 +77,7 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() { return ver; } -bool CPluginManager::addNewPluginRepo(const std::string& url) { - +bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string& rev) { const auto HLVER = getHyprlandVersion(); if (DataState::pluginRepoExists(url)) { @@ -134,6 +133,14 @@ bool CPluginManager::addNewPluginRepo(const std::string& url) { return false; } + if (!rev.empty()) { + std::string ret = execAndGet("git -C /tmp/hyprpm/new reset --hard --recurse-submodules " + rev); + if (ret.compare(0, 6, "fatal:") == 0) { + std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not check out revision " << rev << ". shell returned:\n" << ret << "\n"; + return false; + } + } + progress.m_iSteps = 1; progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " cloned"); progress.m_szCurrentMessage = "Reading the manifest"; @@ -240,6 +247,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url) { repohash.pop_back(); repo.name = pManifest->m_sRepository.name.empty() ? url.substr(url.find_last_of('/') + 1) : pManifest->m_sRepository.name; repo.url = url; + repo.rev = rev; repo.hash = repohash; for (auto& p : pManifest->m_vPlugins) { repo.plugins.push_back(SPlugin{p.name, "/tmp/hyprpm/new/" + p.output, false, p.failed}); @@ -494,6 +502,16 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) { return false; } + if (!repo.rev.empty()) { + progress.printMessageAbove(std::string{Colors::RESET} + " → Plugin has revision set, resetting: " + repo.rev); + + std::string ret = execAndGet("git -C /tmp/hyprpm reset --hard --recurse-submodules " + repo.rev); + if (ret.compare(0, 6, "fatal:") == 0) { + std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " could not check out revision " + repo.rev + ": shell returned:\n" + ret; + return false; + } + } + if (!update) { // check if git has updates std::string hash = execAndGet("cd /tmp/hyprpm/update && git rev-parse HEAD"); @@ -538,8 +556,8 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) { continue; } - if (!pManifest->m_sRepository.commitPins.empty()) { - // check commit pins + if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) { + // check commit pins unless a revision is specified progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking"); diff --git a/hyprpm/src/core/PluginManager.hpp b/hyprpm/src/core/PluginManager.hpp index dedb2d43..028e6357 100644 --- a/hyprpm/src/core/PluginManager.hpp +++ b/hyprpm/src/core/PluginManager.hpp @@ -36,7 +36,7 @@ struct SHyprlandVersion { class CPluginManager { public: - bool addNewPluginRepo(const std::string& url); + bool addNewPluginRepo(const std::string& url, const std::string& rev); bool removePluginRepo(const std::string& urlOrName); eHeadersErrors headersValid(); @@ -60,4 +60,4 @@ class CPluginManager { std::string headerError(const eHeadersErrors err); }; -inline std::unique_ptr g_pPluginManager; \ No newline at end of file +inline std::unique_ptr g_pPluginManager; diff --git a/hyprpm/src/main.cpp b/hyprpm/src/main.cpp index 37972443..e40d336d 100644 --- a/hyprpm/src/main.cpp +++ b/hyprpm/src/main.cpp @@ -11,7 +11,8 @@ const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager ┃ -┣ add [url] → Install a new plugin repository from git +┣ add [url] [git rev] → Install a new plugin repository from git. Git revision +┃ is optional, when set, commit locks are ignored. ┣ remove [url/name] → Remove an installed plugin repository ┣ enable [name] → Enable a plugin ┣ disable [name] → Disable a plugin @@ -77,7 +78,12 @@ int main(int argc, char** argv, char** envp) { return 1; } - return g_pPluginManager->addNewPluginRepo(command[1]) ? 0 : 1; + std::string rev = ""; + if (command.size() >= 3) { + rev = command[2]; + } + + return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1; } else if (command[0] == "remove") { if (ARGS.size() < 2) { std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for remove.\n";