diff --git a/Makefile b/Makefile index 82cfe5b..cdf89a7 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ LOCALEDIR ?= $(PREFIX)/share/locale VARS ?= -DENABLE_NLS=1 DEBUG ?= 1 -VERSION = 0.6.4 +VERSION = 0.6.6 BRANCH = libalpm-test SRC = $(sort $(wildcard src/*.cpp)) OBJ = $(SRC:.cpp=.o) diff --git a/include/args.hpp b/include/args.hpp index d0cf6d6..0c389a6 100644 --- a/include/args.hpp +++ b/include/args.hpp @@ -31,6 +31,8 @@ enum { OP_NOCONFIRM, OP_QUIET, OP_TEST_COLORS, + OP_RECURSIVE, + OP_NOSAVE, }; struct Operation_t { @@ -59,4 +61,5 @@ void invalid_opt(); int parsearg_global(int opt); int parsearg_query(int opt); int parsearg_sync(int opt); +int parsearg_remove(int opt); #endif diff --git a/include/config.hpp b/include/config.hpp index 5deb667..da0976a 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -73,6 +73,8 @@ class Config { bool debug; bool quiet; bool noconfirm; + // alpm transaction flags + int flags; std::map overrides; diff --git a/include/util.hpp b/include/util.hpp index e6756e5..09c4707 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -115,7 +115,7 @@ bool util_db_search(alpm_db_t *db, alpm_list_t *need std::optional> askUserForPkg(vector pkgs, TaurBackend& backend, bool useGit); string_view binarySearch(const vector& arr, string_view target); vector load_aur_list(); -bool update_aur_cache(); +bool update_aur_cache(bool recursiveCall = false); template struct is_fmt_convertible { diff --git a/src/args.cpp b/src/args.cpp index ddfd6d6..7166800 100644 --- a/src/args.cpp +++ b/src/args.cpp @@ -3,6 +3,7 @@ #include "args.hpp" #include "util.hpp" #include "config.hpp" +#include alpm_list_smart_deleter taur_targets(nullptr, free_list_and_internals); @@ -144,3 +145,22 @@ int parsearg_sync(int opt) { } return 0; } + +int parsearg_remove(int opt) { + switch (opt) { + case OP_NOSAVE: + case 'n': + config->flags |= ALPM_TRANS_FLAG_NOSAVE; + break; + case OP_RECURSIVE: + case 's': + if (config->flags & ALPM_TRANS_FLAG_RECURSE) + config->flags |= ALPM_TRANS_FLAG_RECURSEALL; + else + config->flags |= ALPM_TRANS_FLAG_RECURSE; + break; + default: + return 1; + } + return 0; +} diff --git a/src/main.cpp b/src/main.cpp index cfa6fb0..91c1c2f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -163,7 +163,7 @@ int installPkg(alpm_list_t *pkgNames) { } if (!update_aur_cache()) - log_println(ERROR, "Failed to get informations about {}", (config->cacheDir / "packages.aur").string()); + log_println(ERROR, "Failed to get information about {}", (config->cacheDir / "packages.aur").string()); // TODO: translate aurPkgNamesVec = filterAURPkgsNames(pkgNamesVec, alpm_get_syncdbs(config->handle), true); @@ -507,7 +507,7 @@ int parseargs(int argc, char* argv[]) { int opt = 0; int option_index = 0; int result = 0; - const char *optstring = "DFQRSTUVaihqsuryt"; + const char *optstring = "DFQRSTUVaihqsurytns"; static const struct option opts[] = { {"database", no_argument, 0, 'D'}, @@ -537,6 +537,8 @@ int parseargs(int argc, char* argv[]) { {"quiet", no_argument, 0, OP_QUIET}, {"debug", no_argument, 0, OP_DEBUG}, {"noconfirm", no_argument, 0, OP_NOCONFIRM}, + {"nosave", no_argument, 0, OP_NOSAVE}, + {"recursive", no_argument, 0, OP_RECURSIVE}, {0,0,0,0} }; @@ -586,6 +588,9 @@ int parseargs(int argc, char* argv[]) { case OP_QUERY: result = parsearg_query(opt); break; + case OP_REM: + result = parsearg_remove(opt); + break; default: result = 1; break; diff --git a/src/taur.cpp b/src/taur.cpp index 106915b..3d614b4 100644 --- a/src/taur.cpp +++ b/src/taur.cpp @@ -169,7 +169,7 @@ bool TaurBackend::remove_pkg(alpm_pkg_t *pkg, bool ownTransaction) { if (!pkg) return false; - if (ownTransaction && alpm_trans_init(this->config.handle, 0)) { + if (ownTransaction && alpm_trans_init(this->config.handle, this->config.flags)) { log_println(ERROR, _("Failed to initialize transaction ({})"), alpm_strerror(alpm_errno(this->config.handle))); return false; } @@ -196,7 +196,7 @@ bool TaurBackend::remove_pkgs(alpm_list_smart_pointer& pkgs) { if (!pkgs) return false; - if (alpm_trans_init(this->config.handle, 0)) { + if (alpm_trans_init(this->config.handle, this->config.flags)) { log_println(ERROR, _("Failed to initialize transaction ({})"), alpm_strerror(alpm_errno(this->config.handle))); return false; } diff --git a/src/util.cpp b/src/util.cpp index d1fb294..77f4f9a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -567,12 +567,40 @@ vector load_aur_list() { return aur_list; } -bool update_aur_cache() { +bool download_aur_cache(path file_path) { + cpr::Response r = cpr::Get(cpr::Url{AUR_URL"/packages.gz"}); + + if (r.status_code == 200) { + std::ofstream outfile(file_path, std::ios::trunc); + if (!outfile.is_open()) { + log_println(ERROR, "Failed to open/write {}", file_path.c_str()); + return false; + } + outfile << r.text; + } else { + log_println(ERROR, "Failed to download {} with status code: {}", r.url.str(), r.status_code); + return false; + } + + return true; +} + +// recursiveCall indicates whether the function is calling itself. +// This function will automatically try again after downloading the file, if not already present. +// Do not call this with true unless you do not want this behavior. +// It is, by default, false. +bool update_aur_cache(bool recursiveCall) { path file_path = config->cacheDir / "packages.aur"; struct stat file_stat; if (stat(file_path.c_str(), &file_stat) != 0) { - log_println(ERROR, "Unable to get {} metadata: {}", file_path.c_str(), errno); + if (errno == ENOENT && !recursiveCall) { // file not found, download THEN try again once more. + log_println(INFO, "File {} not found, attempting download.", file_path); + return download_aur_cache(file_path) && update_aur_cache(true); + } + + log_println(ERROR, "Unable to get {} metadata: {}", file_path, errno); + return false; } @@ -583,20 +611,8 @@ bool update_aur_cache() { std::time_t now_time_t = std::chrono::system_clock::to_time_t(_current_time); if (file_stat.st_mtim.tv_sec < now_time_t - timeout) { - log_println(INFO, "Refreshing {}", file_path.c_str()); - cpr::Response r = cpr::Get(cpr::Url{AUR_URL"/packages.gz"}); - - if (r.status_code == 200) { - std::ofstream outfile(file_path, std::ios::trunc); - if (!outfile.is_open()) { - log_println(ERROR, "Failed to open/write {}", file_path.c_str()); - return false; - } - outfile << r.text; - } else { - log_println(ERROR, "Failed to download {} with status code: {}", r.url.str(), r.status_code); - return false; - } + log_println(INFO, "Refreshing {}", file_path); + download_aur_cache(file_path); } return true;