Prepare for going-to-be-released 0.6.1.

Includes the following change:

* When replacing a package that is going to be updated in the transaction
   do not remove it, just overwrite its files and continue. The updated
   package will find that old files didn't match the SHA256 hash and will
   skip them. This solves the issue of new package updates requiring new
   dependencies with files that were previously stored in the old version.
   For example gtk+-2.20 containing gdk-pixbuf, and gtk+-2.22 requiring
   gdk-pixbuf externally.
This commit is contained in:
Juan RP 2010-10-23 18:09:35 +02:00
parent 05c841ee9e
commit 8534b79ffc
3 changed files with 72 additions and 10 deletions

10
NEWS
View File

@ -1,3 +1,13 @@
xbps-0.6.1 (2010-10-23):
* When replacing a package that is going to be updated in the transaction
do not remove it, just overwrite its files and continue. The updated
package will find that old files didn't match the SHA256 hash and will
skip them. This solves the issue of new package updates requiring new
dependencies with files that were previously stored in the old version.
For example gtk+-2.20 containing gdk-pixbuf, and gtk+-2.22 requiring
gdk-pixbuf externally.
xbps-0.6.0 (2010-06-03): xbps-0.6.0 (2010-06-03):
* Synced libfetch code with NetBSD pkgsrc, updated to 2.31. * Synced libfetch code with NetBSD pkgsrc, updated to 2.31.

View File

