diff mbox series

[opkg,3/3] libopkg: pkg_hash: consider names stripped of ABI

Message ID 20221017170358.3628154-4-cotequeiroz@gmail.com
State New
Headers show
Series Rework criteria for dependent package selection | expand

Commit Message

Eneas U de Queiroz Oct. 17, 2022, 5:03 p.m. UTC
When resolving dependencies, packages listed in the cli may not have
the ABI version, and they should have a higher priority over anything
picked automatically.

Use powers of two when computing the score to avoid ties due to
different criteria, and so that it reflects what was matched.

The resulting priorities after this change are:
 - base score is 0
 === USER CHOICE CRITERIA ====
 - packages "picked by hand" (local file given in the cli) have absolute
   priority, ending the search regardless of score
 - package whose full name is in the cli: score += 4
 - package whose name stripped of ABI matches one in the cli: score += 2
 === DEVELOPER CRITERIA ====
 - package whose full name matches the dependency name: score += 1
 - in case of a tie, the last package that was looked at is chosen

Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
---
 libopkg/pkg_hash.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git opkglibopkg/pkg_hash.c b/libopkg/pkg_hash.c
index f3fb0c6..9494211 100644
--- opkglibopkg/pkg_hash.c
+++ b/libopkg/pkg_hash.c
@@ -413,7 +413,12 @@  pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
 	for (i = 0; i < matching_pkgs->len; i++) {
 		pkg_t *matching = matching_pkgs->pkgs[i];
 		if (constraint_fcn(matching, cdata)) {
-			int score = 1;
+			int score = 0;
+			char *stripped_name = NULL;
+			const char *abiver;
+			size_t abilen, namelen;
+			int cli_score;
+
 			/* It has been provided by hand, so it is what user want */
 			if (matching->provided_by_hand == 1) {
 				good_pkg_by_name = matching;
@@ -422,15 +427,28 @@  pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
 				break;
 			}
 
+			if ((abiver = pkg_get_string(matching, PKG_ABIVERSION)) &&
+			    ((namelen = strlen(matching->name))) > ((abilen = strlen(abiver))) &&
+			    !strncmp(matching->name + namelen - abilen, abiver, abilen) &&
+			    !(stripped_name = strndup(matching->name, namelen - abilen))) {
+				fprintf (stderr, "Out of memory.\n");
+				exit(EXIT_FAILURE);
+			}
+
 			if (strcmp(matching->name, apkg->name) == 0)
 				score++;
 
-			for (j = 0; j < opkg_cli_argc; ++j) {
+			for (j = 0, cli_score = 0; j < opkg_cli_argc; ++j) {
 				if (!strcmp(matching->name, opkg_cli_argv[j])) {
-					score += 2;
+					cli_score = 4;
 					break;
+				} else if (stripped_name &&
+					   !strcmp(stripped_name, opkg_cli_argv[j])) {
+					cli_score = 2;
 				}
 			}
+			score += cli_score;
+			free(stripped_name);
 
 			opkg_msg(DEBUG, "Candidate: %s %s (score %d).\n",
 				 matching->name, pkg_get_string(matching, PKG_VERSION),