diff --git a/getpkg/src/main.cpp b/getpkg/src/main.cpp index eee97e8..03dd541 100644 --- a/getpkg/src/main.cpp +++ b/getpkg/src/main.cpp @@ -535,40 +535,122 @@ int unpublish_tool(int argc, char* argv[]) { } if (!isHash) { - // Target is a tool name, need to get hash first + // Target is a tool name, need to get hashes for all architectures std::string toolName = target; - std::string arch = "x86_64"; // default + std::string specificArch = ""; // Check if arch is specified (contains :) if (target.find(':') != std::string::npos) { toolName = target.substr(0, target.find(':')); - arch = target.substr(target.find(':') + 1); + specificArch = target.substr(target.find(':') + 1); } - if (!getbin.getHash(toolName, arch, hash)) { - std::cerr << "Failed to get hash for " << target << std::endl; - return 1; + // If a specific architecture was requested, only unpublish that one + if (!specificArch.empty()) { + if (!getbin.getHash(toolName, specificArch, hash)) { + std::cerr << "Failed to get hash for " << target << std::endl; + return 1; + } + + if (hash.empty()) { + std::cerr << "Tool " << target << " not found" << std::endl; + return 1; + } + + // Validate that we got a real hash (should be numeric) + bool validHash = true; + for (char c : hash) { + if (!std::isdigit(c)) { + validHash = false; + break; + } + } + + if (!validHash) { + std::cerr << "Error: Invalid hash received: " << hash << std::endl; + std::cerr << "The server may not have found the package." << std::endl; + return 1; + } + + std::cout << "Found hash " << hash << " for " << target << std::endl; + + // Delete the specific architecture + if (getbin.deleteObject(hash, token)) { + std::cout << "Successfully unpublished " << target << " (hash: " << hash << ")" << std::endl; + return 0; + } else { + std::cerr << "Failed to unpublish " << target << std::endl; + return 1; + } + } else { + // No specific architecture - unpublish all architectures + std::vector allArchitectures = {"x86_64", "aarch64", "universal"}; + std::vector> foundPackages; + + std::cout << "Searching for " << toolName << " across all architectures..." << 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 (foundPackages.empty()) { + std::cerr << "No packages found for " << toolName << std::endl; + std::cerr << "Searched architectures: x86_64, aarch64, universal" << std::endl; + return 1; + } + + // Unpublish all found packages + std::cout << std::endl; + std::cout << "Unpublishing " << foundPackages.size() << " package(s)..." << std::endl; + + int successCount = 0; + int failCount = 0; + + for (const auto& [arch, archHash] : foundPackages) { + std::cout << " Unpublishing " << toolName << ":" << arch << "... "; + if (getbin.deleteObject(archHash, token)) { + std::cout << "OK" << std::endl; + successCount++; + } else { + std::cout << "FAILED" << std::endl; + failCount++; + } + } + + std::cout << std::endl; + if (failCount == 0) { + std::cout << "Successfully unpublished all " << successCount << " version(s) of " << toolName << std::endl; + return 0; + } else { + std::cerr << "Failed to unpublish " << failCount << " out of " << foundPackages.size() << " packages" << std::endl; + return 1; + } } - - if (hash.empty()) { - std::cerr << "Tool " << target << " not found" << std::endl; - return 1; - } - - std::cout << "Found hash " << hash << " for " << target << std::endl; - } - - // Delete the object - if (getbin.deleteObject(hash, token)) { - std::cout << "Successfully unpublished " << target; - if (!isHash) { - std::cout << " (hash: " << hash << ")"; - } - std::cout << std::endl; - return 0; } else { - std::cerr << "Failed to unpublish " << target << std::endl; - return 1; + // Target is a hash - just delete it directly + if (getbin.deleteObject(hash, token)) { + std::cout << "Successfully unpublished hash " << hash << std::endl; + return 0; + } else { + std::cerr << "Failed to unpublish hash " << hash << std::endl; + return 1; + } } } @@ -897,9 +979,11 @@ void show_help() { std::cout << " ARCH is optional (defaults to 'universal')" << std::endl; std::cout << " Requires SOS_WRITE_TOKEN environment variable" << std::endl; std::cout << std::endl; - std::cout << " unpublish Remove a published tool" << std::endl; - std::cout << " unpublish Remove a published tool by hash" << std::endl; + std::cout << " unpublish Remove ALL architectures of a tool" << std::endl; + std::cout << " unpublish Remove specific architecture only" << std::endl; + std::cout << " unpublish Remove a tool by hash" << std::endl; std::cout << " Requires SOS_WRITE_TOKEN environment variable" << std::endl; + std::cout << " Without :ARCH, removes x86_64, aarch64, and universal versions" << std::endl; std::cout << std::endl; std::cout << " update Update getpkg and all installed tools" << std::endl; std::cout << std::endl; @@ -924,7 +1008,8 @@ void show_help() { std::cout << " getpkg install myapp Install myapp" << std::endl; std::cout << " getpkg publish myapp:x86_64 ./build Publish architecture-specific build" << std::endl; std::cout << " getpkg publish myapp ./build Publish universal build" << std::endl; - std::cout << " getpkg unpublish myapp:x86_64 Remove published myapp" << std::endl; + std::cout << " getpkg unpublish myapp Remove ALL architectures of myapp" << std::endl; + std::cout << " getpkg unpublish myapp:x86_64 Remove only x86_64 version" << std::endl; std::cout << " getpkg uninstall myapp Remove myapp from system" << std::endl; std::cout << " getpkg update Update everything" << std::endl; std::cout << std::endl; diff --git a/test-multi-arch/test-multi b/test-multi-arch/test-multi new file mode 100755 index 0000000..de01420 --- /dev/null +++ b/test-multi-arch/test-multi @@ -0,0 +1,2 @@ +#\!/bin/bash +echo "Test multi-arch package" diff --git a/test-noarch-pkg/test-noarch b/test-noarch-pkg/test-noarch new file mode 100755 index 0000000..e38df9c --- /dev/null +++ b/test-noarch-pkg/test-noarch @@ -0,0 +1,2 @@ +#\!/bin/bash +echo "Test noarch package"