lib/transaction_{revdeps,prepare}.c: try to update packages if necessary

`xbps_transaction_revdeps` will now try to add updates for packages to the
transaction if the dependency is not satisified anymore due to a package
install/update.

`xbps_transaction_prepare` will now check the return value of
`xbps_transaction_revdeps` and repeat the dependency resolution,
until `xbps_transaction_revdeps` returns 0, which means that it didn't
add any new packages to the transaction.
This commit is contained in:
Duncaen 2019-07-02 15:22:58 +02:00 committed by Juan RP
parent 5e4d33a58f
commit 0e950156fc
3 changed files with 87 additions and 47 deletions

View File

@ -127,7 +127,7 @@ xbps_dictionary_t HIDDEN xbps_find_pkg_in_array(xbps_array_t, const char *,
const char *);
xbps_dictionary_t HIDDEN xbps_find_virtualpkg_in_array(struct xbps_handle *,
xbps_array_t, const char *, const char *);
void HIDDEN xbps_transaction_revdeps(struct xbps_handle *, xbps_array_t);
int HIDDEN xbps_transaction_revdeps(struct xbps_handle *, xbps_array_t);
bool HIDDEN xbps_transaction_shlibs(struct xbps_handle *, xbps_array_t,
xbps_array_t);
int HIDDEN xbps_transaction_init(struct xbps_handle *);

View File

@ -272,11 +272,13 @@ xbps_transaction_init(struct xbps_handle *xhp)
return 0;
}
#define MAX_REPEAT 512
int
xbps_transaction_prepare(struct xbps_handle *xhp)
{
xbps_array_t array, pkgs, edges;
unsigned int i, cnt;
unsigned int i, j, cnt;
int rv = 0;
if ((rv = xbps_transaction_init(xhp)) != 0)
@ -285,6 +287,7 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
if (xhp->transd == NULL)
return ENXIO;
for (j = 0; j < MAX_REPEAT; j++) {
/*
* Collect dependencies for pkgs in transaction.
*/
@ -335,10 +338,28 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
xhp->transd = NULL;
return rv;
}
/*
* Check reverse dependencies.
*/
if ((rv = xbps_transaction_revdeps(xhp, pkgs)) == 0)
break;
if (rv != EAGAIN)
return rv;
}
/*
* Repeated too many times.
*/
if (j == MAX_REPEAT) {
xbps_dbg_printf(xhp, "[trans] aborted due to too many repetitions"
" while resolving dependencies!\n");
return ELOOP;
} else {
xbps_dbg_printf(xhp, "[trans] resolved dependencies in"
" %d repetitions.\n", j);
}
/*
* If there are missing deps or revdeps bail out.
*/
xbps_transaction_revdeps(xhp, pkgs);
array = xbps_dictionary_get(xhp->transd, "missing_deps");
if (xbps_array_count(array)) {
if (xhp->flags & XBPS_FLAG_FORCE_REMOVE_REVDEPS) {

View File

@ -101,10 +101,21 @@ broken_pkg(xbps_array_t mdeps, const char *dep, const char *pkg, const char *tra
free(str);
}
void HIDDEN
static int
update_pkg(struct xbps_handle *xhp, const char *pkg)
{
int rv = 0;
rv = xbps_transaction_update_pkg(xhp, pkg);
if (rv == EEXIST)
return 0;
return rv;
}
int HIDDEN
xbps_transaction_revdeps(struct xbps_handle *xhp, xbps_array_t pkgs)
{
xbps_array_t mdeps;
int updated = 0;
mdeps = xbps_dictionary_get(xhp->transd, "missing_deps");
@ -235,9 +246,17 @@ xbps_transaction_revdeps(struct xbps_handle *xhp, xbps_array_t pkgs)
free(pkgname);
continue;
}
if (update_pkg(xhp, pkgname) == 0) {
updated++;
free(pkgname);
continue;
}
free(pkgname);
broken_pkg(mdeps, curpkgver, pkgver, tract);
}
}
if (updated > 0)
return EAGAIN;
return 0;
}