From 04e8048725441465788a6c76a326ff252c2fd815 Mon Sep 17 00:00:00 2001
From: Florian Pritz <bluewind@xinu.at>
Date: Fri, 4 Jul 2014 23:12:01 +0200
Subject: Add --assume-installed option

This allows to ignore specific dependencies.

Signed-off-by: Florian Pritz <bluewind@xinu.at>
---
 lib/libalpm/alpm.h   | 11 +++++++++++
 lib/libalpm/deps.c   |  8 ++++++--
 lib/libalpm/handle.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/libalpm/handle.h |  1 +
 4 files changed, 74 insertions(+), 2 deletions(-)

(limited to 'lib/libalpm')

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 888b6a00..1831fcf0 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -851,6 +851,17 @@ int alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
 int alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp);
 /** @} */
 
+/** @name Accessors to the list of ignored dependencies.
+ * These functions modify the list of dependencies that
+ * should be ignored by a sysupgrade.
+ * @{
+ */
+alpm_list_t *alpm_option_get_assumeinstalled(alpm_handle_t *handle);
+int alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep);
+int alpm_option_set_assumeinstalled(alpm_handle_t *handle, alpm_list_t *deps);
+int alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep);
+/** @} */
+
 /** Returns the targeted architecture. */
 const char *alpm_option_get_arch(alpm_handle_t *handle);
 /** Sets the targeted architecture. */
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index c280336b..f2ee8f41 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -333,8 +333,10 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
 			}
 			/* 1. we check the upgrade list */
 			/* 2. we check database for untouched satisfying packages */
+			/* 3. we check the dependency ignore list */
 			if(!find_dep_satisfier(upgrade, depend) &&
-					!find_dep_satisfier(dblist, depend)) {
+					!find_dep_satisfier(dblist, depend) &&
+					!_alpm_depcmp_provides(depend, handle->assumeinstalled)) {
 				/* Unsatisfied dependency in the upgrade list */
 				alpm_depmissing_t *miss;
 				char *missdepstring = alpm_dep_compute_string(depend);
@@ -363,9 +365,11 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
 				/* we won't break this depend, if it is already broken, we ignore it */
 				/* 1. check upgrade list for satisfiers */
 				/* 2. check dblist for satisfiers */
+				/* 3. we check the dependency ignore list */
 				if(causingpkg &&
 						!find_dep_satisfier(upgrade, depend) &&
-						!find_dep_satisfier(dblist, depend)) {
+						!find_dep_satisfier(dblist, depend) &&
+						!_alpm_depcmp_provides(depend, handle->assumeinstalled)) {
 					alpm_depmissing_t *miss;
 					char *missdepstring = alpm_dep_compute_string(depend);
 					_alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 0d8ea34a..dd284ac5 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -37,6 +37,7 @@
 #include "delta.h"
 #include "trans.h"
 #include "alpm.h"
+#include "deps.h"
 
 alpm_handle_t *_alpm_handle_new(void)
 {
@@ -85,6 +86,10 @@ void _alpm_handle_free(alpm_handle_t *handle)
 	FREELIST(handle->noextract);
 	FREELIST(handle->ignorepkg);
 	FREELIST(handle->ignoregroup);
+
+	alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
+	alpm_list_free(handle->assumeinstalled);
+
 	FREE(handle);
 }
 
@@ -251,6 +256,12 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle)
 	return handle->ignoregroup;
 }
 
+alpm_list_t SYMEXPORT *alpm_option_get_assumeinstalled(alpm_handle_t *handle)
+{
+	CHECK_HANDLE(handle, return NULL);
+	return handle->assumeinstalled;
+}
+
 const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
 {
 	CHECK_HANDLE(handle, return NULL);
@@ -557,6 +568,51 @@ int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *
 	return _alpm_option_strlist_rem(handle, &(handle->ignoregroup), grp);
 }
 
+int SYMEXPORT alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
+{
+	CHECK_HANDLE(handle, return -1);
+
+	handle->assumeinstalled = alpm_list_add(handle->assumeinstalled, (void *)dep);
+	return 0;
+}
+
+int SYMEXPORT alpm_option_set_assumeinstalled(alpm_handle_t *handle, alpm_list_t *deps)
+{
+	CHECK_HANDLE(handle, return -1);
+	if(handle->assumeinstalled) {
+		alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
+		alpm_list_free(handle->assumeinstalled);
+	}
+	handle->assumeinstalled = deps;
+	return 0;
+}
+
+static int assumeinstalled_cmp(const void *d1, const void *d2)
+{
+	const alpm_depend_t *dep1 = d1;
+	const alpm_depend_t *dep2 = d2;
+
+	if(strcmp(dep1->name, dep2->name) == 0 && strcmp(dep1->version, dep2->version) == 0) {
+		return 0;
+	}
+
+	return -1;
+}
+
+int SYMEXPORT alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
+{
+	alpm_depend_t *vdata = NULL;
+	CHECK_HANDLE(handle, return -1);
+
+	handle->assumeinstalled = alpm_list_remove(handle->assumeinstalled, dep, &assumeinstalled_cmp, (void **)&vdata);
+	if(vdata != NULL) {
+		alpm_dep_free(vdata);
+		return 1;
+	}
+
+	return 0;
+}
+
 int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
 {
 	CHECK_HANDLE(handle, return -1);
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index 9cd3a210..b92d3cfb 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -84,6 +84,7 @@ struct __alpm_handle_t {
 	alpm_list_t *noextract;   /* List of files NOT to extract */
 	alpm_list_t *ignorepkg;   /* List of packages to ignore */
 	alpm_list_t *ignoregroup; /* List of groups to ignore */
+	alpm_list_t *assumeinstalled;   /* List of virtual packages used to satisfy dependencies */
 
 	/* options */
 	char *arch;              /* Architecture of packages we should allow */
-- 
cgit v1.2.3-70-g09d2