aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2024-04-28 20:27:44 +0100
committerVaxry <[email protected]>2024-04-28 20:27:44 +0100
commit335015fe2defae76b4fd22ebfe8e3614a01495b7 (patch)
tree196fe4eb985aa9d4bda3c05141612b3e9916ff99
parentf7815dab42ee570c38bd7ae85a4f2a6e36803809 (diff)
downloadHyprland-335015fe2defae76b4fd22ebfe8e3614a01495b7.tar.gz
Hyprland-335015fe2defae76b4fd22ebfe8e3614a01495b7.zip
hyprpm: fix for multi-user + improve directory structure
-rw-r--r--hyprpm/src/core/PluginManager.cpp135
-rw-r--r--hyprpm/src/core/PluginManager.hpp5
2 files changed, 87 insertions, 53 deletions
diff --git a/hyprpm/src/core/PluginManager.cpp b/hyprpm/src/core/PluginManager.cpp
index 6ac5445e..14b93d3e 100644
--- a/hyprpm/src/core/PluginManager.cpp
+++ b/hyprpm/src/core/PluginManager.cpp
@@ -12,6 +12,10 @@
#include <algorithm>
#include <format>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
#include <toml++/toml.hpp>
static std::string removeBeginEndSpacesTabs(std::string str) {
@@ -92,6 +96,22 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
return ver;
}
+bool CPluginManager::createSafeDirectory(const std::string& path) {
+ if (path.empty() || !path.starts_with("/tmp"))
+ return false;
+
+ if (std::filesystem::exists(path))
+ std::filesystem::remove_all(path);
+
+ if (std::filesystem::exists(path))
+ return false;
+
+ if (mkdir(path.c_str(), S_IRWXU) < 0)
+ return false;
+
+ return true;
+}
+
bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string& rev) {
const auto HLVER = getHyprlandVersion();
@@ -137,24 +157,31 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
if (!std::filesystem::exists("/tmp/hyprpm")) {
std::filesystem::create_directory("/tmp/hyprpm");
std::filesystem::permissions("/tmp/hyprpm", std::filesystem::perms::all, std::filesystem::perm_options::replace);
+ } else if (!std::filesystem::is_directory("/tmp/hyprpm")) {
+ std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for hyprpm\n";
+ return false;
}
- if (std::filesystem::exists("/tmp/hyprpm/new")) {
- progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " old plugin repo build files found in temp directory, removing.");
- std::filesystem::remove_all("/tmp/hyprpm/new");
+ const std::string USERNAME = getpwuid(getuid())->pw_name;
+
+ m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
+
+ if (!createSafeDirectory(m_szWorkingPluginDirectory)) {
+ std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for repo\n";
+ return false;
}
progress.printMessageAbove(std::string{Colors::RESET} + " → Cloning " + url);
- std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + url + " new");
+ std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + url + " " + USERNAME);
- if (!std::filesystem::exists("/tmp/hyprpm/new")) {
+ if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the plugin repository. shell returned:\n" << ret << "\n";
return false;
}
if (!rev.empty()) {
- std::string ret = execAndGet("git -C /tmp/hyprpm/new reset --hard --recurse-submodules " + rev);
+ std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " 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;
@@ -168,12 +195,12 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
std::unique_ptr<CManifest> pManifest;
- if (std::filesystem::exists("/tmp/hyprpm/new/hyprpm.toml")) {
+ if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprpm manifest");
- pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, "/tmp/hyprpm/new/hyprpm.toml");
- } else if (std::filesystem::exists("/tmp/hyprpm/new/hyprload.toml")) {
+ pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
+ } else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprload manifest");
- pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, "/tmp/hyprpm/new/hyprload.toml");
+ pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
}
if (!pManifest) {
@@ -212,7 +239,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
- execAndGet("cd /tmp/hyprpm/new/ && git reset --hard --recurse-submodules " + plugin);
+ execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
}
}
@@ -243,14 +270,14 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + p.name);
for (auto& bs : p.buildSteps) {
- std::string cmd = std::format("cd /tmp/hyprpm/new && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", DataState::getHeadersPath(), bs);
+ std::string cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
}
if (m_bVerbose)
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
- if (!std::filesystem::exists("/tmp/hyprpm/new/" + p.output)) {
+ if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Plugin " + p.name + " failed to build.\n" +
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n If you are on -git, update "
"first.\n Try re-running with -v to see "
@@ -270,7 +297,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
// add repo toml to DataState
SPluginRepository repo;
- std::string repohash = execAndGet("cd /tmp/hyprpm/new/ && git rev-parse HEAD");
+ std::string repohash = execAndGet("cd " + m_szWorkingPluginDirectory + " && git rev-parse HEAD");
if (repohash.length() > 0)
repohash.pop_back();
repo.name = pManifest->m_sRepository.name.empty() ? url.substr(url.find_last_of('/') + 1) : pManifest->m_sRepository.name;
@@ -278,7 +305,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
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});
+ repo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, false, p.failed});
}
DataState::addNewPluginRepo(repo);
@@ -291,7 +318,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
std::cout << "\n";
// remove build files
- std::filesystem::remove_all("/tmp/hyprpm/new");
+ std::filesystem::remove_all(m_szWorkingPluginDirectory);
return true;
}
@@ -404,9 +431,12 @@ bool CPluginManager::updateHeaders(bool force) {
progress.m_szCurrentMessage = "Cloning the hyprland repository";
progress.print();
- if (std::filesystem::exists("/tmp/hyprpm/hyprland")) {
- progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " old hyprland source files found in temp directory, removing.");
- std::filesystem::remove_all("/tmp/hyprpm/hyprland");
+ const std::string USERNAME = getpwuid(getuid())->pw_name;
+ const auto WORKINGDIR = "/tmp/hyprpm/hyprland-" + USERNAME;
+
+ if (!createSafeDirectory(WORKINGDIR)) {
+ std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for hl\n";
+ return false;
}
progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " Cloning https://github.com/hyprwm/hyprland, this might take a moment.");
@@ -418,14 +448,14 @@ bool CPluginManager::updateHeaders(bool force) {
if (m_bVerbose)
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "will shallow since: " + SHALLOW_DATE);
- std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland --shallow-since='" + SHALLOW_DATE + "'");
+ std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland-" + USERNAME + " --shallow-since='" + SHALLOW_DATE + "'");
- if (!std::filesystem::exists("/tmp/hyprpm/hyprland")) {
+ if (!std::filesystem::exists(WORKINGDIR)) {
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Clone failed. Retrying without shallow.");
- ret = execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland");
+ ret = execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland-" + USERNAME);
}
- if (!std::filesystem::exists("/tmp/hyprpm/hyprland")) {
+ if (!std::filesystem::exists(WORKINGDIR + "/.git")) {
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the hyprland repository. shell returned:\n" << ret << "\n";
return false;
}
@@ -435,12 +465,12 @@ bool CPluginManager::updateHeaders(bool force) {
progress.m_szCurrentMessage = "Checking out sources";
progress.print();
- ret = execAndGet("cd /tmp/hyprpm/hyprland && git checkout " + HLVER.branch + " 2>&1");
+ ret = execAndGet("cd " + WORKINGDIR + " && git checkout " + HLVER.branch + " 2>&1");
if (m_bVerbose)
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "git returned (co): " + ret);
- ret = execAndGet("cd /tmp/hyprpm/hyprland && git rm subprojects/tracy && git submodule update --init 2>&1 && git reset --hard --recurse-submodules " + HLVER.hash);
+ ret = execAndGet("cd " + WORKINGDIR + " && git rm subprojects/tracy && git submodule update --init 2>&1 && git reset --hard --recurse-submodules " + HLVER.hash);
if (m_bVerbose)
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "git returned (rs): " + ret);
@@ -455,14 +485,13 @@ bool CPluginManager::updateHeaders(bool force) {
if (m_bVerbose)
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "setting PREFIX for cmake to " + DataState::getHeadersPath());
- ret = execAndGet(
- std::format("cd /tmp/hyprpm/hyprland && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=\"{}\" -S . -B ./build -G Ninja",
- DataState::getHeadersPath()));
+ ret = execAndGet(std::format("cd {} && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=\"{}\" -S . -B ./build -G Ninja", WORKINGDIR,
+ DataState::getHeadersPath()));
if (m_bVerbose)
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "cmake returned: " + ret);
// le hack. Wlroots has to generate its build/include
- ret = execAndGet("cd /tmp/hyprpm/hyprland/subprojects/wlroots-hyprland && meson setup -Drenderers=gles2 -Dexamples=false build");
+ ret = execAndGet("cd " + WORKINGDIR + "/subprojects/wlroots-hyprland && meson setup -Drenderers=gles2 -Dexamples=false build");
if (m_bVerbose)
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "meson returned: " + ret);
@@ -471,8 +500,8 @@ bool CPluginManager::updateHeaders(bool force) {
progress.m_szCurrentMessage = "Installing sources";
progress.print();
- std::string cmd = std::format("sed -i -e \"s#PREFIX = /usr/local#PREFIX = {}#\" /tmp/hyprpm/hyprland/Makefile && cd /tmp/hyprpm/hyprland && make installheaders",
- DataState::getHeadersPath());
+ std::string cmd =
+ std::format("sed -i -e \"s#PREFIX = /usr/local#PREFIX = {}#\" {}/Makefile && cd {} && make installheaders", WORKINGDIR, WORKINGDIR, DataState::getHeadersPath());
if (m_bVerbose)
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "installation will run: " + cmd);
@@ -482,7 +511,7 @@ bool CPluginManager::updateHeaders(bool force) {
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "installer returned: " << ret << "\n";
// remove build files
- std::filesystem::remove_all("/tmp/hyprpm/hyprland");
+ std::filesystem::remove_all(WORKINGDIR);
auto HEADERSVALID = headersValid();
if (HEADERSVALID == HEADERS_OK) {
@@ -529,6 +558,9 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
progress.m_szCurrentMessage = "Updating repositories";
progress.print();
+ const std::string USERNAME = getpwuid(getuid())->pw_name;
+ m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
+
for (auto& repo : REPOS) {
bool update = forceUpdateAll;
@@ -538,16 +570,13 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
progress.printMessageAbove(std::string{Colors::RESET} + " → checking for updates for " + repo.name);
- if (std::filesystem::exists("/tmp/hyprpm/update")) {
- progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " old update build files found in temp directory, removing.");
- std::filesystem::remove_all("/tmp/hyprpm/update");
- }
+ createSafeDirectory(m_szWorkingPluginDirectory);
progress.printMessageAbove(std::string{Colors::RESET} + " → Cloning " + repo.url);
- std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + repo.url + " update");
+ std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + repo.url + " " + USERNAME);
- if (!std::filesystem::exists("/tmp/hyprpm/update")) {
+ if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " could not clone repo: shell returned:\n" + ret;
return false;
}
@@ -555,7 +584,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
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/update reset --hard --recurse-submodules " + repo.rev);
+ std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " 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;
@@ -564,7 +593,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
if (!update) {
// check if git has updates
- std::string hash = execAndGet("cd /tmp/hyprpm/update && git rev-parse HEAD");
+ std::string hash = execAndGet("cd " + m_szWorkingPluginDirectory + " && git rev-parse HEAD");
if (!hash.empty())
hash.pop_back();
@@ -572,7 +601,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
}
if (!update) {
- std::filesystem::remove_all("/tmp/hyprpm/update");
+ std::filesystem::remove_all(m_szWorkingPluginDirectory);
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " repository " + repo.name + " is up-to-date.");
progress.m_iSteps++;
progress.print();
@@ -588,12 +617,12 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
std::unique_ptr<CManifest> pManifest;
- if (std::filesystem::exists("/tmp/hyprpm/update/hyprpm.toml")) {
+ if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprpm manifest");
- pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, "/tmp/hyprpm/update/hyprpm.toml");
- } else if (std::filesystem::exists("/tmp/hyprpm/update/hyprload.toml")) {
+ pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
+ } else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprload manifest");
- pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, "/tmp/hyprpm/update/hyprload.toml");
+ pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
}
if (!pManifest) {
@@ -617,7 +646,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
- execAndGet("cd /tmp/hyprpm/update/ && git reset --hard --recurse-submodules " + plugin);
+ execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
}
}
@@ -633,14 +662,14 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + p.name);
for (auto& bs : p.buildSteps) {
- std::string cmd = std::format("cd /tmp/hyprpm/update && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", DataState::getHeadersPath(), bs);
+ std::string cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
}
if (m_bVerbose)
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
- if (!std::filesystem::exists("/tmp/hyprpm/update/" + p.output)) {
+ if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
std::cerr << "\n"
<< Colors::RED << "✖" << Colors::RESET << " Plugin " << p.name << " failed to build.\n"
<< " This likely means that the plugin is either outdated, not yet available for your version, or broken.\n If you are on -git, update first.\n Try "
@@ -656,20 +685,20 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
// add repo toml to DataState
SPluginRepository newrepo = repo;
newrepo.plugins.clear();
- execAndGet(
- "cd /tmp/hyprpm/update/ && git pull --recurse-submodules && git reset --hard --recurse-submodules"); // repo hash in the state.toml has to match head and not any pin
- std::string repohash = execAndGet("cd /tmp/hyprpm/update && git rev-parse HEAD");
+ execAndGet("cd " + m_szWorkingPluginDirectory +
+ " && git pull --recurse-submodules && git reset --hard --recurse-submodules"); // repo hash in the state.toml has to match head and not any pin
+ std::string repohash = execAndGet("cd " + m_szWorkingPluginDirectory + " && git rev-parse HEAD");
if (repohash.length() > 0)
repohash.pop_back();
newrepo.hash = repohash;
for (auto& p : pManifest->m_vPlugins) {
const auto OLDPLUGINIT = std::find_if(repo.plugins.begin(), repo.plugins.end(), [&](const auto& other) { return other.name == p.name; });
- newrepo.plugins.push_back(SPlugin{p.name, "/tmp/hyprpm/update/" + p.output, OLDPLUGINIT != repo.plugins.end() ? OLDPLUGINIT->enabled : false});
+ newrepo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, OLDPLUGINIT != repo.plugins.end() ? OLDPLUGINIT->enabled : false});
}
DataState::removePluginRepo(newrepo.name);
DataState::addNewPluginRepo(newrepo);
- std::filesystem::remove_all("/tmp/hyprpm/update");
+ std::filesystem::remove_all(m_szWorkingPluginDirectory);
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " updated " + repo.name);
}
diff --git a/hyprpm/src/core/PluginManager.hpp b/hyprpm/src/core/PluginManager.hpp
index f934d34a..a87240e3 100644
--- a/hyprpm/src/core/PluginManager.hpp
+++ b/hyprpm/src/core/PluginManager.hpp
@@ -60,8 +60,13 @@ class CPluginManager {
bool m_bVerbose = false;
+ // will delete recursively if exists!!
+ bool createSafeDirectory(const std::string& path);
+
private:
std::string headerError(const eHeadersErrors err);
+
+ std::string m_szWorkingPluginDirectory = "";
};
inline std::unique_ptr<CPluginManager> g_pPluginManager;