Skip to content

Commit

Permalink
bin/xbps-remove: allow removing uninstalled packages from the cache
Browse files Browse the repository at this point in the history
Change "obsolete packages" to "outdated packages" when describing the
old behaviour.
  • Loading branch information
Duncaen committed Jun 24, 2023
1 parent 6d940e6 commit ee770cb
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 23 deletions.
35 changes: 22 additions & 13 deletions bin/xbps-remove/clean-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,23 @@ binpkg_parse(char *buf, size_t bufsz, const char *path, const char **pkgver, con
return 0;
}

struct cleaner_data {
bool dry;
bool uninstalled;
};

static int
cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
const char *key UNUSED, void *arg,
bool *done UNUSED)
{
char buf[PATH_MAX];
xbps_dictionary_t repo_pkgd;
xbps_dictionary_t pkgd;
const char *binpkg, *rsha256;
const char *binpkgver, *binpkgarch;
bool drun = false;
struct cleaner_data *data = arg;
int r;

/* Extract drun (dry-run) flag from arg*/
if (arg != NULL)
drun = *(bool*)arg;

binpkg = xbps_string_cstring_nocopy(obj);
r = binpkg_parse(buf, sizeof(buf), binpkg, &binpkgver, &binpkgarch);
if (r < 0) {
Expand All @@ -96,9 +97,13 @@ cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
* Remove binary pkg if it's not registered in any repository
* or if hash doesn't match.
*/
repo_pkgd = xbps_rpool_get_pkg(xhp, binpkgver);
if (repo_pkgd) {
xbps_dictionary_get_cstring_nocopy(repo_pkgd,
if (data->uninstalled) {
pkgd = xbps_pkgdb_get_pkg(xhp, binpkgver);
} else {
pkgd = xbps_rpool_get_pkg(xhp, binpkgver);
}
if (pkgd) {
xbps_dictionary_get_cstring_nocopy(pkgd,
"filename-sha256", &rsha256);
r = xbps_file_sha256_check(binpkg, rsha256);
if (r == 0) {
Expand All @@ -111,13 +116,13 @@ cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
}
}
snprintf(buf, sizeof(buf), "%s.sig", binpkg);
if (!drun && unlink(binpkg) == -1) {
if (!data->dry && unlink(binpkg) == -1) {
xbps_error_printf("Failed to remove `%s': %s\n",
binpkg, strerror(errno));
} else {
printf("Removed %s from cachedir (obsolete)\n", binpkg);
}
if (!drun && unlink(buf) == -1 && errno != ENOENT) {
if (!data->dry && unlink(buf) == -1 && errno != ENOENT) {
xbps_error_printf("Failed to remove `%s': %s\n",
buf, strerror(errno));
}
Expand All @@ -126,7 +131,7 @@ cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
}

int
clean_cachedir(struct xbps_handle *xhp, bool drun)
clean_cachedir(struct xbps_handle *xhp, bool uninstalled, bool drun)
{
xbps_array_t array = NULL;
DIR *dirp;
Expand Down Expand Up @@ -158,7 +163,11 @@ clean_cachedir(struct xbps_handle *xhp, bool drun)
(void)closedir(dirp);

if (xbps_array_count(array)) {
rv = xbps_array_foreach_cb_multi(xhp, array, NULL, cleaner_cb, (void*)&drun);
struct cleaner_data data = {
.dry = drun,
.uninstalled = uninstalled,
};
rv = xbps_array_foreach_cb_multi(xhp, array, NULL, cleaner_cb, (void*)&data);
xbps_object_release(array);
}
return rv;
Expand Down
2 changes: 1 addition & 1 deletion bin/xbps-remove/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
#define _XBPS_REMOVE_DEFS_H_

/* From clean-cache.c */
int clean_cachedir(struct xbps_handle *, bool drun);
int clean_cachedir(struct xbps_handle *, bool uninstalled, bool drun);

#endif /* !_XBPS_REMOVE_DEFS_H_ */
16 changes: 9 additions & 7 deletions bin/xbps-remove/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ usage(bool fail)
" -f, --force Force package files removal\n"
" -h, --help Show usage\n"
" -n, --dry-run Dry-run mode\n"
" -O, --clean-cache Remove obsolete packages in cachedir\n"
" -O, --clean-cache Remove outdated packages from the cache\n"
" If specified twice, also remove uninstalled packages\n"
" -o, --remove-orphans Remove package orphans\n"
" -R, --recursive Recursively remove dependencies\n"
" -r, --rootdir <dir> Full path to rootdir\n"
Expand Down Expand Up @@ -179,12 +180,13 @@ main(int argc, char **argv)
struct xbps_handle xh;
const char *rootdir, *cachedir, *confdir;
int c, flags, rv;
bool yes, drun, recursive, clean_cache, orphans;
bool yes, drun, recursive, orphans;
int maxcols, missing;
int clean_cache = 0;

rootdir = cachedir = confdir = NULL;
flags = rv = 0;
drun = recursive = clean_cache = yes = orphans = false;
drun = recursive = yes = orphans = false;

while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
switch (c) {
Expand All @@ -210,7 +212,7 @@ main(int argc, char **argv)
drun = true;
break;
case 'O':
clean_cache = true;
clean_cache++;
break;
case 'o':
orphans = true;
Expand All @@ -236,7 +238,7 @@ main(int argc, char **argv)
/* NOTREACHED */
}
}
if (!clean_cache && !orphans && (argc == optind)) {
if (clean_cache == 0 && !orphans && (argc == optind)) {
usage(true);
/* NOTREACHED */
}
Expand All @@ -263,8 +265,8 @@ main(int argc, char **argv)

maxcols = get_maxcols();

if (clean_cache) {
rv = clean_cachedir(&xh, drun);
if (clean_cache > 0) {
rv = clean_cachedir(&xh, clean_cache > 1, drun);
if (!orphans || rv)
exit(rv);;
}
Expand Down
4 changes: 3 additions & 1 deletion bin/xbps-remove/xbps-remove.1
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ Show the help message.
Dry-run mode. Show what actions would be done but don't do anything. The current output
prints 6 arguments: "<pkgver> <action> <arch> <repository> <installedsize> <downloadsize>".
.It Fl O, Fl -clean-cache
Cleans cache directory removing obsolete binary packages.
Cleans cache directory removing outdated binary packages.
If specified twice,
also remove packages that are not installed from the cache.
.It Fl o, Fl -remove-orphans
Removes installed package orphans that were installed automatically
(as dependencies) and are not currently dependencies of any installed package.
Expand Down
43 changes: 42 additions & 1 deletion tests/xbps/xbps-remove/basic_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ clean_cache_head() {
}

clean_cache_body() {
mkdir -p repo pkg_A/B/C
mkdir -p repo pkg_A/B/C pkg_B
touch pkg_A/
cd repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n A-1.0_2 -s "A pkg" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n B-1.0_1 -s "B pkg" ../pkg_B
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
Expand All @@ -69,12 +71,15 @@ clean_cache_body() {
cp repo/*.xbps root/var/cache/xbps
atf_check_equal $? 0
echo "repository=https://localhost/" >root/etc/xbps.d/localrepo.conf
xbps-install -r root -C etc/xbps.d -R repo -dvy B
xbps-remove -r root -C etc/xbps.d -dvO
atf_check_equal $? 0
test -f root/var/cache/xbps/A-1.0_2.noarch.xbps
atf_check_equal $? 0
test -f root/var/cache/xbps/A-1.0_1.noarch.xbps
atf_check_equal $? 1
test -f root/var/cache/xbps/B-1.0_1.noarch.xbps
atf_check_equal $? 0
}

atf_test_case clean_cache_dry_run
Expand Down Expand Up @@ -136,10 +141,46 @@ clean_cache_dry_run_perm_body() {
atf_check_equal "$out" "Removed A-1.0_1.noarch.xbps from cachedir (obsolete)"
}

clean_cache_uninstalled_head() {
atf_set "descr" "xbps-remove(1): clean uninstalled package from cache"
}

clean_cache_uninstalled_body() {
mkdir -p repo pkg_A/B/C pkg_B
touch pkg_A/
cd repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n A-1.0_2 -s "A pkg" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n B-1.0_1 -s "B pkg" ../pkg_B
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
mkdir -p root/etc/xbps.d root/var/db/xbps/https___localhost_ root/var/cache/xbps
cp repo/*-repodata root/var/db/xbps/https___localhost_
atf_check_equal $? 0
cp repo/*.xbps root/var/cache/xbps
atf_check_equal $? 0
echo "repository=https://localhost/" >root/etc/xbps.d/localrepo.conf
xbps-install -r root -C etc/xbps.d -R repo -dvy B
atf_check_equal $? 0
xbps-remove -r root -C etc/xbps.d -dvOO
atf_check_equal $? 0
test -f root/var/cache/xbps/A-1.0_2.noarch.xbps
atf_check_equal $? 1
test -f root/var/cache/xbps/A-1.0_1.noarch.xbps
atf_check_equal $? 1
test -f root/var/cache/xbps/B-1.0_1.noarch.xbps
atf_check_equal $? 0
}

atf_init_test_cases() {
atf_add_test_case remove_directory
atf_add_test_case remove_orphans
atf_add_test_case clean_cache
atf_add_test_case clean_cache_dry_run
atf_add_test_case clean_cache_dry_run_perm
atf_add_test_case clean_cache_uninstalled
}

0 comments on commit ee770cb

Please sign in to comment.