summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2013-06-18 08:03:40 +0300
committerTimo Teräs <timo.teras@iki.fi>2013-06-18 08:03:40 +0300
commit01ec60f718c388f620598c39bdc0816a0dbe09ac (patch)
tree0d3f482967c0453ee240185c2cda41e411616675
parent54509e7a1a33923569848ce69c6e7f94fc6a021b (diff)
downloadapk-tools-01ec60f718c388f620598c39bdc0816a0dbe09ac.tar.gz
apk-tools-01ec60f718c388f620598c39bdc0816a0dbe09ac.tar.bz2
apk-tools-01ec60f718c388f620598c39bdc0816a0dbe09ac.tar.xz
apk-tools-01ec60f718c388f620598c39bdc0816a0dbe09ac.zip
errors: improve analysis for virtual packages
if all packages named N provide the virtual package, list only the name N instead of all packages providing it.
-rw-r--r--src/commit.c35
-rw-r--r--src/solver.c10
-rw-r--r--test/provides.repo6
-rw-r--r--test/provides2.test2
4 files changed, 35 insertions, 18 deletions
diff --git a/src/commit.c b/src/commit.c
index 6279e53..01ac4a8 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -334,9 +334,9 @@ all_done:
}
enum {
- STATE_UNSET = 0,
- STATE_PRESENT,
- STATE_MISSING
+ STATE_PRESENT = 0x80000000,
+ STATE_MISSING = 0x40000000,
+ STATE_COUNT_MASK = 0x0000ffff,
};
struct print_state {
@@ -460,16 +460,27 @@ static void analyze_name(struct print_state *ps, struct apk_name *name)
struct apk_provider *p0;
struct apk_dependency *d0;
char tmp[256];
+ int refs;
if (name->providers->num) {
snprintf(tmp, sizeof(tmp), "%s (virtual)", name->name);
ps->label = tmp;
label_start(ps, "provided by:");
+ foreach_array_item(p0, name->providers)
+ p0->pkg->name->state_int++;
foreach_array_item(p0, name->providers) {
- /* FIXME: print only name if all pkgs provide it */
- struct apk_package *pkg = p0->pkg;
- apk_print_indented_fmt(&ps->i, PKG_VER_FMT, PKG_VER_PRINTF(pkg));
+ name0 = p0->pkg->name;
+ refs = (name0->state_int & STATE_COUNT_MASK);
+ if (refs == name0->providers->num) {
+ /* name only */
+ apk_print_indented(&ps->i, APK_BLOB_STR(name0->name));
+ name0->state_int &= ~STATE_COUNT_MASK;
+ } else if (refs > 0) {
+ /* individual package */
+ apk_print_indented_fmt(&ps->i, PKG_VER_FMT, PKG_VER_PRINTF(p0->pkg));
+ name0->state_int--;
+ }
}
label_end(ps);
} else {
@@ -508,12 +519,14 @@ static void analyze_name(struct print_state *ps, struct apk_name *name)
static void analyze_deps(struct print_state *ps, struct apk_dependency_array *deps)
{
struct apk_dependency *d0;
+ struct apk_name *name0;
foreach_array_item(d0, deps) {
- if (d0->name->state_int != STATE_UNSET)
+ name0 = d0->name;
+ if ((name0->state_int & (STATE_PRESENT | STATE_MISSING)) != 0)
continue;
- d0->name->state_int = STATE_MISSING;
- analyze_name(ps, d0->name);
+ name0->state_int |= STATE_MISSING;
+ analyze_name(ps, name0);
}
}
@@ -570,9 +583,9 @@ void apk_solver_print_errors(struct apk_database *db,
if (pkg == NULL)
continue;
pkg->marked = 1;
- pkg->name->state_int = STATE_PRESENT;
+ pkg->name->state_int |= STATE_PRESENT;
foreach_array_item(p, pkg->provides)
- p->name->state_int = STATE_PRESENT;
+ p->name->state_int |= STATE_PRESENT;
}
/* Analyze is package, and missing names referred to */
diff --git a/src/solver.c b/src/solver.c
index 279d1f6..b1a078c 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -529,10 +529,14 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
if (name->ss.requirers || name->ss.has_iif) {
foreach_array_item(p, name->providers) {
+ /* Ensure valid pinning and install-if trigger */
if (name->ss.requirers == 0 &&
(!p->pkg->ss.iif_triggered ||
!p->pkg->ss.tag_ok))
continue;
+ /* Virtual packages cannot be autoselected */
+ if (p->version == &apk_null_blob && p->pkg->name->ss.requirers == 0)
+ continue;
if (compare_providers(ss, p, &chosen) > 0)
chosen = *p;
}
@@ -540,12 +544,6 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
pkg = chosen.pkg;
if (pkg) {
- if (chosen.version == &apk_null_blob) {
- /* Pure virtual package */
- assign_name(ss, name, provider_none);
- ss->errors += (name->ss.requirers > 0);
- return;
- }
if (!pkg->ss.available || !pkg->ss.tag_ok) {
/* Selecting broken or unallowed package */
mark_error(ss, pkg);
diff --git a/test/provides.repo b/test/provides.repo
index a3dfec4..6418f18 100644
--- a/test/provides.repo
+++ b/test/provides.repo
@@ -26,6 +26,12 @@ S:1
I:1
D:so:foo.so.2
+C:Q1EyN5AdpAOBJWKMR89ppC66EEEEj=
+P:mymailreader
+V:0.1
+S:1
+I:1
+
C:Q1EyN5AdpAOBJWKMR89pp/C66FFFF=
P:mymailreader
V:1
diff --git a/test/provides2.test b/test/provides2.test
index 9d3a2e4..37fc9d8 100644
--- a/test/provides2.test
+++ b/test/provides2.test
@@ -4,5 +4,5 @@ add mail-reader
@EXPECT
ERROR: unsatisfiable constraints:
mail-reader (virtual):
- provided by: mymailreader-1 mailreadplus-1
+ provided by: mymailreader-1 mailreadplus
required by: world[mail-reader]