Open gergesh opened 3 years ago
This isn't terrible, because you can just run with -o
for orphans later, but it can be a pain if you have other orphans you wish to keep, and shouldn't be necessary.
It's probably a limitation of the current solver, or maybe it just checks for new orphans in the wrong place. Will try to investigate.
Hi, I took a look around to see where it might come from after reproducing the steps above with the exact same results. In bin/xbps-remove/main.c
, in the loop where it removes the packages, it doesn't seem to do anything special when doing it recursively so it just passes each individual package to remove_pkg
with a flag to remove recursively or not.
bin/xbps-remove/main.c
@@ -290,10 +290,10 @@ main(int argc, char **argv)
for (int i = optind; i < argc; i++) {
rv = remove_pkg(&xh, argv[i], recursive);
if (rv == ENOENT) {
missing++;
continue;
} else if (rv != 0) {
xbps_end(&xh);
exit(rv);
}
}
And remove_pkg
seems to just pass it through to xbps_transaction_remove_pkg
if it exists. which does check for orphans, but it can only check for orphans while treating one package at a time as removed.
lib/transaction_ops.c
@@ -479,13 +479,13 @@ xbps_transaction_remove_pkg(struct xbps_handle *xhp,
xbps_array_set_cstring_nocopy(orphans_pkg, 0, pkgname);
orphans = xbps_find_pkg_orphans(xhp, orphans_pkg);
xbps_object_release(orphans_pkg);
if (xbps_object_type(orphans) != XBPS_TYPE_ARRAY)
return EINVAL;
for (unsigned int i = 0; i < xbps_array_count(orphans); i++) {
obj = xbps_array_get(orphans, i);
xbps_transaction_pkg_type_set(obj, XBPS_TRANS_REMOVE);
if (!xbps_transaction_store(xhp, pkgs, obj, false)) {
return EINVAL;
}
}
xbps_find_pkg_orphans
does have the ability to accept multiple package names for those to be treated as already removed it seems.
xbps_array_t xbps_find_pkg_orphans(struct xbps_handle *xhp, xbps_array_t orphans);
It seems then, that a potential solution would be to have a seperate function in lib/transaction_ops.c
that would remove multiple packages recursively (xbps_transaction_remove_pkgs_recursive(struct xbps_handle *xhp, xbps_array_t pkgs)
)? and in bin/xbps-remove/main.c
if the recursive flag is passed, then call that function instead? Have I understood this correctly?
I ended up not looking into this part of the code at all, but that sounds reasonable.
Is it worth fixing? (I’d be willing to submit a PR if it is)
The following commands were ran after each other, nothing in between:
As for my two cents, if I had to guess I'd say it's due to them having shared dependencies which are not considered for removal (checking if the dependencies are orphaned for each of them separately, not taking into consideration that both are removed).