diff --git a/getpkg/src/GetbinClient.cpp b/getpkg/src/GetbinClient.cpp index 2129a1f..3f5e1e3 100644 --- a/getpkg/src/GetbinClient.cpp +++ b/getpkg/src/GetbinClient.cpp @@ -267,4 +267,51 @@ bool GetbinClient::listPackages(std::vector& outPackages) { std::cerr << "[GetbinClient::listPackages] Exception: " << e.what() << std::endl; return false; } -} \ No newline at end of file +} + +bool GetbinClient::listAllEntries(std::vector>>& outEntries) { + try { + std::string url = "https://" + SERVER_HOST + "/dir"; + + auto response = cpr::Get(cpr::Url{url}, + cpr::Header{{"User-Agent", getUserAgent()}}, + cpr::Timeout{30000}, // 30 seconds + cpr::VerifySsl{true}); + + if (response.status_code == 200) { + try { + auto resp_json = json::parse(response.text); + if (resp_json.contains("entries") && resp_json["entries"].is_array()) { + outEntries.clear(); + + for (const auto& entry : resp_json["entries"]) { + if (entry.contains("hash") && entry.contains("labeltags") && + entry["hash"].is_string() && entry["labeltags"].is_array()) { + + std::string hash = entry["hash"].get(); + std::vector labeltags; + + for (const auto& tag : entry["labeltags"]) { + if (tag.is_string()) { + labeltags.push_back(tag.get()); + } + } + + outEntries.push_back({hash, labeltags}); + } + } + return true; + } + } catch (const json::exception& e) { + std::cerr << "[GetbinClient::listAllEntries] JSON parse error: " << e.what() << std::endl; + } + } else { + std::cerr << "[GetbinClient::listAllEntries] HTTP " << response.status_code << ": " << response.error.message << std::endl; + } + + return false; + } catch (const std::exception& e) { + std::cerr << "[GetbinClient::listAllEntries] Exception: " << e.what() << std::endl; + return false; + } +} diff --git a/getpkg/src/GetbinClient.hpp b/getpkg/src/GetbinClient.hpp index d45eca1..9208e99 100644 --- a/getpkg/src/GetbinClient.hpp +++ b/getpkg/src/GetbinClient.hpp @@ -17,8 +17,9 @@ public: bool getHash(const std::string& toolName, const std::string& arch, std::string& outHash); bool deleteObject(const std::string& hash, const std::string& token); bool listPackages(std::vector& outPackages); + bool listAllEntries(std::vector>>& outEntries); private: static const std::string SERVER_HOST; std::string getUserAgent() const; -}; \ No newline at end of file +}; diff --git a/getpkg/src/main.cpp b/getpkg/src/main.cpp index 4815d39..dacddbb 100644 --- a/getpkg/src/main.cpp +++ b/getpkg/src/main.cpp @@ -701,35 +701,34 @@ int unpublish_tool(int argc, char* argv[]) { return 1; } } else { - // No specific architecture - unpublish all architectures - std::vector allArchitectures = {"x86_64", "aarch64", "universal"}; - std::vector> foundPackages; + // No specific architecture - unpublish ALL entries with this tool name + std::vector>> allEntries; + std::vector> foundPackages; // (tag, hash) - std::cout << "Searching for " << toolName << " across all architectures..." << std::endl; + std::cout << "Searching for all entries with label '" << toolName << "'..." << std::endl; - // Find all existing versions - for (const auto& arch : allArchitectures) { - std::string archHash; - if (getbin.getHash(toolName, arch, archHash) && !archHash.empty()) { - // Validate hash - bool validHash = true; - for (char c : archHash) { - if (!std::isdigit(c)) { - validHash = false; - break; - } - } - - if (validHash) { - foundPackages.push_back({arch, archHash}); - std::cout << " Found " << toolName << ":" << arch << " (hash: " << archHash << ")" << std::endl; + if (!getbin.listAllEntries(allEntries)) { + std::cerr << "Failed to get directory listing from server" << std::endl; + return 1; + } + + // Find all entries with labeltags starting with toolName: + for (const auto& entry : allEntries) { + const std::string& hash = entry.first; + const std::vector& labeltags = entry.second; + + for (const std::string& tag : labeltags) { + if (tag.find(toolName + ":") == 0) { + // Found a matching labeltag + foundPackages.push_back({tag, hash}); + std::cout << " Found " << tag << " (hash: " << hash << ")" << std::endl; + break; // Only count each hash once even if it has multiple matching tags } } } if (foundPackages.empty()) { std::cerr << "No packages found for " << toolName << std::endl; - std::cerr << "Searched architectures: x86_64, aarch64, universal" << std::endl; return 1; } @@ -741,7 +740,7 @@ int unpublish_tool(int argc, char* argv[]) { int failCount = 0; for (const auto& [arch, archHash] : foundPackages) { - std::cout << " Unpublishing " << toolName << ":" << arch << "... "; + std::cout << " Unpublishing " << arch << "... "; if (getbin.deleteObject(archHash, token)) { std::cout << "OK" << std::endl; successCount++; diff --git a/getpkg/test_display/test-display b/getpkg/test_display/test-display new file mode 100755 index 0000000..d31b42e --- /dev/null +++ b/getpkg/test_display/test-display @@ -0,0 +1 @@ +#!/bin/bash\necho display test diff --git a/getpkg/test_multi/test-multi b/getpkg/test_multi/test-multi new file mode 100755 index 0000000..fa15ed5 --- /dev/null +++ b/getpkg/test_multi/test-multi @@ -0,0 +1 @@ +#!/bin/bash\necho multi arch diff --git a/getpkg/test_robust/test-robust b/getpkg/test_robust/test-robust new file mode 100755 index 0000000..8f679a0 --- /dev/null +++ b/getpkg/test_robust/test-robust @@ -0,0 +1 @@ +#!/bin/bash\necho robust test