2 Commits

Author SHA1 Message Date
0f5421630a feat: Update 3 files
Some checks failed
Build-Test-Publish / build (linux/amd64) (push) Successful in 1m16s
Build-Test-Publish / build (linux/arm64) (push) Failing after 2m7s
Build-Test-Publish / test-install-from-scratch (linux/amd64) (push) Has been skipped
Build-Test-Publish / test-install-from-scratch (linux/arm64) (push) Has been skipped
2025-06-29 19:55:07 +12:00
50fb5f9da6 feat: Update 2 files
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 1m15s
Build-Test-Publish / build (linux/arm64) (push) Successful in 2m6s
Build-Test-Publish / test-install-from-scratch (linux/amd64) (push) Successful in 7s
Build-Test-Publish / test-install-from-scratch (linux/arm64) (push) Successful in 7s
2025-06-29 19:46:55 +12:00
6 changed files with 99 additions and 37 deletions

View File

@ -5,6 +5,7 @@
#include <iostream>
#include <filesystem>
#include <sstream>
#include <set>
#include <algorithm>
using json = nlohmann::json;
@ -207,7 +208,7 @@ bool GetbinClient::deleteObject(const std::string& hash, const std::string& toke
bool GetbinClient::listPackages(std::vector<std::string>& outPackages) {
try {
std::string url = "https://" + SERVER_HOST + "/packages";
std::string url = "https://" + SERVER_HOST + "/dir";
auto response = cpr::Get(cpr::Url{url},
cpr::Header{{"User-Agent", getUserAgent()}},
@ -217,20 +218,31 @@ bool GetbinClient::listPackages(std::vector<std::string>& outPackages) {
if (response.status_code == 200) {
try {
auto resp_json = json::parse(response.text);
if (resp_json.is_array()) {
if (resp_json.contains("entries") && resp_json["entries"].is_array()) {
outPackages.clear();
for (const auto& item : resp_json) {
if (item.is_string()) {
outPackages.push_back(item.get<std::string>());
std::set<std::string> uniqueTools;
for (const auto& entry : resp_json["entries"]) {
if (entry.contains("labeltags") && entry["labeltags"].is_array()) {
for (const auto& labeltag : entry["labeltags"]) {
if (labeltag.is_string()) {
std::string tag = labeltag.get<std::string>();
// Extract tool name from "tool:arch" format
size_t colonPos = tag.find(":");
if (colonPos != std::string::npos) {
std::string toolName = tag.substr(0, colonPos);
if (!toolName.empty()) {
uniqueTools.insert(toolName);
}
}
}
}
}
}
return true;
} else if (resp_json.contains("packages") && resp_json["packages"].is_array()) {
outPackages.clear();
for (const auto& item : resp_json["packages"]) {
if (item.is_string()) {
outPackages.push_back(item.get<std::string>());
}
// Convert set to vector
for (const auto& tool : uniqueTools) {
outPackages.push_back(tool);
}
return true;
}
@ -255,4 +267,51 @@ bool GetbinClient::listPackages(std::vector<std::string>& outPackages) {
std::cerr << "[GetbinClient::listPackages] Exception: " << e.what() << std::endl;
return false;
}
}
}
bool GetbinClient::listAllEntries(std::vector<std::pair<std::string, std::vector<std::string>>>& 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::string>();
std::vector<std::string> labeltags;
for (const auto& tag : entry["labeltags"]) {
if (tag.is_string()) {
labeltags.push_back(tag.get<std::string>());
}
}
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;
}
}

View File

@ -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<std::string>& outPackages);
bool listAllEntries(std::vector<std::pair<std::string, std::vector<std::string>>>& outEntries);
private:
static const std::string SERVER_HOST;
std::string getUserAgent() const;
};
};

View File

@ -701,35 +701,34 @@ int unpublish_tool(int argc, char* argv[]) {
return 1;
}
} else {
// No specific architecture - unpublish all architectures
std::vector<std::string> allArchitectures = {"x86_64", "aarch64", "universal"};
std::vector<std::pair<std::string, std::string>> foundPackages;
// No specific architecture - unpublish ALL entries with this tool name
std::vector<std::pair<std::string, std::vector<std::string>>> allEntries;
std::vector<std::pair<std::string, std::string>> 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<std::string>& 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++;
@ -824,7 +823,7 @@ int list_packages(int argc, char* argv[]) {
for (const auto& packageName : availablePackages) {
std::string status = "Available";
std::string localVersion = "-";
std::string remoteStatus = "";
std::string remoteStatus = "-";
auto it = installedPackages.find(packageName);
if (it != installedPackages.end()) {

View File

@ -0,0 +1 @@
#!/bin/bash\necho display test

1
getpkg/test_multi/test-multi Executable file
View File

@ -0,0 +1 @@
#!/bin/bash\necho multi arch

1
getpkg/test_robust/test-robust Executable file
View File

@ -0,0 +1 @@
#!/bin/bash\necho robust test