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
parent
54509e7a1a
commit
01ec60f718
35
src/commit.c
35
src/commit.c
|
@ -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 */
|
||||||
|
|
10
src/solver.c
10
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) {
|
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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Reference in New Issue