@ -399,18 +399,21 @@ xbps_update_pkg(const char *pkgname)
} }
static int static int
replace_packages(prop_object_iterator_t iter, const char *pkgver) replace_packages(prop_dictionary_t trans_dict, prop_dictionary_t pkgd,
prop_object_iterator_t replaces_iter, const char *pkgver)
{ {
prop_dictionary_t instd; prop_dictionary_t instd = NULL, transd = NULL;
prop_object_t obj; prop_object_t obj;
const char *pattern, *reppkgn, *reppkgver, *version; const char *pattern, *reppkgn, *reppkgver, *version;
int rv = 0; int rv = 0;
/* /*
* This package replaces other package(s), so we remove * This package replaces other package(s), so we remove
* them before upgrading or installing new one. * them before upgrading or installing new one. If the package
* to be replaced is in the transaction and to be updated,
* the new package will overwrite its files.
*/ */
while ((obj = prop_object_iterator_next(iter))) { while ((obj = prop_object_iterator_next(replaces_iter))) {
pattern = prop_string_cstring_nocopy(obj); pattern = prop_string_cstring_nocopy(obj);
if (pattern == NULL) if (pattern == NULL)
return errno; return errno;
@ -424,6 +427,25 @@ replace_packages(prop_object_iterator_t iter, const char *pkgver)
prop_dictionary_get_cstring_nocopy(instd, "pkgname", &reppkgn); prop_dictionary_get_cstring_nocopy(instd, "pkgname", &reppkgn);
prop_dictionary_get_cstring_nocopy(instd, "pkgver", &reppkgver); prop_dictionary_get_cstring_nocopy(instd, "pkgver", &reppkgver);
/*
* If the package to be replaced is in the transaction due to
* an update, do not remove it; just overwrite its files.
*/
transd = xbps_find_pkg_in_dict_by_name(trans_dict,
"packages", reppkgn);
if (transd) {
/*
* Set the bool property 'replace-files-in-pkg-update'.
*/
prop_dictionary_set_bool(pkgd,
"replace-files-in-pkg-update", true);
printf("Replacing some files from '%s (will be "
"updated)' with '%s' (matched by '%s')...\n",
reppkgver, pkgver, pattern);
prop_object_release(instd);
continue;
}
printf("Replacing package '%s' with '%s' " printf("Replacing package '%s' with '%s' "
"(matched by '%s')...\n", reppkgver, pkgver, pattern); "(matched by '%s')...\n", reppkgver, pkgver, pattern);
prop_object_release(instd); prop_object_release(instd);
@ -436,7 +458,7 @@ replace_packages(prop_object_iterator_t iter, const char *pkgver)
return rv; return rv;
} }
} }
prop_object_iterator_release(iter); prop_object_iterator_release(replaces_iter);
return 0; return 0;
} }
@ -496,14 +518,15 @@ exec_transaction(struct transaction *trans)
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgver", &pkgver)) "pkgver", &pkgver))
return errno; return errno;
prop_dictionary_get_bool(obj, "automatic-install", &autoinst);
prop_dictionary_get_bool(obj, "preserve", &preserve);
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"filename", &filename)) "filename", &filename))
return errno; return errno;
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"trans-action", &tract)) "trans-action", &tract))
return errno; return errno;
prop_dictionary_get_bool(obj, "automatic-install", &autoinst);
prop_dictionary_get_bool(obj, "preserve", &preserve);
replaces_iter = xbps_get_array_iter_from_dict(obj, "replaces"); replaces_iter = xbps_get_array_iter_from_dict(obj, "replaces");
/* /*
@ -520,7 +543,7 @@ exec_transaction(struct transaction *trans)
* Replace package(s) if necessary. * Replace package(s) if necessary.
*/ */
if (replaces_iter != NULL) { if (replaces_iter != NULL) {
rv = replace_packages(replaces_iter, pkgver); rv = replace_packages(trans->dict, obj, replaces_iter, pkgver);
if (rv != 0) { if (rv != 0) {
fprintf(stderr, fprintf(stderr,
"xbps-bin: couldn't replace some " "xbps-bin: couldn't replace some "
@ -635,6 +658,7 @@ xbps_exec_transaction(bool yes)
goto out; goto out;
} }
DPRINTF(("Dictionary before transaction happens:\n"));
DPRINTF(("%s", prop_dictionary_externalize(trans->dict))); DPRINTF(("%s", prop_dictionary_externalize(trans->dict)));
/* /*
@ -649,6 +673,8 @@ xbps_exec_transaction(bool yes)
trans->yes = yes; trans->yes = yes;
rv = exec_transaction(trans); rv = exec_transaction(trans);
DPRINTF(("Dictionary AFTER transaction happened:\n"));
DPRINTF(("%s", prop_dictionary_externalize(trans->dict)));
out: out:
if (trans->iter) if (trans->iter)

View File

@ -98,13 +98,13 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
const char *pkgname, *version, *rootdir, *entry_str, *transact; const char *pkgname, *version, *rootdir, *entry_str, *transact;
char *buf; char *buf;
int rv, flags, lflags; int rv, flags, lflags;
bool preserve, skip_entry, update; bool preserve, skip_entry, update, replace_files_in_pkg_update;
bool props_plist_found, files_plist_found; bool props_plist_found, files_plist_found;
assert(ar != NULL); assert(ar != NULL);
assert(pkg != NULL); assert(pkg != NULL);
preserve = skip_entry = update = false; preserve = skip_entry = update = replace_files_in_pkg_update = false;
props_plist_found = files_plist_found = false; props_plist_found = files_plist_found = false;
rootdir = xbps_get_rootdir(); rootdir = xbps_get_rootdir();
flags = xbps_get_flags(); flags = xbps_get_flags();
@ -281,6 +281,32 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
continue; continue;
} }
/*
* Account for the following scenario (real example):
*
* - gtk+-2.20 is currently installed.
* - gtk+-2.20 contains libgdk_pixbuf.so.
* - gtk+-2.20 will be updated to 2.22 in the transaction.
* - gtk+-2.22 depends on gdk-pixbuf>=2.22.
* - gdk-pixbuf-2.22 contains libgdk_pixbuf.so.
* - gdk-pixbuf-2.22 will be installed in the transaction.
*
* We do the following to fix this:
*
* - gdk-pixbuf-2.22 installs its files overwritting
* current ones if they exist.
* - gtk+ is updated to 2.22, it checks for obsolete files
* and detects that the files that were owned in 2.20
* don't match the SHA256 hash and skips them.
*/
replace_files_in_pkg_update = false;
prop_dictionary_get_bool(pkg, "replace-files-in-pkg-update",
&replace_files_in_pkg_update);
if (replace_files_in_pkg_update) {
lflags &= ~ARCHIVE_EXTRACT_NO_OVERWRITE;
lflags &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
}
/* /*
* Extract entry from archive. * Extract entry from archive.
*/ */