From 3cc7124e143a9e3c546ce9612ff455b7dafe8d8c Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 22 Jun 2025 12:35:54 +1200 Subject: [PATCH] 'Generic Commit' --- getpkg/src/main.cpp | 38 ++++++++++----------- getpkg/src/temp_directory.cpp | 63 +++++++++++++++++++++++++++++++++++ getpkg/src/temp_directory.hpp | 30 +++++++++++++++++ 3 files changed, 111 insertions(+), 20 deletions(-) create mode 100644 getpkg/src/temp_directory.cpp create mode 100644 getpkg/src/temp_directory.hpp diff --git a/getpkg/src/main.cpp b/getpkg/src/main.cpp index 30a6f32..345e28e 100644 --- a/getpkg/src/main.cpp +++ b/getpkg/src/main.cpp @@ -70,6 +70,8 @@ #include #include +#include "temp_directory.hpp" + namespace { using json = nlohmann::json; @@ -145,21 +147,13 @@ int install_tool(int argc, char* argv[]) { std::string arch = get_arch(); std::string home = get_home(); + getpkg::TempDirectory tempDir; std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg"; std::filesystem::path binDir = std::filesystem::path(home) / ".getpkg" / toolName; - std::filesystem::path archivePath = configDir / (toolName + ".tgz"); + std::filesystem::path archivePath = tempDir.path() / (toolName + ".tgz"); std::filesystem::path toolInfoPath = configDir / (toolName + ".json"); - // Initialize directories - std::filesystem::create_directories(configDir); - std::filesystem::create_directories(binDir.parent_path()); - - // Initialize bashrc - dropshelltool::BashrcEditor bashrcEditor; - bashrcEditor.addSourceLine(); - // Check if tool needs update or install - bool needsUpdate = false; if (std::filesystem::exists(toolInfoPath)) { // Tool exists, check if update needed std::ifstream tfile(toolInfoPath); @@ -175,7 +169,6 @@ int install_tool(int argc, char* argv[]) { std::string remoteHash; if (getbin.getHash(toolName, localArch, remoteHash) && !remoteHash.empty()) { if (localHash != remoteHash) { - needsUpdate = true; std::cout << "Updating " << toolName << "..." << std::endl; } else { std::cout << toolName << " is already up to date." << std::endl; @@ -183,26 +176,34 @@ int install_tool(int argc, char* argv[]) { } } else { // If we can't get remote hash, assume update is needed - needsUpdate = true; std::cout << "Updating " << toolName << "..." << std::endl; } } else { std::cout << "Installing " << toolName << "..." << std::endl; } + + // Initialize directories + std::filesystem::create_directories(configDir); + std::filesystem::create_directories(binDir.parent_path()); + + // Initialize bashrc + dropshelltool::BashrcEditor bashrcEditor; + bashrcEditor.addSourceLine(); // Remove existing installation DropshellScriptManager scriptManager; scriptManager.removeToolEntry(toolName); - if (std::filesystem::exists(binDir)) std::filesystem::remove_all(binDir); + if (std::filesystem::exists(binDir)) + std::filesystem::remove_all(binDir); // Download tool - try arch-specific version first, then universal fallback GetbinClient getbin2; std::string downloadArch = arch; - std::cout << "Downloading " << toolName << ":" << arch << "..." << std::endl; + //std::cout << "Downloading " << toolName << ":" << arch << "..." << std::endl; if (!getbin2.download(toolName, arch, archivePath.string())) { // Try universal version as fallback - std::cout << "Arch-specific version not found, trying universal version..." << std::endl; - std::cout << "Downloading " << toolName << ":universal..." << std::endl; + //std::cout << "Arch-specific version not found, trying universal version..." << std::endl; + //std::cout << "Downloading " << toolName << ":universal..." << std::endl; if (!getbin2.download(toolName, "universal", archivePath.string())) { std::cerr << "Failed to download tool archive (tried both " << arch << " and universal)." << std::endl; return 1; @@ -216,10 +217,7 @@ int install_tool(int argc, char* argv[]) { std::cerr << "Failed to unpack tool archive." << std::endl; return 1; } - - // Clean up the archive file - std::filesystem::remove(archivePath); - + // Add to PATH and autocomplete scriptManager.addToolEntry(toolName, binDir.string()); scriptManager.addAutocomplete(toolName); diff --git a/getpkg/src/temp_directory.cpp b/getpkg/src/temp_directory.cpp new file mode 100644 index 0000000..7c1465d --- /dev/null +++ b/getpkg/src/temp_directory.cpp @@ -0,0 +1,63 @@ +#include "temp_directory.hpp" + +#include +#include +#include +#include +#include +#include // For error reporting in destructor + +namespace simple_object_storage { + +TempDirectory::TempDirectory(const std::string& prefix) { + auto temp_dir_base = std::filesystem::temp_directory_path(); + std::mt19937_64 rng(std::chrono::high_resolution_clock::now().time_since_epoch().count()); + std::uniform_int_distribution dist; + + int retries = 5; // Avoid infinite loop in edge cases + while (retries-- > 0) { + std::string random_suffix = std::to_string(dist(rng)); + path_ = temp_dir_base / (prefix + random_suffix); + if (!std::filesystem::exists(path_)) { + break; // Found a unique path + } + } + + if (std::filesystem::exists(path_)) { + throw std::runtime_error("Failed to find unique temporary directory path after multiple retries."); + } + + try { + if (!std::filesystem::create_directory(path_)) { + throw std::runtime_error("Failed to create temporary directory: " + path_.string()); + } + } catch (const std::filesystem::filesystem_error& e) { + throw std::runtime_error("Filesystem error creating temporary directory: " + path_.string() + " - " + e.what()); + } +} + +TempDirectory::~TempDirectory() { + try { + if (std::filesystem::exists(path_)) { + std::error_code ec; // Use error code to avoid exceptions in destructor + std::filesystem::remove_all(path_, ec); + if (ec) { + std::cerr << "Error removing temporary directory " << path_.string() << ": " << ec.message() << std::endl; + } + } + } catch (const std::exception& e) { // Catch potential exceptions from exists() though unlikely + std::cerr << "Error during temporary directory cleanup for " << path_.string() << ": " << e.what() << std::endl; + } catch (...) { + std::cerr << "Unknown error during temporary directory cleanup for " << path_.string() << std::endl; + } +} + +const std::filesystem::path& TempDirectory::path() const { + return path_; +} + +std::string TempDirectory::string() const { + return path_.string(); +} + +} // namespace simple_object_storage \ No newline at end of file diff --git a/getpkg/src/temp_directory.hpp b/getpkg/src/temp_directory.hpp new file mode 100644 index 0000000..c65a2e4 --- /dev/null +++ b/getpkg/src/temp_directory.hpp @@ -0,0 +1,30 @@ +#ifndef TEMP_DIRECTORY_HPP +#define TEMP_DIRECTORY_HPP + +#include +#include + +namespace getpkg { + +// RAII helper for temporary directory cleanup +class TempDirectory { +public: + TempDirectory(const std::string& prefix = "temp_"); + ~TempDirectory(); + + // Disable copy/move semantics for simplicity + TempDirectory(const TempDirectory&) = delete; + TempDirectory& operator=(const TempDirectory&) = delete; + TempDirectory(TempDirectory&&) = delete; + TempDirectory& operator=(TempDirectory&&) = delete; + + const std::filesystem::path& path() const; + std::string string() const; + +private: + std::filesystem::path path_; +}; + +} // namespace simple_object_storage + +#endif // TEMP_DIRECTORY_HPP \ No newline at end of file