bin/xbps-remove: allow removing uninstalled packages from the cache
Change "obsolete packages" to "outdated packages" when describing the old behaviour.
This commit is contained in:
parent
6d940e647f
commit
ee770cb8e4
@ -64,22 +64,23 @@ binpkg_parse(char *buf, size_t bufsz, const char *path, const char **pkgver, con
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cleaner_data {
|
||||||
|
bool dry;
|
||||||
|
bool uninstalled;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
|
cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
|
||||||
const char *key UNUSED, void *arg,
|
const char *key UNUSED, void *arg,
|
||||||
bool *done UNUSED)
|
bool *done UNUSED)
|
||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
xbps_dictionary_t repo_pkgd;
|
xbps_dictionary_t pkgd;
|
||||||
const char *binpkg, *rsha256;
|
const char *binpkg, *rsha256;
|
||||||
const char *binpkgver, *binpkgarch;
|
const char *binpkgver, *binpkgarch;
|
||||||
bool drun = false;
|
struct cleaner_data *data = arg;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Extract drun (dry-run) flag from arg*/
|
|
||||||
if (arg != NULL)
|
|
||||||
drun = *(bool*)arg;
|
|
||||||
|
|
||||||
binpkg = xbps_string_cstring_nocopy(obj);
|
binpkg = xbps_string_cstring_nocopy(obj);
|
||||||
r = binpkg_parse(buf, sizeof(buf), binpkg, &binpkgver, &binpkgarch);
|
r = binpkg_parse(buf, sizeof(buf), binpkg, &binpkgver, &binpkgarch);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -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
|
* Remove binary pkg if it's not registered in any repository
|
||||||
* or if hash doesn't match.
|
* or if hash doesn't match.
|
||||||
*/
|
*/
|
||||||
repo_pkgd = xbps_rpool_get_pkg(xhp, binpkgver);
|
if (data->uninstalled) {
|
||||||
if (repo_pkgd) {
|
pkgd = xbps_pkgdb_get_pkg(xhp, binpkgver);
|
||||||
xbps_dictionary_get_cstring_nocopy(repo_pkgd,
|
} else {
|
||||||
|
pkgd = xbps_rpool_get_pkg(xhp, binpkgver);
|
||||||
|
}
|
||||||
|
if (pkgd) {
|
||||||
|
xbps_dictionary_get_cstring_nocopy(pkgd,
|
||||||
"filename-sha256", &rsha256);
|
"filename-sha256", &rsha256);
|
||||||
r = xbps_file_sha256_check(binpkg, rsha256);
|
r = xbps_file_sha256_check(binpkg, rsha256);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
@ -111,13 +116,13 @@ cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf(buf, sizeof(buf), "%s.sig", binpkg);
|
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",
|
xbps_error_printf("Failed to remove `%s': %s\n",
|
||||||
binpkg, strerror(errno));
|
binpkg, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
printf("Removed %s from cachedir (obsolete)\n", binpkg);
|
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",
|
xbps_error_printf("Failed to remove `%s': %s\n",
|
||||||
buf, strerror(errno));
|
buf, strerror(errno));
|
||||||
}
|
}
|
||||||
@ -126,7 +131,7 @@ cleaner_cb(struct xbps_handle *xhp, xbps_object_t obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
clean_cachedir(struct xbps_handle *xhp, bool drun)
|
clean_cachedir(struct xbps_handle *xhp, bool uninstalled, bool drun)
|
||||||
{
|
{
|
||||||
xbps_array_t array = NULL;
|
xbps_array_t array = NULL;
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
@ -158,7 +163,11 @@ clean_cachedir(struct xbps_handle *xhp, bool drun)
|
|||||||
(void)closedir(dirp);
|
(void)closedir(dirp);
|
||||||
|
|
||||||
if (xbps_array_count(array)) {
|
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);
|
xbps_object_release(array);
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -27,6 +27,6 @@
|
|||||||
#define _XBPS_REMOVE_DEFS_H_
|
#define _XBPS_REMOVE_DEFS_H_
|
||||||
|
|
||||||
/* From clean-cache.c */
|
/* 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_ */
|
#endif /* !_XBPS_REMOVE_DEFS_H_ */
|
||||||
|
@ -53,7 +53,8 @@ usage(bool fail)
|
|||||||
" -f, --force Force package files removal\n"
|
" -f, --force Force package files removal\n"
|
||||||
" -h, --help Show usage\n"
|
" -h, --help Show usage\n"
|
||||||
" -n, --dry-run Dry-run mode\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"
|
" -o, --remove-orphans Remove package orphans\n"
|
||||||
" -R, --recursive Recursively remove dependencies\n"
|
" -R, --recursive Recursively remove dependencies\n"
|
||||||
" -r, --rootdir <dir> Full path to rootdir\n"
|
" -r, --rootdir <dir> Full path to rootdir\n"
|
||||||
@ -179,12 +180,13 @@ main(int argc, char **argv)
|
|||||||
struct xbps_handle xh;
|
struct xbps_handle xh;
|
||||||
const char *rootdir, *cachedir, *confdir;
|
const char *rootdir, *cachedir, *confdir;
|
||||||
int c, flags, rv;
|
int c, flags, rv;
|
||||||
bool yes, drun, recursive, clean_cache, orphans;
|
bool yes, drun, recursive, orphans;
|
||||||
int maxcols, missing;
|
int maxcols, missing;
|
||||||
|
int clean_cache = 0;
|
||||||
|
|
||||||
rootdir = cachedir = confdir = NULL;
|
rootdir = cachedir = confdir = NULL;
|
||||||
flags = rv = 0;
|
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) {
|
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@ -210,7 +212,7 @@ main(int argc, char **argv)
|
|||||||
drun = true;
|
drun = true;
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
clean_cache = true;
|
clean_cache++;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
orphans = true;
|
orphans = true;
|
||||||
@ -236,7 +238,7 @@ main(int argc, char **argv)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!clean_cache && !orphans && (argc == optind)) {
|
if (clean_cache == 0 && !orphans && (argc == optind)) {
|
||||||
usage(true);
|
usage(true);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
@ -263,8 +265,8 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
maxcols = get_maxcols();
|
maxcols = get_maxcols();
|
||||||
|
|
||||||
if (clean_cache) {
|
if (clean_cache > 0) {
|
||||||
rv = clean_cachedir(&xh, drun);
|
rv = clean_cachedir(&xh, clean_cache > 1, drun);
|
||||||
if (!orphans || rv)
|
if (!orphans || rv)
|
||||||
exit(rv);;
|
exit(rv);;
|
||||||
}
|
}
|
||||||
|
@ -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
|
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>".
|
prints 6 arguments: "<pkgver> <action> <arch> <repository> <installedsize> <downloadsize>".
|
||||||
.It Fl O, Fl -clean-cache
|
.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
|
.It Fl o, Fl -remove-orphans
|
||||||
Removes installed package orphans that were installed automatically
|
Removes installed package orphans that were installed automatically
|
||||||
(as dependencies) and are not currently dependencies of any installed package.
|
(as dependencies) and are not currently dependencies of any installed package.
|
||||||
|
@ -53,13 +53,15 @@ clean_cache_head() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clean_cache_body() {
|
clean_cache_body() {
|
||||||
mkdir -p repo pkg_A/B/C
|
mkdir -p repo pkg_A/B/C pkg_B
|
||||||
touch pkg_A/
|
touch pkg_A/
|
||||||
cd repo
|
cd repo
|
||||||
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
|
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
|
||||||
atf_check_equal $? 0
|
atf_check_equal $? 0
|
||||||
xbps-create -A noarch -n A-1.0_2 -s "A pkg" ../pkg_A
|
xbps-create -A noarch -n A-1.0_2 -s "A pkg" ../pkg_A
|
||||||
atf_check_equal $? 0
|
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
|
xbps-rindex -d -a $PWD/*.xbps
|
||||||
atf_check_equal $? 0
|
atf_check_equal $? 0
|
||||||
cd ..
|
cd ..
|
||||||
@ -69,12 +71,15 @@ clean_cache_body() {
|
|||||||
cp repo/*.xbps root/var/cache/xbps
|
cp repo/*.xbps root/var/cache/xbps
|
||||||
atf_check_equal $? 0
|
atf_check_equal $? 0
|
||||||
echo "repository=https://localhost/" >root/etc/xbps.d/localrepo.conf
|
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
|
xbps-remove -r root -C etc/xbps.d -dvO
|
||||||
atf_check_equal $? 0
|
atf_check_equal $? 0
|
||||||
test -f root/var/cache/xbps/A-1.0_2.noarch.xbps
|
test -f root/var/cache/xbps/A-1.0_2.noarch.xbps
|
||||||
atf_check_equal $? 0
|
atf_check_equal $? 0
|
||||||
test -f root/var/cache/xbps/A-1.0_1.noarch.xbps
|
test -f root/var/cache/xbps/A-1.0_1.noarch.xbps
|
||||||
atf_check_equal $? 1
|
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
|
atf_test_case clean_cache_dry_run
|
||||||
@ -136,10 +141,46 @@ clean_cache_dry_run_perm_body() {
|
|||||||
atf_check_equal "$out" "Removed A-1.0_1.noarch.xbps from cachedir (obsolete)"
|
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_init_test_cases() {
|
||||||
atf_add_test_case remove_directory
|
atf_add_test_case remove_directory
|
||||||
atf_add_test_case remove_orphans
|
atf_add_test_case remove_orphans
|
||||||
atf_add_test_case clean_cache
|
atf_add_test_case clean_cache
|
||||||
atf_add_test_case clean_cache_dry_run
|
atf_add_test_case clean_cache_dry_run
|
||||||
atf_add_test_case clean_cache_dry_run_perm
|
atf_add_test_case clean_cache_dry_run_perm
|
||||||
|
atf_add_test_case clean_cache_uninstalled
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user