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:
parent
2401e72b8a
commit
237991fd79
4
NEWS
4
NEWS
@ -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.
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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!
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user