xbps-bin: added -F flag for the remove target.

Unless it's set, packages that are dependencies of other installed packages
won't be removed. This flag overrides this behaviour and forces the package removal.

While being here, misc cleanups.
This commit is contained in:
Juan RP 2010-12-03 17:36:07 +01:00
parent 2401e72b8a
commit 237991fd79
9 changed files with 124 additions and 165 deletions

4
NEWS
View File

@ -1,5 +1,9 @@
xbps-0.7.0 (?)
* xbps-bin(8): added -F flag for the remove target. Unless it's set,
packages that are dependencies of other installed packages won't be removed.
This flag overrides this behaviour and forces the package removal.
* xbps-{bin,repo}(8): indent uniformly all lines while listing packages
in xbps-bin or while searching for packages in xbps-repo.

View File

@ -26,12 +26,6 @@
#ifndef _XBPS_BIN_DEFS_H_
#define _XBPS_BIN_DEFS_H_
#ifdef DEBUG
#define DPRINTF(x) printf x
#else
#define DPRINTF(x)
#endif
#ifndef __UNCONST
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#endif
@ -39,9 +33,9 @@
int xbps_install_new_pkg(const char *);
int xbps_update_pkg(const char *);
int xbps_autoupdate_pkgs(bool);
int xbps_autoremove_pkgs(bool, bool, bool);
int xbps_autoremove_pkgs(bool, bool);
int xbps_exec_transaction(bool);
int xbps_remove_installed_pkgs(int, char **, bool, bool);
int xbps_remove_installed_pkgs(int, char **, bool, bool, bool);
int xbps_check_pkg_integrity(const char *);
int xbps_check_pkg_integrity_all(void);
int xbps_show_pkg_deps(const char *);
@ -50,5 +44,4 @@ int show_pkg_info_from_metadir(const char *);
int show_pkg_files_from_metadir(const char *);
int find_files_in_packages(const char *);
#endif /* !_XBPS_BIN_DEFS_H_ */

View File

