summaryrefslogtreecommitdiff
path: root/src/database.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2011-10-29 05:18:21 +0300
committerTimo Teräs <timo.teras@iki.fi>2011-10-29 05:18:21 +0300
commit500f8d4a7d7b17871647392e79e4c7a17c210534 (patch)
tree47d4b1cd04e374d88e26e352eeac9f51da083451 /src/database.c
parente682e6596c101d634b3780a98773c8433b3baadb (diff)
downloadapk-tools-500f8d4a7d7b17871647392e79e4c7a17c210534.tar.gz
apk-tools-500f8d4a7d7b17871647392e79e4c7a17c210534.tar.bz2
apk-tools-500f8d4a7d7b17871647392e79e4c7a17c210534.tar.xz
apk-tools-500f8d4a7d7b17871647392e79e4c7a17c210534.zip
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
Diffstat (limited to 'src/database.c')
-rw-r--r--src/database.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/src/database.c b/src/database.c
index 482f406..8eaba6c 100644
--- a/src/database.c
+++ b/src/database.c
@@ -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;