From 2973746acbdbbb0cac0e49d5be588c2004233949 Mon Sep 17 00:00:00 2001 From: zawz Date: Thu, 14 Nov 2019 17:23:32 +0100 Subject: [PATCH] V1 commit --- .gitignore | 2 + Makefile | 48 ++++++++++++ README.md | 34 ++++++++- commands/apt_fetch | 2 + commands/pacman_fetch | 6 ++ include/colors.hpp | 12 +++ include/commands.h | 32 ++++++++ include/fetch.hpp | 11 +++ include/opt_bool.h | 41 ++++++++++ include/options.hpp | 21 +++++ include/package_man.hpp | 19 +++++ include/print.hpp | 30 ++++++++ include/repos.hpp | 36 +++++++++ src/colors.cpp | 6 ++ src/fetch.cpp | 108 ++++++++++++++++++++++++++ src/main.cpp | 88 +++++++++++++++++++++ src/opt_bool.c | 38 ++++++++++ src/options.cpp | 92 ++++++++++++++++++++++ src/package_man.cpp | 164 ++++++++++++++++++++++++++++++++++++++++ src/print.cpp | 116 ++++++++++++++++++++++++++++ src/repos.cpp | 3 + 21 files changed, 908 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 commands/apt_fetch create mode 100644 commands/pacman_fetch create mode 100644 include/colors.hpp create mode 100644 include/commands.h create mode 100644 include/fetch.hpp create mode 100644 include/opt_bool.h create mode 100644 include/options.hpp create mode 100644 include/package_man.hpp create mode 100644 include/print.hpp create mode 100644 include/repos.hpp create mode 100644 src/colors.cpp create mode 100644 src/fetch.cpp create mode 100644 src/main.cpp create mode 100644 src/opt_bool.c create mode 100644 src/options.cpp create mode 100644 src/package_man.cpp create mode 100644 src/print.cpp create mode 100644 src/repos.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..94089cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +obj +zupdate diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fe3b7da --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +IDIR=include +SRCDIR=src +ODIR=obj +BINDIR=. + +NAME = zupdate + +LDFLAGS = -lpthread + +CC=g++ +CXXFLAGS= -I$(IDIR) -Wall -std=c++17 -fopenmp +ifeq ($(DEBUG),true) + CXXFLAGS += -g +endif +ifeq ($(STATIC),true) + LDFLAGS += -l:libztd.a +else + LDFLAGS += -lztd +endif + +$(shell mkdir -p $(ODIR)) +$(shell mkdir -p $(BINDIR)) + +# automatically finds .h and .hpp +DEPS = $(shell if [ -n "$(ld $(IDIR))" ] ; then ls $(IDIR)/*.hpp $(IDIR)/*.h 2>/dev/null ; fi) +# automatically finds .c and .cpp and makes the corresponding .o rule +OBJ = $(shell ls $(SRCDIR)/*.cpp $(SRCDIR)/*.c 2>/dev/null | sed 's|\.cpp|.o|g;s|\.c|.o|g;s|$(SRCDIR)/|$(ODIR)/|g') + +$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS) + $(CC) $(CXXFLAGS) -c -o $@ $< + +$(ODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS) + $(CC) $(CXXFLAGS) -c -o $@ $< + +$(BINDIR)/$(NAME): $(OBJ) $(DEPS) + $(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +test: $(BINDIR)/$(NAME) + $(BINDIR)/$(NAME) + +clean: + rm $(ODIR)/*.o + +clear: clean + rm $(BINDIR)/$(NAME) + +install: $(BINDIR)/$(NAME) + mv $(BINDIR)/$(NAME) /usr/local/bin diff --git a/README.md b/README.md index 3bcdcc0..4de9999 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,34 @@ # zupdate -Cross-distro updates and safe update previewing + +Cross-distro updating and safe update preview + +## Installing + +### From source + +#### Dependencies + +Dependencies: +- [ztd](https://github.com/zawwz/ztd) + +Supported package managers: +- pacman +- apt + +Optional dependencies: +- yay (AUR support for arch) + +#### Building + +``make -j8`` for a shared build +``STATIC=true make -j8`` for a static build + +## Usage + +Full update preview: `zupdate` +Upgrade: `zupdate -yu` + +Parsable package list: `zupdate -L` +Download size: `zupdate -kd` + +See `zupdate -h` for full details diff --git a/commands/apt_fetch b/commands/apt_fetch new file mode 100644 index 0000000..b4e3286 --- /dev/null +++ b/commands/apt_fetch @@ -0,0 +1,2 @@ +sudo apt update >/dev/null 2>&1 || exit +apt list --upgradable 2>/dev/null | tail -n +2 | awk -F "/" '{print $1" "$2}' | tr -d ']' | awk '{print $1" "$7" -> "$3}' diff --git a/commands/pacman_fetch b/commands/pacman_fetch new file mode 100644 index 0000000..b2969a3 --- /dev/null +++ b/commands/pacman_fetch @@ -0,0 +1,6 @@ +CHECKUPDATES_DB="${TMPDIR:-/tmp}/checkup-db-${USER}/" +DBPath="$(pacman-conf DBPath)" +mkdir -p "$CHECKUPDATES_DB" +ln -sf "${DBPath}/local" "$CHECKUPDATES_DB" > /dev/null 2>&1 +fakeroot pacman -Sy --dbpath "$CHECKUPDATES_DB" --logfile /dev/null >/dev/null 2>&1 +pacman -Qu --dbpath "$CHECKUPDATES_DB/" 2> /dev/null | grep -v '\[.*\]' diff --git a/include/colors.hpp b/include/colors.hpp new file mode 100644 index 0000000..b0dbc0c --- /dev/null +++ b/include/colors.hpp @@ -0,0 +1,12 @@ +#ifndef COLORS_HPP +#define COLORS_HPP + +#include + +// Global constants +extern const ztd::color no_color; +extern const ztd::color repo_color; +extern const ztd::color aur_color; +extern const ztd::color error_color; + +#endif //COLORS_HPP diff --git a/include/commands.h b/include/commands.h new file mode 100644 index 0000000..f810b06 --- /dev/null +++ b/include/commands.h @@ -0,0 +1,32 @@ +#ifndef COMMANDS_H +#define COMMANDS_H + +// pacman +#define PACMAN_FETCH_COMMAND "CHECKUPDATES_DB=\"${TMPDIR:-/tmp}/checkup-db-${USER}/\"\nDBPath=\"$(pacman-conf DBPath)\"\nmkdir -p \"$CHECKUPDATES_DB\"\nln -sf \"${DBPath}/local\" \"$CHECKUPDATES_DB\" > /dev/null 2>&1\nfakeroot pacman -Sy --dbpath \"$CHECKUPDATES_DB\" --logfile /dev/null >/dev/null 2>&1\npacman -Qu --dbpath \"$CHECKUPDATES_DB/\" 2> /dev/null | grep -v '\\[.*\\]'" +#define AUR_FETCH_COMMAND "yay -Qau 2>/dev/null" + +#define PACMAN_UPDATE_COMMAND "sudo pacman -Syu" +#define PACMAN_UPDATE_COMMAND_NOCONFIRM "sudo pacman -Syu --noconfirm" +#define AUR_UPDATE_COMMAND "yay -Sau" +#define AUR_UPDATE_COMMAND_NOCONFIRM "yay -Sau --noconfirm" + +#define PACMAN_EXT_INFO_COMMAND "pacman -Si --dbpath \"${TMPDIR:-/tmp}/checkup-db-${USER}/\" --logfile /dev/null " +#define PACMAN_LOCAL_INFO_COMMAND "pacman -Qi " + +#define PACMAN_EXT_SIZE_CUT_COMMAND " |grep -E 'Download Size|Installed Size'|cut -d':' -f2|tr -d ' '|cut -d'i' -f1 | tr -d 'B'|numfmt --from=iec" +#define PACMAN_LOCAL_SIZE_CUT_COMMAND " |grep 'Installed Size'|cut -d':' -f2|tr -d ' '|cut -d'i' -f1 | tr -d 'B'|numfmt --from=iec|tr -d '\n'" + +// apt/dpkg +#define APT_FETCH_COMMAND "sudo apt update >/dev/null 2>&1 || exit\napt list --upgradable 2>/dev/null | tail -n +2 | awk -F \"/\" '{print $1\" \"$2}' | tr -d ']' | awk '{print $1\" \"$7\" -> \"$3}'" +#define APT_UPDATE_COMMAND "sudo apt upgrade" +#define APT_UPDATE_COMMAND_NOCONFIRM "echo y | sudo apt upgrade" + +#define APT_EXT_INFO_COMMAND "apt show " +#define APT_LOCAL_INFO_COMMAND "dpkg -s " + +#define APT_EXT_SIZE_CUT_COMMAND " 2>/dev/null| grep -E 'Installed-Size:|Download-Size:' | cut -d' ' -f2- | tr -d ', B' | tr 'k' 'K' | numfmt --from=iec | awk '{s=$0;getline;s=$0\"\\n\"s;print s}'" +#define APT_LOCAL_SIZE_CUT_COMMAND " 2>/dev/null| grep 'Installed-Size:' | cut -d' ' -f2 | xargs echo '1024 *' | bc" + + + +#endif //COMMANDS_H diff --git a/include/fetch.hpp b/include/fetch.hpp new file mode 100644 index 0000000..74ee8df --- /dev/null +++ b/include/fetch.hpp @@ -0,0 +1,11 @@ +#ifndef FETCH_HPP +#define FETCH_HPP + +#include "repos.hpp" + +//functions +void fetch_update(repo_update* r, const std::string& name, const std::string& command); + +void import_sizes(repo_update* ru, const char* ext_info_command, const char* loc_info_command, const char* ext_cut_command, const char* loc_cut_command); + +#endif //FETCH_HPP diff --git a/include/opt_bool.h b/include/opt_bool.h new file mode 100644 index 0000000..48fec5a --- /dev/null +++ b/include/opt_bool.h @@ -0,0 +1,41 @@ +#ifndef OPT_BOOL_H +#define OPT_BOOL_H + +// OPTIONS +//help +extern bool opt_help; +//targets +extern bool opt_repo; +extern bool opt_aur; +//print +extern bool opt_pall; +extern bool opt_notitles; +extern bool opt_plist; +extern bool opt_plistraw; +extern bool opt_psizes; +extern bool opt_pdownload; +extern bool opt_pinstall; +extern bool opt_pnet; +//size +extern unsigned int size_index; +//operation +extern bool opt_update; +extern bool opt_noconfirm; +//package man +extern bool opt_pacman; +extern bool opt_apt; + +// COMBINES +//target +extern bool combine_target; +//print +extern bool combine_list; +extern bool combine_size; +extern bool combine_print; +//operation +extern bool combine_op; +extern bool combine_op_any; +//fetch required +extern bool combine_fetch; + +#endif //OPT_BOOL_H diff --git a/include/options.hpp b/include/options.hpp new file mode 100644 index 0000000..6977648 --- /dev/null +++ b/include/options.hpp @@ -0,0 +1,21 @@ +#ifndef OPTIONS_HPP +#define OPTIONS_HPP + +#include + +#include "opt_bool.h" + +extern ztd::option_set options; + +void help(); + +void create_options(); + +void process_options(int argc, char** argv); + +void options_bool(); + +void process_combines(); + + +#endif //OPTIONS_HPP diff --git a/include/package_man.hpp b/include/package_man.hpp new file mode 100644 index 0000000..e8b650f --- /dev/null +++ b/include/package_man.hpp @@ -0,0 +1,19 @@ +#ifndef PACKAGE_MAN_HPP +#define PACKAGE_MAN_HPP + +#include + +// types +enum package_manager { none, pacman, apt, dnf }; + +// globals +extern package_manager cur_pkgman; + +// functions +bool exec_find(const std::string& name); + +void pacman_process(bool yay); + +void apt_process(); + +#endif //PACKAGE_MAN_HPP diff --git a/include/print.hpp b/include/print.hpp new file mode 100644 index 0000000..ea46dcb --- /dev/null +++ b/include/print.hpp @@ -0,0 +1,30 @@ +#ifndef PRINT_HPP +#define PRINT_HPP + +#include + +#include + +#include "repos.hpp" +#include "colors.hpp" + +//constants +extern const char* size_suffixes[6]; +extern const int size_print_padding; + +//functions +void help(); + +std::pair convertN(const long int size, unsigned int n); + +std::pair convertHReadable(const long int size); + +void print_update(repo_update& ru, ztd::color color, bool dlsize=false, bool nisize=false, bool nusize=false); + +void print_update_sizes(repo_update& ru, ztd::color color, bool dlsize, bool nisize, bool cisize, bool notitle); + +void print_size(long int size, bool printTitle=false, std::string title="", int padding=0, ztd::color color=ztd::color::none, unsigned int precision=2, unsigned int sizepow=2, const char* line_end="\n"); + +void print_listraw(repo_update& ru); + +#endif //PRINT_HPP diff --git a/include/repos.hpp b/include/repos.hpp new file mode 100644 index 0000000..7a3e7e7 --- /dev/null +++ b/include/repos.hpp @@ -0,0 +1,36 @@ +#ifndef REPOS_HPP +#define REPOS_HPP + +#include +#include + +//types +typedef struct package_update +{ + std::string name; + std::string current_version; + std::string new_version; + + long unsigned int download_size; + long unsigned int new_install_size; + long unsigned int current_install_size; + long int net_size; +} package_update; + +typedef struct repo_update +{ + std::vector packages; + std::string name; + unsigned int name_max_length; + unsigned int vcur_max_length; + unsigned int vnew_max_length; + + long unsigned int download_size; + long unsigned int new_install_size; + long unsigned int current_install_size; + long int net_size; +} repo_update; + +extern repo_update repo, aur; + +#endif //REPOS_HPP diff --git a/src/colors.cpp b/src/colors.cpp new file mode 100644 index 0000000..7b91c32 --- /dev/null +++ b/src/colors.cpp @@ -0,0 +1,6 @@ +#include "colors.hpp" + +const ztd::color no_color(ztd::color::none); +const ztd::color repo_color(ztd::color::b_white); +const ztd::color aur_color(ztd::color::b_cyan); +const ztd::color error_color(ztd::color::b_red); diff --git a/src/fetch.cpp b/src/fetch.cpp new file mode 100644 index 0000000..1645933 --- /dev/null +++ b/src/fetch.cpp @@ -0,0 +1,108 @@ +#include "fetch.hpp" + +#include +#include +#include +#include + +#include + +#include "commands.h" + +//functions +void fetch_update(repo_update* r, const std::string& name, const std::string& command) +{ + r->packages.clear(); + r->name=name; + r->name_max_length=0; + r->vcur_max_length=0; + r->vnew_max_length=0; + std::string str=ztd::sh(command); + + unsigned long int i=0,j=0; + while(i r->name_max_length) + r->name_max_length = pkg.name.size(); + //end name + i++; + //current version + j=i; + while( str[i]!=' ' ) + i++; + pkg.current_version = str.substr(j,i-j); + if(pkg.current_version.size() > r->vcur_max_length) + r->vcur_max_length = pkg.current_version.size(); + //end current version + i++; + //skip arrow + while( str[i]!=' ' ) + i++; + //end arrow + i++; + //new version + j=i; + while( str[i]!='\n' ) + i++; + pkg.new_version = str.substr(j,i-j); + if(pkg.new_version.size() > r->vnew_max_length) + r->vnew_max_length = pkg.new_version.size(); + //end new version + i++; + j=i; + r->packages.push_back(pkg); + } + +} + + + +void get_ext_sizes(package_update* pkg, const char* info_command, const char* cut_command) +{ + std::string sizes=ztd::sh(info_command + pkg->name + cut_command); + unsigned int i=0, j=0; + while(sizes[i]!='\n') + i++; + pkg->download_size = std::stoul(sizes.substr(0,i)); + i++; + j=i; + while(sizes[i]!='\n') + i++; + pkg->new_install_size = std::stoul(sizes.substr(j,i-j)); +} +void get_loc_size(package_update* pkg, const char* info_command, const char* cut_command) +{ + std::string size=ztd::sh(info_command + pkg->name + cut_command); + if(size.size() > 0) + pkg->current_install_size = std::stoul(size); + else + pkg->current_install_size = 0; +} + +void import_sizes(repo_update* ru, const char* ext_info_command, const char* loc_info_command, const char* ext_cut_command, const char* loc_cut_command) +{ + const unsigned int n=ru->packages.size(); + #pragma omp parallel for + for(unsigned int i=0; ipackages[i]); + get_ext_sizes(pkg, ext_info_command, ext_cut_command); + get_loc_size(pkg, loc_info_command, loc_cut_command); + pkg->net_size = (long int) pkg->new_install_size - (long int) pkg->current_install_size; + } + ru->download_size = 0; + ru->new_install_size = 0; + ru->current_install_size = 0; + for(auto pkg : ru->packages) + { + ru->download_size += pkg.download_size; + ru->new_install_size += pkg.new_install_size; + ru->current_install_size += pkg.current_install_size; + } + ru->net_size = (long int) ru->new_install_size - (long int) ru->current_install_size; +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..928917a --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,88 @@ +#include + +#include + +#include "options.hpp" +#include "package_man.hpp" + +long unsigned int new_download_size=0; +long unsigned int new_install_size=0; +long unsigned int current_install_size=0; +long int net_size=0; + +int main(int argc, char* argv[]) +{ + //option process start + try + { + create_options(); + process_options(argc, argv); + options_bool(); + process_combines(); + } + catch(ztd::option_error& e) + { + printf("%s\n", e.what()); + return 1; + } + + if( !combine_target ) //no target -> all + { + opt_repo = true; + opt_aur = true; + } + if( !combine_op_any ) //no operation -> print all + { + opt_pall = true; + } + + if ( opt_pall ) //all -> list + sizes + { + opt_plist=true; + opt_psizes=true; + } + if ( opt_psizes ) //sizes -> download, install, net + { + opt_pdownload=true; + opt_pinstall=true; + opt_pnet=true; + } + process_combines(); + //option process end + + //halt options + if( opt_help ) + { + help(); + return 0; + } + + if(opt_pacman) + cur_pkgman=pacman; + else if(opt_apt) + cur_pkgman=apt; + + if(cur_pkgman == none) + { + if(exec_find("pacman")) + { + cur_pkgman=pacman; + } + else if(exec_find("apt") && exec_find("dpkg")) + { + cur_pkgman=apt; + } + } + + switch(cur_pkgman) + { + case pacman : + pacman_process(exec_find("yay")); break; + case apt : + apt_process(); break; + default : std::cerr << "Unsupported package manager\n"; break; + } + + + return 0; +} diff --git a/src/opt_bool.c b/src/opt_bool.c new file mode 100644 index 0000000..99a72ba --- /dev/null +++ b/src/opt_bool.c @@ -0,0 +1,38 @@ +#include "opt_bool.h" + +// OPTIONS +//help +bool opt_help=false; +//targets +bool opt_repo=false; +bool opt_aur=false; +//print +bool opt_pall=false; +bool opt_notitles=false; +bool opt_plist=false; +bool opt_plistraw=false; +bool opt_psizes=false; +bool opt_pdownload=false; +bool opt_pinstall=false; +bool opt_pnet=false; +//size +unsigned int size_index=2; +//operation +bool opt_update=false; +bool opt_noconfirm=false; +//package man +bool opt_pacman=false; +bool opt_apt=false; + +// COMBINES +//target +bool combine_target=false; +//print +bool combine_list=false; +bool combine_size=false; +bool combine_print=false; +//operation +bool combine_op=false; +bool combine_op_any=false; +//fetch required +bool combine_fetch=false; diff --git a/src/options.cpp b/src/options.cpp new file mode 100644 index 0000000..7b786d4 --- /dev/null +++ b/src/options.cpp @@ -0,0 +1,92 @@ +#include "options.hpp" + +ztd::option_set options; + +void help() +{ + printf("zupdate [options]\n\nOptions:\n"); + options.print_help(5,23); + printf("\n"); + printf("Option order does not matter\n"); + printf("No print or operation options suggests -p\n"); + printf("No target specified will target all\n"); + printf("Default size in MB\n"); +} + +void create_options() +{ + options.add(ztd::option("\r [HELP]")); + options.add(ztd::option('h', "help", false, "Print this help message")); + options.add(ztd::option("\r [PRINT]")); + options.add(ztd::option('p', "print", false, "Print all update info")); + options.add(ztd::option('l', "list", false, "Print a detailed list of packages")); + options.add(ztd::option('L', "list-raw", false, "Print a raw list of packages")); + options.add(ztd::option('s', "size", false, "Print all sizes")); + options.add(ztd::option('d', "download-size", false, "Download size (repo only)")); + options.add(ztd::option('i', "install-size", false, "Install size (repo only)")); + options.add(ztd::option('n', "net-size", false, "Net difference size (repo only)")); + options.add(ztd::option('k', "no-titles", false, "Don't print titles on -d -i and -n")); + options.add(ztd::option("\r [OPERATION]")); + options.add(ztd::option('u', "update", false, "Update targeted repositories")); + options.add(ztd::option('y', "noconfirm", false, "Doesn't ask for confirmation")); + options.add(ztd::option("\r [PKGMAN]")); + options.add(ztd::option( "pacman", false, "Force pacman as package manager")); + options.add(ztd::option( "apt", false, "Force apt as package manager")); + options.add(ztd::option("\r [TARGET]")); + options.add(ztd::option('r', "repo", false, "Target official repository (pacman only)")); + options.add(ztd::option('a', "aur", false, "Target AUR (pacman only, yay required)")); + options.add(ztd::option("\r [SIZE]")); + options.add(ztd::option('B', "byte", false, "Print sizes in bytes")); + options.add(ztd::option('K', "kilobyte", false, "Print sizes in kilobytes")); + options.add(ztd::option('M', "megabyte", false, "Print sizes in megabytes")); + options.add(ztd::option('G', "gigabyte", false, "Print sizes in gigabytes")); +} + +void process_options(int argc, char** argv) +{ + options.process(argc, argv); +} + +void options_bool() +{ + //help + opt_help = options.find('h')->activated; + //targets + opt_repo = options.find('r')->activated; + opt_aur = options.find('a')->activated; + //print + opt_pall = options.find('p')->activated; + opt_notitles = options.find('k')->activated; + opt_plist = options.find('l')->activated; + opt_plistraw = options.find('L')->activated; + opt_psizes = options.find('s')->activated; + opt_pdownload = options.find('d')->activated; + opt_pinstall = options.find('i')->activated; + opt_pnet = options.find('n')->activated; + //size + if(options.find('B')->activated) size_index = 0; + if(options.find('K')->activated) size_index = 1; + if(options.find('M')->activated) size_index = 2; + if(options.find('G')->activated) size_index = 3; + //operation + opt_update = options.find('u')->activated; + opt_noconfirm = options.find('y')->activated; + //packageman + opt_pacman = options.find("pacman")->activated; + opt_apt = options.find("apt")->activated; +} + +void process_combines() +{ + //target + combine_target = opt_repo || opt_aur; + //print + combine_list = opt_pall || opt_plist; + combine_size = opt_pall || opt_psizes || opt_pdownload || opt_pinstall || opt_pnet; + combine_print = combine_list || combine_size || opt_plistraw; + //operation + combine_op = opt_update; + combine_op_any = combine_print || combine_op; + //fetch required + combine_fetch = combine_print; +} diff --git a/src/package_man.cpp b/src/package_man.cpp new file mode 100644 index 0000000..8ed26b5 --- /dev/null +++ b/src/package_man.cpp @@ -0,0 +1,164 @@ +#include "package_man.hpp" + +#include +#include + +#include "fetch.hpp" +#include "print.hpp" +#include "repos.hpp" + +#include "opt_bool.h" +#include "commands.h" + +#include + +package_manager cur_pkgman = none; + +bool exec_find(const std::string& name) +{ + std::string which=ztd::sh("which "+name+" 2>/dev/null"); + return which != ""; +} + +void repo_print_process(repo_update& ru, ztd::color cl, bool print_size=true) +{ + //only if there are packages + if(ru.packages.size() > 0) + { + //list + if( opt_plist ) + print_update(ru, cl, print_size && opt_pdownload, print_size && opt_pinstall, print_size && opt_pnet); + //sizes + if( print_size ) + print_update_sizes(ru, cl, opt_pdownload, opt_pinstall, opt_pnet, opt_notitles); + } +} + +void pacman_process(bool yay) +{ + if(!exec_find("pacman")) + { + std::cerr << "pacman not found\n"; + return; + } + //fetch + if(combine_fetch) + { + #pragma omp parallel sections + { + #pragma omp section + { + if(opt_repo) + fetch_update(&repo, "REPO", PACMAN_FETCH_COMMAND); + } + #pragma omp section + { + if(opt_aur && yay) + fetch_update(&aur, "AUR", AUR_FETCH_COMMAND); + } + } + } + + //process + if(opt_repo) + { + //size fetch + if( combine_size ) + { + import_sizes(&repo, PACMAN_EXT_INFO_COMMAND, PACMAN_LOCAL_INFO_COMMAND, PACMAN_EXT_SIZE_CUT_COMMAND, PACMAN_LOCAL_SIZE_CUT_COMMAND); + } + + repo_print_process(repo, ztd::color::b_white); + + if(opt_plistraw) + { + print_listraw(repo); + } + + if(opt_update) + { + signal(SIGINT, SIG_IGN); + if(opt_noconfirm) + system(PACMAN_UPDATE_COMMAND_NOCONFIRM); + else + system(PACMAN_UPDATE_COMMAND); + } + + + } + if(opt_aur && yay) + { + repo_print_process(aur, ztd::color::b_cyan, false); + + if(opt_plistraw) + { + print_listraw(aur); + } + + if(opt_update) + { + signal(SIGINT, SIG_IGN); + if(opt_noconfirm) + system(AUR_UPDATE_COMMAND_NOCONFIRM); + else + system(AUR_UPDATE_COMMAND); + } + } +} + +std::string apt_getrepo() +{ + if ( ztd::sh("apt-cache policy | grep '/main' -A2 | grep '=exp'").size()>0) + return "EXPERIMENTAL"; + if ( ztd::sh("apt-cache policy | grep '/main' -A2 | grep '=unstable'").size()>0) + return "UNSTABLE"; + if ( ztd::sh("apt-cache policy | grep '/main' -A2 | grep '=stable'").size()>0) + return "STABLE"; + if ( ztd::sh("apt-cache policy | grep '/main' -A2 | grep '=oldstable'").size()>0) + return "OLDSTABLE"; + + return "UNKNOWN"; +} + +void apt_process() +{ + if(!exec_find("apt")) + { + std::cerr << "apt not found\n"; + return; + } + if(!exec_find("apt-cache")) + { + std::cerr << "apt-cache not found\n"; + return; + } + if(!exec_find("dpkg")) + { + std::cerr << "dpkg not found\n"; + return; + } + if(combine_fetch) + { + fetch_update(&repo, apt_getrepo(), APT_FETCH_COMMAND); + } + if( combine_size ) + { + import_sizes(&repo, APT_EXT_INFO_COMMAND, APT_LOCAL_INFO_COMMAND, APT_EXT_SIZE_CUT_COMMAND, APT_LOCAL_SIZE_CUT_COMMAND); + } + + repo_print_process(repo, ztd::color::b_white); + + if(opt_plistraw) + { + print_listraw(repo); + } + + if(opt_update) + { + signal(SIGINT, SIG_IGN); + if(opt_noconfirm) + system(APT_UPDATE_COMMAND_NOCONFIRM); + else + system(APT_UPDATE_COMMAND); + } +} diff --git a/src/print.cpp b/src/print.cpp new file mode 100644 index 0000000..39b3a7f --- /dev/null +++ b/src/print.cpp @@ -0,0 +1,116 @@ +#include "print.hpp" + +#include +#include + +#include + +#include "opt_bool.h" + +//constants +const char* size_suffixes[6] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB"}; +const int size_print_padding=-21; + +//functions +std::pair convertN(const long int size, unsigned int n) +{ + double ret = size; + for(unsigned int i=0; i convertHReadable(const long int size) +{ + double ret = size; + unsigned char pow1k=0; + while(abs(ret) >= 1024.0) + { + ret /= 1024; + pow1k++; + } + return std::make_pair( ret, size_suffixes[pow1k] ); +} + +void print_update(repo_update& ru, ztd::color color, bool dlsize, bool nisize, bool nusize) +{ + if(ru.packages.size() > 0) + { + printf("%s[%s] %lu updates%s\n", color.code(), ru.name.c_str(), ru.packages.size(), no_color.code()); + for(auto it : ru.packages) + { + std::string v1; + std::string v2; + if(ztd::sh("command -v zdiffcolor").size() > 0) + { + std::string command="zdiffcolor -n b_white -c b_red -s b_green " + it.current_version + ' ' + it.new_version; + std::string str=ztd::sh(command); + auto newline = str.find('\n'); + v1=str.substr(0, newline); + newline++; + v2=str.substr(newline, str.size()-newline-1); + } + else + { + ztd::color v1c = ztd::color::b_red, v2c = ztd::color::b_green, noc = ztd::color::none; + v1 = v1c.code() + it.current_version + noc.code(); + v2 = v2c.code() + it.new_version + noc.code(); + } + printf(" %*s %*s -> %*s | ", -1*(ru.name_max_length + 2), it.name.c_str(), -1*(ru.vcur_max_length + 20), v1.c_str(), -1*(ru.vnew_max_length + 20), v2.c_str()); + if(dlsize) + print_size(it.download_size, true, "", 0, ztd::color::none, 2, size_index, " : "); + if(nusize) + print_size(it.net_size, true, "", 0, ztd::color::none, 2, size_index, ""); + printf("\n"); + } + std::cout << color; + std::cout << "================================"; + std::cout << no_color << std::endl; + } +} + +void print_update_sizes(repo_update& ru, ztd::color color, bool dlsize, bool nisize, bool nusize, bool notitle) +{ + if(dlsize) + print_size(ru.download_size, !notitle, "Total Download Size:", size_print_padding, color, 2, size_index); + if(nisize) + print_size(ru.new_install_size, !notitle, "Total Install Size:", size_print_padding, color, 2, size_index); + if(nusize) + print_size(ru.net_size, !notitle, "Net Upgrade Size:", size_print_padding, color, 2, size_index); + if(!notitle && (dlsize || nisize || nusize)) + { + std::cout << color; + std::cout << "================================"; + std::cout << no_color << std::endl; + } +} + +void print_size(long int size, bool printTitle, std::string title, int padding, ztd::color color, unsigned int precision, unsigned int sizepow, const char* line_end) +{ + auto tpair = convertN(size, sizepow); + if( printTitle ) + { + printf("%s%*s%s", color.code(), padding, title.c_str(), no_color.code()); + } + unsigned int sizepad=precision+5; + if(sizepow == 0) + { + precision = 0; + sizepad = 9; + } + if(!printTitle) + { + sizepad = 0; + } + printf("%*.*f %s%s", sizepad, precision, tpair.first, tpair.second, line_end); +} + +void print_listraw(repo_update& ru) +{ + for(auto it : ru.packages) + { + printf("%s %s -> %s\n", it.name.c_str(), it.current_version.c_str(), it.new_version.c_str()); + } +} diff --git a/src/repos.cpp b/src/repos.cpp new file mode 100644 index 0000000..da69203 --- /dev/null +++ b/src/repos.cpp @@ -0,0 +1,3 @@ +#include "repos.hpp" + +repo_update repo, aur;