Compare commits
1 Commits
v2025.0626
...
v2025.0628
Author | SHA1 | Date | |
---|---|---|---|
902e68069a |
@ -326,73 +326,161 @@ int update_tool(int argc, char* argv[]) {
|
|||||||
std::string home = get_home();
|
std::string home = get_home();
|
||||||
std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg";
|
std::filesystem::path configDir = std::filesystem::path(home) / ".config/getpkg";
|
||||||
|
|
||||||
// Collect all installed tools
|
// Structure to hold tool information
|
||||||
std::vector<std::tuple<std::string, std::string, std::string>> updateResults; // name, status, version
|
struct ToolInfo {
|
||||||
|
std::string name;
|
||||||
// Capture stdout to process install_tool output
|
std::string localHash;
|
||||||
auto processToolUpdate = [&](const std::string& toolName) -> std::tuple<std::string, std::string> {
|
std::string remoteHash;
|
||||||
// Redirect stdout and stderr to capture output
|
std::string arch;
|
||||||
std::stringstream buffer;
|
std::string version;
|
||||||
std::stringstream errBuffer;
|
bool needsUpdate = false;
|
||||||
std::streambuf* oldOut = std::cout.rdbuf(buffer.rdbuf());
|
std::string status = "Up to date";
|
||||||
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
|
std::vector<ToolInfo> tools;
|
||||||
auto [getpkgStatus, getpkgVersion] = processToolUpdate("getpkg");
|
|
||||||
updateResults.push_back(std::make_tuple("getpkg", getpkgStatus, getpkgVersion));
|
|
||||||
|
|
||||||
// Then update all other installed tools
|
// Collect all installed tools
|
||||||
if (std::filesystem::exists(configDir)) {
|
if (std::filesystem::exists(configDir)) {
|
||||||
for (const auto& entry : std::filesystem::directory_iterator(configDir)) {
|
for (const auto& entry : std::filesystem::directory_iterator(configDir)) {
|
||||||
if (entry.path().extension() == ".json") {
|
if (entry.path().extension() == ".json") {
|
||||||
std::string tname = entry.path().stem();
|
std::string tname = entry.path().stem();
|
||||||
if (tname != "getpkg") { // Skip getpkg since we already did it
|
|
||||||
auto [status, version] = processToolUpdate(tname);
|
ToolInfo tool;
|
||||||
updateResults.push_back(std::make_tuple(tname, status, version));
|
tool.name = tname;
|
||||||
|
|
||||||
|
// Read local tool info
|
||||||
|
std::ifstream tfile(entry.path());
|
||||||
|
if (tfile.good()) {
|
||||||
|
json toolInfo;
|
||||||
|
tfile >> toolInfo;
|
||||||
|
tool.localHash = toolInfo.value("hash", "");
|
||||||
|
tool.arch = toolInfo.value("arch", get_arch());
|
||||||
|
tool.version = toolInfo.value("version", "-");
|
||||||
|
if (!tool.version.empty() && tool.version.back() == '\n') {
|
||||||
|
tool.version.pop_back();
|
||||||
|
}
|
||||||
|
if (tool.version.empty() || tool.version == "-") {
|
||||||
|
tool.version = "installed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tools.push_back(tool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tools.empty()) {
|
||||||
|
std::cout << "No tools installed." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Check for updates (with progress)
|
||||||
|
std::cout << "Checking " << tools.size() << " tools for updates..." << std::endl;
|
||||||
|
|
||||||
|
GetbinClient getbin;
|
||||||
|
for (size_t i = 0; i < tools.size(); ++i) {
|
||||||
|
auto& tool = tools[i];
|
||||||
|
|
||||||
|
// Show progress
|
||||||
|
std::cout << "\r[" << (i + 1) << "/" << tools.size() << "] Checking " << tool.name << "..." << std::flush;
|
||||||
|
|
||||||
|
// Check remote hash
|
||||||
|
std::string remoteHash;
|
||||||
|
if (getbin.getHash(tool.name, tool.arch, remoteHash) && !remoteHash.empty()) {
|
||||||
|
tool.remoteHash = remoteHash;
|
||||||
|
if (tool.localHash != remoteHash) {
|
||||||
|
tool.needsUpdate = true;
|
||||||
|
tool.status = "Needs update";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tool.status = "Check failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "\r" << std::string(50, ' ') << "\r" << std::flush; // Clear progress line
|
||||||
|
|
||||||
|
// Step 2: Update tools that need updating
|
||||||
|
std::vector<std::tuple<std::string, std::string, std::string>> updateResults;
|
||||||
|
|
||||||
|
// First update getpkg if it needs updating
|
||||||
|
auto getpkgIt = std::find_if(tools.begin(), tools.end(),
|
||||||
|
[](const ToolInfo& t) { return t.name == "getpkg"; });
|
||||||
|
|
||||||
|
if (getpkgIt != tools.end() && getpkgIt->needsUpdate) {
|
||||||
|
std::cout << "Updating getpkg..." << std::flush;
|
||||||
|
|
||||||
|
// Use install_tool for actual update
|
||||||
|
std::stringstream buffer, errBuffer;
|
||||||
|
std::streambuf* oldOut = std::cout.rdbuf(buffer.rdbuf());
|
||||||
|
std::streambuf* oldErr = std::cerr.rdbuf(errBuffer.rdbuf());
|
||||||
|
|
||||||
|
char* toolArgv[] = {argv[0], (char*)"install", (char*)"getpkg"};
|
||||||
|
int result = install_tool(3, toolArgv);
|
||||||
|
|
||||||
|
std::cout.rdbuf(oldOut);
|
||||||
|
std::cerr.rdbuf(oldErr);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
getpkgIt->status = "Updated";
|
||||||
|
std::cout << " Updated" << std::endl;
|
||||||
|
} else {
|
||||||
|
getpkgIt->status = "Failed";
|
||||||
|
std::cout << " Failed" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update other tools
|
||||||
|
int toolsToUpdate = std::count_if(tools.begin(), tools.end(),
|
||||||
|
[](const ToolInfo& t) { return t.needsUpdate && t.name != "getpkg"; });
|
||||||
|
|
||||||
|
if (toolsToUpdate > 0) {
|
||||||
|
std::cout << "Updating " << toolsToUpdate << " tools..." << std::endl;
|
||||||
|
|
||||||
|
int updatedCount = 0;
|
||||||
|
for (auto& tool : tools) {
|
||||||
|
if (tool.needsUpdate && tool.name != "getpkg") {
|
||||||
|
updatedCount++;
|
||||||
|
std::cout << "[" << updatedCount << "/" << toolsToUpdate << "] Updating " << tool.name << "..." << std::flush;
|
||||||
|
|
||||||
|
// Use install_tool for actual update
|
||||||
|
std::stringstream buffer, errBuffer;
|
||||||
|
std::streambuf* oldOut = std::cout.rdbuf(buffer.rdbuf());
|
||||||
|
std::streambuf* oldErr = std::cerr.rdbuf(errBuffer.rdbuf());
|
||||||
|
|
||||||
|
char* toolArgv[] = {argv[0], (char*)"install", (char*)tool.name.c_str()};
|
||||||
|
int result = install_tool(3, toolArgv);
|
||||||
|
|
||||||
|
std::cout.rdbuf(oldOut);
|
||||||
|
std::cerr.rdbuf(oldErr);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
tool.status = "Updated";
|
||||||
|
std::cout << " Updated" << std::endl;
|
||||||
|
|
||||||
|
// Re-read version after update
|
||||||
|
std::filesystem::path toolInfoPath = configDir / (tool.name + ".json");
|
||||||
|
if (std::filesystem::exists(toolInfoPath)) {
|
||||||
|
std::ifstream tfile(toolInfoPath);
|
||||||
|
json toolInfo;
|
||||||
|
tfile >> toolInfo;
|
||||||
|
tool.version = toolInfo.value("version", tool.version);
|
||||||
|
if (!tool.version.empty() && tool.version.back() == '\n') {
|
||||||
|
tool.version.pop_back();
|
||||||
|
}
|
||||||
|
if (tool.version.empty() || tool.version == "-") {
|
||||||
|
tool.version = "installed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tool.status = "Failed";
|
||||||
|
std::cout << " Failed" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare results for display
|
||||||
|
for (const auto& tool : tools) {
|
||||||
|
updateResults.push_back(std::make_tuple(tool.name, tool.status, tool.version));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display results in a table
|
// Display results in a table
|
||||||
|
Reference in New Issue
Block a user