From 627a5afaafa0fc066e9f519958ee6473a2b7bedb Mon Sep 17 00:00:00 2001
From: Juan RP <xtraeme@gmail.com>
Date: Mon, 20 Oct 2014 07:59:06 +0200
Subject: [PATCH] Make sure that automatic/manual installation modes are set as
 expected.

---
 include/xbps_api_impl.h                      |  2 +-
 lib/repo_pkgdeps.c                           |  4 +-
 lib/transaction_ops.c                        |  6 +-
 lib/transaction_store.c                      |  5 +-
 tests/xbps/libxbps/shell/installmode_test.sh | 64 ++++++++++++++++++++
 5 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h
index dd3910d8..f185f547 100644
--- a/include/xbps_api_impl.h
+++ b/include/xbps_api_impl.h
@@ -198,7 +198,7 @@ bool HIDDEN xbps_transaction_shlibs(struct xbps_handle *, xbps_array_t, xbps_arr
  */
 int HIDDEN xbps_transaction_init(struct xbps_handle *);
 
-int HIDDEN xbps_transaction_store(struct xbps_handle *, xbps_array_t, xbps_dictionary_t);
+int HIDDEN xbps_transaction_store(struct xbps_handle *, xbps_array_t, xbps_dictionary_t, bool);
 
 /**
  * @private
diff --git a/lib/repo_pkgdeps.c b/lib/repo_pkgdeps.c
index a03770f1..30c76a88 100644
--- a/lib/repo_pkgdeps.c
+++ b/lib/repo_pkgdeps.c
@@ -330,7 +330,7 @@ find_repo_deps(struct xbps_handle *xhp,
 			 * Package is on repo, add it into the transaction dictionary.
 			 */
 			xbps_dictionary_set_cstring_nocopy(curpkgd, "transaction", reason);
-			rv = xbps_transaction_store(xhp, unsorted, curpkgd);
+			rv = xbps_transaction_store(xhp, unsorted, curpkgd, true);
 			if (rv != 0) {
 				xbps_dbg_printf(xhp, "xbps_transaction_store failed for `%s': %s\n", reqpkg, strerror(rv));
 				break;
@@ -359,7 +359,7 @@ find_repo_deps(struct xbps_handle *xhp,
 		 * Package is on repo, add it into the transaction dictionary.
 		 */
 		xbps_dictionary_set_cstring_nocopy(curpkgd, "transaction", reason);
-		rv = xbps_transaction_store(xhp, unsorted, curpkgd);
+		rv = xbps_transaction_store(xhp, unsorted, curpkgd, true);
 		if (rv != 0) {
 			xbps_dbg_printf(xhp, "xbps_transaction_store failed for `%s': %s\n", reqpkg, strerror(rv));
 			break;
diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c
index 7b5deebb..b4a9c053 100644
--- a/lib/transaction_ops.c
+++ b/lib/transaction_ops.c
@@ -197,7 +197,7 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
 		free(pkgname);
 		return EINVAL;
 	}
-	if ((rv = xbps_transaction_store(xhp, pkgs, pkg_repod)) != 0) {
+	if ((rv = xbps_transaction_store(xhp, pkgs, pkg_repod, false)) != 0) {
 		free(pkgname);
 		return rv;
 	}
@@ -310,7 +310,7 @@ xbps_transaction_remove_pkg(struct xbps_handle *xhp,
 		obj = xbps_array_get(orphans, count);
 		xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
 		xbps_dictionary_set_cstring_nocopy(obj, "transaction", "remove");
-		if ((rv = xbps_transaction_store(xhp, pkgs, obj)) != 0)
+		if ((rv = xbps_transaction_store(xhp, pkgs, obj, false)) != 0)
 			return EINVAL;
 		xbps_dbg_printf(xhp, "%s: added into transaction (remove).\n", pkgver);
 	}
@@ -332,7 +332,7 @@ rmpkg:
 	 */
 	xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
 	xbps_dictionary_set_cstring_nocopy(pkgd, "transaction", "remove");
-	if ((rv = xbps_transaction_store(xhp, pkgs, pkgd)) != 0)
+	if ((rv = xbps_transaction_store(xhp, pkgs, pkgd, false)) != 0)
 		return EINVAL;
 	xbps_dbg_printf(xhp, "%s: added into transaction (remove).\n", pkgver);
 	reqby = xbps_pkgdb_get_pkg_revdeps(xhp, pkgver);
diff --git a/lib/transaction_store.c b/lib/transaction_store.c
index 684c3d7c..f0717647 100644
--- a/lib/transaction_store.c
+++ b/lib/transaction_store.c
@@ -32,7 +32,7 @@
 
 int HIDDEN
 xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs,
-		xbps_dictionary_t pkgd)
+		xbps_dictionary_t pkgd, bool autoinst)
 {
 	xbps_array_t replaces;
 	const char *pkgver;
@@ -44,8 +44,7 @@ xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs,
 	/*
 	 * Add required objects into package dep's dictionary.
 	 */
-	if (!xbps_dictionary_get(pkgd, "automatic-install") &&
-	    !xbps_dictionary_set_bool(pkgd, "automatic-install", true))
+	if (autoinst && !xbps_dictionary_set_bool(pkgd, "automatic-install", true))
 		return EINVAL;
 
 	/*
diff --git a/tests/xbps/libxbps/shell/installmode_test.sh b/tests/xbps/libxbps/shell/installmode_test.sh
index fc21cd4c..e0b4943e 100644
--- a/tests/xbps/libxbps/shell/installmode_test.sh
+++ b/tests/xbps/libxbps/shell/installmode_test.sh
@@ -1,5 +1,67 @@
 #! /usr/bin/env atf-sh
 
+atf_test_case instmode
+
+instmode_head() {
+	atf_set "descr" "installation mode: basic test"
+}
+
+instmode_body() {
+	mkdir some_repo
+	mkdir -p pkg_a/usr/bin pkg_b/usr/bin
+	touch -f pkg_a/usr/bin/foo pkg_b/usr/bin/blah
+
+	cd some_repo
+	xbps-create -A noarch -n a-1.0_1 -s "foo pkg" ../pkg_a
+	atf_check_equal $? 0
+	xbps-create -A noarch -n b-1.0_1 -s "foo pkg" --dependencies "a>=0" ../pkg_b
+	atf_check_equal $? 0
+	xbps-rindex -a *.xbps
+	atf_check_equal $? 0
+
+	cd ..
+	xbps-install -r root -c null.conf --repository=$PWD/some_repo -yd b
+	atf_check_equal $? 0
+
+	out=$(xbps-query -r root --property=automatic-install a)
+	atf_check_equal $out yes
+	out=$(xbps-query -r root --property=automatic-install b)
+	rv=0
+	if [ "$out" != "" -a "$out" != "no" ]; then
+		rv=1
+	fi
+	atf_check_equal $rv 0
+}
+
+atf_test_case instmode_auto
+
+instmode_auto_head() {
+	atf_set "descr" "installation mode: basic test for automatic mode"
+}
+
+instmode_auto_body() {
+	mkdir some_repo
+	mkdir -p pkg_a/usr/bin pkg_b/usr/bin
+	touch -f pkg_a/usr/bin/foo pkg_b/usr/bin/blah
+
+	cd some_repo
+	xbps-create -A noarch -n a-1.0_1 -s "foo pkg" ../pkg_a
+	atf_check_equal $? 0
+	xbps-create -A noarch -n b-1.0_1 -s "foo pkg" --dependencies "a>=0" ../pkg_b
+	atf_check_equal $? 0
+	xbps-rindex -a *.xbps
+	atf_check_equal $? 0
+
+	cd ..
+	xbps-install -r root -c null.conf --repository=$PWD/some_repo -Ayd b
+	atf_check_equal $? 0
+
+	out=$(xbps-query -r root --property=automatic-install a)
+	atf_check_equal $out yes
+	out=$(xbps-query -r root --property=automatic-install b)
+	atf_check_equal $out yes
+}
+
 # 1- preserve installation mode on updates
 atf_test_case instmode_update
 
@@ -62,6 +124,8 @@ instmode_reinstall_body() {
 }
 
 atf_init_test_cases() {
+	atf_add_test_case instmode
+	atf_add_test_case instmode_auto
 	atf_add_test_case instmode_update
 	atf_add_test_case instmode_reinstall
 }