add support for back end fnmatch'd options

This is work originally provided by Sascha Kruse on FS#20360 with only
minor adjustments to the implementation. It's been expanded to cover:
NoUpgrade, NoExtract, IgnorePkg, IgnoreGroup.

Adds tests ignore008, sync139, sync502, and sync503.

Also satisfies FS#18988.

Original-work-by: Sascha Kruse <knopwob@googlemail.com>
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
This commit is contained in:
Dave Reisner 2011-10-30 13:33:14 -04:00
parent 64d54f6741
commit 902305f163
10 changed files with 107 additions and 10 deletions

View file

@ -90,7 +90,7 @@ Options
*IgnorePkg =* package ...::
Instructs pacman to ignore any upgrades for this package when performing
a '\--sysupgrade'.
a '\--sysupgrade'. Shell-style glob patterns are allowed.
*SyncFirst =* package ...::
Instructs pacman to check for newer version of these packages before any
@ -103,7 +103,8 @@ Options
*IgnoreGroup =* group ...::
Instructs pacman to ignore any upgrades for all packages in this
group when performing a '\--sysupgrade'.
group when performing a '\--sysupgrade'. Shell-style glob patterns are
allowed.
*Include =* path::
Include another config file. This file can include repositories or
@ -134,7 +135,8 @@ Options
a package install/upgrade, and the new files will be installed with a
'.pacnew' extension.
These files refer to files in the package archive, so do not include the
leading slash (the RootDir) when specifying them.
leading slash (the RootDir) when specifying them. Shell-style glob patterns
are allowed.
*NoExtract =* file ...::
All files listed with a `NoExtract` directive will never be extracted from
@ -143,7 +145,8 @@ Options
'index.php', then you would not want the 'index.html' file to be extracted
from the 'apache' package.
These files refer to files in the package archive, so do not include the
leading slash (the RootDir) when specifying them.
leading slash (the RootDir) when specifying them. Shell-style glob patterns
are allowed.
*CleanMethod =* KeepInstalled &| KeepCurrent::
If set to `KeepInstalled` (the default), the '-Sc' operation will clean

View file

