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 #575
cute-signatures
Timo Teräs 2011-10-29 05:18:21 +03:00
parent e682e6596c
commit 500f8d4a7d
17 changed files with 182 additions and 54 deletions

View File

@ -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,

View File

@ -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);

View File

@ -44,8 +44,10 @@ 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) {
*l = APK_BLOB_PTR_LEN(blob.ptr, i);
*r = APK_BLOB_PTR_LEN(blob.ptr+i, blob.len-i);
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,8 +60,10 @@ 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) {
*l = APK_BLOB_PTR_LEN(blob.ptr, i);
*r = APK_BLOB_PTR_LEN(blob.ptr+i, blob.len-i);
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;
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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);
}
}

20
test/pinning.repo Normal file
View File

@ -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

2
test/pinning1.expect Normal file
View File

@ -0,0 +1,2 @@
Installing b (2)
Installing a (2)

2
test/pinning1.test Normal file
View File

@ -0,0 +1,2 @@
--raw-repository basic.repo --raw-repository +pinning.repo
a

2
test/pinning2.expect Normal file
View File

@ -0,0 +1,2 @@
Installing b (2)
Installing a (3)

2
test/pinning2.test Normal file
View File

@ -0,0 +1,2 @@
--raw-repository basic.repo --raw-repository +pinning.repo
a@testing

2
test/pinning3.expect Normal file
View File

@ -0,0 +1,2 @@
Installing b (3)
Installing a (3)

2
test/pinning3.test Normal file
View File

@ -0,0 +1,2 @@
--raw-repository basic.repo --raw-repository +pinning.repo
a@testing b@testing

3
test/pinning4.expect Normal file
View File

@ -0,0 +1,3 @@
Installing b (2)
Installing a (3)
Installing c (3)

2
test/pinning4.test Normal file
View File

@ -0,0 +1,2 @@
--raw-repository basic.repo --raw-repository +pinning.repo
c@testing