From f5c585c67df70220087c29f45570cdff4d181ea6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 28 May 2025 21:00:47 +1200 Subject: [PATCH] :-'Generic Commit' --- dropshell-tool/build.sh | 14 ++- dropshell-tool/src/main.cpp | 191 +++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 10 deletions(-) diff --git a/dropshell-tool/build.sh b/dropshell-tool/build.sh index b93804b..6c920c2 100755 --- a/dropshell-tool/build.sh +++ b/dropshell-tool/build.sh @@ -3,19 +3,23 @@ set -euo pipefail SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" -DROPSHELL_BUILD_DIR="${SCRIPT_DIR}/../dropshell-build/dropshell-build.sh" +DROPSHELL_BUILD_DIR="${SCRIPT_DIR}/../dropshell-build/" # make canonical path DROPSHELL_BUILD_DIR=$(realpath "${DROPSHELL_BUILD_DIR}") # make sure the build script exists -if [ ! -f "${DROPSHELL_BUILD_DIR}" ]; then +if [ ! -f "${DROPSHELL_BUILD_DIR}/dropshell-build.sh" ]; then echo "Error: dropshell-build.sh not found" exit 1 fi +if [ ! -f "${DROPSHELL_BUILD_DIR}/install_host.sh" ]; then + echo "Error: install_host.sh not found" + exit 1 +fi - -"${SCRIPT_DIR}/build_openssl.sh" +# install host dependencies +"${DROPSHELL_BUILD_DIR}/install_host.sh" # run the build script -"${DROPSHELL_BUILD_DIR}" "${SCRIPT_DIR}" +"${DROPSHELL_BUILD_DIR}/dropshell-build.sh" "$@" "${SCRIPT_DIR}" diff --git a/dropshell-tool/src/main.cpp b/dropshell-tool/src/main.cpp index 1317988..d300796 100644 --- a/dropshell-tool/src/main.cpp +++ b/dropshell-tool/src/main.cpp @@ -61,6 +61,189 @@ #include #include #include +#include +#include +#include + +namespace { +using json = nlohmann::json; + +std::string get_arch() { +#if defined(__x86_64__) || defined(_M_X64) + return "x86_64"; +#elif defined(__aarch64__) + return "aarch64"; +#else + return "unknown"; +#endif +} + +std::string get_home() { + const char* home = getenv("HOME"); + return home ? std::string(home) : std::string(""); +} + +int install_tool(int argc, char* argv[]) { + if (argc < 3) { + std::cerr << "Usage: dropshell-tool install " << std::endl; + return 1; + } + std::string toolName = argv[2]; + std::string arch = get_arch(); + std::string home = get_home(); + std::filesystem::path configDir = std::filesystem::path(home) / ".config/dropshell-tool"; + std::filesystem::path binDir = std::filesystem::path(home) / ".local/bin/dropshell-tool" / toolName; + std::filesystem::path archivePath = configDir / (toolName + ".tgz"); + std::filesystem::create_directories(configDir); + std::filesystem::create_directories(binDir); + dropshelltool::BashrcEditor bashrcEditor; + bashrcEditor.addSourceLine(); + DropshellScriptManager scriptManager; + scriptManager.removeToolEntry(toolName); + if (std::filesystem::exists(binDir)) std::filesystem::remove_all(binDir); + GetbinClient getbin; + std::cout << "Downloading " << toolName << ":" << arch << "..." << std::endl; + if (!getbin.download(toolName, arch, archivePath.string())) { + std::cerr << "Failed to download tool archive." << std::endl; + return 1; + } + ArchiveManager archiver; + if (!archiver.unpack(archivePath.string(), binDir.string())) { + std::cerr << "Failed to unpack tool archive." << std::endl; + return 1; + } + scriptManager.addToolEntry(toolName, binDir.string()); + scriptManager.addAutocomplete(toolName); + std::string hash; + getbin.getHash(toolName, arch, hash); + std::string version; + std::string toolPath = binDir.string() + "/" + toolName; + FILE* fp = popen((toolPath + " version").c_str(), "r"); + if (fp) { + char buf[128]; + if (fgets(buf, sizeof(buf), fp)) version = std::string(buf); + pclose(fp); + } + json toolInfo = { + {"name", toolName}, + {"version", version}, + {"hash", hash}, + {"arch", arch} + }; + std::ofstream toolInfoFile(configDir / (toolName + ".json")); + toolInfoFile << toolInfo.dump(2); + toolInfoFile.close(); + std::string configJson; + if (archiver.readConfigJson(archivePath.string(), configJson)) { + try { + auto config = json::parse(configJson); + if (config.contains("aliases")) { + for (const auto& alias : config["aliases"]) { + std::string aliasStr = alias.get(); + if (!scriptManager.hasAlias(aliasStr)) { + scriptManager.addAlias(aliasStr, toolName); + } + } + } + if (config.contains("setup_script")) { + std::string setupScript = config["setup_script"].get(); + bool useSudo = config.value("sudo", false); + std::string setupPath = binDir.string() + "/" + setupScript; + std::string cmd = (useSudo ? "sudo " : "") + setupPath; + std::system(cmd.c_str()); + } + } catch (...) { + std::cerr << "Warning: failed to parse dropshell-tool-config.json" << std::endl; + } + } + std::cout << "Installed " << toolName << " successfully." << std::endl; + return 0; +} + +int publish_tool(int argc, char* argv[]) { + if (argc < 4) { + std::cerr << "Usage: dropshell-tool publish " << std::endl; + return 1; + } + std::string labeltag = argv[2]; + std::string folder = argv[3]; + std::string home = get_home(); + std::filesystem::path configPath = std::filesystem::path(folder) / "dropshell-tool-config.json"; + if (!std::filesystem::exists(configPath)) { + std::cerr << "dropshell-tool-config.json not found in " << folder << std::endl; + return 1; + } + std::filesystem::path archivePath = std::filesystem::path(folder) / (labeltag + ".tgz"); + ArchiveManager archiver; + if (!archiver.pack(folder, archivePath.string())) { + std::cerr << "Failed to create archive." << std::endl; + return 1; + } + std::filesystem::path tokenPath = std::filesystem::path(home) / ".config/getbin.xyz/write_token.txt"; + std::string token; + if (std::filesystem::exists(tokenPath)) { + std::ifstream tfile(tokenPath); + std::getline(tfile, token); + } else { + std::cout << "Enter getbin.xyz write token: "; + std::getline(std::cin, token); + std::filesystem::create_directories(tokenPath.parent_path()); + std::ofstream tfile(tokenPath); + tfile << token << std::endl; + } + GetbinClient getbin; + std::string url, hash; + if (!getbin.upload(archivePath.string(), url, hash, token)) { + std::cerr << "Failed to upload archive." << std::endl; + return 1; + } + std::cout << "Published! URL: " << url << "\nHash: " << hash << std::endl; + return 0; +} + +int update_tool(int argc, char* argv[]) { + if (argc < 3) { + std::cerr << "Usage: dropshell-tool update " << std::endl; + return 1; + } + std::string toolName = argv[2]; + std::string home = get_home(); + std::filesystem::path configDir = std::filesystem::path(home) / ".config/dropshell-tool"; + if (toolName == "all") { + for (const auto& entry : std::filesystem::directory_iterator(configDir)) { + if (entry.path().extension() == ".json") { + std::string tname = entry.path().stem(); + char* fakeArgv[] = {argv[0], (char*)"update", (char*)tname.c_str()}; + update_tool(3, fakeArgv); + } + } + return 0; + } + std::filesystem::path toolInfoPath = configDir / (toolName + ".json"); + if (!std::filesystem::exists(toolInfoPath)) { + std::cerr << "Tool not installed: " << toolName << std::endl; + return 1; + } + std::ifstream tfile(toolInfoPath); + json toolInfo; + tfile >> toolInfo; + tfile.close(); + std::string arch = toolInfo.value("arch", get_arch()); + std::string localHash = toolInfo.value("hash", ""); + std::string localVersion = toolInfo.value("version", ""); + GetbinClient getbin; + std::string remoteHash; + getbin.getHash(toolName, arch, remoteHash); + if (remoteHash.empty() || remoteHash == localHash) { + std::cout << "No update needed for " << toolName << std::endl; + return 0; + } + std::cout << "Updating " << toolName << "..." << std::endl; + char* fakeArgv[] = {argv[0], (char*)"install", (char*)toolName.c_str()}; + return install_tool(3, fakeArgv); +} + +} // end anonymous namespace int main(int argc, char* argv[]) { if (argc < 2) { @@ -69,13 +252,11 @@ int main(int argc, char* argv[]) { } std::string command = argv[1]; if (command == "install") { - dropshelltool::BashrcEditor bashrcEditor; - bashrcEditor.addSourceLine(); - // TODO: Implement install logic using utility classes + return install_tool(argc, argv); } else if (command == "publish") { - // TODO: Implement publish logic + return publish_tool(argc, argv); } else if (command == "update") { - // TODO: Implement update logic + return update_tool(argc, argv); } else if (command == "autocomplete") { std::vector args(argv + 2, argv + argc); if (args.empty()) std::cout << R"(install