Resolve file paths during inter-package conflict check

File paths are resolved if necessary during inter-package conflict
checks so that packages carrying the same effective file due to
directory symlinks on the filesystem are flagged as conflicting.

Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Allan McRae 2012-07-20 22:25:18 +10:00
parent 28d404f16a
commit 88e7ea421e
5 changed files with 36 additions and 12 deletions

View File

@ -361,12 +361,17 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
int percent = (current * 100) / numtargs; int percent = (current * 100) / numtargs;
PROGRESS(handle, ALPM_PROGRESS_CONFLICTS_START, "", percent, PROGRESS(handle, ALPM_PROGRESS_CONFLICTS_START, "", percent,
numtargs, current); numtargs, current);
_alpm_filelist_resolve(handle, alpm_pkg_get_files(p1));
/* CHECK 1: check every target against every target */ /* CHECK 1: check every target against every target */
_alpm_log(handle, ALPM_LOG_DEBUG, "searching for file conflicts: %s\n", _alpm_log(handle, ALPM_LOG_DEBUG, "searching for file conflicts: %s\n",
p1->name); p1->name);
for(j = i->next; j; j = j->next) { for(j = i->next; j; j = j->next) {
alpm_list_t *common_files; alpm_list_t *common_files;
alpm_pkg_t *p2 = j->data; alpm_pkg_t *p2 = j->data;
_alpm_filelist_resolve(handle, alpm_pkg_get_files(p2));
common_files = _alpm_filelist_intersection(alpm_pkg_get_files(p1), common_files = _alpm_filelist_intersection(alpm_pkg_get_files(p1),
alpm_pkg_get_files(p2)); alpm_pkg_get_files(p2));

View File

@ -268,21 +268,18 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
int cmp, isdirA, isdirB; int cmp, isdirA, isdirB;
char *strA, *strB; char *strA, *strB;
alpm_file_t *fileA = filesA->files + ctrA;
alpm_file_t *fileB = filesB->files + ctrB;
isdirA = 0; isdirA = 0;
strA = fileA->name; strA = filesA->resolved_path[ctrA];
if(strA[strlen(strA)-1] == '/') { if(strA[strlen(strA)-1] == '/') {
isdirA = 1; isdirA = 1;
strA = strndup(fileA->name, strlen(strA)-1); strA = strndup(filesA->resolved_path[ctrA], strlen(strA)-1);
} }
isdirB = 0; isdirB = 0;
strB = fileB->name; strB = filesB->resolved_path[ctrB];
if(strB[strlen(strB)-1] == '/') { if(strB[strlen(strB)-1] == '/') {
isdirB = 1; isdirB = 1;
strB = strndup(fileB->name, strlen(strB)-1); strB = strndup(filesB->resolved_path[ctrB], strlen(strB)-1);
} }
cmp = strcmp(strA, strB); cmp = strcmp(strA, strB);
@ -300,7 +297,7 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
/* when not directories, item in both qualifies as an intersect */ /* when not directories, item in both qualifies as an intersect */
if(! (isdirA && isdirB)) { if(! (isdirA && isdirB)) {
ret = alpm_list_add(ret, fileA); ret = alpm_list_add(ret, filesA->files + ctrA);
} }
ctrA++; ctrA++;
ctrB++; ctrB++;

View File

@ -25,5 +25,3 @@
self.addrule("!PKG_EXIST=pkg2") self.addrule("!PKG_EXIST=pkg2")
self.addrule("FILE_EXIST=dir/realdir/realfile") self.addrule("FILE_EXIST=dir/realdir/realfile")
self.addrule("!FILE_EXIST=dir/realdir/file") self.addrule("!FILE_EXIST=dir/realdir/file")
self.expectfailure = True

View File

@ -22,5 +22,3 @@
self.addrule("PACMAN_RETCODE=1") self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2") self.addrule("!PKG_EXIST=pkg2")
self.expectfailure = True

View File

@ -0,0 +1,26 @@
self.description = "file conflict with same effective path across packages (directory symlink - deep)"
lp1 = pmpkg("filesystem", "1.0-1")
lp1.files = ["usr/",
"usr/lib/",
"lib -> usr/lib/"]
self.addpkg2db("local", lp1)
p1 = pmpkg("pkg1")
p1.files = ["lib/",
"lib/foo/",
"lib/foo/bar"]
self.addpkg2db("sync", p1)
p2 = pmpkg("pkg2")
p2.files = ["usr/",
"usr/lib/",
"usr/lib/foo/",
"usr/lib/foo/bar"]
self.addpkg2db("sync", p2)
self.args = "-S pkg1 pkg2"
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")