Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
options: give more explanation on option change
Baptiste Daroussin committed 18 days ago
commit c58a26b003ce84a3b0876e879b5d53d2ff7106c5
parent 7bd8319
2 files changed +132 -27
modified libpkg/pkg_jobs.c
@@ -56,6 +56,7 @@
#include <ctype.h>

#include "pkg.h"
+
#include <xstring.h>
#include "private/event.h"
#include "private/pkg.h"
#include "private/pkgdb.h"
@@ -1046,35 +1047,51 @@ pkg_jobs_need_upgrade(charv_t *system_shlibs, struct pkg *rp, struct pkg *lp)
	}

	/* compare options */
-
	for (;;) {
-
		if (!pkg_object_bool(pkg_config_get("PKG_REINSTALL_ON_OPTIONS_CHANGE")))
-
			break;
-
		ret1 = pkg_options(rp, &ro);
-
		ret2 = pkg_options(lp, &lo);
-
		if (ret1 != ret2) {
+
	if (pkg_object_bool(pkg_config_get("PKG_REINSTALL_ON_OPTIONS_CHANGE"))) {
+
		xstring *optdiff = NULL;
+
		int ndiffs = 0;
+
		for (;;) {
+
			ret1 = pkg_options(rp, &ro);
+
			ret2 = pkg_options(lp, &lo);
+
			if (ret1 != ret2) {
+
				if (optdiff == NULL)
+
					optdiff = xstring_new();
+
				if (ro == NULL) {
+
					fprintf(optdiff->fp, "%s%s (removed)",
+
					    ndiffs ? ", " : "", lo->key);
+
				} else if (lo == NULL) {
+
					fprintf(optdiff->fp, "%s%s (added)",
+
					    ndiffs ? ", " : "", ro->key);
+
				}
+
				ndiffs++;
+
				/* lists have different lengths, done */
+
				break;
+
			}
+
			if (ret1 != EPKG_OK)
+
				break;
+
			if (!STREQ(lo->key, ro->key)) {
+
				if (optdiff == NULL)
+
					optdiff = xstring_new();
+
				fprintf(optdiff->fp, "%s%s (removed), %s (added)",
+
				    ndiffs ? ", " : "", lo->key, ro->key);
+
				ndiffs++;
+
			} else if (!STREQ(lo->value, ro->value)) {
+
				if (optdiff == NULL)
+
					optdiff = xstring_new();
+
				fprintf(optdiff->fp, "%s%s (%s -> %s)",
+
				    ndiffs ? ", " : "", lo->key,
+
				    lo->value, ro->value);
+
				ndiffs++;
+
			}
+
		}
+
		if (ndiffs > 0) {
+
			fflush(optdiff->fp);
			free(rp->reason);
-
			if (ro == NULL)
-
				xasprintf(&rp->reason, "option removed: %s",
-
				    lo->key);
-
			else if (lo == NULL)
-
				xasprintf(&rp->reason, "option added: %s",
-
				    ro->key);
-
			else
-
				xasprintf(&rp->reason, "option changed: %s",
-
				    ro->key);
-
			assert(rp->reason != NULL);
+
			xasprintf(&rp->reason, "option changed: %s",
+
			    optdiff->buf);
+
			xstring_free(optdiff);
			return (true);
		}
-
		if (ret1 == EPKG_OK) {
-
			if (!STREQ(lo->key, ro->key) ||
-
			    !STREQ(lo->value, ro->value)) {
-
				free(rp->reason);
-
				xasprintf(&rp->reason, "options changed");
-
				return (true);
-
			}
-
		}
-
		else
-
			break;
	}

	/* What about the direct deps */
modified tests/frontend/upgrade.sh
@@ -23,7 +23,9 @@ tests_init \
	newpkgversion_two_repos \
	upgrade_disabled_repo \
	upgrade_all_disabled_repos \
-
	upgrade_vulnerable
+
	upgrade_vulnerable \
+
	upgrade_options_changed \
+
	upgrade_options_added_removed

issue1881_body() {
	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg pkg1 pkg_a 1
@@ -938,3 +940,89 @@ VULN
		pkg -o REPOS_DIR="${TMPDIR}/repoconf" -o PKG_CACHEDIR="${TMPDIR}" \
		upgrade -n
}
+

+
upgrade_options_changed_body()
+
{
+
	# Install v1 with OPT1=on OPT2=off
+
	atf_check sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+
	cat <<EOF >> test.ucl
+
options: {
+
	"OPT1": "on"
+
	"OPT2": "off"
+
}
+
EOF
+
	atf_check -o ignore pkg register -M test.ucl
+

+
	# Create v1 in repo with OPT1=off OPT2=on (same version, options differ)
+
	atf_check sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+
	cat <<EOF >> test.ucl
+
options: {
+
	"OPT1": "off"
+
	"OPT2": "on"
+
}
+
EOF
+
	atf_check pkg create -M test.ucl
+
	atf_check -o ignore pkg repo .
+

+
	mkdir repoconf
+
	cat <<EOF > repoconf/repo.conf
+
local: {
+
	url: "file://${TMPDIR}",
+
	enabled: true
+
}
+
EOF
+

+
	atf_check -o ignore pkg -o REPOS_DIR="${TMPDIR}/repoconf" \
+
		-o PKG_CACHEDIR="${TMPDIR}" update
+

+
	# Upgrade dry-run: should show which options changed
+
	atf_check \
+
		-o match:"REINSTALL" \
+
		-o match:"OPT1 \(on -> off\)" \
+
		-o match:"OPT2 \(off -> on\)" \
+
		-s exit:0 \
+
		pkg -o REPOS_DIR="${TMPDIR}/repoconf" \
+
		-o PKG_CACHEDIR="${TMPDIR}" upgrade -n
+
}
+

+
upgrade_options_added_removed_body()
+
{
+
	# Install v1 with OPT1=on
+
	atf_check sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+
	cat <<EOF >> test.ucl
+
options: {
+
	"OPT1": "on"
+
}
+
EOF
+
	atf_check -o ignore pkg register -M test.ucl
+

+
	# Create v1 in repo with OPT2=on (OPT1 removed, OPT2 added)
+
	atf_check sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+
	cat <<EOF >> test.ucl
+
options: {
+
	"OPT2": "on"
+
}
+
EOF
+
	atf_check pkg create -M test.ucl
+
	atf_check -o ignore pkg repo .
+

+
	mkdir repoconf
+
	cat <<EOF > repoconf/repo.conf
+
local: {
+
	url: "file://${TMPDIR}",
+
	enabled: true
+
}
+
EOF
+

+
	atf_check -o ignore pkg -o REPOS_DIR="${TMPDIR}/repoconf" \
+
		-o PKG_CACHEDIR="${TMPDIR}" update
+

+
	# Upgrade dry-run: should show added/removed options
+
	atf_check \
+
		-o match:"REINSTALL" \
+
		-o match:"OPT1 \(removed\)" \
+
		-o match:"OPT2 \(added\)" \
+
		-s exit:0 \
+
		pkg -o REPOS_DIR="${TMPDIR}/repoconf" \
+
		-o PKG_CACHEDIR="${TMPDIR}" upgrade -n
+
}