@ -34,6 +34,7 @@
#include <xbps_api.h>
#include "defs.h"
#include "../xbps-repo/defs.h"
struct transaction {
prop_dictionary_t dict;
@ -183,27 +184,14 @@ static void
show_package_list(prop_object_iterator_t iter, const char *match)
{
prop_object_t obj;
size_t cols = 0;
const char *pkgver, *tract;
bool first = false;
while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "trans-action", &tract);
if (strcmp(match, tract))
continue;
cols += strlen(pkgver) + 4;
if (cols <= 80) {
if (first == false) {
printf(" ");
first = true;
}
} else {
printf("\n ");
cols = strlen(pkgver) + 4;
}
printf("%s ", pkgver);
print_package_line(pkgver);
}
prop_object_iterator_reset(iter);
}
@ -625,8 +613,8 @@ xbps_exec_transaction(bool yes)
goto out;
}
DPRINTF(("Dictionary before transaction happens:\n"));
DPRINTF(("%s", prop_dictionary_externalize(trans->dict)));
xbps_dbg_printf("Dictionary before transaction happens:\n");
xbps_dbg_printf_append("%s", prop_dictionary_externalize(trans->dict));
/*
* It's time to run the transaction!

View File

@ -45,36 +45,8 @@ static void
usage(void)
{
fprintf(stderr,
"Usage: xbps-bin [options] [target] [arguments]\n\n"
" Available targets:\n"
" autoremove\n"
" autoupdate\n"
" check\t\t[<pkgname>|<all>]\n"
" find-files\t\t<pattern>\n"
" install\t\t[<pkgname(s)>|<pkgpattern(s)>]\n"
" list\t\t[state]\n"
" list-manual\n"
" purge\t\t[<pkgname>|<all>]\n"
" reconfigure\t\t[<pkgname>|<all>]\n"
" remove\t\t<pkgname(s)>\n"
" show\t\t<pkgname>\n"
" show-deps\t\t<pkgname>\n"
" show-files\t\t<pkgname>\n"
" show-orphans\n"
" show-revdeps\t<pkgname>\n"
" update\t\t<pkgname(s)>\n"
" Options shared by all targets:\n"
" -c\t\t<cachedir>\n"
" -d\t\tDebug output\n"
" -r\t\t<rootdir>\n"
" -v\t\tShows verbose messages\n"
" -V\t\tPrints the xbps release version\n"
" Options used by the install/(auto)remove/update targets:\n"
" -y\t\tAssume \"yes\" for all questions.\n"
" -p\t\tAlso purge package(s) in the (auto)remove targets.\n"
" Options used by the purge/reconfigure/remove targets:\n"
" -f\t\tForce reconfiguration or removal of files.\n"
"\n");
"Usage: xbps-bin [options] [target] [arguments]\n"
"See xbps-bin(8) for more information.\n");
exit(EXIT_FAILURE);
}
@ -137,6 +109,33 @@ list_manual_packages(prop_object_t obj, void *arg, bool *loop_done)
return 0;
}
static int
show_orphans(void)
{
prop_array_t orphans;
prop_object_iterator_t iter;
prop_object_t obj;
const char *pkgver;
orphans = xbps_find_orphan_packages();
if (orphans == NULL)
return EINVAL;
if (prop_array_count(orphans) == 0)
return 0;
iter = prop_array_iterator(orphans);
if (iter == NULL)
return ENOMEM;
while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
printf("%s\n", pkgver);
}
prop_object_iterator_release(iter);
return 0;
}
static void
cleanup(int signum)
@ -151,12 +150,13 @@ main(int argc, char **argv)
prop_dictionary_t dict;
struct list_pkgver_cb lpc;
struct sigaction sa;
int i = 0, c, flags = 0, rv = 0;
bool yes, purge, with_debug;
int i , c, flags, rv;
bool yes, purge, with_debug, force_rm_with_deps;
yes = purge = with_debug = false;
i = c = flags = rv = 0;
yes = purge = force_rm_with_deps = with_debug = false;
while ((c = getopt(argc, argv, "Vcdfpr:vy")) != -1) {
while ((c = getopt(argc, argv, "VcdFfpr:vy")) != -1) {
switch (c) {
case 'c':
xbps_set_cachedir(optarg);
@ -164,6 +164,9 @@ main(int argc, char **argv)
case 'd':
with_debug = true;
break;
case 'F':
force_rm_with_deps = true;
break;
case 'f':
flags |= XBPS_FLAG_FORCE;
break;
@ -292,7 +295,8 @@ main(int argc, char **argv)
if (argc < 2)
usage();
rv = xbps_remove_installed_pkgs(argc, argv, yes, purge);
rv = xbps_remove_installed_pkgs(argc, argv, yes, purge,
force_rm_with_deps);
} else if (strcasecmp(argv[0], "show") == 0) {
/* Shows info about an installed binary package. */
@ -343,7 +347,7 @@ main(int argc, char **argv)
if (argc != 1)
usage();
rv = xbps_autoremove_pkgs(yes, purge, true);
rv = show_orphans();
} else if (strcasecmp(argv[0], "autoremove") == 0) {
/*
@ -354,7 +358,7 @@ main(int argc, char **argv)
if (argc != 1)
usage();
rv = xbps_autoremove_pkgs(yes, purge, false);
rv = xbps_autoremove_pkgs(yes, purge);
} else if (strcasecmp(argv[0], "purge") == 0) {
/*

View File

@ -61,15 +61,13 @@ pkg_remove_and_purge(const char *pkgname, const char *version, bool purge)
}
int
xbps_autoremove_pkgs(bool force, bool purge, bool only_show)
xbps_autoremove_pkgs(bool yes, bool purge)
{
prop_array_t orphans = NULL;
prop_object_t obj = NULL;
prop_object_iterator_t iter = NULL;
const char *pkgver, *pkgname, *version;
size_t cols = 0;
int rv = 0;
bool first = false;
/*
* Removes orphan pkgs. These packages were installed
@ -95,25 +93,12 @@ xbps_autoremove_pkgs(bool force, bool purge, bool only_show)
"(as dependencies) and aren't needed anymore:\n\n");
while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
cols += strlen(pkgver) + 4;
if (cols <= 80) {
if (first == false) {
printf(" ");
first = true;
}
} else {
printf("\n ");
cols = strlen(pkgver) + 4;
}
printf("%s ", pkgver);
print_package_line(pkgver);
}
prop_object_iterator_reset(iter);
printf("\n\n");
if (only_show)
goto out;
if (!force && !xbps_noyes("Do you want to continue?")) {
if (!yes && !xbps_noyes("Do you want to continue?")) {
printf("Cancelled!\n");
goto out;
}
@ -135,14 +120,20 @@ out:
}
int
xbps_remove_installed_pkgs(int argc, char **argv, bool force, bool purge)
xbps_remove_installed_pkgs(int argc, char **argv, bool yes, bool purge,
bool force_rm_with_deps)
{
prop_array_t sorted_pkgs;
prop_array_t reqby;
prop_dictionary_t dict;
size_t cols = 0;
const char *version;
size_t x;
const char *version, *pkgver, *pkgname;
int i, rv = 0;
bool found = false, first = false, reqby_force = false;
bool found = false, reqby_force = false;
sorted_pkgs = prop_array_create();
if (sorted_pkgs == NULL)
return -1;
/*
* First check if package is required by other packages.
@ -153,58 +144,58 @@ xbps_remove_installed_pkgs(int argc, char **argv, bool force, bool purge)
printf("Package %s is not installed.\n", argv[i]);
continue;
}
prop_dictionary_get_cstring_nocopy(dict, "version", &version);
prop_array_add(sorted_pkgs, dict);
prop_dictionary_get_cstring_nocopy(dict, "pkgver", &pkgver);
found = true;
reqby = prop_dictionary_get(dict, "requiredby");
if (reqby != NULL && prop_array_count(reqby) > 0) {
printf("WARNING: %s-%s IS REQUIRED BY OTHER "
"PACKAGES!\n", argv[i], version);
printf("WARNING: %s IS REQUIRED BY %u PACKAGES!\n",
pkgver, prop_array_count(reqby));
reqby_force = true;
}
prop_object_release(dict);
}
if (!found)
if (!found) {
prop_object_release(sorted_pkgs);
return 0;
}
/*
* Show the list of going-to-be removed packages.
*/
printf("The following packages will be removed:\n\n");
for (i = 1; i < argc; i++) {
dict = xbps_find_pkg_dict_installed(argv[i], false);
if (dict == NULL)
continue;
prop_dictionary_get_cstring_nocopy(dict, "version", &version);
cols += strlen(argv[i]) + strlen(version) + 4;
if (cols <= 80) {
if (first == false) {
printf(" ");
first = true;
}
} else {
printf("\n ");
cols = strlen(argv[i]) + strlen(version) + 4;
}
printf("%s-%s ", argv[i], version);
prop_object_release(dict);
for (x = 0; x < prop_array_count(sorted_pkgs); x++) {
dict = prop_array_get(sorted_pkgs, x);
prop_dictionary_get_cstring_nocopy(dict, "pkgver", &pkgver);
print_package_line(pkgver);
}
printf("\n\n");
if (!force && !xbps_noyes("Do you want to continue?")) {
if (!yes && !xbps_noyes("Do you want to continue?")) {
printf("Cancelling!\n");
prop_object_release(sorted_pkgs);
return 0;
}
if (reqby_force)
printf("Forcing removal!\n");
if (reqby_force && !force_rm_with_deps) {
printf("\nYou haven't specified the -F flag to force removal with dependencies. The package(s)\n"
"you are going to remove are required by other installed packages, therefore\n"
"it might break packages that currently depend on them. If you are entirely sure\n"
"that's what you want, use 'xbps-bin -F remove ...' to continue with the operation.\n");
prop_object_release(sorted_pkgs);
return 0;
} else if (reqby_force && force_rm_with_deps)
printf("WARNING: Forcing removal! you've been alerted.\n");
for (i = 1; i < argc; i++) {
dict = xbps_find_pkg_dict_installed(argv[i], false);
if (dict == NULL)
continue;
for (x = 0; x < prop_array_count(sorted_pkgs); x++) {
dict = prop_array_get(sorted_pkgs, x);
prop_dictionary_get_cstring_nocopy(dict, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(dict, "version", &version);
prop_object_release(dict);
if ((rv = pkg_remove_and_purge(argv[i], version, purge)) != 0)
if ((rv = pkg_remove_and_purge(pkgname, version, purge)) != 0) {
prop_object_release(sorted_pkgs);
return rv;
}
}
prop_object_release(sorted_pkgs);
return 0;
}

View File

@ -1,13 +1,4 @@
'\" t
.\" Title: xbps-bin
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 18/11/2010
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "XBPS\-BIN" "8" "18/11/2010" "\ \&" "\ \&"
.TH "XBPS\-BIN" "8" "03/12/2010" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@ -48,6 +39,12 @@ of
Enables extra debugging output to be shown to stderr.
.RE
.PP
\fB\-F\fR
.RS 4
Used currently in the \fIremove\fR target. If set, package will be removed even if other packages
are currently depending on it, i.e package is a dependency of other packages. Use this option with care.
.RE
.PP
\fB\-f\fR
.RS 4
Used currently in the

View File

@ -42,6 +42,7 @@ int show_pkg_namedesc(prop_object_t, void *, bool *);
int list_strings_in_array(prop_object_t, void *, bool *);
int list_strings_sep_in_array(prop_object_t, void *, bool *);
size_t find_longest_pkgver(prop_dictionary_t);
void print_package_line(const char *);
struct repo_search_data {
char *pattern;

View File

@ -39,31 +39,8 @@ static void
usage(void)
{
fprintf(stderr,
"Usage: xbps-repo [options] [action] [arguments]\n\n"
" Available actions:\n"
" add, genindex, list, remove, search, show, show-deps,\n"
" show-files, sync\n"
" Actions with arguments:\n"
" add\t\t<URI>\n"
" genindex\t<path>\n"
" remove\t<URI>\n"
" search\t<string>\n"
" show\t<pkgname>\n"
" show-deps\t<pkgname>\n"
" show-files\t<pkgname>\n"
" Options shared by all actions:\n"
" -c\t\t<cachedir>\n"
" -r\t\t<rootdir>\n"
" -V\t\tPrints xbps release version\n"
"\n"
" Examples:\n"
" $ xbps-repo add /path/to/directory\n"
" $ xbps-repo add http://www.location.org/xbps-repo\n"
" $ xbps-repo list\n"
" $ xbps-repo remove /path/to/directory\n"
" $ xbps-repo search klibc\n"
" $ xbps-repo show klibc\n"
" $ xbps-repo genindex /pkgdir\n");
"Usage: xbps-repo [options] [action] [arguments]\n"
"See xbps-repo(8) for more information.\n");
exit(EXIT_FAILURE);
}

View File

@ -245,25 +245,11 @@ show_pkg_namedesc(prop_object_t obj, void *arg, bool *loop_done)
int
list_strings_in_array(prop_object_t obj, void *arg, bool *loop_done)
{
static size_t cols;
static bool first;
(void)arg;
(void)loop_done;
assert(prop_object_type(obj) == PROP_TYPE_STRING);
cols += strlen(prop_string_cstring_nocopy(obj)) + 4;
if (cols <= 80) {
if (first == false) {
printf(" ");
first = true;
}
} else {
printf("\n ");
cols = strlen(prop_string_cstring_nocopy(obj)) + 4;
}
printf("%s ", prop_string_cstring_nocopy(obj));
print_package_line(prop_string_cstring_nocopy(obj));
return 0;
}
@ -276,8 +262,26 @@ list_strings_sep_in_array(prop_object_t obj, void *arg, bool *loop_done)
(void)loop_done;
assert(prop_object_type(obj) == PROP_TYPE_STRING);
printf("%s%s\n", sep ? sep : "", prop_string_cstring_nocopy(obj));
return 0;
}
void
print_package_line(const char *str)
{
static size_t cols;
static bool first;
cols += strlen(str) + 4;
if (cols <= 80) {
if (first == false) {
printf(" ");
first = true;
}
} else {
printf("\n ");
cols = strlen(str) + 4;
}
printf("%s ", str);
}