for FS#29935 https://bugs.archlinux.org/task/29935

This patch will cause packages like notification-daemon to be ignored if
something providing notification-daemon is installed, mostly useful for
when installing groups like pacman -Syu gnome.  It also causes packages
to be ignored based on if the things it provides are already installed,
tested on jre7 from aur and then trying to install jre7-openjdk with the
--needed flag. This also works with sysv and initscripts, if you have
removed them in favor of sysvcompat, pacman -Syu base --needed should
ignore those packages

Signed-off-by: Daniel Wallace <[email protected]>
---
 lib/libalpm/add.c     |   11 ++++++++++-
 lib/libalpm/package.c |   23 +++++++++++++++++++++++
 lib/libalpm/package.h |    2 ++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index edddc31..6ebd9cf 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -93,7 +93,16 @@ int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t 
*pkg)
                                        localpkgname, localpkgver, pkgver);
                }
        }
-
+       /* find if the package is provided by something else and  */
+       int provided = _alpm_pkg_is_provided(handle, pkg);
+       int 
provisionprovided=_alpm_pkg_provision_provided(handle,pkg->provides);
+       if(provided==0||provisionprovided==0){
+               if(trans->flags & ALPM_TRANS_FLAG_NEEDED){
+                       _alpm_log(handle, ALPM_LOG_WARNING, _("%s-%s is up to 
date -- skipping\n"),
+                                       pkgname, pkgver);
+                       return 0;
+               }
+       }
        /* add the package to the transaction */
        pkg->reason = ALPM_PKG_REASON_EXPLICIT;
        _alpm_log(handle, ALPM_LOG_DEBUG, "adding package %s-%s to the 
transaction add list\n",
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 46d1473..d346c70 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -646,6 +646,29 @@ int _alpm_pkg_compare_versions(alpm_pkg_t *spkg, 
alpm_pkg_t *localpkg)
        return alpm_pkg_vercmp(spkg->version, localpkg->version);
 }
 
+int _alpm_pkg_is_provided(alpm_handle_t *handle,alpm_pkg_t *pkg)
+{
+       alpm_db_t *localdb = alpm_get_localdb(handle);
+       if(alpm_find_satisfier(alpm_db_get_pkgcache(localdb), pkg->name)) {
+               return 0;
+       }
+       return 1;
+}
+int _alpm_pkg_provision_provided(alpm_handle_t *handle,alpm_list_t *provs)
+{
+       if(provs==NULL){
+               return 1;
+       }
+       const alpm_list_t *i;
+       alpm_db_t *localdb = alpm_get_localdb(handle);
+       for (i=provs;i;i=i->next){
+               if(!(alpm_find_satisfier(alpm_db_get_pkgcache(localdb),(char 
*)i->data))) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 /* Helper function for comparing packages
  */
 int _alpm_pkg_cmp(const void *p1, const void *p2)
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index c473549..b3c56f3 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -141,6 +141,8 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
 
 int _alpm_pkg_cmp(const void *p1, const void *p2);
 int _alpm_pkg_compare_versions(alpm_pkg_t *local_pkg, alpm_pkg_t *pkg);
+int _alpm_pkg_is_provided(alpm_handle_t *handle,alpm_pkg_t *pkg);
+int _alpm_pkg_provision_provided(alpm_handle_t *handle,alpm_list_t *provs);
 alpm_pkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle);
 int _alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg);
 
-- 
1.7.10.2


Reply via email to