'Generic Commit'
Some checks failed
Build-Test-Publish / build (linux/amd64) (push) Failing after 28s
Build-Test-Publish / build (linux/arm64) (push) Failing after 29s

This commit is contained in:
Your Name 2025-06-22 13:13:27 +12:00
parent 0b7fdd3e1a
commit 7cf3d879d1

View File

@ -66,6 +66,7 @@
#include <map>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <cstring>
#include <iomanip>
#include <nlohmann/json.hpp>
@ -324,38 +325,128 @@ int publish_tool(int argc, char* argv[]) {
}
int update_tool(int argc, char* argv[]) {
std::cout << "Updating getpkg itself..." << std::endl;
// First try to update getpkg itself
char* fakeArgv[] = {argv[0], (char*)"install", (char*)"getpkg"};
int result = install_tool(3, fakeArgv);
if (result != 0) {
std::cerr << "Warning: Failed to update getpkg (may not be published)" << std::endl;
// Continue with updating other tools instead of failing
}
// Then update all installed tools
std::string home = get_home();
std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg";
std::cout << "Updating all installed tools..." << std::endl;
bool anyUpdates = false;
// Collect all installed tools
std::vector<std::tuple<std::string, std::string, std::string>> updateResults; // name, status, version
// Capture stdout to process install_tool output
auto processToolUpdate = [&](const std::string& toolName) -> std::tuple<std::string, std::string> {
// Redirect stdout and stderr to capture output
std::stringstream buffer;
std::stringstream errBuffer;
std::streambuf* oldOut = std::cout.rdbuf(buffer.rdbuf());
std::streambuf* oldErr = std::cerr.rdbuf(errBuffer.rdbuf());
char* toolArgv[] = {argv[0], (char*)"install", (char*)toolName.c_str()};
int result = install_tool(3, toolArgv);
// Restore stdout and stderr
std::cout.rdbuf(oldOut);
std::cerr.rdbuf(oldErr);
std::string output = buffer.str();
std::string status = "Failed";
std::string version = "-";
if (result == 0) {
if (output.find("is already up to date") != std::string::npos) {
status = "Up to date";
} else if (output.find("Installed " + toolName + " successfully") != std::string::npos) {
// Check if it was an update or fresh install
if (output.find("Updating " + toolName) != std::string::npos) {
status = "Updated";
} else {
status = "Installed";
}
}
// Try to get version from config
std::filesystem::path toolInfoPath = configDir / (toolName + ".json");
if (std::filesystem::exists(toolInfoPath)) {
std::ifstream tfile(toolInfoPath);
json toolInfo;
tfile >> toolInfo;
version = toolInfo.value("version", "-");
if (!version.empty() && version.back() == '\n') version.pop_back();
// If version is empty, try to show something useful
if (version.empty() || version == "-") {
version = "installed";
}
}
}
return std::make_tuple(status, version);
};
// First update getpkg itself
auto [getpkgStatus, getpkgVersion] = processToolUpdate("getpkg");
updateResults.push_back(std::make_tuple("getpkg", getpkgStatus, getpkgVersion));
// Then update all other installed tools
if (std::filesystem::exists(configDir)) {
for (const auto& entry : std::filesystem::directory_iterator(configDir)) {
if (entry.path().extension() == ".json") {
std::string tname = entry.path().stem();
if (tname != "getpkg") { // Skip getpkg since we already tried it
std::cout << "Checking " << tname << "..." << std::endl;
char* toolArgv[] = {argv[0], (char*)"install", (char*)tname.c_str()};
if (install_tool(3, toolArgv) == 0) {
anyUpdates = true;
}
if (tname != "getpkg") { // Skip getpkg since we already did it
auto [status, version] = processToolUpdate(tname);
updateResults.push_back(std::make_tuple(tname, status, version));
}
}
}
}
std::cout << "Update complete." << std::endl;
// Display results in a table
std::cout << std::endl;
std::cout << "+" << std::string(25, '-') << "+" << std::string(15, '-') << "+" << std::string(20, '-') << "+" << std::endl;
std::cout << "|" << std::setw(25) << std::left << " Tool"
<< "|" << std::setw(15) << std::left << " Status"
<< "|" << std::setw(20) << std::left << " Version"
<< "|" << std::endl;
std::cout << "+" << std::string(25, '-') << "+" << std::string(15, '-') << "+" << std::string(20, '-') << "+" << std::endl;
int updatedCount = 0;
int upToDateCount = 0;
int failedCount = 0;
for (const auto& [name, status, version] : updateResults) {
std::string displayStatus = status;
if (status == "Updated") {
displayStatus = "" + status;
updatedCount++;
} else if (status == "Up to date") {
displayStatus = "" + status;
upToDateCount++;
} else {
displayStatus = "" + status;
failedCount++;
}
std::cout << "|" << std::setw(25) << std::left << (" " + name)
<< "|" << std::setw(15) << std::left << (" " + displayStatus)
<< "|" << std::setw(20) << std::left << (" " + version)
<< "|" << std::endl;
}
std::cout << "+" << std::string(25, '-') << "+" << std::string(15, '-') << "+" << std::string(20, '-') << "+" << std::endl;
std::cout << std::endl;
// Summary
std::cout << "Update Summary: ";
if (updatedCount > 0) {
std::cout << updatedCount << " updated";
}
if (upToDateCount > 0) {
if (updatedCount > 0) std::cout << ", ";
std::cout << upToDateCount << " already up to date";
}
if (failedCount > 0) {
if (updatedCount > 0 || upToDateCount > 0) std::cout << ", ";
std::cout << failedCount << " failed";
}
std::cout << std::endl;
return 0;
}