state: improve error messages from dependency failures
Print more information why installation changeset calculation failed. Fixes #187.cute-signatures
parent
2165547bad
commit
038b672061
24
src/add.c
24
src/add.c
|
@ -67,12 +67,12 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
|
|
||||||
if (actx->virtpkg) {
|
if (actx->virtpkg) {
|
||||||
if (non_repository_check(db))
|
if (non_repository_check(db))
|
||||||
goto err;
|
return -1;
|
||||||
|
|
||||||
virtpkg = apk_pkg_new();
|
virtpkg = apk_pkg_new();
|
||||||
if (virtpkg == NULL) {
|
if (virtpkg == NULL) {
|
||||||
apk_error("Failed to allocate virtual meta package");
|
apk_error("Failed to allocate virtual meta package");
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
virtpkg->name = apk_db_get_name(db, APK_BLOB_STR(actx->virtpkg));
|
virtpkg->name = apk_db_get_name(db, APK_BLOB_STR(actx->virtpkg));
|
||||||
apk_blob_checksum(APK_BLOB_STR(virtpkg->name->name),
|
apk_blob_checksum(APK_BLOB_STR(virtpkg->name->name),
|
||||||
|
@ -96,7 +96,7 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
struct apk_sign_ctx sctx;
|
struct apk_sign_ctx sctx;
|
||||||
|
|
||||||
if (non_repository_check(db))
|
if (non_repository_check(db))
|
||||||
goto err;
|
return -1;
|
||||||
|
|
||||||
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
|
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
|
||||||
NULL, db->keys_fd);
|
NULL, db->keys_fd);
|
||||||
|
@ -104,14 +104,13 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
apk_sign_ctx_free(&sctx);
|
apk_sign_ctx_free(&sctx);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
apk_error("%s: %s", argv[i], apk_error_str(r));
|
apk_error("%s: %s", argv[i], apk_error_str(r));
|
||||||
goto err;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
apk_dep_from_pkg(&dep, db, pkg);
|
apk_dep_from_pkg(&dep, db, pkg);
|
||||||
} else {
|
} else {
|
||||||
r = apk_dep_from_blob(&dep, db, APK_BLOB_STR(argv[i]));
|
r = apk_dep_from_blob(&dep, db, APK_BLOB_STR(argv[i]));
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virtpkg)
|
if (virtpkg)
|
||||||
|
@ -126,7 +125,7 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
|
|
||||||
state = apk_state_new(db);
|
state = apk_state_new(db);
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
goto err;
|
return -1;
|
||||||
|
|
||||||
for (i = 0; i < num_deps; i++) {
|
for (i = 0; i < num_deps; i++) {
|
||||||
r = apk_state_lock_dependency(state, &deps[i]);
|
r = apk_state_lock_dependency(state, &deps[i]);
|
||||||
|
@ -134,16 +133,15 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
apk_deps_add(&db->world, &deps[i]);
|
apk_deps_add(&db->world, &deps[i]);
|
||||||
deps[i].name->flags |= APK_NAME_TOPLEVEL;
|
deps[i].name->flags |= APK_NAME_TOPLEVEL;
|
||||||
} else {
|
} else {
|
||||||
apk_error("Unable to install '%s': %d",
|
|
||||||
deps[i].name->name, r);
|
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errors && !(apk_flags & APK_FORCE))
|
if (errors && !(apk_flags & APK_FORCE)) {
|
||||||
goto err;
|
apk_state_print_errors(state);
|
||||||
|
r = -1;
|
||||||
|
} else {
|
||||||
r = apk_state_commit(state, db);
|
r = apk_state_commit(state, db);
|
||||||
err:
|
}
|
||||||
if (state != NULL)
|
if (state != NULL)
|
||||||
apk_state_unref(state);
|
apk_state_unref(state);
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -74,6 +74,7 @@ int apk_blob_spn(apk_blob_t blob, const char *accept, apk_blob_t *l, apk_blob_t
|
||||||
int apk_blob_cspn(apk_blob_t blob, const char *reject, apk_blob_t *l, apk_blob_t *r);
|
int apk_blob_cspn(apk_blob_t blob, const char *reject, apk_blob_t *l, apk_blob_t *r);
|
||||||
int apk_blob_split(apk_blob_t blob, apk_blob_t split, apk_blob_t *l, apk_blob_t *r);
|
int apk_blob_split(apk_blob_t blob, apk_blob_t split, apk_blob_t *l, apk_blob_t *r);
|
||||||
int apk_blob_rsplit(apk_blob_t blob, char split, apk_blob_t *l, apk_blob_t *r);
|
int apk_blob_rsplit(apk_blob_t blob, char split, apk_blob_t *l, apk_blob_t *r);
|
||||||
|
apk_blob_t apk_blob_pushed(apk_blob_t buffer, apk_blob_t left);
|
||||||
unsigned long apk_blob_hash_seed(apk_blob_t, unsigned long seed);
|
unsigned long apk_blob_hash_seed(apk_blob_t, unsigned long seed);
|
||||||
unsigned long apk_blob_hash(apk_blob_t str);
|
unsigned long apk_blob_hash(apk_blob_t str);
|
||||||
int apk_blob_compare(apk_blob_t a, apk_blob_t b);
|
int apk_blob_compare(apk_blob_t a, apk_blob_t b);
|
||||||
|
|
|
@ -112,6 +112,8 @@ int apk_dep_from_blob(struct apk_dependency *dep, struct apk_database *db,
|
||||||
apk_blob_t blob);
|
apk_blob_t blob);
|
||||||
void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
|
void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
|
||||||
struct apk_package *pkg);
|
struct apk_package *pkg);
|
||||||
|
void apk_blob_push_dep(apk_blob_t *to, struct apk_dependency *dep);
|
||||||
|
|
||||||
int apk_deps_add(struct apk_dependency_array **depends,
|
int apk_deps_add(struct apk_dependency_array **depends,
|
||||||
struct apk_dependency *dep);
|
struct apk_dependency *dep);
|
||||||
void apk_deps_del(struct apk_dependency_array **deps,
|
void apk_deps_del(struct apk_dependency_array **deps,
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct apk_state {
|
||||||
unsigned int refs, num_names;
|
unsigned int refs, num_names;
|
||||||
struct apk_database *db;
|
struct apk_database *db;
|
||||||
struct list_head change_list_head;
|
struct list_head change_list_head;
|
||||||
|
struct apk_package_array *conflicts;
|
||||||
apk_name_state_t name[];
|
apk_name_state_t name[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ struct apk_state *apk_state_new(struct apk_database *db);
|
||||||
struct apk_state *apk_state_dup(struct apk_state *state);
|
struct apk_state *apk_state_dup(struct apk_state *state);
|
||||||
void apk_state_unref(struct apk_state *state);
|
void apk_state_unref(struct apk_state *state);
|
||||||
|
|
||||||
|
void apk_state_print_errors(struct apk_state *state);
|
||||||
int apk_state_commit(struct apk_state *state, struct apk_database *db);
|
int apk_state_commit(struct apk_state *state, struct apk_database *db);
|
||||||
int apk_state_lock_dependency(struct apk_state *state,
|
int apk_state_lock_dependency(struct apk_state *state,
|
||||||
struct apk_dependency *dep);
|
struct apk_dependency *dep);
|
||||||
|
|
|
@ -98,6 +98,14 @@ int apk_blob_split(apk_blob_t blob, apk_blob_t split, apk_blob_t *l, apk_blob_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apk_blob_t apk_blob_pushed(apk_blob_t buffer, apk_blob_t left)
|
||||||
|
{
|
||||||
|
if (buffer.ptr + buffer.len != left.ptr + left.len)
|
||||||
|
return APK_BLOB_NULL;
|
||||||
|
|
||||||
|
return APK_BLOB_PTR_LEN(buffer.ptr, left.ptr - buffer.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long apk_blob_hash_seed(apk_blob_t blob, unsigned long seed)
|
unsigned long apk_blob_hash_seed(apk_blob_t blob, unsigned long seed)
|
||||||
{
|
{
|
||||||
unsigned long hash = seed;
|
unsigned long hash = seed;
|
||||||
|
|
|
@ -56,13 +56,12 @@ static int del_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||||
.result_mask = APK_DEPMASK_CONFLICT,
|
.result_mask = APK_DEPMASK_CONFLICT,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = apk_state_lock_dependency(state, &dep);
|
r |= apk_state_lock_dependency(state, &dep);
|
||||||
if (r != 0) {
|
|
||||||
apk_error("Unable to remove '%s'", name->name);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (r == 0)
|
||||||
r = apk_state_commit(state, db);
|
r = apk_state_commit(state, db);
|
||||||
|
else
|
||||||
|
apk_state_print_errors(state);
|
||||||
err:
|
err:
|
||||||
if (state != NULL)
|
if (state != NULL)
|
||||||
apk_state_unref(state);
|
apk_state_unref(state);
|
||||||
|
|
13
src/fix.c
13
src/fix.c
|
@ -84,14 +84,13 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||||
name->flags |= APK_NAME_REINSTALL;
|
name->flags |= APK_NAME_REINSTALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++)
|
||||||
r = apk_state_lock_dependency(state, &deps[i]);
|
r |= apk_state_lock_dependency(state, &deps[i]);
|
||||||
if (r != 0) {
|
|
||||||
if (!(apk_flags & APK_FORCE))
|
if (r == 0 || (apk_flags & APK_FORCE))
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r = apk_state_commit(state, db);
|
r = apk_state_commit(state, db);
|
||||||
|
else
|
||||||
|
apk_state_print_errors(state);
|
||||||
err:
|
err:
|
||||||
if (r != 0 && i < argc)
|
if (r != 0 && i < argc)
|
||||||
apk_error("Error while processing '%s'", argv[i]);
|
apk_error("Error while processing '%s'", argv[i]);
|
||||||
|
|
|
@ -286,43 +286,41 @@ void apk_deps_parse(struct apk_database *db,
|
||||||
apk_blob_for_each_segment(blob, " ", parse_depend, &ctx);
|
apk_blob_for_each_segment(blob, " ", parse_depend, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apk_blob_push_dep(apk_blob_t *to, struct apk_dependency *dep)
|
||||||
|
{
|
||||||
|
if (dep->result_mask == APK_DEPMASK_CONFLICT)
|
||||||
|
apk_blob_push_blob(to, APK_BLOB_PTR_LEN("!", 1));
|
||||||
|
|
||||||
|
apk_blob_push_blob(to, APK_BLOB_STR(dep->name->name));
|
||||||
|
|
||||||
|
if (dep->result_mask != APK_DEPMASK_CONFLICT &&
|
||||||
|
dep->result_mask != APK_DEPMASK_REQUIRE) {
|
||||||
|
apk_blob_push_blob(to, APK_BLOB_STR(apk_version_op_string(dep->result_mask)));
|
||||||
|
apk_blob_push_blob(to, APK_BLOB_STR(dep->version));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os)
|
int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os)
|
||||||
{
|
{
|
||||||
int i, r, n = 0;
|
apk_blob_t blob;
|
||||||
|
char tmp[256];
|
||||||
|
int i, n = 0;
|
||||||
|
|
||||||
if (deps == NULL)
|
if (deps == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < deps->num; i++) {
|
for (i = 0; i < deps->num; i++) {
|
||||||
if (i) {
|
blob = APK_BLOB_BUF(tmp);
|
||||||
if (os->write(os, " ", 1) != 1)
|
if (i)
|
||||||
|
apk_blob_push_blob(&blob, APK_BLOB_PTR_LEN(" ", 1));
|
||||||
|
apk_blob_push_dep(&blob, &deps->item[i]);
|
||||||
|
|
||||||
|
blob = apk_blob_pushed(APK_BLOB_BUF(tmp), blob);
|
||||||
|
if (APK_BLOB_IS_NULL(blob) ||
|
||||||
|
os->write(os, blob.ptr, blob.len) != blob.len)
|
||||||
return -1;
|
return -1;
|
||||||
n += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deps->item[i].result_mask == APK_DEPMASK_CONFLICT) {
|
n += blob.len;
|
||||||
if (os->write(os, "!", 1) != 1)
|
|
||||||
return -1;
|
|
||||||
n += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = apk_ostream_write_string(os, deps->item[i].name->name);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
n += r;
|
|
||||||
|
|
||||||
if (deps->item[i].result_mask != APK_DEPMASK_CONFLICT &&
|
|
||||||
deps->item[i].result_mask != APK_DEPMASK_REQUIRE) {
|
|
||||||
r = apk_ostream_write_string(os, apk_version_op_string(deps->item[i].result_mask));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
n += r;
|
|
||||||
|
|
||||||
r = apk_ostream_write_string(os, deps->item[i].version);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
n += r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -967,7 +965,8 @@ int apk_pkg_write_index_entry(struct apk_package *info,
|
||||||
if (APK_BLOB_IS_NULL(bbuf))
|
if (APK_BLOB_IS_NULL(bbuf))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (os->write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
|
bbuf = apk_blob_pushed(APK_BLOB_BUF(buf), bbuf);
|
||||||
|
if (os->write(os, bbuf.ptr, bbuf.len) != bbuf.len)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (info->depends != NULL) {
|
if (info->depends != NULL) {
|
||||||
|
|
145
src/state.c
145
src/state.c
|
@ -34,6 +34,16 @@ int apk_state_prune_dependency(struct apk_state *state,
|
||||||
|
|
||||||
#define APK_NS_LOCKED 0x00000001
|
#define APK_NS_LOCKED 0x00000001
|
||||||
#define APK_NS_PENDING 0x00000002
|
#define APK_NS_PENDING 0x00000002
|
||||||
|
#define APK_NS_ERROR 0x00000004
|
||||||
|
|
||||||
|
static void apk_state_record_conflict(struct apk_state *state,
|
||||||
|
struct apk_package *pkg)
|
||||||
|
{
|
||||||
|
struct apk_name *name = pkg->name;
|
||||||
|
|
||||||
|
state->name[name->id] = (void*) (((intptr_t)state->name[name->id]) | APK_NS_ERROR);
|
||||||
|
*apk_package_array_add(&state->conflicts) = pkg;
|
||||||
|
}
|
||||||
|
|
||||||
static int inline ns_locked(apk_name_state_t name)
|
static int inline ns_locked(apk_name_state_t name)
|
||||||
{
|
{
|
||||||
|
@ -49,6 +59,13 @@ static int inline ns_pending(apk_name_state_t name)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int inline ns_error(apk_name_state_t name)
|
||||||
|
{
|
||||||
|
if (((intptr_t) name) & APK_NS_ERROR)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static int ns_empty(apk_name_state_t name)
|
static int ns_empty(apk_name_state_t name)
|
||||||
{
|
{
|
||||||
return name == NULL;
|
return name == NULL;
|
||||||
|
@ -67,7 +84,7 @@ static apk_name_state_t ns_from_pkg_non_pending(struct apk_package *pkg)
|
||||||
static struct apk_package *ns_to_pkg(apk_name_state_t name)
|
static struct apk_package *ns_to_pkg(apk_name_state_t name)
|
||||||
{
|
{
|
||||||
return (struct apk_package *)
|
return (struct apk_package *)
|
||||||
(((intptr_t) name) & ~(APK_NS_LOCKED | APK_NS_PENDING));
|
(((intptr_t) name) & ~(APK_NS_LOCKED | APK_NS_PENDING | APK_NS_ERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
static apk_name_state_t ns_from_choices(struct apk_name_choices *nc)
|
static apk_name_state_t ns_from_choices(struct apk_name_choices *nc)
|
||||||
|
@ -247,7 +264,9 @@ int apk_state_prune_dependency(struct apk_state *state,
|
||||||
struct apk_package *pkg = ns_to_pkg(state->name[name->id]);
|
struct apk_package *pkg = ns_to_pkg(state->name[name->id]);
|
||||||
|
|
||||||
/* Locked to not-installed / remove? */
|
/* Locked to not-installed / remove? */
|
||||||
if (pkg == NULL) {
|
if (ns_error(state->name[name->id])) {
|
||||||
|
return -1;
|
||||||
|
} else if (pkg == NULL) {
|
||||||
if (dep->result_mask != APK_DEPMASK_CONFLICT)
|
if (dep->result_mask != APK_DEPMASK_CONFLICT)
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -258,6 +277,7 @@ int apk_state_prune_dependency(struct apk_state *state,
|
||||||
|
|
||||||
if (ns_pending(state->name[name->id]))
|
if (ns_pending(state->name[name->id]))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,22 +390,29 @@ int apk_state_lock_dependency(struct apk_state *state,
|
||||||
static int apk_state_fix_package(struct apk_state *state,
|
static int apk_state_fix_package(struct apk_state *state,
|
||||||
struct apk_package *pkg)
|
struct apk_package *pkg)
|
||||||
{
|
{
|
||||||
int i, r;
|
int i, r, ret = 0;
|
||||||
|
|
||||||
|
if (pkg == NULL || pkg->depends == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < pkg->depends->num; i++) {
|
for (i = 0; i < pkg->depends->num; i++) {
|
||||||
r = apk_state_lock_dependency(state,
|
r = apk_state_lock_dependency(state,
|
||||||
&pkg->depends->item[i]);
|
&pkg->depends->item[i]);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int call_if_dependency_broke(struct apk_state *state,
|
static int call_if_dependency_broke(struct apk_state *state,
|
||||||
struct apk_package *pkg,
|
struct apk_package *pkg,
|
||||||
struct apk_name *dep_name,
|
struct apk_name *dep_name,
|
||||||
int (*cb)(struct apk_state *state,
|
int (*cb)(struct apk_state *state,
|
||||||
struct apk_package *pkg))
|
struct apk_package *pkg,
|
||||||
|
struct apk_dependency *dep,
|
||||||
|
void *ctx),
|
||||||
|
void *ctx)
|
||||||
{
|
{
|
||||||
struct apk_package *dep_pkg;
|
struct apk_package *dep_pkg;
|
||||||
int k;
|
int k;
|
||||||
|
@ -405,7 +432,7 @@ static int call_if_dependency_broke(struct apk_state *state,
|
||||||
(apk_version_compare(dep_pkg->version, dep->version)
|
(apk_version_compare(dep_pkg->version, dep->version)
|
||||||
& dep->result_mask))
|
& dep->result_mask))
|
||||||
continue;
|
continue;
|
||||||
return cb(state, pkg);
|
return cb(state, pkg, dep, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -414,7 +441,10 @@ static int call_if_dependency_broke(struct apk_state *state,
|
||||||
static int for_each_broken_reverse_depency(struct apk_state *state,
|
static int for_each_broken_reverse_depency(struct apk_state *state,
|
||||||
struct apk_name *name,
|
struct apk_name *name,
|
||||||
int (*cb)(struct apk_state *state,
|
int (*cb)(struct apk_state *state,
|
||||||
struct apk_package *pkg))
|
struct apk_package *pkg,
|
||||||
|
struct apk_dependency *dep,
|
||||||
|
void *ctx),
|
||||||
|
void *ctx)
|
||||||
{
|
{
|
||||||
struct apk_package *pkg0;
|
struct apk_package *pkg0;
|
||||||
int i, j, r;
|
int i, j, r;
|
||||||
|
@ -429,7 +459,8 @@ static int for_each_broken_reverse_depency(struct apk_state *state,
|
||||||
pkg0 = ns_to_pkg(state->name[name0->id]);
|
pkg0 = ns_to_pkg(state->name[name0->id]);
|
||||||
if (pkg0 == NULL)
|
if (pkg0 == NULL)
|
||||||
continue;
|
continue;
|
||||||
r = call_if_dependency_broke(state, pkg0, name, cb);
|
r = call_if_dependency_broke(state, pkg0, name,
|
||||||
|
cb, ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
} else if (!ns_empty(state->name[name0->id])) {
|
} else if (!ns_empty(state->name[name0->id])) {
|
||||||
|
@ -441,7 +472,7 @@ static int for_each_broken_reverse_depency(struct apk_state *state,
|
||||||
continue;
|
continue;
|
||||||
r = call_if_dependency_broke(state,
|
r = call_if_dependency_broke(state,
|
||||||
ns->pkgs[j],
|
ns->pkgs[j],
|
||||||
name, cb);
|
name, cb, ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
@ -455,7 +486,7 @@ static int for_each_broken_reverse_depency(struct apk_state *state,
|
||||||
|
|
||||||
r = call_if_dependency_broke(state,
|
r = call_if_dependency_broke(state,
|
||||||
name0->pkgs->item[j],
|
name0->pkgs->item[j],
|
||||||
name, cb);
|
name, cb, ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
@ -467,20 +498,24 @@ static int for_each_broken_reverse_depency(struct apk_state *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int delete_broken_package(struct apk_state *state,
|
static int delete_broken_package(struct apk_state *state,
|
||||||
struct apk_package *pkg)
|
struct apk_package *pkg,
|
||||||
|
struct apk_dependency *dep,
|
||||||
|
void *ctx)
|
||||||
{
|
{
|
||||||
return apk_state_lock_name(state, pkg->name, NULL);
|
return apk_state_lock_name(state, pkg->name, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reinstall_broken_package(struct apk_state *state,
|
static int reinstall_broken_package(struct apk_state *state,
|
||||||
struct apk_package *pkg)
|
struct apk_package *pkg,
|
||||||
|
struct apk_dependency *dep,
|
||||||
|
void *ctx)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct apk_dependency dep = {
|
struct apk_dependency dep0 = {
|
||||||
.name = pkg->name,
|
.name = pkg->name,
|
||||||
.result_mask = APK_DEPMASK_REQUIRE,
|
.result_mask = APK_DEPMASK_REQUIRE,
|
||||||
};
|
};
|
||||||
return apk_state_lock_dependency(state, &dep);
|
return apk_state_lock_dependency(state, &dep0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_state_lock_name(struct apk_state *state,
|
int apk_state_lock_name(struct apk_state *state,
|
||||||
|
@ -512,15 +547,18 @@ int apk_state_lock_name(struct apk_state *state,
|
||||||
r = for_each_broken_reverse_depency(state, name,
|
r = for_each_broken_reverse_depency(state, name,
|
||||||
newpkg == NULL ?
|
newpkg == NULL ?
|
||||||
delete_broken_package :
|
delete_broken_package :
|
||||||
reinstall_broken_package);
|
reinstall_broken_package,
|
||||||
if (r != 0)
|
NULL);
|
||||||
|
if (r != 0) {
|
||||||
|
apk_state_record_conflict(state, newpkg);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that all other dependencies hold for the new package. */
|
/* Check that all other dependencies hold for the new package. */
|
||||||
if (newpkg != NULL && newpkg->depends != NULL) {
|
|
||||||
r = apk_state_fix_package(state, newpkg);
|
r = apk_state_fix_package(state, newpkg);
|
||||||
if (r != 0)
|
if (r != 0) {
|
||||||
|
apk_state_record_conflict(state, newpkg);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,7 +747,9 @@ static int cmp_upgrade(struct apk_change *change)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fail_if_something_broke(struct apk_state *state,
|
static int fail_if_something_broke(struct apk_state *state,
|
||||||
struct apk_package *pkg)
|
struct apk_package *pkg,
|
||||||
|
struct apk_dependency *dep,
|
||||||
|
void *ctx)
|
||||||
|
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -735,7 +775,8 @@ static int apk_state_autoclean(struct apk_state *state,
|
||||||
oldns = state->name[n->id];
|
oldns = state->name[n->id];
|
||||||
state->name[n->id] = ns_from_pkg(NULL);
|
state->name[n->id] = ns_from_pkg(NULL);
|
||||||
r = for_each_broken_reverse_depency(state, n,
|
r = for_each_broken_reverse_depency(state, n,
|
||||||
fail_if_something_broke);
|
fail_if_something_broke,
|
||||||
|
NULL);
|
||||||
state->name[n->id] = oldns;
|
state->name[n->id] = oldns;
|
||||||
|
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
|
@ -747,6 +788,68 @@ static int apk_state_autoclean(struct apk_state *state,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct error_state {
|
||||||
|
struct apk_indent indent;
|
||||||
|
struct apk_package *prevpkg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int print_dep(struct apk_state *state,
|
||||||
|
struct apk_package *pkg,
|
||||||
|
struct apk_dependency *dep,
|
||||||
|
void *ctx)
|
||||||
|
{
|
||||||
|
struct error_state *es = (struct error_state *) ctx;
|
||||||
|
apk_blob_t blob;
|
||||||
|
char buf[256];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (pkg != es->prevpkg) {
|
||||||
|
printf("\n");
|
||||||
|
es->indent.x = 0;
|
||||||
|
len = snprintf(buf, sizeof(buf), "%s-%s:",
|
||||||
|
pkg->name->name, pkg->version);
|
||||||
|
apk_print_indented(&es->indent, APK_BLOB_PTR_LEN(buf, len));
|
||||||
|
es->prevpkg = pkg;
|
||||||
|
}
|
||||||
|
|
||||||
|
blob = APK_BLOB_BUF(buf);
|
||||||
|
apk_blob_push_dep(&blob, dep);
|
||||||
|
blob = apk_blob_pushed(APK_BLOB_BUF(buf), blob);
|
||||||
|
apk_print_indented(&es->indent, blob);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void apk_state_print_errors(struct apk_state *state)
|
||||||
|
{
|
||||||
|
struct apk_package *pkg;
|
||||||
|
struct error_state es;
|
||||||
|
int i, j, r;
|
||||||
|
|
||||||
|
if (state->conflicts == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
apk_error("Unable to satisfy all dependencies:");
|
||||||
|
for (i = 0; i < state->conflicts->num; i++) {
|
||||||
|
es.prevpkg = pkg = state->conflicts->item[i];
|
||||||
|
es.indent.x = es.indent.indent =
|
||||||
|
printf(" %s-%s:",
|
||||||
|
pkg->name->name, pkg->version);
|
||||||
|
|
||||||
|
for (j = 0; j < pkg->depends->num; j++) {
|
||||||
|
r = apk_state_lock_dependency(state,
|
||||||
|
&pkg->depends->item[j]);
|
||||||
|
if (r != 0)
|
||||||
|
print_dep(state, pkg, &pkg->depends->item[j], &es);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print conflicting reverse deps */
|
||||||
|
for_each_broken_reverse_depency(state, pkg->name,
|
||||||
|
print_dep, &es);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int apk_state_commit(struct apk_state *state,
|
int apk_state_commit(struct apk_state *state,
|
||||||
struct apk_database *db)
|
struct apk_database *db)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,14 +46,12 @@ static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **arg
|
||||||
dep->result_mask = APK_VERSION_EQUAL | APK_VERSION_LESS | APK_VERSION_GREATER;
|
dep->result_mask = APK_VERSION_EQUAL | APK_VERSION_LESS | APK_VERSION_GREATER;
|
||||||
dep->version = NULL;
|
dep->version = NULL;
|
||||||
}
|
}
|
||||||
r = apk_state_lock_dependency(state, dep);
|
r |= apk_state_lock_dependency(state, dep);
|
||||||
if (r != 0) {
|
|
||||||
apk_error("Unable to upgrade '%s'",
|
|
||||||
dep->name->name);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (r == 0)
|
||||||
r = apk_state_commit(state, db);
|
r = apk_state_commit(state, db);
|
||||||
|
else
|
||||||
|
apk_state_print_errors(state);
|
||||||
err:
|
err:
|
||||||
if (state != NULL)
|
if (state != NULL)
|
||||||
apk_state_unref(state);
|
apk_state_unref(state);
|
||||||
|
|
Loading…
Reference in New Issue