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.
cute-signatures
Timo Teräs 2013-06-18 08:03:40 +03:00
parent 54509e7a1a
commit 01ec60f718
4 changed files with 35 additions and 18 deletions

View File

@ -334,9 +334,9 @@ all_done:
} }
enum { enum {
STATE_UNSET = 0, STATE_PRESENT = 0x80000000,
STATE_PRESENT, STATE_MISSING = 0x40000000,
STATE_MISSING STATE_COUNT_MASK = 0x0000ffff,
}; };
struct print_state { 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_provider *p0;
struct apk_dependency *d0; struct apk_dependency *d0;
char tmp[256]; char tmp[256];
int refs;
if (name->providers->num) { if (name->providers->num) {
snprintf(tmp, sizeof(tmp), "%s (virtual)", name->name); snprintf(tmp, sizeof(tmp), "%s (virtual)", name->name);
ps->label = tmp; ps->label = tmp;
label_start(ps, "provided by:"); label_start(ps, "provided by:");
foreach_array_item(p0, name->providers)
p0->pkg->name->state_int++;
foreach_array_item(p0, name->providers) { foreach_array_item(p0, name->providers) {
/* FIXME: print only name if all pkgs provide it */ name0 = p0->pkg->name;
struct apk_package *pkg = p0->pkg; refs = (name0->state_int & STATE_COUNT_MASK);
apk_print_indented_fmt(&ps->i, PKG_VER_FMT, PKG_VER_PRINTF(pkg)); 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); label_end(ps);
} else { } 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) static void analyze_deps(struct print_state *ps, struct apk_dependency_array *deps)
{ {
struct apk_dependency *d0; struct apk_dependency *d0;
struct apk_name *name0;
foreach_array_item(d0, deps) { 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; continue;
d0->name->state_int = STATE_MISSING; name0->state_int |= STATE_MISSING;
analyze_name(ps, d0->name); analyze_name(ps, name0);
} }
} }
@ -570,9 +583,9 @@ void apk_solver_print_errors(struct apk_database *db,
if (pkg == NULL) if (pkg == NULL)
continue; continue;
pkg->marked = 1; pkg->marked = 1;
pkg->name->state_int = STATE_PRESENT; pkg->name->state_int |= STATE_PRESENT;
foreach_array_item(p, pkg->provides) 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 */ /* Analyze is package, and missing names referred to */

View File

@ -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) { if (name->ss.requirers || name->ss.has_iif) {
foreach_array_item(p, name->providers) { foreach_array_item(p, name->providers) {
/* Ensure valid pinning and install-if trigger */
if (name->ss.requirers == 0 && if (name->ss.requirers == 0 &&
(!p->pkg->ss.iif_triggered || (!p->pkg->ss.iif_triggered ||
!p->pkg->ss.tag_ok)) !p->pkg->ss.tag_ok))
continue; 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) if (compare_providers(ss, p, &chosen) > 0)
chosen = *p; chosen = *p;
} }
@ -540,12 +544,6 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
pkg = chosen.pkg; pkg = chosen.pkg;
if (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) { if (!pkg->ss.available || !pkg->ss.tag_ok) {
/* Selecting broken or unallowed package */ /* Selecting broken or unallowed package */
mark_error(ss, pkg); mark_error(ss, pkg);

View File

@ -26,6 +26,12 @@ S:1
I:1 I:1
D:so:foo.so.2 D:so:foo.so.2
C:Q1EyN5AdpAOBJWKMR89ppC66EEEEj=
P:mymailreader
V:0.1
S:1
I:1
C:Q1EyN5AdpAOBJWKMR89pp/C66FFFF= C:Q1EyN5AdpAOBJWKMR89pp/C66FFFF=
P:mymailreader P:mymailreader
V:1 V:1

View File

@ -4,5 +4,5 @@ add mail-reader
@EXPECT @EXPECT
ERROR: unsatisfiable constraints: ERROR: unsatisfiable constraints:
mail-reader (virtual): mail-reader (virtual):
provided by: mymailreader-1 mailreadplus-1 provided by: mymailreader-1 mailreadplus
required by: world[mail-reader] required by: world[mail-reader]