From 79fe3123026d363d5ff633cb8ce4b4ee1d0ada70 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sun, 13 Jul 2014 09:56:06 +0200 Subject: [PATCH] Gather proper transaction stats (take into account binpkgs in cachedir, and "preserved" pkgs). --- NEWS | 4 ++++ include/xbps.h.in | 13 ++++++++++- lib/transaction_dictionary.c | 45 +++++++++++++++++++----------------- lib/util.c | 16 +++++++++++++ 4 files changed, 56 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index a05c1259..f874d493 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ xbps-0.38 (???): + * When installing or updating packages, now proper statistics are generated + when a binary package from a repository repository exists in the cachedir, + and when a package has the "preserve" property. + * libxbps: return ENXIO and a meaningful error message if a package that is going to be installed or updated has invalid dependencies, i.e: diff --git a/include/xbps.h.in b/include/xbps.h.in index cb67d323..d81dfc41 100644 --- a/include/xbps.h.in +++ b/include/xbps.h.in @@ -48,7 +48,7 @@ * * This header documents the full API for the XBPS Library. */ -#define XBPS_API_VERSION "20140702" +#define XBPS_API_VERSION "20140713" #ifndef XBPS_VERSION #define XBPS_VERSION "UNSET" @@ -1609,6 +1609,17 @@ bool xbps_verify_file_signature(struct xbps_repo *repo, const char *fname); */ int xbps_pkg_is_installed(struct xbps_handle *xhp, const char *pkg); +/** + * Returns true if binary package exists in cachedir or in a local repository, + * false otherwise. + * + * @param[in] xhp The pointer to an xbps_handle struct. + * @param[in] pkgd Package dictionary returned by rpool. + * + * @return true if exists, false otherwise. + */ +bool xbps_binpkg_exists(struct xbps_handle *xhp, xbps_dictionary_t pkgd); + /** * Checks if the URI specified by \a uri is remote or local. * diff --git a/lib/transaction_dictionary.c b/lib/transaction_dictionary.c index 65139fb3..bcbf3695 100644 --- a/lib/transaction_dictionary.c +++ b/lib/transaction_dictionary.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2013 Juan Romero Pardines. + * Copyright (c) 2009-2014 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,6 +70,7 @@ compute_transaction_stats(struct xbps_handle *xhp) return EINVAL; while ((obj = xbps_object_iterator_next(iter)) != NULL) { + bool preserve = false; /* * Count number of pkgs to be removed, configured, * installed and updated. @@ -77,6 +78,7 @@ compute_transaction_stats(struct xbps_handle *xhp) xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); xbps_dictionary_get_cstring_nocopy(obj, "transaction", &tract); xbps_dictionary_get_cstring_nocopy(obj, "repository", &repo); + xbps_dictionary_get_bool(obj, "preserve", &preserve); if (strcmp(tract, "configure") == 0) { cf_pkgcnt++; @@ -95,7 +97,8 @@ compute_transaction_stats(struct xbps_handle *xhp) xbps_dictionary_get_uint64(obj, "installed_size", &tsize); instsize += tsize; - if (xbps_repository_is_remote(repo)) { + if (xbps_repository_is_remote(repo) && + !xbps_binpkg_exists(xhp, obj)) { xbps_dictionary_get_uint64(obj, "filename-size", &tsize); dlsize += tsize; @@ -107,7 +110,7 @@ compute_transaction_stats(struct xbps_handle *xhp) * from pkg's metadata dictionary. */ if ((strcmp(tract, "remove") == 0) || - (strcmp(tract, "update") == 0)) { + ((strcmp(tract, "update") == 0) && !preserve)) { char *pkgname; pkgname = xbps_pkg_name(pkgver); @@ -162,7 +165,7 @@ compute_transaction_stats(struct xbps_handle *xhp) int HIDDEN xbps_transaction_init(struct xbps_handle *xhp) { - xbps_array_t unsorted, mdeps, conflicts; + xbps_array_t array; if (xhp->transd != NULL) return 0; @@ -170,41 +173,41 @@ xbps_transaction_init(struct xbps_handle *xhp) if ((xhp->transd = xbps_dictionary_create()) == NULL) return ENOMEM; - if ((unsorted = xbps_array_create()) == NULL) { + if ((array = xbps_array_create()) == NULL) { xbps_object_release(xhp->transd); xhp->transd = NULL; return ENOMEM; } - if (!xbps_dictionary_set(xhp->transd, "unsorted_deps", unsorted)) { + if (!xbps_dictionary_set(xhp->transd, "unsorted_deps", array)) { xbps_object_release(xhp->transd); xhp->transd = NULL; return EINVAL; } - xbps_object_release(unsorted); + xbps_object_release(array); - if ((mdeps = xbps_array_create()) == NULL) { + if ((array = xbps_array_create()) == NULL) { xbps_object_release(xhp->transd); xhp->transd = NULL; return ENOMEM; } - if (!xbps_dictionary_set(xhp->transd, "missing_deps", mdeps)) { + if (!xbps_dictionary_set(xhp->transd, "missing_deps", array)) { xbps_object_release(xhp->transd); xhp->transd = NULL; return EINVAL; } - xbps_object_release(mdeps); + xbps_object_release(array); - if ((conflicts = xbps_array_create()) == NULL) { + if ((array = xbps_array_create()) == NULL) { xbps_object_release(xhp->transd); xhp->transd = NULL; return ENOMEM; } - if (!xbps_dictionary_set(xhp->transd, "conflicts", conflicts)) { + if (!xbps_dictionary_set(xhp->transd, "conflicts", array)) { xbps_object_release(xhp->transd); xhp->transd = NULL; return EINVAL; } - xbps_object_release(conflicts); + xbps_object_release(array); return 0; } @@ -212,7 +215,7 @@ xbps_transaction_init(struct xbps_handle *xhp) int xbps_transaction_prepare(struct xbps_handle *xhp) { - xbps_array_t pkgs, mdeps, conflicts; + xbps_array_t array; int rv = 0; if (xhp->transd == NULL) @@ -222,18 +225,18 @@ xbps_transaction_prepare(struct xbps_handle *xhp) * If there are missing deps or revdeps bail out. */ xbps_transaction_revdeps(xhp); - mdeps = xbps_dictionary_get(xhp->transd, "missing_deps"); - if (xbps_array_count(mdeps)) + array = xbps_dictionary_get(xhp->transd, "missing_deps"); + if (xbps_array_count(array)) return ENODEV; - pkgs = xbps_dictionary_get(xhp->transd, "unsorted_deps"); - for (unsigned int i = 0; i < xbps_array_count(pkgs); i++) - xbps_pkg_find_conflicts(xhp, pkgs, xbps_array_get(pkgs, i)); + array = xbps_dictionary_get(xhp->transd, "unsorted_deps"); + for (unsigned int i = 0; i < xbps_array_count(array); i++) + xbps_pkg_find_conflicts(xhp, array, xbps_array_get(array, i)); /* * If there are package conflicts bail out. */ - conflicts = xbps_dictionary_get(xhp->transd, "conflicts"); - if (xbps_array_count(conflicts)) + array = xbps_dictionary_get(xhp->transd, "conflicts"); + if (xbps_array_count(array)) return EAGAIN; /* diff --git a/lib/util.c b/lib/util.c index 4b355540..d10bcee4 100644 --- a/lib/util.c +++ b/lib/util.c @@ -228,6 +228,22 @@ xbps_repository_pkg_path(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod) return xbps_xasprintf("%s/%s.%s.xbps", repoloc, pkgver, arch); } +bool +xbps_binpkg_exists(struct xbps_handle *xhp, xbps_dictionary_t pkgd) +{ + char *binpkg; + bool exists = true; + + if ((binpkg = xbps_repository_pkg_path(xhp, pkgd)) == NULL) + return false; + + if (access(binpkg, R_OK) == -1) + exists = false; + + free(binpkg); + return exists; +} + bool xbps_pkg_has_rundeps(xbps_dictionary_t pkgd) {