solver, db: implement repository pinning
Improves /etc/apk/repositories format so you can say: http://nl.alpinelinux.org/alpine/v2.3/main @edge http://nl.alpinelinux.org/alpine/edge/main @testing http://nl.alpinelinux.org/alpine/edge/testing After which you can pin dependencies to these tags using: apk add stableapp newapp@edge bleedingapp@testing Apk will now by default only use the untagged repositories, but adding a tag to specific dependency: 1. will prefer that tag for the name 2. allowing pulling in dependencies from that tag (though, it prefers untagged packages to satisfy deps if possible) fixes #575cute-signatures
parent
e682e6596c
commit
500f8d4a7d
|
@ -115,10 +115,15 @@ struct apk_db_options {
|
|||
struct list_head repository_list;
|
||||
};
|
||||
|
||||
struct apk_repository_tag {
|
||||
unsigned int allowed_repos;
|
||||
apk_blob_t *name;
|
||||
};
|
||||
|
||||
struct apk_database {
|
||||
char *root;
|
||||
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
|
||||
unsigned num_repos;
|
||||
unsigned num_repos, num_repo_tags;
|
||||
const char *cache_dir;
|
||||
char *cache_remount_dir;
|
||||
apk_blob_t *arch;
|
||||
|
@ -131,6 +136,7 @@ struct apk_database {
|
|||
struct apk_dependency_array *world;
|
||||
struct apk_string_array *protected_paths;
|
||||
struct apk_repository repos[APK_MAX_REPOS];
|
||||
struct apk_repository_tag repo_tags[APK_MAX_REPOS];
|
||||
struct apk_id_cache id_cache;
|
||||
|
||||
struct {
|
||||
|
@ -158,6 +164,7 @@ typedef union apk_database_or_void {
|
|||
|
||||
struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name);
|
||||
struct apk_name *apk_db_query_name(struct apk_database *db, apk_blob_t name);
|
||||
int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag);
|
||||
struct apk_db_dir *apk_db_dir_query(struct apk_database *db,
|
||||
apk_blob_t name);
|
||||
struct apk_db_file *apk_db_file_query(struct apk_database *db,
|
||||
|
|
|
@ -59,6 +59,7 @@ struct apk_sign_ctx {
|
|||
struct apk_dependency {
|
||||
struct apk_name *name;
|
||||
apk_blob_t *version;
|
||||
unsigned short repository_tag;
|
||||
unsigned optional : 1;
|
||||
unsigned result_mask : 3;
|
||||
};
|
||||
|
@ -120,12 +121,13 @@ void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
|
|||
struct apk_package *pkg);
|
||||
int apk_dep_is_satisfied(struct apk_dependency *dep, struct apk_package *pkg);
|
||||
|
||||
void apk_blob_push_dep(apk_blob_t *to, struct apk_dependency *dep);
|
||||
void apk_blob_push_deps(apk_blob_t *to, struct apk_dependency_array *deps);
|
||||
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);
|
||||
void apk_blob_pull_dep(apk_blob_t *from, struct apk_database *, struct apk_dependency *);
|
||||
void apk_blob_pull_deps(apk_blob_t *from, struct apk_database *, struct apk_dependency_array **);
|
||||
|
||||
int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os);
|
||||
int apk_deps_write(struct apk_database *db, struct apk_dependency_array *deps,
|
||||
struct apk_ostream *os);
|
||||
|
||||
int apk_deps_add(struct apk_dependency_array **depends,
|
||||
struct apk_dependency *dep);
|
||||
|
|
|
@ -44,7 +44,9 @@ int apk_blob_spn(apk_blob_t blob, const char *accept, apk_blob_t *l, apk_blob_t
|
|||
|
||||
for (i = 0; i < blob.len; i++) {
|
||||
if (strchr(accept, blob.ptr[i]) == NULL) {
|
||||
if (l != NULL)
|
||||
*l = APK_BLOB_PTR_LEN(blob.ptr, i);
|
||||
if (r != NULL)
|
||||
*r = APK_BLOB_PTR_LEN(blob.ptr+i, blob.len-i);
|
||||
return 1;
|
||||
}
|
||||
|
@ -58,7 +60,9 @@ int apk_blob_cspn(apk_blob_t blob, const char *reject, apk_blob_t *l, apk_blob_t
|
|||
|
||||
for (i = 0; i < blob.len; i++) {
|
||||
if (strchr(reject, blob.ptr[i]) != NULL) {
|
||||
if (l != NULL)
|
||||
*l = APK_BLOB_PTR_LEN(blob.ptr, i);
|
||||
if (r != NULL)
|
||||
*r = APK_BLOB_PTR_LEN(blob.ptr+i, blob.len-i);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -713,7 +713,7 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
|||
|
||||
if (ipkg->replaces->num) {
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("r:"));
|
||||
apk_blob_push_deps(&bbuf, ipkg->replaces);
|
||||
apk_blob_push_deps(&bbuf, db, ipkg->replaces);
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
||||
}
|
||||
if (ipkg->replaces_priority) {
|
||||
|
@ -1156,6 +1156,9 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
|
|||
apk_string_array_init(&db->protected_paths);
|
||||
db->permanent = 1;
|
||||
|
||||
/* Get first repository tag (the NULL tag) */
|
||||
apk_db_get_tag_id(db, APK_BLOB_NULL);
|
||||
|
||||
if (dbopts->root && dbopts->arch) {
|
||||
db->arch = apk_blob_atomize(APK_BLOB_STR(dbopts->arch));
|
||||
} else {
|
||||
|
@ -1351,7 +1354,7 @@ int apk_db_write_config(struct apk_database *db)
|
|||
if (os == NULL)
|
||||
return -1;
|
||||
|
||||
apk_deps_write(db->world, os);
|
||||
apk_deps_write(db, db->world, os);
|
||||
os->write(os, "\n", 1);
|
||||
r = os->close(os);
|
||||
if (r < 0)
|
||||
|
@ -1443,6 +1446,25 @@ void apk_db_close(struct apk_database *db)
|
|||
}
|
||||
}
|
||||
|
||||
int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag)
|
||||
{
|
||||
apk_blob_t *b = apk_blob_atomize_dup(tag);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < db->num_repo_tags; i++) {
|
||||
if (db->repo_tags[i].name == b)
|
||||
return i;
|
||||
}
|
||||
if (i < ARRAY_SIZE(db->repo_tags)) {
|
||||
db->num_repo_tags++;
|
||||
db->repo_tags[i] = (struct apk_repository_tag) {
|
||||
.name = b
|
||||
};
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fire_triggers(apk_hash_item item, void *ctx)
|
||||
{
|
||||
struct apk_database *db = (struct apk_database *) ctx;
|
||||
|
@ -1696,30 +1718,38 @@ int apk_db_index_read_file(struct apk_database *db, const char *file, int repo)
|
|||
return load_index(db, apk_bstream_from_file(AT_FDCWD, file), targz, repo);
|
||||
}
|
||||
|
||||
int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
||||
int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository)
|
||||
{
|
||||
struct apk_database *db = _db.db;
|
||||
struct apk_bstream *bs = NULL;
|
||||
struct apk_repository *repo;
|
||||
int r, targz = 1;
|
||||
apk_blob_t brepo, btag;
|
||||
int r, targz = 1, tag_id = 0;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
if (repository.ptr == NULL || repository.len == 0 ||
|
||||
*repository.ptr == '#')
|
||||
return 0;
|
||||
|
||||
if (db->num_repos >= APK_MAX_REPOS)
|
||||
return -1;
|
||||
|
||||
r = db->num_repos++;
|
||||
brepo = _repository;
|
||||
btag = APK_BLOB_NULL;
|
||||
if (brepo.ptr == NULL || brepo.len == 0 || *brepo.ptr == '#')
|
||||
return 0;
|
||||
|
||||
if (brepo.ptr[0] == '@') {
|
||||
apk_blob_pull_char(&brepo, '@');
|
||||
apk_blob_cspn(brepo, ": ", &btag, &brepo);
|
||||
apk_blob_spn(brepo, ": ", NULL, &brepo);
|
||||
tag_id = apk_db_get_tag_id(db, btag);
|
||||
}
|
||||
|
||||
r = db->num_repos++;
|
||||
repo = &db->repos[r];
|
||||
*repo = (struct apk_repository) {
|
||||
.url = apk_blob_cstr(repository),
|
||||
.url = apk_blob_cstr(brepo),
|
||||
};
|
||||
|
||||
if (apk_url_local_file(repo->url) == NULL) {
|
||||
apk_blob_checksum(repository, apk_checksum_default(), &repo->csum);
|
||||
apk_blob_checksum(brepo, apk_checksum_default(), &repo->csum);
|
||||
|
||||
if (apk_flags & APK_UPDATE_CACHE)
|
||||
apk_repository_update(db, repo);
|
||||
|
@ -1730,6 +1760,7 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
|||
db->local_repos |= BIT(r);
|
||||
bs = apk_repo_file_open(repo, db->arch, apkindex_tar_gz, buf, sizeof(buf));
|
||||
}
|
||||
db->repo_tags[tag_id].allowed_repos |= BIT(r);
|
||||
if (bs == NULL) {
|
||||
apk_warning("%s: index failed to open", buf);
|
||||
return 0;
|
||||
|
|
34
src/info.c
34
src/info.c
|
@ -18,6 +18,7 @@
|
|||
#include "apk_print.h"
|
||||
|
||||
struct info_ctx {
|
||||
struct apk_database *db;
|
||||
int (*action)(struct info_ctx *ctx, struct apk_database *db,
|
||||
int argc, char **argv);
|
||||
int subaction_mask;
|
||||
|
@ -130,7 +131,7 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db,
|
|||
struct apk_ostream *os;
|
||||
|
||||
os = apk_ostream_to_fd(STDOUT_FILENO);
|
||||
apk_deps_write(deps, os);
|
||||
apk_deps_write(db, deps, os);
|
||||
os->write(os, "\n", 1);
|
||||
os->close(os);
|
||||
}
|
||||
|
@ -139,7 +140,7 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db,
|
|||
return r;
|
||||
}
|
||||
|
||||
static void info_print_description(struct apk_package *pkg)
|
||||
static void info_print_description(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
if (apk_verbosity > 1)
|
||||
printf("%s: %s", pkg->name->name, pkg->description);
|
||||
|
@ -149,7 +150,7 @@ static void info_print_description(struct apk_package *pkg)
|
|||
pkg->description);
|
||||
}
|
||||
|
||||
static void info_print_url(struct apk_package *pkg)
|
||||
static void info_print_url(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
if (apk_verbosity > 1)
|
||||
printf("%s: %s", pkg->name->name, pkg->url);
|
||||
|
@ -159,7 +160,7 @@ static void info_print_url(struct apk_package *pkg)
|
|||
pkg->url);
|
||||
}
|
||||
|
||||
static void info_print_size(struct apk_package *pkg)
|
||||
static void info_print_size(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
if (apk_verbosity > 1)
|
||||
printf("%s: %zu", pkg->name->name, pkg->installed_size);
|
||||
|
@ -169,7 +170,7 @@ static void info_print_size(struct apk_package *pkg)
|
|||
pkg->installed_size);
|
||||
}
|
||||
|
||||
static void info_print_depends(struct apk_package *pkg)
|
||||
static void info_print_depends(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
apk_blob_t separator = APK_BLOB_STR(apk_verbosity > 1 ? " " : "\n");
|
||||
char dep[256];
|
||||
|
@ -182,14 +183,14 @@ static void info_print_depends(struct apk_package *pkg)
|
|||
printf("%s: ", pkg->name->name);
|
||||
for (i = 0; i < pkg->depends->num; i++) {
|
||||
apk_blob_t b = APK_BLOB_BUF(dep);
|
||||
apk_blob_push_dep(&b, &pkg->depends->item[i]);
|
||||
apk_blob_push_dep(&b, db, &pkg->depends->item[i]);
|
||||
apk_blob_push_blob(&b, separator);
|
||||
b = apk_blob_pushed(APK_BLOB_BUF(dep), b);
|
||||
fwrite(b.ptr, b.len, 1, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
static void info_print_required_by(struct apk_package *pkg)
|
||||
static void info_print_required_by(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
int i, j, k;
|
||||
char *separator = apk_verbosity > 1 ? " " : "\n";
|
||||
|
@ -221,7 +222,7 @@ static void info_print_required_by(struct apk_package *pkg)
|
|||
}
|
||||
}
|
||||
|
||||
static void info_print_install_if(struct apk_package *pkg)
|
||||
static void info_print_install_if(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
apk_blob_t separator = APK_BLOB_STR(apk_verbosity > 1 ? " " : "\n");
|
||||
char dep[256];
|
||||
|
@ -234,14 +235,14 @@ static void info_print_install_if(struct apk_package *pkg)
|
|||
printf("%s: ", pkg->name->name);
|
||||
for (i = 0; i < pkg->install_if->num; i++) {
|
||||
apk_blob_t b = APK_BLOB_BUF(dep);
|
||||
apk_blob_push_dep(&b, &pkg->install_if->item[i]);
|
||||
apk_blob_push_dep(&b, db, &pkg->install_if->item[i]);
|
||||
apk_blob_push_blob(&b, separator);
|
||||
b = apk_blob_pushed(APK_BLOB_BUF(dep), b);
|
||||
fwrite(b.ptr, b.len, 1, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
static void info_print_rinstall_if(struct apk_package *pkg)
|
||||
static void info_print_rinstall_if(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
int i, j, k;
|
||||
char *separator = apk_verbosity > 1 ? " " : "\n";
|
||||
|
@ -273,7 +274,7 @@ static void info_print_rinstall_if(struct apk_package *pkg)
|
|||
}
|
||||
}
|
||||
|
||||
static void info_print_contents(struct apk_package *pkg)
|
||||
static void info_print_contents(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
struct apk_installed_package *ipkg = pkg->ipkg;
|
||||
struct apk_db_dir_instance *diri;
|
||||
|
@ -295,7 +296,7 @@ static void info_print_contents(struct apk_package *pkg)
|
|||
}
|
||||
}
|
||||
|
||||
static void info_print_triggers(struct apk_package *pkg)
|
||||
static void info_print_triggers(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
struct apk_installed_package *ipkg = pkg->ipkg;
|
||||
int i;
|
||||
|
@ -311,7 +312,7 @@ static void info_print_triggers(struct apk_package *pkg)
|
|||
}
|
||||
}
|
||||
|
||||
static void info_print_replaces(struct apk_package *pkg)
|
||||
static void info_print_replaces(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
apk_blob_t separator = APK_BLOB_STR(apk_verbosity > 1 ? " " : "\n");
|
||||
char dep[256];
|
||||
|
@ -324,7 +325,7 @@ static void info_print_replaces(struct apk_package *pkg)
|
|||
printf("%s: ", pkg->name->name);
|
||||
for (i = 0; i < pkg->ipkg->replaces->num; i++) {
|
||||
apk_blob_t b = APK_BLOB_BUF(dep);
|
||||
apk_blob_push_dep(&b, &pkg->ipkg->replaces->item[i]);
|
||||
apk_blob_push_dep(&b, db, &pkg->ipkg->replaces->item[i]);
|
||||
apk_blob_push_blob(&b, separator);
|
||||
b = apk_blob_pushed(APK_BLOB_BUF(dep), b);
|
||||
fwrite(b.ptr, b.len, 1, stdout);
|
||||
|
@ -333,7 +334,7 @@ static void info_print_replaces(struct apk_package *pkg)
|
|||
|
||||
static void info_subaction(struct info_ctx *ctx, struct apk_package *pkg)
|
||||
{
|
||||
typedef void (*subaction_t)(struct apk_package *);
|
||||
typedef void (*subaction_t)(struct apk_database *, struct apk_package *);
|
||||
static subaction_t subactions[] = {
|
||||
info_print_description,
|
||||
info_print_url,
|
||||
|
@ -358,7 +359,7 @@ static void info_subaction(struct info_ctx *ctx, struct apk_package *pkg)
|
|||
if (pkg->ipkg == NULL && (BIT(i) & requireipkg))
|
||||
continue;
|
||||
|
||||
subactions[i](pkg);
|
||||
subactions[i](ctx->db, pkg);
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
@ -437,6 +438,7 @@ static int info_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
|||
{
|
||||
struct info_ctx *ictx = (struct info_ctx *) ctx;
|
||||
|
||||
ictx->db = db;
|
||||
if (ictx->action != NULL)
|
||||
return ictx->action(ictx, db, argc, argv);
|
||||
|
||||
|
|
|
@ -194,8 +194,8 @@ struct parse_depend_ctx {
|
|||
void apk_blob_pull_dep(apk_blob_t *b, struct apk_database *db, struct apk_dependency *dep)
|
||||
{
|
||||
struct apk_name *name;
|
||||
apk_blob_t bname, bop, bver = APK_BLOB_NULL;
|
||||
int mask = APK_DEPMASK_REQUIRE, optional = 0;
|
||||
apk_blob_t bname, bop, bver = APK_BLOB_NULL, btag;
|
||||
int mask = APK_DEPMASK_REQUIRE, optional = 0, tag = 0;
|
||||
size_t len;
|
||||
|
||||
/* [!]name[<,<=,=,>=,>]ver */
|
||||
|
@ -239,6 +239,9 @@ void apk_blob_pull_dep(apk_blob_t *b, struct apk_database *db, struct apk_depend
|
|||
b->ptr += len;
|
||||
b->len -= len;
|
||||
|
||||
if (apk_blob_split(bname, APK_BLOB_STR("@"), &bname, &btag))
|
||||
tag = apk_db_get_tag_id(db, btag);
|
||||
|
||||
name = apk_db_get_name(db, bname);
|
||||
if (name == NULL)
|
||||
goto fail;
|
||||
|
@ -249,6 +252,7 @@ void apk_blob_pull_dep(apk_blob_t *b, struct apk_database *db, struct apk_depend
|
|||
*dep = (struct apk_dependency){
|
||||
.name = name,
|
||||
.version = apk_blob_atomize_dup(bver),
|
||||
.repository_tag = tag,
|
||||
.result_mask = mask,
|
||||
.optional = optional,
|
||||
};
|
||||
|
@ -325,7 +329,7 @@ void apk_blob_pull_deps(apk_blob_t *b, struct apk_database *db, struct apk_depen
|
|||
apk_blob_for_each_segment(*b, " ", parse_depend, &ctx);
|
||||
}
|
||||
|
||||
void apk_blob_push_dep(apk_blob_t *to, struct apk_dependency *dep)
|
||||
void apk_blob_push_dep(apk_blob_t *to, struct apk_database *db, struct apk_dependency *dep)
|
||||
{
|
||||
int result_mask = dep->result_mask;
|
||||
|
||||
|
@ -335,14 +339,17 @@ void apk_blob_push_dep(apk_blob_t *to, struct apk_dependency *dep)
|
|||
}
|
||||
|
||||
apk_blob_push_blob(to, APK_BLOB_STR(dep->name->name));
|
||||
|
||||
if (!APK_BLOB_IS_NULL(*dep->version)) {
|
||||
apk_blob_push_blob(to, APK_BLOB_STR(apk_version_op_string(dep->result_mask)));
|
||||
apk_blob_push_blob(to, *dep->version);
|
||||
}
|
||||
if (dep->repository_tag && db != NULL) {
|
||||
apk_blob_push_blob(to, APK_BLOB_PTR_LEN("@", 1));
|
||||
apk_blob_push_blob(to, *db->repo_tags[dep->repository_tag].name);
|
||||
}
|
||||
}
|
||||
|
||||
void apk_blob_push_deps(apk_blob_t *to, struct apk_dependency_array *deps)
|
||||
void apk_blob_push_deps(apk_blob_t *to, struct apk_database *db, struct apk_dependency_array *deps)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -352,11 +359,11 @@ void apk_blob_push_deps(apk_blob_t *to, struct apk_dependency_array *deps)
|
|||
for (i = 0; i < deps->num; i++) {
|
||||
if (i)
|
||||
apk_blob_push_blob(to, APK_BLOB_PTR_LEN(" ", 1));
|
||||
apk_blob_push_dep(to, &deps->item[i]);
|
||||
apk_blob_push_dep(to, db, &deps->item[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os)
|
||||
int apk_deps_write(struct apk_database *db, struct apk_dependency_array *deps, struct apk_ostream *os)
|
||||
{
|
||||
apk_blob_t blob;
|
||||
char tmp[256];
|
||||
|
@ -369,7 +376,7 @@ int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os)
|
|||
blob = APK_BLOB_BUF(tmp);
|
||||
if (i)
|
||||
apk_blob_push_blob(&blob, APK_BLOB_PTR_LEN(" ", 1));
|
||||
apk_blob_push_dep(&blob, &deps->item[i]);
|
||||
apk_blob_push_dep(&blob, db, &deps->item[i]);
|
||||
|
||||
blob = apk_blob_pushed(APK_BLOB_BUF(tmp), blob);
|
||||
if (APK_BLOB_IS_NULL(blob) ||
|
||||
|
@ -998,7 +1005,7 @@ static int write_depends(struct apk_ostream *os, const char *field,
|
|||
|
||||
if (os->write(os, field, 2) != 2)
|
||||
return -1;
|
||||
r = apk_deps_write(deps, os);
|
||||
r = apk_deps_write(NULL, deps, os);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (os->write(os, "\n", 1) != 1)
|
||||
|
|
39
src/solver.c
39
src/solver.c
|
@ -47,6 +47,7 @@ struct apk_name_state {
|
|||
struct list_head unsolved_list;
|
||||
struct apk_name *name;
|
||||
struct apk_package *chosen;
|
||||
unsigned int allowed_repos, preferred_repos;
|
||||
unsigned short requirers;
|
||||
unsigned short install_ifs;
|
||||
|
||||
|
@ -280,9 +281,18 @@ static void foreach_dependency(struct apk_solver_state *ss, struct apk_dependenc
|
|||
}
|
||||
|
||||
static int compare_package_preference(unsigned short solver_flags,
|
||||
unsigned int preferred_repos,
|
||||
struct apk_package *pkgA,
|
||||
struct apk_package *pkgB)
|
||||
{
|
||||
/* preferred repository pinning */
|
||||
if ((pkgA->ipkg || (pkgA->repos & preferred_repos)) &&
|
||||
!(pkgB->ipkg || (pkgB->repos & preferred_repos)))
|
||||
return 1;
|
||||
if ((pkgB->ipkg || (pkgB->repos & preferred_repos)) &&
|
||||
!(pkgA->ipkg || (pkgA->repos & preferred_repos)))
|
||||
return -1;
|
||||
|
||||
if (solver_flags & APK_SOLVERF_AVAILABLE) {
|
||||
if (pkgA->repos != 0 && pkgB->repos == 0)
|
||||
return 1;
|
||||
|
@ -320,6 +330,7 @@ static int get_preference(struct apk_solver_state *ss,
|
|||
unsigned short name_flags = ns->solver_flags_local
|
||||
| ns->solver_flags_inherited
|
||||
| ss->solver_flags;
|
||||
unsigned int preferred_repos = ns->preferred_repos | ss->db->repo_tags[0].allowed_repos;
|
||||
unsigned short preference = 0;
|
||||
int i;
|
||||
|
||||
|
@ -330,7 +341,9 @@ static int get_preference(struct apk_solver_state *ss,
|
|||
if (pkg0 == pkg || ps0 == NULL)
|
||||
continue;
|
||||
|
||||
if (compare_package_preference(name_flags, pkg, pkg0) < 0) {
|
||||
if (compare_package_preference(name_flags,
|
||||
preferred_repos,
|
||||
pkg, pkg0) < 0) {
|
||||
if (installable_only) {
|
||||
if (ss->topology_position > pkg0->topology_hard &&
|
||||
!(ps0->flags & APK_PKGSTF_DECIDED))
|
||||
|
@ -364,6 +377,7 @@ static int update_name_state(struct apk_solver_state *ss, struct apk_name *name)
|
|||
struct apk_name_state *ns = name_to_ns(name);
|
||||
struct apk_package *best_pkg = NULL;
|
||||
unsigned int best_topology = 0;
|
||||
unsigned int allowed_repos = ns->allowed_repos | ss->db->repo_tags[0].allowed_repos;
|
||||
int i, options = 0, skipped_options = 0;
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
|
@ -372,6 +386,7 @@ static int update_name_state(struct apk_solver_state *ss, struct apk_name *name)
|
|||
|
||||
if (ps0 == NULL ||
|
||||
pkg0->topology_hard >= ss->topology_position ||
|
||||
((pkg0->repos != 0) && (pkg0->ipkg == NULL) && !(pkg0->repos & allowed_repos)) ||
|
||||
(ps0->flags & APK_PKGSTF_DECIDED))
|
||||
continue;
|
||||
|
||||
|
@ -571,6 +586,7 @@ static void inherit_name_state(struct apk_name *to, struct apk_name *from)
|
|||
tns->solver_flags_inherited |=
|
||||
fns->solver_flags_inherited |
|
||||
(fns->solver_flags_local & fns->solver_flags_local_mask);
|
||||
tns->allowed_repos |= fns->allowed_repos;
|
||||
}
|
||||
|
||||
static void inherit_name_state_wrapper(struct apk_package *rdepend, void *ctx)
|
||||
|
@ -587,6 +603,8 @@ static int has_inherited_state(struct apk_name *name)
|
|||
return 0;
|
||||
if (ns->solver_flags_inherited || (ns->solver_flags_local & ns->solver_flags_local_mask))
|
||||
return 1;
|
||||
if (ns->allowed_repos)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -595,6 +613,7 @@ static void recalculate_inherted_name_state(struct apk_name *name)
|
|||
struct apk_name_state *ns = name_to_ns(name);
|
||||
|
||||
ns->solver_flags_inherited = 0;
|
||||
ns->allowed_repos = 0;
|
||||
foreach_locked_reverse_dependency(name, inherit_name_state_wrapper, name);
|
||||
}
|
||||
|
||||
|
@ -614,6 +633,16 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
|
|||
return;
|
||||
}
|
||||
|
||||
if (dep->repository_tag) {
|
||||
unsigned int allowed_repos;
|
||||
|
||||
dbg_printf("%s: enabling repository tag %d\n",
|
||||
dep->name->name, dep->repository_tag);
|
||||
allowed_repos = ss->db->repo_tags[dep->repository_tag].allowed_repos;
|
||||
ns->allowed_repos |= allowed_repos;
|
||||
ns->preferred_repos |= allowed_repos;
|
||||
}
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[i];
|
||||
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
|
||||
|
@ -1256,7 +1285,7 @@ all_done:
|
|||
return r;
|
||||
}
|
||||
|
||||
static void print_dep_errors(char *label, struct apk_dependency_array *deps)
|
||||
static void print_dep_errors(struct apk_database *db, char *label, struct apk_dependency_array *deps)
|
||||
{
|
||||
int i, print_label = 1;
|
||||
char buf[256];
|
||||
|
@ -1276,7 +1305,7 @@ static void print_dep_errors(char *label, struct apk_dependency_array *deps)
|
|||
indent.indent = indent.x + 1;
|
||||
}
|
||||
p = APK_BLOB_BUF(buf);
|
||||
apk_blob_push_dep(&p, dep);
|
||||
apk_blob_push_dep(&p, db, dep);
|
||||
p = apk_blob_pushed(APK_BLOB_BUF(buf), p);
|
||||
apk_print_indented(&indent, p);
|
||||
}
|
||||
|
@ -1298,12 +1327,12 @@ void apk_solver_print_errors(struct apk_database *db,
|
|||
pkg->name->state_ptr = pkg;
|
||||
}
|
||||
|
||||
print_dep_errors("world", world);
|
||||
print_dep_errors(db, "world", world);
|
||||
for (i = 0; i < solution->num; i++) {
|
||||
struct apk_package *pkg = solution->item[i];
|
||||
char pkgtext[256];
|
||||
snprintf(pkgtext, sizeof(pkgtext), PKG_VER_FMT, PKG_VER_PRINTF(solution->item[i]));
|
||||
print_dep_errors(pkgtext, pkg->depends);
|
||||
print_dep_errors(db, pkgtext, pkg->depends);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
19
src/test.c
19
src/test.c
|
@ -91,7 +91,7 @@ static inline void print_change(struct apk_package *oldpkg,
|
|||
}
|
||||
}
|
||||
|
||||
static void print_dep_errors(char *label, struct apk_dependency_array *deps)
|
||||
static void print_dep_errors(struct apk_database *db, char *label, struct apk_dependency_array *deps)
|
||||
{
|
||||
int i, print_label = 1;
|
||||
char buf[256];
|
||||
|
@ -110,7 +110,7 @@ static void print_dep_errors(char *label, struct apk_dependency_array *deps)
|
|||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
apk_blob_push_dep(&p, dep);
|
||||
apk_blob_push_dep(&p, db, dep);
|
||||
p = apk_blob_pushed(APK_BLOB_BUF(buf), p);
|
||||
fwrite(p.ptr, p.len, 1, stdout);
|
||||
}
|
||||
|
@ -131,12 +131,12 @@ static void print_errors_in_solution(struct apk_database *db, int unsatisfiable,
|
|||
pkg->name->state_ptr = pkg;
|
||||
}
|
||||
|
||||
print_dep_errors("world", db->world);
|
||||
print_dep_errors(db, "world", db->world);
|
||||
for (i = 0; i < solution->num; i++) {
|
||||
struct apk_package *pkg = solution->item[i];
|
||||
char pkgtext[256];
|
||||
snprintf(pkgtext, sizeof(pkgtext), PKG_VER_FMT, PKG_VER_PRINTF(solution->item[i]));
|
||||
print_dep_errors(pkgtext, pkg->depends);
|
||||
print_dep_errors(db, pkgtext, pkg->depends);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -153,6 +153,8 @@ static int test_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
if (argc != 1)
|
||||
return -EINVAL;
|
||||
|
||||
apk_db_get_tag_id(db, APK_BLOB_STR("testing"));
|
||||
|
||||
/* load installed db */
|
||||
if (ctx->installed_db != NULL) {
|
||||
bs = apk_bstream_from_file(AT_FDCWD, ctx->installed_db);
|
||||
|
@ -165,9 +167,16 @@ static int test_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
/* load additional indexes */
|
||||
if (ctx->repos) {
|
||||
for (i = 0; i < ctx->repos->num; i++) {
|
||||
bs = apk_bstream_from_file(AT_FDCWD, ctx->repos->item[i]);
|
||||
char *fn = ctx->repos->item[i];
|
||||
int repo = 0;
|
||||
if (fn[0] == '+') {
|
||||
fn++;
|
||||
repo = 1;
|
||||
}
|
||||
bs = apk_bstream_from_file(AT_FDCWD, fn);
|
||||
if (bs != NULL) {
|
||||
apk_db_index_read(db, bs, i);
|
||||
db->repo_tags[repo].allowed_repos |= BIT(i);
|
||||
bs->close(bs, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
C:Q1eVpkasfqZAukAXFYbgwt4xffZWU=
|
||||
P:a
|
||||
V:3
|
||||
S:1
|
||||
I:1
|
||||
D:b
|
||||
|
||||
C:Q1hdUpqRv5mYgJEqW52UmVsv23ysE=
|
||||
P:b
|
||||
V:3
|
||||
S:1
|
||||
I:1
|
||||
|
||||
C:Q1eVpkasfqZAukAXFYbg324xAt4WU=
|
||||
P:c
|
||||
V:3
|
||||
S:1
|
||||
I:1
|
||||
D:a>=3
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Installing b (2)
|
||||
Installing a (2)
|
|
@ -0,0 +1,2 @@
|
|||
--raw-repository basic.repo --raw-repository +pinning.repo
|
||||
a
|
|
@ -0,0 +1,2 @@
|
|||
Installing b (2)
|
||||
Installing a (3)
|
|
@ -0,0 +1,2 @@
|
|||
--raw-repository basic.repo --raw-repository +pinning.repo
|
||||
a@testing
|
|
@ -0,0 +1,2 @@
|
|||
Installing b (3)
|
||||
Installing a (3)
|
|
@ -0,0 +1,2 @@
|
|||
--raw-repository basic.repo --raw-repository +pinning.repo
|
||||
a@testing b@testing
|
|
@ -0,0 +1,3 @@
|
|||
Installing b (2)
|
||||
Installing a (3)
|
||||
Installing c (3)
|
|
@ -0,0 +1,2 @@
|
|||
--raw-repository basic.repo --raw-repository +pinning.repo
|
||||
c@testing
|
Loading…
Reference in New Issue