Commit e51232e7 authored by Timo Teräs's avatar Timo Teräs

errors: rewrite the logic how errors are reported

Instead of the dependency oriented logic, switch to print them
for each package or name needed. Might give a bit more readable
errors now. There's still few corner cases that proper error is
not output, which are cought by the test cases.
parent 25ff68a8
......@@ -143,6 +143,9 @@ void *apk_array_resize(void *array, size_t new_size, size_t elem_size);
APK_ARRAY(apk_string_array, char *);
#define foreach_array_item(iter, array) \
for (iter = &(array)->item[0]; iter < &(array)->item[(array)->num]; iter++)
#define LIST_END (void *) 0xe01
#define LIST_POISON1 (void *) 0xdeadbeef
#define LIST_POISON2 (void *) 0xabbaabba
......
......@@ -37,6 +37,10 @@ struct apk_provider;
#define APK_SIGN_GENERATE 4
#define APK_SIGN_VERIFY_AND_GENERATE 5
#define APK_DEP_IRRELEVANT 0
#define APK_DEP_SATISFIED 1
#define APK_DEP_CONFLICTED 2
struct apk_sign_ctx {
int keys_fd;
int action;
......@@ -129,6 +133,8 @@ void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
int apk_dep_is_materialized(struct apk_dependency *dep, struct apk_package *pkg);
int apk_dep_is_materialized_or_provided(struct apk_dependency *dep, struct apk_package *pkg);
int apk_dep_is_provided(struct apk_dependency *dep, struct apk_provider *p);
int apk_dep_analyze(struct apk_dependency *dep, struct apk_package *pkg);
char *apk_dep_snprintf(char *buf, size_t n, struct apk_dependency *dep);
void apk_blob_push_dep(apk_blob_t *to, struct apk_database *, struct apk_dependency *dep);
void apk_blob_push_deps(apk_blob_t *to, struct apk_database *, struct apk_dependency_array *deps);
......
......@@ -31,5 +31,6 @@ struct apk_indent {
int apk_print_indented(struct apk_indent *i, apk_blob_t blob);
void apk_print_indented_words(struct apk_indent *i, const char *text);
void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...);
#endif
This diff is collapsed.
......@@ -399,6 +399,40 @@ int apk_dep_is_materialized_or_provided(struct apk_dependency *dep, struct apk_p
return dep->conflict;
}
int apk_dep_analyze(struct apk_dependency *dep, struct apk_package *pkg)
{
int i;
if (pkg == NULL)
return APK_DEP_IRRELEVANT;
if (dep->name == pkg->name)
return apk_dep_is_materialized(dep, pkg) ? APK_DEP_SATISFIED : APK_DEP_CONFLICTED;
for (i = 0; i < pkg->provides->num; i++) {
struct apk_provider p;
if (pkg->provides->item[i].name != dep->name)
continue;
p = APK_PROVIDER_FROM_PROVIDES(pkg, &pkg->provides->item[i]);
return apk_dep_is_provided(dep, &p) ? APK_DEP_SATISFIED : APK_DEP_CONFLICTED;
}
return APK_DEP_IRRELEVANT;
}
char *apk_dep_snprintf(char *buf, size_t n, struct apk_dependency *dep)
{
apk_blob_t b = APK_BLOB_PTR_LEN(buf, n);
apk_blob_push_dep(&b, NULL, dep);
if (b.len)
apk_blob_push_blob(&b, APK_BLOB_PTR_LEN("", 1));
else
b.ptr[-1] = 0;
return buf;
}
void apk_blob_push_dep(apk_blob_t *to, struct apk_database *db, struct apk_dependency *dep)
{
int result_mask = dep->result_mask;
......
......@@ -57,6 +57,18 @@ void apk_print_indented_words(struct apk_indent *i, const char *text)
(apk_blob_cb) apk_print_indented, i);
}
void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...)
{
char tmp[256];
size_t n;
va_list va;
va_start(va, fmt);
n = vsnprintf(tmp, sizeof(tmp), fmt, va);
apk_print_indented(i, APK_BLOB_PTR_LEN(tmp, n));
va_end(va);
}
const char *apk_error_str(int error)
{
if (error < 0)
......
......@@ -435,6 +435,9 @@ static int compare_providers(struct apk_solver_state *ss,
/* Prefer those that were in last dependency merging group */
r = (int)pkgA->ss.dependencies_used - (int)pkgB->ss.dependencies_used;
if (r)
return r;
r = pkgB->ss.conflicts - pkgA->ss.conflicts;
if (r)
return r;
......
......@@ -2,5 +2,7 @@
--test-repo conflict.repo
add a b>1
@EXPECT
ERROR: unsatisfiable dependencies:
world: b>1
ERROR: unsatisfiable constraints:
b-2:
breaks: a-1[!b>1]
satisfies: world[b>1]
......@@ -2,5 +2,7 @@
--test-repo complicated1.repo
add a d>1.5
@EXPECT
ERROR: unsatisfiable dependencies:
b-1: d<2.0
ERROR: unsatisfiable constraints:
d-2.0:
breaks: b-1[d<2.0]
satisfies: world[d>1.5] c-1[d>1.0]
......@@ -2,5 +2,7 @@
--test-repo complicated1.repo
add a d<1.5
@EXPECT
ERROR: unsatisfiable dependencies:
world: d<1.5
ERROR: unsatisfiable constraints:
d-1.0:
breaks: c-1[d>1.0]
satisfies: world[d<1.5] b-1[d<2.0]
......@@ -2,5 +2,10 @@
--test-repo complicated1.repo
add a !b
@EXPECT
ERROR: unsatisfiable dependencies:
a-3: b
ERROR: unsatisfiable constraints:
d-2.0:
breaks: b-1[d<2.0]
satisfies: c-1[d>1.0]
b-1:
breaks: world[!b]
satisfies: a-3[b]
......@@ -2,5 +2,6 @@
--test-repo complicated1.repo
add a nonexistant
@EXPECT
ERROR: unsatisfiable dependencies:
world: nonexistant
ERROR: unsatisfiable constraints:
nonexistant (missing):
required by: world[nonexistant]
......@@ -2,5 +2,5 @@
--test-repo complicated1.repo
add a>2
@EXPECT
ERROR: unsatisfiable dependencies:
ERROR: unsatisfiable constraints:
b-1: d<2.0
......@@ -4,5 +4,7 @@
--test-world "a@testing"
add c>=3
@EXPECT
ERROR: unsatisfiable dependencies:
c-3: not pinned: @testing
ERROR: unsatisfiable constraints:
c-3:
masked in: testing
satisfies: world[c>=3]
......@@ -5,6 +5,13 @@ S:1
I:1
p:so:foo.so.1=1.0
C:Q1EyN5AdpAOBJWKMR89pp/C66o+FE=
P:libfoo
V:2
S:1
I:1
p:so:foo.so.2=1.0
C:Q1eVpkasfqZAukAXFYbgwt4xAMZWU=
P:app
V:2
......@@ -12,6 +19,13 @@ S:1
I:1
D:so:foo.so.1
C:Q1eVpsasfqZAukAXFYbgwt4xAMZWX=
P:app2
V:2
S:1
I:1
D:so:foo.so.2
C:Q1EyN5AdpAOBJWKMR89pp/C66FFFF=
P:mymailreader
V:1
......@@ -40,3 +54,10 @@ S:1
I:1
p:theservice=2
C:Q1eVpkasfqZAukAXFYbgwt444Edde=
P:selfconflicting
V:1
S:1
I:1
p:selfprovided=2
p:selfprovided=3
......@@ -2,8 +2,7 @@
--test-repo provides.repo
add mail-reader
@EXPECT
ERROR: unsatisfiable dependencies:
world: mail-reader
mail-reader is a virtual package provided by:
mymailreader-1 mailreadplus-1
ERROR: unsatisfiable constraints:
mail-reader (virtual):
provided by: mymailreader-1 mailreadplus-1
required by: world[mail-reader]
......@@ -2,5 +2,10 @@
--test-repo provides.repo
add server-a server-b
@EXPECT
ERROR: unsatisfiable dependencies:
world: server-a
ERROR: unsatisfiable constraints:
server-a-1:
conflicts: server-b-1[theservice]
satisfies: world[server-a]
server-b-1:
conflicts: server-a-1[theservice]
satisfies: world[server-b]
@ARGS
--test-repo provides.repo
add app app2
@EXPECT
ERROR: unsatisfiable constraints:
libfoo-1:
conflicts: libfoo-2
satisfies: app-2[so:foo.so.1]
libfoo-2:
conflicts: libfoo-1
satisfies: app2-2[so:foo.so.2]
@ARGS
--test-repo provides.repo
add selfconflicting
@EXPECT
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment