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:
parent
5e4d33a58f
commit
0e950156fc
@ -127,7 +127,7 @@ xbps_dictionary_t HIDDEN xbps_find_pkg_in_array(xbps_array_t, const char *,
|
|||||||
const char *);
|
const char *);
|
||||||
xbps_dictionary_t HIDDEN xbps_find_virtualpkg_in_array(struct xbps_handle *,
|
xbps_dictionary_t HIDDEN xbps_find_virtualpkg_in_array(struct xbps_handle *,
|
||||||
xbps_array_t, const char *, const char *);
|
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,
|
bool HIDDEN xbps_transaction_shlibs(struct xbps_handle *, xbps_array_t,
|
||||||
xbps_array_t);
|
xbps_array_t);
|
||||||
int HIDDEN xbps_transaction_init(struct xbps_handle *);
|
int HIDDEN xbps_transaction_init(struct xbps_handle *);
|
||||||
|
@ -272,11 +272,13 @@ xbps_transaction_init(struct xbps_handle *xhp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_REPEAT 512
|
||||||
|
|
||||||
int
|
int
|
||||||
xbps_transaction_prepare(struct xbps_handle *xhp)
|
xbps_transaction_prepare(struct xbps_handle *xhp)
|
||||||
{
|
{
|
||||||
xbps_array_t array, pkgs, edges;
|
xbps_array_t array, pkgs, edges;
|
||||||
unsigned int i, cnt;
|
unsigned int i, j, cnt;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
if ((rv = xbps_transaction_init(xhp)) != 0)
|
if ((rv = xbps_transaction_init(xhp)) != 0)
|
||||||
@ -285,60 +287,79 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
|
|||||||
if (xhp->transd == NULL)
|
if (xhp->transd == NULL)
|
||||||
return ENXIO;
|
return ENXIO;
|
||||||
|
|
||||||
/*
|
for (j = 0; j < MAX_REPEAT; j++) {
|
||||||
* Collect dependencies for pkgs in transaction.
|
/*
|
||||||
*/
|
* Collect dependencies for pkgs in transaction.
|
||||||
if ((edges = xbps_array_create()) == NULL)
|
*/
|
||||||
return ENOMEM;
|
if ((edges = xbps_array_create()) == NULL)
|
||||||
/*
|
|
||||||
* The edges are also appended after its dependencies have been
|
|
||||||
* collected; the edges at the original array are removed later.
|
|
||||||
*/
|
|
||||||
pkgs = xbps_dictionary_get(xhp->transd, "packages");
|
|
||||||
assert(xbps_object_type(pkgs) == XBPS_TYPE_ARRAY);
|
|
||||||
cnt = xbps_array_count(pkgs);
|
|
||||||
for (i = 0; i < cnt; i++) {
|
|
||||||
xbps_dictionary_t pkgd;
|
|
||||||
xbps_string_t str;
|
|
||||||
const char *tract = NULL;
|
|
||||||
|
|
||||||
pkgd = xbps_array_get(pkgs, i);
|
|
||||||
str = xbps_dictionary_get(pkgd, "pkgver");
|
|
||||||
xbps_dictionary_get_cstring_nocopy(pkgd, "transaction", &tract);
|
|
||||||
if ((strcmp(tract, "remove") == 0) || strcmp(tract, "hold") == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
assert(xbps_object_type(str) == XBPS_TYPE_STRING);
|
|
||||||
|
|
||||||
if (!xbps_array_add(edges, str))
|
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
/*
|
||||||
|
* The edges are also appended after its dependencies have been
|
||||||
|
* collected; the edges at the original array are removed later.
|
||||||
|
*/
|
||||||
|
pkgs = xbps_dictionary_get(xhp->transd, "packages");
|
||||||
|
assert(xbps_object_type(pkgs) == XBPS_TYPE_ARRAY);
|
||||||
|
cnt = xbps_array_count(pkgs);
|
||||||
|
for (i = 0; i < cnt; i++) {
|
||||||
|
xbps_dictionary_t pkgd;
|
||||||
|
xbps_string_t str;
|
||||||
|
const char *tract = NULL;
|
||||||
|
|
||||||
if ((rv = xbps_repository_find_deps(xhp, pkgs, pkgd)) != 0)
|
pkgd = xbps_array_get(pkgs, i);
|
||||||
|
str = xbps_dictionary_get(pkgd, "pkgver");
|
||||||
|
xbps_dictionary_get_cstring_nocopy(pkgd, "transaction", &tract);
|
||||||
|
if ((strcmp(tract, "remove") == 0) || strcmp(tract, "hold") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
assert(xbps_object_type(str) == XBPS_TYPE_STRING);
|
||||||
|
|
||||||
|
if (!xbps_array_add(edges, str))
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
if ((rv = xbps_repository_find_deps(xhp, pkgs, pkgd)) != 0)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
if (!xbps_array_add(pkgs, pkgd))
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
/* ... remove dup edges at head */
|
||||||
|
for (i = 0; i < xbps_array_count(edges); i++) {
|
||||||
|
const char *pkgver = NULL;
|
||||||
|
xbps_array_get_cstring_nocopy(edges, i, &pkgver);
|
||||||
|
xbps_remove_pkg_from_array_by_pkgver(pkgs, pkgver);
|
||||||
|
}
|
||||||
|
xbps_object_release(edges);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for packages to be replaced.
|
||||||
|
*/
|
||||||
|
if ((rv = xbps_transaction_package_replace(xhp, pkgs)) != 0) {
|
||||||
|
xbps_object_release(xhp->transd);
|
||||||
|
xhp->transd = NULL;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check reverse dependencies.
|
||||||
|
*/
|
||||||
|
if ((rv = xbps_transaction_revdeps(xhp, pkgs)) == 0)
|
||||||
|
break;
|
||||||
|
if (rv != EAGAIN)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
if (!xbps_array_add(pkgs, pkgd))
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
}
|
||||||
/* ... remove dup edges at head */
|
|
||||||
for (i = 0; i < xbps_array_count(edges); i++) {
|
|
||||||
const char *pkgver = NULL;
|
|
||||||
xbps_array_get_cstring_nocopy(edges, i, &pkgver);
|
|
||||||
xbps_remove_pkg_from_array_by_pkgver(pkgs, pkgver);
|
|
||||||
}
|
|
||||||
xbps_object_release(edges);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for packages to be replaced.
|
* Repeated too many times.
|
||||||
*/
|
*/
|
||||||
if ((rv = xbps_transaction_package_replace(xhp, pkgs)) != 0) {
|
if (j == MAX_REPEAT) {
|
||||||
xbps_object_release(xhp->transd);
|
xbps_dbg_printf(xhp, "[trans] aborted due to too many repetitions"
|
||||||
xhp->transd = NULL;
|
" while resolving dependencies!\n");
|
||||||
return rv;
|
return ELOOP;
|
||||||
|
} else {
|
||||||
|
xbps_dbg_printf(xhp, "[trans] resolved dependencies in"
|
||||||
|
" %d repetitions.\n", j);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If there are missing deps or revdeps bail out.
|
* If there are missing deps or revdeps bail out.
|
||||||
*/
|
*/
|
||||||
xbps_transaction_revdeps(xhp, pkgs);
|
|
||||||
array = xbps_dictionary_get(xhp->transd, "missing_deps");
|
array = xbps_dictionary_get(xhp->transd, "missing_deps");
|
||||||
if (xbps_array_count(array)) {
|
if (xbps_array_count(array)) {
|
||||||
if (xhp->flags & XBPS_FLAG_FORCE_REMOVE_REVDEPS) {
|
if (xhp->flags & XBPS_FLAG_FORCE_REMOVE_REVDEPS) {
|
||||||
|
@ -101,10 +101,21 @@ broken_pkg(xbps_array_t mdeps, const char *dep, const char *pkg, const char *tra
|
|||||||
free(str);
|
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_transaction_revdeps(struct xbps_handle *xhp, xbps_array_t pkgs)
|
||||||
{
|
{
|
||||||
xbps_array_t mdeps;
|
xbps_array_t mdeps;
|
||||||
|
int updated = 0;
|
||||||
|
|
||||||
mdeps = xbps_dictionary_get(xhp->transd, "missing_deps");
|
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);
|
free(pkgname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (update_pkg(xhp, pkgname) == 0) {
|
||||||
|
updated++;
|
||||||
|
free(pkgname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
free(pkgname);
|
free(pkgname);
|
||||||
broken_pkg(mdeps, curpkgver, pkgver, tract);
|
broken_pkg(mdeps, curpkgver, pkgver, tract);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (updated > 0)
|
||||||
|
return EAGAIN;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user