Implemented reverse conflicts for pkgs in pkgdb and transaction.

This commit is contained in:
Juan RP 2015-10-28 05:23:42 +01:00
parent 2c81984f48
commit a13a7fa896
8 changed files with 172 additions and 15 deletions

3
NEWS
View File

@ -1,5 +1,8 @@
xbps-0.48 (???):
* libxbps: implemented reverse conflicts. That means that just a single pkg
needs to set conflicts to be effective, rather than all involved pkgs.
* libxbps: with -M (--memory-sync opt of xbps-{install,query}) only process
remote repositories, not local ones.

View File

@ -143,8 +143,7 @@ int HIDDEN xbps_unpack_binary_pkg(struct xbps_handle *, xbps_dictionary_t);
int HIDDEN xbps_transaction_package_replace(struct xbps_handle *, xbps_array_t);
int HIDDEN xbps_remove_pkg(struct xbps_handle *, const char *, bool);
int HIDDEN xbps_register_pkg(struct xbps_handle *, xbps_dictionary_t);
void HIDDEN xbps_pkg_find_conflicts(struct xbps_handle *, xbps_array_t,
xbps_dictionary_t);
void HIDDEN xbps_transaction_conflicts(struct xbps_handle *, xbps_array_t);
char HIDDEN *xbps_archive_get_file(struct archive *, struct archive_entry *);
xbps_dictionary_t HIDDEN xbps_archive_get_dictionary(struct archive *,
struct archive_entry *);

View File

