From: Michael Tremer Date: Wed, 7 Jun 2017 20:54:06 +0000 (+0200) Subject: libpakfire: Implement dumping a transaction X-Git-Tag: 0.9.28~1285^2~1332 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2c4f381c61e7ccd5de393469caebedcf0c06028;p=people%2Fms%2Fpakfire.git libpakfire: Implement dumping a transaction Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/request.c b/src/_pakfire/request.c index dc786baac..6d04d024e 100644 --- a/src/_pakfire/request.c +++ b/src/_pakfire/request.c @@ -194,16 +194,11 @@ static PyObject* Request_solve(RequestObject* self) { int ret = pakfire_request_solve(self->request, 0); if (ret) - Py_RETURN_FALSE; - - Py_RETURN_TRUE; -} + Py_RETURN_NONE; -static PyObject* Request_get_transaction(RequestObject* self) { + // Allocate the transaction and return it PakfireTransaction transaction = pakfire_request_get_transaction(self->request); - - if (!transaction) - Py_RETURN_NONE; + assert(transaction); return new_transaction(self, transaction); } @@ -269,12 +264,6 @@ static struct PyMethodDef Request_methods[] = { METH_NOARGS, NULL }, - { - "get_transaction", - (PyCFunction)Request_get_transaction, - METH_NOARGS, - NULL - }, { NULL } }; diff --git a/src/_pakfire/transaction.c b/src/_pakfire/transaction.c index d6032a234..6004f84db 100644 --- a/src/_pakfire/transaction.c +++ b/src/_pakfire/transaction.c @@ -104,15 +104,22 @@ static PyObject* Transaction_get_installsizechange(TransactionObject* self) { return PyLong_FromLong(installsizechange); } -#if 0 -static PyObject* Transaction_get_installs(TransactionObject* self) { - PakfirePackageList packagelist = pakfire_transaction_get_packages(self->transaction, - SOLVER_TRANSACTION_INSTALL); +static PyObject* Transaction_dump(TransactionObject* self) { + char* string = pakfire_transaction_dump(self->transaction, 80); + assert(string); - PyObject* list = PyList_FromPackageList(self->request->pool, packagelist); - return list; + return PyUnicode_FromString(string); } -#endif + +static struct PyMethodDef Transaction_methods[] = { + { + "dump", + (PyCFunction)Transaction_dump, + METH_NOARGS, + NULL + }, + { NULL }, +}; static struct PyGetSetDef Transaction_getsetters[] = { { @@ -134,6 +141,7 @@ PyTypeObject TransactionType = { tp_dealloc: (destructor)Transaction_dealloc, tp_init: (initproc)Transaction_init, tp_doc: "Transaction object", + tp_methods: Transaction_methods, tp_getset: Transaction_getsetters, tp_iter: (getiterfunc)Transaction_iter, }; diff --git a/src/libpakfire/include/pakfire/transaction.h b/src/libpakfire/include/pakfire/transaction.h index 3ead26303..689954477 100644 --- a/src/libpakfire/include/pakfire/transaction.h +++ b/src/libpakfire/include/pakfire/transaction.h @@ -28,13 +28,15 @@ PakfireTransaction pakfire_transaction_create(PakfirePool pool, Transaction* trans); void pakfire_transaction_free(PakfireTransaction transaction); -int pakfire_transaction_count(PakfireTransaction transaction); +size_t pakfire_transaction_count(PakfireTransaction transaction); -int pakfire_transaction_installsizechange(PakfireTransaction transaction); +ssize_t pakfire_transaction_installsizechange(PakfireTransaction transaction); PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int index); PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transaction, int type); +char* pakfire_transaction_dump(PakfireTransaction transaction, size_t width); + #ifdef PAKFIRE_PRIVATE struct _PakfireTransaction { diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index b6baf71d0..dee81712c 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -264,6 +264,7 @@ global: # transaction pakfire_transaction_create; + pakfire_transaction_dump; pakfire_transaction_free; pakfire_transaction_get_packages; pakfire_transaction_get_step; diff --git a/src/libpakfire/transaction.c b/src/libpakfire/transaction.c index df15f80df..2d6f84dd3 100644 --- a/src/libpakfire/transaction.c +++ b/src/libpakfire/transaction.c @@ -18,10 +18,13 @@ # # #############################################################################*/ +#include #include +#include #include #include +#include #include #include #include @@ -47,18 +50,45 @@ void pakfire_transaction_free(PakfireTransaction transaction) { pakfire_free(transaction); } -int pakfire_transaction_count(PakfireTransaction transaction) { +size_t pakfire_transaction_count(PakfireTransaction transaction) { return transaction->transaction->steps.count; } -int pakfire_transaction_installsizechange(PakfireTransaction transaction) { - int sizechange = transaction_calc_installsizechange(transaction->transaction); - printf("SIZECHANGE %d\n", sizechange); +ssize_t pakfire_transaction_installsizechange(PakfireTransaction transaction) { + ssize_t sizechange = transaction_calc_installsizechange(transaction->transaction); // Convert from kbytes to bytes return sizechange * 1024; } +ssize_t pakfire_transaction_downloadsize(PakfireTransaction transaction) { + PakfirePool pool = pakfire_transaction_pool(transaction); + ssize_t size = 0; + + for (int i = 0; i < transaction->transaction->steps.count; i++) { + Id p = transaction->transaction->steps.elements[i]; + Id t = transaction_type(transaction->transaction, p, + SOLVER_TRANSACTION_SHOW_OBSOLETES | + SOLVER_TRANSACTION_CHANGE_IS_REINSTALL | + SOLVER_TRANSACTION_SHOW_ALL | + SOLVER_TRANSACTION_SHOW_ACTIVE); + + // Erasing a package does not require us to download it + if (t == SOLVER_TRANSACTION_ERASE) + continue; + + // Get the package for this step + PakfirePackage pkg = pakfire_package_create(pool, p); + + if (!pakfire_package_is_cached(pkg)) + size += pakfire_package_get_downloadsize(pkg); + + pakfire_package_free(pkg); + } + + return size; +} + PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int index) { Transaction* trans = transaction->transaction; @@ -70,14 +100,16 @@ PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int ind PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transaction, int type) { PakfirePool pool = pakfire_transaction_pool(transaction); - Transaction* trans = transaction->transaction; PakfirePackageList packagelist = pakfire_packagelist_create(); - for (int i = 0; i < trans->steps.count; i++) { - Id p = trans->steps.elements[i]; - Id t = transaction_type(trans, p, - SOLVER_TRANSACTION_SHOW_ACTIVE|SOLVER_TRANSACTION_CHANGE_IS_REINSTALL); + for (int i = 0; i < transaction->transaction->steps.count; i++) { + Id p = transaction->transaction->steps.elements[i]; + Id t = transaction_type(transaction->transaction, p, + SOLVER_TRANSACTION_SHOW_OBSOLETES | + SOLVER_TRANSACTION_CHANGE_IS_REINSTALL | + SOLVER_TRANSACTION_SHOW_ALL | + SOLVER_TRANSACTION_SHOW_ACTIVE); if (t == type) { PakfirePackage package = pakfire_package_create(pool, p); @@ -85,5 +117,150 @@ PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transacti } } + // Sort list in place + pakfire_packagelist_sort(packagelist); + return packagelist; } + +static void pakfire_transaction_add_headline(char** str, size_t width, const char* headline) { + assert(headline); + + asprintf(str, "%s%s\n", *str, headline); +} + +static void pakfire_transaction_add_newline(char** str, size_t width) { + asprintf(str, "%s\n", *str); +} + +static void pakfire_transaction_add_line(char** str, size_t width, const char* name, + const char* arch, const char* version, const char* repo, const char* size) { + // XXX need to adapt to size + asprintf(str, "%s %-21s %-8s %-21s %-18s %6s \n", *str, name, arch, version, repo, size); +} + +static void pakfire_transaction_add_package(char** str, size_t width, PakfirePackage pkg) { + PakfireRepo repo = pakfire_package_get_repo(pkg); + + unsigned long long size = pakfire_package_get_size(pkg); + char* size_str = pakfire_format_size(size); + + pakfire_transaction_add_line(str, width, + pakfire_package_get_name(pkg), + pakfire_package_get_arch(pkg), + pakfire_package_get_evr(pkg), + pakfire_repo_get_name(repo), + size_str + ); + + pakfire_repo_free(repo); + pakfire_free(size_str); +} + +static void pakfire_transaction_add_separator(char** str, size_t width) { + while (width-- > 0) + asprintf(str, "%s=", *str); + + // newline + asprintf(str, "%s\n", *str); +} + +static size_t pakfire_transaction_add_section(char** str, size_t width, PakfireTransaction transaction, + const char* headline, int type) { + PakfirePackageList list = pakfire_transaction_get_packages(transaction, type); + + // Nothing to do if there are no packages in this stage + size_t c = pakfire_packagelist_count(list); + if (c == 0) + goto END; + + // Headline + pakfire_transaction_add_headline(str, width, headline); + + // List each package + for (unsigned int i = 0; i < c; i++) { + PakfirePackage pkg = pakfire_packagelist_get(list, i); + pakfire_transaction_add_package(str, width, pkg); + } + + // newline + pakfire_transaction_add_newline(str, width); + +END: + pakfire_packagelist_free(list); + + return c; +} + +static void pakfire_transaction_add_summary_line(char** str, size_t width, const char* headline, size_t pkgs) { + if (pkgs > 0) + asprintf(str, "%s%-20s %-4zu %s\n", *str, headline, pkgs, _("package(s)")); +} + +static void pakfire_transaction_add_usage_line(char** str, size_t width, const char* headline, ssize_t size) { + char* s = pakfire_format_size(size); + + asprintf(str, "%s%-21s: %s\n", *str, headline, s); + + pakfire_free(s); +} + +char* pakfire_transaction_dump(PakfireTransaction transaction, size_t width) { + char* string = ""; + + // Header + pakfire_transaction_add_separator(&string, width); + pakfire_transaction_add_line(&string, width, + _("Package"), + _("Arch"), + _("Version"), + _("Repository"), + _("Size") + ); + pakfire_transaction_add_separator(&string, width); + + // Show what we are doing + size_t installing = pakfire_transaction_add_section(&string, width, transaction, + _("Installing:"), SOLVER_TRANSACTION_INSTALL); + size_t reinstalling = pakfire_transaction_add_section(&string, width, transaction, + _("Reinstalling:"), SOLVER_TRANSACTION_REINSTALL); + size_t updating = pakfire_transaction_add_section(&string, width, transaction, + _("Updating:"), SOLVER_TRANSACTION_UPGRADE); + size_t downgrading = pakfire_transaction_add_section(&string, width, transaction, + _("Downgrading:"), SOLVER_TRANSACTION_DOWNGRADE); + size_t removing = pakfire_transaction_add_section(&string, width, transaction, + _("Removing:"), SOLVER_TRANSACTION_ERASE); + size_t obsoleting = pakfire_transaction_add_section(&string, width, transaction, + _("Obsoleting:"), SOLVER_TRANSACTION_OBSOLETES); + + // Summary + pakfire_transaction_add_headline(&string, width, _("Transaction Summary")); + pakfire_transaction_add_separator(&string, width); + + pakfire_transaction_add_summary_line(&string, width, _("Installing:"), installing); + pakfire_transaction_add_summary_line(&string, width, _("Reinstalling:"), reinstalling); + pakfire_transaction_add_summary_line(&string, width, _("Updating:"), updating); + pakfire_transaction_add_summary_line(&string, width, _("Downgrading:"), downgrading); + pakfire_transaction_add_summary_line(&string, width, _("Removing:"), removing); + pakfire_transaction_add_summary_line(&string, width, _("Obsoleting:"), obsoleting); + + // How much do we need to download? + size_t downloadsize = pakfire_transaction_downloadsize(transaction); + if (downloadsize > 0) + pakfire_transaction_add_usage_line(&string, width, + _("Total Download Size"), downloadsize); + + // How much more space do we need? + ssize_t sizechange = pakfire_transaction_installsizechange(transaction); + + pakfire_transaction_add_usage_line(&string, width, + (sizechange >= 0) ? _("Installed Size") : _("Freed Size"), sizechange); + + // Remove trailing newline + size_t l = strlen(string) - 1; + + if (l > 0 && string[l] == '\n') + string[l] = '\0'; + + return string; +}