Multiple changes to pkgs on hold mode.

- Added transaction stats for pkgs on hold.

- Always add packages on hold to the transaction dictionary,
  its type will be set to XBPS_TRANS_HOLD.

- Changed xbps_transaction_update_pkg() to have a new "force"
  bool argument to force an update with a pkg on hold.

- As discussed in #274 with @Duncaen the only way to update a
  pkg on hold is by using `-f`, i.e `xbps-install -f foo`.

Closes #265
Closes #274
This commit is contained in:
Juan RP
2020-04-23 06:03:56 +02:00
parent 6b6b394686
commit 7d8247ae56
9 changed files with 127 additions and 108 deletions

View File

@@ -43,11 +43,12 @@ struct transaction {
uint32_t cf_pkgcnt;
uint32_t rm_pkgcnt;
uint32_t dl_pkgcnt;
uint32_t hold_pkgcnt;
};
/* from transaction.c */
int install_new_pkg(struct xbps_handle *, const char *, bool);
int update_pkg(struct xbps_handle *, const char *);
int update_pkg(struct xbps_handle *, const char *, bool);
int dist_upgrade(struct xbps_handle *, unsigned int, bool, bool);
int exec_transaction(struct xbps_handle *, unsigned int, bool, bool);
@@ -65,5 +66,6 @@ int state_cb(const struct xbps_state_cb_data *, void *);
void print_package_line(const char *, unsigned int, bool);
bool print_trans_colmode(struct transaction *, unsigned int);
int get_maxcols(void);
const char *ttype2str(xbps_dictionary_t);
#endif /* !_XBPS_INSTALL_DEFS_H_ */

View File