@ -179,7 +179,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
}
/* if a file is in NoExtract then we never extract it */
if(alpm_list_find_str(handle->noextract, entryname)) {
if(alpm_list_find(handle->noextract, entryname, _alpm_fnmatch)) {
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract, skipping extraction\n",
entryname);
alpm_logaction(handle, "note: %s is in NoExtract, skipping extraction\n",
@ -259,7 +259,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
} else if(S_ISREG(entrymode)) {
/* case 4,7: */
/* if file is in NoUpgrade, don't touch it */
if(alpm_list_find_str(handle->noupgrade, entryname)) {
if(alpm_list_find(handle->noupgrade, entryname, _alpm_fnmatch)) {
notouch = 1;
} else {
alpm_backup_t *backup;

View file

@ -690,14 +690,14 @@ int _alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg)
alpm_list_t *groups = NULL;
/* first see if the package is ignored */
if(alpm_list_find_str(handle->ignorepkg, pkg->name)) {
if(alpm_list_find(handle->ignorepkg, pkg->name, _alpm_fnmatch)) {
return 1;
}
/* next see if the package is in a group that is ignored */
for(groups = alpm_pkg_get_groups(pkg); groups; groups = groups->next) {
char *grp = groups->data;
if(alpm_list_find_str(handle->ignoregroup, grp)) {
if(alpm_list_find(handle->ignoregroup, grp, _alpm_fnmatch)) {
return 1;
}
}

View file

@ -216,7 +216,7 @@ static int can_remove_file(alpm_handle_t *handle, const alpm_file_t *file,
{
char filepath[PATH_MAX];
if(alpm_list_find_str(skip_remove, file->name)) {
if(alpm_list_find(skip_remove, file->name, _alpm_fnmatch)) {
/* return success because we will never actually remove this file */
return 1;
}
@ -251,7 +251,7 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg,
/* check the remove skip list before removing the file.
* see the big comment block in db_find_fileconflicts() for an
* explanation. */
if(alpm_list_find_str(skip_remove, fileobj->name)) {
if(alpm_list_find(skip_remove, fileobj->name, _alpm_fnmatch)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"%s is in skip_remove, skipping removal\n", file);
return 1;

View file

@ -34,6 +34,7 @@
#include <limits.h>
#include <sys/wait.h>
#include <locale.h> /* setlocale */
#include <fnmatch.h>
/* libarchive */
#include <archive.h>
@ -1188,6 +1189,11 @@ int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int a
return ret;
}
int _alpm_fnmatch(const void *pattern, const void *string)
{
return fnmatch(pattern, string, 0);
}
#ifndef HAVE_STRNDUP
/* A quick and dirty implementation derived from glibc */
static size_t strnlen(const char *s, size_t max)

View file

@ -140,6 +140,7 @@ alpm_time_t _alpm_parsedate(const char *line);
int _alpm_raw_cmp(const char *first, const char *second);
int _alpm_raw_ncmp(const char *first, const char *second, size_t max);
int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode);
int _alpm_fnmatch(const void *pattern, const void *string);
#ifndef HAVE_STRSEP
char *strsep(char **, const char *);

View file

@ -0,0 +1,29 @@
self.description = "Sync with relevant ignored fnmatched packages"
package1 = pmpkg("foopkg", "1.0-1")
self.addpkg2db("local", package1)
package2 = pmpkg("barpkg", "2.0-1")
self.addpkg2db("local", package2)
package3 = pmpkg("bazpkg", "3.0-1")
self.addpkg2db("local", package3)
package1up = pmpkg("foopkg", "2.0-1")
self.addpkg2db("sync", package1up)
package2up = pmpkg("barpkg", "3.0-1")
self.addpkg2db("sync", package2up)
package3up = pmpkg("bazpkg", "4.0-1")
self.addpkg2db("sync", package3up)
self.option["IgnorePkg"] = ["foo*", "ba?pkg"]
self.args = "-Su"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_VERSION=foopkg|1.0-1")
self.addrule("PKG_VERSION=barpkg|2.0-1")
self.addrule("PKG_VERSION=bazpkg|3.0-1")

View file

@ -0,0 +1,23 @@
self.description = "Sysupgrade of packages in fnmatch'd IgnoreGroup"
sp1 = pmpkg("pkg1", "1.0-2")
sp1.groups = ["grp"]
sp2 = pmpkg("pkg2", "1.0-2")
sp2.groups = ["grp2"]
for p in sp1, sp2:
self.addpkg2db("sync", p)
lp1 = pmpkg("pkg1", "1.0-1")
lp2 = pmpkg("pkg2", "1.0-1")
for p in lp1, lp2:
self.addpkg2db("local", p)
self.option["IgnoreGroup"] = ["grp"]
self.args = "-Su"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_VERSION=pkg1|1.0-1")
self.addrule("PKG_VERSION=pkg2|1.0-2")

View file

@ -0,0 +1,17 @@
self.description = "Install a package from a sync db with fnmatch'ed NoExtract"
sp = pmpkg("dummy")
sp.files = ["bin/dummy",
"usr/share/man/man8",
"usr/share/man/man1/dummy.1"]
self.addpkg2db("sync", sp)
self.option["NoExtract"] = ["usr/share/man/*"]
self.args = "-S %s" % sp.name
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=dummy")
self.addrule("FILE_EXIST=bin/dummy")
self.addrule("!FILE_EXIST=usr/share/man/man8")
self.addrule("!FILE_EXIST=usr/share/man/man1/dummy.1")

View file

@ -0,0 +1,18 @@
self.description = "Upgrade a package, with a fnmatch in NoUpgrade"
sp = pmpkg("dummy", "1.0-2")
sp.files = ["etc/dummy.conf"]
self.addpkg2db("sync", sp)
lp = pmpkg("dummy")
lp.files = ["etc/dummy.conf"]
self.addpkg2db("local", lp)
self.option["NoUpgrade"] = ["etc/dummy.*"]
self.args = "-S %s" % sp.name
self.addrule("PKG_VERSION=dummy|1.0-2")
self.addrule("!FILE_MODIFIED=etc/dummy.conf")
self.addrule("FILE_PACNEW=etc/dummy.conf")
self.addrule("!FILE_PACSAVE=etc/dummy.conf")