diff --git a/bin/xbps-bin/install.c b/bin/xbps-bin/install.c index 661239c4..349c4860 100644 --- a/bin/xbps-bin/install.c +++ b/bin/xbps-bin/install.c @@ -341,7 +341,8 @@ static int exec_transaction(struct transaction *trans) { prop_dictionary_t instpkgd; - prop_object_t obj; + prop_object_t obj, obj2; + prop_object_iterator_t replaces_iter; const char *pkgname, *version, *instver, *filename, *tract; int rv = 0; bool essential, isdep, autoinst; @@ -384,6 +385,7 @@ exec_transaction(struct transaction *trans) prop_dictionary_get_bool(obj, "essential", &essential); prop_dictionary_get_cstring_nocopy(obj, "filename", &filename); prop_dictionary_get_cstring_nocopy(obj, "trans-action", &tract); + replaces_iter = xbps_get_array_iter_from_dict(obj, "replaces"); if (trans->originpkgname && strcmp(trans->originpkgname, pkgname)) @@ -399,6 +401,37 @@ exec_transaction(struct transaction *trans) if (state == XBPS_PKG_STATE_UNPACKED) continue; + /* + * This package replaces other package(s), so we remove + * them before upgrading or installing new one. + */ + if (replaces_iter != NULL) { + while ((obj2 = + prop_object_iterator_next(replaces_iter))) { + printf("Replacing package '%s' with '%s-%s' " + "...\n", prop_string_cstring(obj2), + pkgname, version); + rv = xbps_remove_pkg(prop_string_cstring(obj2), + NULL, false); + if (rv != 0) { + printf("Couldn't remove %s (%s)\n", + prop_string_cstring(obj2), + strerror(rv)); + return rv; + } + rv = xbps_purge_pkg(prop_string_cstring(obj2), + false); + if (rv != 0) { + printf("Couldn't purge %s (%s)\n", + prop_string_cstring(obj2), + strerror(rv)); + return rv; + } + } + prop_object_iterator_release(replaces_iter); + replaces_iter = NULL; + } + if (strcmp(tract, "update") == 0) { instpkgd = xbps_find_pkg_installed_from_plist(pkgname); if (instpkgd == NULL) { diff --git a/doc/README b/doc/README index 7e1eb1ed..9b759486 100644 --- a/doc/README +++ b/doc/README @@ -47,7 +47,7 @@ and install xbps binary packages: * sudo Super-user privileges are required as well, because all packages are built -in a chroot (except the ones that are included in a virtual package to be +in a chroot (except the ones that are included in a meta package to be able to build a minimal system for the chroot). PLEASE NOTE THAT fakechroot or fakeroot-ng DO NOT WORK. @@ -65,9 +65,6 @@ Once the xbps distfiles are installed into prefix, you can start building packages from source, add local repositories with binary packages, install or remove them, etc. -If you are only interested in building/using packages from source, see the -SRCPKG_INFO file. - For information about binary packages, see the BINPKG_INFO file. ------------------------------------------------------------------------------ diff --git a/shutils/metadata.sh b/shutils/metadata.sh index aa7ffbdb..90c40703 100644 --- a/shutils/metadata.sh +++ b/shutils/metadata.sh @@ -311,6 +311,16 @@ _EOF echo "" >> $TMPFPROPS fi + # Replace package(s). + if [ -n "$replaces" ]; then + echo "replaces" >> $TMPFPROPS + echo "" >> $TMPFPROPS + for f in ${replaces}; do + echo "$f" >> $TMPFPROPS + done + echo "" >> $TMPFPROPS + fi + # Terminate the property list file. echo "" >> $TMPFPROPS echo "" >> $TMPFPROPS diff --git a/shutils/tmpl_funcs.sh b/shutils/tmpl_funcs.sh index 5a22559d..56d8a218 100644 --- a/shutils/tmpl_funcs.sh +++ b/shutils/tmpl_funcs.sh @@ -76,7 +76,7 @@ reset_tmpl_vars() only_for_archs conf_files keep_libtool_archives \ noarch subpackages sourcepkg gtk_iconcache_dirs \ abi_depends api_depends triggers openrc_services \ - XBPS_EXTRACT_DONE XBPS_CONFIGURE_DONE \ + replaces XBPS_EXTRACT_DONE XBPS_CONFIGURE_DONE \ XBPS_BUILD_DONE XBPS_INSTALL_DONE FILESDIR DESTDIR \ SRCPKGDESTDIR PATCHESDIR"