hyprpm: Add support for specifying exact git revisions for plugin repo (#4983)

* hyprpm(feat): support specifying exact git revs

* Mention git rev argument in help

* Mention git rev arg is optional

* Wrap text
This commit is contained in:
ItsDrike 2024-03-06 13:01:04 +01:00 committed by GitHub
parent d6f1b151b2
commit 082bf00254
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 37 additions and 9 deletions

View file

@ -45,7 +45,8 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) {
{"repository", toml::table{ {"repository", toml::table{
{"name", repo.name}, {"name", repo.name},
{"hash", repo.hash}, {"hash", repo.hash},
{"url", repo.url} {"url", repo.url},
{"rev", repo.rev}
}} }}
}; };
for (auto& p : repo.plugins) { for (auto& p : repo.plugins) {
@ -178,12 +179,14 @@ std::vector<SPluginRepository> DataState::getAllRepositories() {
const auto NAME = STATE["repository"]["name"].value_or(""); const auto NAME = STATE["repository"]["name"].value_or("");
const auto URL = STATE["repository"]["url"].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(""); const auto HASH = STATE["repository"]["hash"].value_or("");
SPluginRepository repo; SPluginRepository repo;
repo.hash = HASH; repo.hash = HASH;
repo.name = NAME; repo.name = NAME;
repo.url = URL; repo.url = URL;
repo.rev = REV;
for (const auto& [key, val] : STATE) { for (const auto& [key, val] : STATE) {
if (key == "repository") if (key == "repository")

View file

@ -12,6 +12,7 @@ struct SPlugin {
struct SPluginRepository { struct SPluginRepository {
std::string url; std::string url;
std::string rev;
std::string name; std::string name;
std::vector<SPlugin> plugins; std::vector<SPlugin> plugins;
std::string hash; std::string hash;

View file

@ -77,8 +77,7 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
return ver; return ver;
} }
bool CPluginManager::addNewPluginRepo(const std::string& url) { bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string& rev) {
const auto HLVER = getHyprlandVersion(); const auto HLVER = getHyprlandVersion();
if (DataState::pluginRepoExists(url)) { if (DataState::pluginRepoExists(url)) {
@ -134,6 +133,14 @@ bool CPluginManager::addNewPluginRepo(const std::string& url) {
return false; 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.m_iSteps = 1;
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " cloned"); progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " cloned");
progress.m_szCurrentMessage = "Reading the manifest"; progress.m_szCurrentMessage = "Reading the manifest";
@ -240,6 +247,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url) {
repohash.pop_back(); repohash.pop_back();
repo.name = pManifest->m_sRepository.name.empty() ? url.substr(url.find_last_of('/') + 1) : pManifest->m_sRepository.name; repo.name = pManifest->m_sRepository.name.empty() ? url.substr(url.find_last_of('/') + 1) : pManifest->m_sRepository.name;
repo.url = url; repo.url = url;
repo.rev = rev;
repo.hash = repohash; repo.hash = repohash;
for (auto& p : pManifest->m_vPlugins) { for (auto& p : pManifest->m_vPlugins) {
repo.plugins.push_back(SPlugin{p.name, "/tmp/hyprpm/new/" + p.output, false, p.failed}); 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; 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) { if (!update) {
// check if git has updates // check if git has updates
std::string hash = execAndGet("cd /tmp/hyprpm/update && git rev-parse HEAD"); std::string hash = execAndGet("cd /tmp/hyprpm/update && git rev-parse HEAD");
@ -538,8 +556,8 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
continue; continue;
} }
if (!pManifest->m_sRepository.commitPins.empty()) { if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) {
// check commit pins // 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"); progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");

View file

@ -36,7 +36,7 @@ struct SHyprlandVersion {
class CPluginManager { class CPluginManager {
public: public:
bool addNewPluginRepo(const std::string& url); bool addNewPluginRepo(const std::string& url, const std::string& rev);
bool removePluginRepo(const std::string& urlOrName); bool removePluginRepo(const std::string& urlOrName);
eHeadersErrors headersValid(); eHeadersErrors headersValid();
@ -60,4 +60,4 @@ class CPluginManager {
std::string headerError(const eHeadersErrors err); std::string headerError(const eHeadersErrors err);
}; };
inline std::unique_ptr<CPluginManager> g_pPluginManager; inline std::unique_ptr<CPluginManager> g_pPluginManager;

View file

@ -11,7 +11,8 @@
const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager 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 remove [url/name] Remove an installed plugin repository
enable [name] Enable a plugin enable [name] Enable a plugin
disable [name] Disable a plugin disable [name] Disable a plugin
@ -77,7 +78,12 @@ int main(int argc, char** argv, char** envp) {
return 1; 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") { } else if (command[0] == "remove") {
if (ARGS.size() < 2) { if (ARGS.size() < 2) {
std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for remove.\n"; std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for remove.\n";