@ -36,8 +36,9 @@ OBJS += package_unpack.o package_register.o package_script.o verifysig.o
OBJS += package_msg.o pkgdb_conversion.o transaction_shlibs.o
OBJS += transaction_commit.o transaction_package_replace.o
OBJS += transaction_dictionary.o transaction_ops.o transaction_store.o
OBJS += transaction_revdeps.o pubkey2fp.o package_fulldeptree.o
OBJS += download.o initend.o pkgdb.o package_conflicts.o
OBJS += transaction_revdeps.o transaction_conflicts.o
OBJS += pubkey2fp.o package_fulldeptree.o
OBJS += download.o initend.o pkgdb.o
OBJS += plist.o plist_find.o plist_match.o archive.o
OBJS += plist_remove.o plist_fetch.o util.o util_hash.o
OBJS += repo.o repo_pkgdeps.o repo_sync.o

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2012-2014 Juan Romero Pardines.
* Copyright (c) 2012-2015 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,10 +31,9 @@
#include "xbps_api_impl.h"
void HIDDEN
xbps_pkg_find_conflicts(struct xbps_handle *xhp,
xbps_array_t unsorted,
xbps_dictionary_t pkg_repod)
static void
pkg_conflicts_trans(struct xbps_handle *xhp, xbps_array_t array,
xbps_dictionary_t pkg_repod)
{
xbps_array_t pkg_cflicts, trans_cflicts;
xbps_dictionary_t pkgd, tpkgd;
@ -76,7 +75,7 @@ xbps_pkg_find_conflicts(struct xbps_handle *xhp,
* the transaction and does not match the pattern,
* ignore it.
*/
if ((tpkgd = xbps_find_pkg_in_array(unsorted, pkgname, NULL))) {
if ((tpkgd = xbps_find_pkg_in_array(array, pkgname, NULL))) {
const char *tract, *p;
xbps_dictionary_get_cstring_nocopy(tpkgd,
@ -104,8 +103,8 @@ xbps_pkg_find_conflicts(struct xbps_handle *xhp,
/*
* Check if current pkg conflicts with any pkg in transaction.
*/
if ((pkgd = xbps_find_pkg_in_array(unsorted, cfpkg, NULL)) ||
(pkgd = xbps_find_virtualpkg_in_array(xhp, unsorted, cfpkg, NULL))) {
if ((pkgd = xbps_find_pkg_in_array(array, cfpkg, NULL)) ||
(pkgd = xbps_find_virtualpkg_in_array(xhp, array, cfpkg, NULL))) {
xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
pkgname = xbps_pkg_name(pkgver);
@ -129,3 +128,70 @@ xbps_pkg_find_conflicts(struct xbps_handle *xhp,
xbps_object_iterator_release(iter);
free(repopkgname);
}
static int
pkgdb_conflicts_cb(struct xbps_handle *xhp, xbps_object_t obj,
const char *key _unused, void *arg, bool *done _unused)
{
xbps_array_t pkg_cflicts, trans_cflicts, pkgs = arg;
xbps_dictionary_t pkgd;
xbps_object_t obj2;
xbps_object_iterator_t iter;
const char *cfpkg, *repopkgver, *pkgver;
char *pkgname, *repopkgname, *buf;
pkg_cflicts = xbps_dictionary_get(obj, "conflicts");
if (xbps_array_count(pkg_cflicts) == 0)
return 0;
trans_cflicts = xbps_dictionary_get(xhp->transd, "conflicts");
xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &repopkgver);
repopkgname = xbps_pkg_name(repopkgver);
assert(repopkgname);
iter = xbps_array_iterator(pkg_cflicts);
assert(iter);
while ((obj2 = xbps_object_iterator_next(iter))) {
cfpkg = xbps_string_cstring_nocopy(obj2);
if ((pkgd = xbps_find_pkg_in_array(pkgs, cfpkg, NULL)) ||
(pkgd = xbps_find_virtualpkg_in_array(xhp, pkgs, cfpkg, NULL))) {
xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
if (strcmp(pkgname, repopkgname) == 0) {
free(pkgname);
continue;
}
free(pkgname);
xbps_dbg_printf(xhp, "found conflicting pkgs in "
"transaction %s <-> %s\n", pkgver, repopkgver);
buf = xbps_xasprintf("CONFLICT: %s with "
"%s in transaction", repopkgver, pkgver);
if (!xbps_match_string_in_array(trans_cflicts, buf))
xbps_array_add_cstring(trans_cflicts, buf);
free(buf);
continue;
}
}
xbps_object_iterator_release(iter);
free(repopkgname);
return 0;
}
void HIDDEN
xbps_transaction_conflicts(struct xbps_handle *xhp, xbps_array_t pkgs)
{
xbps_dictionary_t pkgd;
unsigned int i;
/* find conflicts in transaction */
for (i = 0; i < xbps_array_count(pkgs); i++) {
pkgd = xbps_array_get(pkgs, i);
pkg_conflicts_trans(xhp, pkgs, pkgd);
}
/* find conflicts in pkgdb */
(void)xbps_pkgdb_foreach_cb_multi(xhp, pkgdb_conflicts_cb, pkgs);
}

View File

@ -319,11 +319,10 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
return ENODEV;
}
}
for (i = 0; i < xbps_array_count(pkgs); i++)
xbps_pkg_find_conflicts(xhp, pkgs, xbps_array_get(pkgs, i));
/*
* If there are package conflicts bail out.
*/
xbps_transaction_conflicts(xhp, pkgs);
array = xbps_dictionary_get(xhp->transd, "conflicts");
if (xbps_array_count(array))
return EAGAIN;

View File

@ -21,3 +21,4 @@ atf_test_program{name="update_shlibs"}
atf_test_program{name="update_hold"}
atf_test_program{name="update_repolock"}
atf_test_program{name="cyclic_deps"}
atf_test_program{name="conflicts"}

View File

@ -6,7 +6,7 @@ TESTSHELL = conf_files_test issue6_test issue18_test issue20_test remove_test
TESTSHELL+= replace_test installmode_test obsoletefiles_test
TESTSHELL+= issue31_test scripts_test incorrect_deps_test
TESTSHELL+= vpkg_test install_test preserve_files_test configure_test
TESTSHELL+= update_shlibs update_hold update_repolock cyclic_deps
TESTSHELL+= update_shlibs update_hold update_repolock cyclic_deps conflicts
EXTRA_FILES = Kyuafile
include $(TOPDIR)/mk/test.mk

View File

@ -0,0 +1,88 @@
#!/usr/bin/env atf-sh
atf_test_case conflicts_trans
conflicts_trans_head() {
atf_set "descr" "Tests for pkg conflicts: conflicting pkgs in transaction"
}
conflicts_trans_body() {
mkdir some_repo
mkdir -p pkg_{A,B}/usr/bin
cd some_repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" --conflicts "B>=0" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n B-1.0_1 -s "B pkg" ../pkg_B
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
xbps-install -r root --repository=$PWD/some_repo -dy A B
# EAGAIN, conflicts.
atf_check_equal $? 11
# 0 pkgs installed.
xbps-query -r root -l|wc -l
atf_check_equal $(xbps-query -r root -l|wc -l) 0
}
atf_test_case conflicts_installed
conflicts_installed_head() {
atf_set "descr" "Tests for pkg conflicts: installed pkg conflicts with pkg in transaction"
}
conflicts_installed_body() {
mkdir some_repo
mkdir -p pkg_{A,B}/usr/bin
cd some_repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" --conflicts "B>=0" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n B-1.0_1 -s "B pkg" ../pkg_B
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
xbps-install -r root --repository=$PWD/some_repo -dy A
atf_check_equal $? 0
xbps-install -r root --repository=$PWD/some_repo -dy B
atf_check_equal $? 11
xbps-query -r root -l|wc -l
atf_check_equal $(xbps-query -r root -l|wc -l) 1
}
atf_test_case conflicts_trans_installed
conflicts_trans_installed_head() {
atf_set "descr" "Tests for pkg conflicts: pkg in transaction conflicts with installed pkg"
}
conflicts_trans_installed_body() {
mkdir some_repo
mkdir -p pkg_{A,B}/usr/bin
cd some_repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" --conflicts "B>=0" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n B-1.0_1 -s "B pkg" ../pkg_B
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
xbps-install -r root --repository=$PWD/some_repo -dy B
atf_check_equal $? 0
xbps-install -r root --repository=$PWD/some_repo -dy A
atf_check_equal $? 11
xbps-query -r root -l|wc -l
atf_check_equal $(xbps-query -r root -l|wc -l) 1
}
atf_init_test_cases() {
atf_add_test_case conflicts_trans
atf_add_test_case conflicts_trans_installed
atf_add_test_case conflicts_installed
}