@@ -124,12 +124,12 @@ main(int argc, char **argv)
struct xferstat xfer;
const char *rootdir, *cachedir, *confdir;
int i, c, flags, rv, fflag = 0;
bool syncf, yes, reinstall, drun, update;
bool syncf, yes, force, drun, update;
int maxcols, eexist = 0;
rootdir = cachedir = confdir = NULL;
flags = rv = 0;
syncf = yes = reinstall = drun = update = false;
syncf = yes = force = drun = update = false;
memset(&xh, 0, sizeof(xh));
@@ -157,7 +157,7 @@ main(int argc, char **argv)
fflag++;
if (fflag > 1)
flags |= XBPS_FLAG_FORCE_UNPACK;
reinstall = true;
force = true;
break;
case 'h':
usage(false);
@@ -258,7 +258,7 @@ main(int argc, char **argv)
} else if (update) {
/* Update target packages */
for (i = optind; i < argc; i++) {
rv = update_pkg(&xh, argv[i]);
rv = update_pkg(&xh, argv[i], force);
if (rv == EEXIST) {
/* pkg already updated, ignore */
rv = 0;
@@ -275,7 +275,7 @@ main(int argc, char **argv)
} else if (!update) {
/* Install target packages */
for (i = optind; i < argc; i++) {
rv = install_new_pkg(&xh, argv[i], reinstall);
rv = install_new_pkg(&xh, argv[i], force);
if (rv == EEXIST) {
/* pkg already installed, ignore */
rv = 0;

View File

@@ -47,38 +47,6 @@ print_array(xbps_array_t a)
}
}
static const char *
ttype2str(xbps_dictionary_t pkg_repod)
{
uint8_t r;
assert(pkg_repod);
if (!xbps_dictionary_get_uint8(pkg_repod, "transaction", &r))
return NULL;
switch (r) {
case XBPS_TRANS_INSTALL:
return "install";
case XBPS_TRANS_REINSTALL:
return "reinstall";
case XBPS_TRANS_UPDATE:
return "update";
case XBPS_TRANS_REMOVE:
return "remove";
case XBPS_TRANS_CONFIGURE:
return "configure";
case XBPS_TRANS_HOLD:
return "hold";
case XBPS_TRANS_DOWNLOAD:
return "download";
default:
return "unknown";
}
return NULL;
}
static void
show_actions(xbps_object_iterator_t iter)
{
@@ -123,7 +91,11 @@ show_package_list(struct transaction *trans, xbps_trans_type_t ttype, unsigned i
xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
xbps_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
xbps_dictionary_get_bool(obj, "download", &dload);
tt = xbps_transaction_pkg_type(obj);
if (ttype == XBPS_TRANS_DOWNLOAD && dload) {
tt = XBPS_TRANS_DOWNLOAD;
} else {
tt = xbps_transaction_pkg_type(obj);
}
buf = NULL;
if (tt == XBPS_TRANS_UPDATE) {
@@ -135,7 +107,7 @@ show_package_list(struct transaction *trans, xbps_trans_type_t ttype, unsigned i
iversion = xbps_pkg_version(ipkgver);
buf = xbps_xasprintf("%s (%s -> %s)", pkgname, iversion, version);
}
if ((ttype && (ttype == tt)) || (!ttype && dload)) {
if (ttype == tt) {
if (buf) {
print_package_line(buf, cols, false);
free(buf);
@@ -154,51 +126,62 @@ show_transaction_sizes(struct transaction *trans, int cols)
uint64_t dlsize = 0, instsize = 0, rmsize = 0, disk_free_size = 0;
char size[8];
/*
* Get stats from transaction dictionary.
*/
xbps_dictionary_get_uint32(trans->d, "total-download-pkgs",
&trans->dl_pkgcnt);
xbps_dictionary_get_uint32(trans->d, "total-install-pkgs",
&trans->inst_pkgcnt);
xbps_dictionary_get_uint32(trans->d, "total-update-pkgs",
&trans->up_pkgcnt);
xbps_dictionary_get_uint32(trans->d, "total-configure-pkgs",
&trans->cf_pkgcnt);
xbps_dictionary_get_uint32(trans->d, "total-remove-pkgs",
&trans->rm_pkgcnt);
xbps_dictionary_get_uint32(trans->d, "total-hold-pkgs",
&trans->hold_pkgcnt);
if (!print_trans_colmode(trans, cols)) {
/*
* Show the list of packages that will be downloaded, installed, updated,
* removed or configured.
* Show the list of packages and its action.
*/
xbps_dictionary_get_uint32(trans->d, "total-download-pkgs",
&trans->dl_pkgcnt);
if (trans->dl_pkgcnt) {
printf("%u package%s will be downloaded:\n",
trans->dl_pkgcnt, trans->dl_pkgcnt == 1 ? "" : "s");
show_package_list(trans, XBPS_TRANS_DOWNLOAD, cols);
printf("\n");
}
xbps_dictionary_get_uint32(trans->d, "total-install-pkgs",
&trans->inst_pkgcnt);
if (trans->inst_pkgcnt) {
printf("%u package%s will be installed:\n",
trans->inst_pkgcnt, trans->inst_pkgcnt == 1 ? "" : "s");
show_package_list(trans, XBPS_TRANS_INSTALL, cols);
printf("\n");
}
xbps_dictionary_get_uint32(trans->d, "total-update-pkgs",
&trans->up_pkgcnt);
if (trans->up_pkgcnt) {
printf("%u package%s will be updated:\n",
trans->up_pkgcnt, trans->up_pkgcnt == 1 ? "" : "s");
show_package_list(trans, XBPS_TRANS_UPDATE, cols);
printf("\n");
}
xbps_dictionary_get_uint32(trans->d, "total-configure-pkgs",
&trans->cf_pkgcnt);
if (trans->cf_pkgcnt) {
printf("%u package%s will be configured:\n",
trans->cf_pkgcnt, trans->cf_pkgcnt == 1 ? "" : "s");
show_package_list(trans, XBPS_TRANS_CONFIGURE, cols);
printf("\n");
}
xbps_dictionary_get_uint32(trans->d, "total-remove-pkgs",
&trans->rm_pkgcnt);
if (trans->rm_pkgcnt) {
printf("%u package%s will be removed:\n",
trans->rm_pkgcnt, trans->rm_pkgcnt == 1 ? "" : "s");
show_package_list(trans, XBPS_TRANS_REMOVE, cols);
printf("\n");
}
if (trans->hold_pkgcnt) {
printf("%u package%s are on hold:\n",
trans->hold_pkgcnt, trans->hold_pkgcnt == 1 ? "" : "s");
show_package_list(trans, XBPS_TRANS_HOLD, cols);
printf("\n");
}
}
/*
* Show total download/installed/removed size for all required packages.
@@ -294,11 +277,11 @@ dist_upgrade(struct xbps_handle *xhp, unsigned int cols, bool yes, bool drun)
}
int
install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
{
int rv;
rv = xbps_transaction_install_pkg(xhp, pkg, reinstall);
rv = xbps_transaction_install_pkg(xhp, pkg, force);
if (rv == EEXIST)
printf("Package `%s' already installed.\n", pkg);
else if (rv == ENOENT)
@@ -317,11 +300,11 @@ install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
}
int
update_pkg(struct xbps_handle *xhp, const char *pkg)
update_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
{
int rv;
rv = xbps_transaction_update_pkg(xhp, pkg);
rv = xbps_transaction_update_pkg(xhp, pkg, force);
if (rv == EEXIST)
printf("Package '%s' is up to date.\n", pkg);
else if (rv == ENOENT)
@@ -441,11 +424,12 @@ exec_transaction(struct xbps_handle *xhp, unsigned int maxcols, bool yes, bool d
*/
if ((rv = xbps_transaction_commit(xhp)) == 0) {
printf("\n%u downloaded, %u installed, %u updated, "
"%u configured, %u removed.\n",
"%u configured, %u removed, %u on hold.\n",
trans->dl_pkgcnt, trans->inst_pkgcnt,
trans->up_pkgcnt,
trans->cf_pkgcnt + trans->inst_pkgcnt + trans->up_pkgcnt,
trans->rm_pkgcnt);
trans->rm_pkgcnt,
trans->hold_pkgcnt);
} else {
fprintf(stderr, "Transaction failed! see above for errors.\n");
}

View File

@@ -95,6 +95,38 @@ find_longest_pkgname(struct transaction *trans)
return max+1;
}
const char *
ttype2str(xbps_dictionary_t pkgd)
{
uint8_t r;
assert(pkgd);
if (!xbps_dictionary_get_uint8(pkgd, "transaction", &r))
return NULL;
switch (r) {
case XBPS_TRANS_INSTALL:
return "install";
case XBPS_TRANS_REINSTALL:
return "reinstall";
case XBPS_TRANS_UPDATE:
return "update";
case XBPS_TRANS_REMOVE:
return "remove";
case XBPS_TRANS_CONFIGURE:
return "configure";
case XBPS_TRANS_HOLD:
return "hold";
case XBPS_TRANS_DOWNLOAD:
return "download";
default:
return "unknown";
}
return NULL;
}
bool
print_trans_colmode(struct transaction *trans, unsigned int cols)
{
@@ -131,36 +163,11 @@ print_trans_colmode(struct transaction *trans, unsigned int cols)
xbps_dictionary_get_bool(obj, "download", &dload);
ttype = xbps_transaction_pkg_type(obj);
tract = "unknown";
tract = ttype2str(obj);
if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
tract = "download";
}
if (ttype == XBPS_TRANS_INSTALL) {
trans->inst_pkgcnt++;
tract = "install";
} else if (ttype == XBPS_TRANS_REINSTALL) {
trans->inst_pkgcnt++;
tract = "reinstall";
} else if (ttype == XBPS_TRANS_UPDATE) {
trans->up_pkgcnt++;
tract = "update";
} else if (ttype == XBPS_TRANS_REMOVE) {
trans->rm_pkgcnt++;
tract = "remove";
} else if (ttype == XBPS_TRANS_CONFIGURE) {
trans->cf_pkgcnt++;
tract = "configure";
} else if (ttype == XBPS_TRANS_HOLD) {
tract = "hold";
} else if (ttype == XBPS_TRANS_DOWNLOAD) {
tract = "download";
}
if (dload) {
trans->dl_pkgcnt++;
}
ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname);
if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
ipkgd = NULL;

View File

@@ -1,4 +1,4 @@
.Dd March 3, 2020
.Dd April 23, 2020
.Dt XBPS-INSTALL 1
.Sh NAME
.Nm xbps-install
@@ -78,11 +78,14 @@ This may be useful for doing system upgrades while offline, or automatically
downloading updates while leaving you with the option of still manually running
the update.
.It Fl f, Fl -force
Force downgrade installation (if package version in repos is less than installed version),
Force installation (downgrade if package version in repos is less than installed version),
or reinstallation (if package version in repos is the same) to the target
.Ar PKG ,
overwriting regular package files and symlinks (if they have been modified) but
.Em preserving configuration files .
The only way to update packages on
.Em hold
mode is by using this flag.
If
.Fl f
is specified twice all files will be unpacked, even