summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2023-04-12 09:43:22 +0300
committerTimo Teräs <timo.teras@iki.fi>2023-04-12 10:09:33 +0300
commitf184a4a2425a6c81548ae2ec9576472f44201fff (patch)
tree7f96473e35c5f5c852c81443648f33d3948d0330
parent20e30a3dc66c5e7289991705fbe88a4672b54936 (diff)
downloadapk-tools-f184a4a2425a6c81548ae2ec9576472f44201fff.tar.gz
apk-tools-f184a4a2425a6c81548ae2ec9576472f44201fff.tar.bz2
apk-tools-f184a4a2425a6c81548ae2ec9576472f44201fff.tar.xz
apk-tools-f184a4a2425a6c81548ae2ec9576472f44201fff.zip
index: implement --merge and --prune-origin
fixes #10886
-rw-r--r--doc/apk-index.8.scd7
-rw-r--r--src/app_index.c54
2 files changed, 52 insertions, 9 deletions
diff --git a/doc/apk-index.8.scd b/doc/apk-index.8.scd
index 82a6a48..bb54f65 100644
--- a/doc/apk-index.8.scd
+++ b/doc/apk-index.8.scd
@@ -23,9 +23,16 @@ will accept it. See *abuild-sign*(1) for details.
information based on the git commit SHA of aports HEAD at the time of
index generation.
+*--merge*
+ Merge _packages_ into the existing _INDEX_.
+
*-o, --output* _FILE_
Output generated index to _FILE_.
+*--prune-origin*
+ Prune packages from the existing _INDEX_ with same origin as any of
+ the new _packages_ during merge.
+
*-x, --index* _INDEX_
Read an existing index from _INDEX_ to speed up the creation of the new
index by reusing data when possible.
diff --git a/src/app_index.c b/src/app_index.c
index 56fbe7c..4a5a7d3 100644
--- a/src/app_index.c
+++ b/src/app_index.c
@@ -17,7 +17,9 @@
#include "apk_database.h"
#include "apk_print.h"
-#define APK_INDEXF_NO_WARNINGS 0x0001
+#define APK_INDEXF_NO_WARNINGS BIT(0)
+#define APK_INDEXF_MERGE BIT(1)
+#define APK_INDEXF_PRUNE_ORIGIN BIT(2)
struct counts {
struct apk_indent indent;
@@ -38,8 +40,10 @@ struct index_ctx {
#define INDEX_OPTIONS(OPT) \
OPT(OPT_INDEX_description, APK_OPT_ARG APK_OPT_SH("d") "description") \
OPT(OPT_INDEX_index, APK_OPT_ARG APK_OPT_SH("x") "index") \
+ OPT(OPT_INDEX_merge, "merge") \
OPT(OPT_INDEX_no_warnings, "no-warnings") \
OPT(OPT_INDEX_output, APK_OPT_ARG APK_OPT_SH("o") "output") \
+ OPT(OPT_INDEX_prune_origin, "prune-origin") \
OPT(OPT_INDEX_rewrite_arch, APK_OPT_ARG "rewrite-arch")
APK_OPT_APPLET(option_desc, INDEX_OPTIONS);
@@ -55,9 +59,15 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt
case OPT_INDEX_index:
ictx->index = optarg;
break;
+ case OPT_INDEX_merge:
+ ictx->index_flags |= APK_INDEXF_MERGE;
+ break;
case OPT_INDEX_output:
ictx->output = optarg;
break;
+ case OPT_INDEX_prune_origin:
+ ictx->index_flags |= APK_INDEXF_PRUNE_ORIGIN;
+ break;
case OPT_INDEX_rewrite_arch:
ictx->rewrite_arch = optarg;
break;
@@ -78,22 +88,42 @@ static const struct apk_option_group optgroup_applet = {
struct index_writer {
struct apk_ostream *os;
int count;
+ unsigned short index_flags;
};
+static int mark_origin(struct apk_database *db, struct apk_package *pkg, int mark)
+{
+ struct apk_name *n;
+ if (pkg->origin == NULL) return 0;
+ n = apk_db_get_name(db, *pkg->origin);
+ n->state_int |= mark;
+ return n->state_int;
+}
+
static int index_write_entry(struct apk_database *db, const char *match, struct apk_package *pkg, void *ctx)
{
struct index_writer *iw = ctx;
- if (!pkg->filename) return 0;
+ switch (iw->index_flags & (APK_INDEXF_MERGE|APK_INDEXF_PRUNE_ORIGIN)) {
+ case APK_INDEXF_MERGE:
+ break;
+ case APK_INDEXF_MERGE|APK_INDEXF_PRUNE_ORIGIN:
+ if (mark_origin(db, pkg, 0) && !pkg->marked) return 0;
+ break;
+ default:
+ if (!pkg->marked) return 0;
+ break;
+ }
iw->count++;
apk_pkg_write_index_entry(pkg, iw->os);
return 0;
}
-static int index_write(struct apk_database *db, struct apk_ostream *os)
+static int index_write(struct index_ctx *ictx, struct apk_database *db, struct apk_ostream *os)
{
struct index_writer iw = {
+ .index_flags = ictx->index_flags,
.os = os,
};
@@ -131,6 +161,13 @@ static int warn_if_no_providers(struct apk_database *db, const char *match, stru
return 0;
}
+static void index_mark_package(struct apk_database *db, struct apk_package *pkg, apk_blob_t *rewrite_arch)
+{
+ if (rewrite_arch) pkg->arch = rewrite_arch;
+ pkg->marked = 1;
+ mark_origin(db, pkg, 1);
+}
+
static int index_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
struct counts counts = { .unsatisfied=0 };
@@ -200,8 +237,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
if (pkg->name != name) continue;
if (apk_blob_compare(bver, *pkg->version) != 0) continue;
if (pkg->size != fi.size) continue;
- pkg->filename = strdup(*parg);
- if (rewrite_arch) pkg->arch = rewrite_arch;
+ index_mark_package(db, pkg, rewrite_arch);
found = TRUE;
break;
}
@@ -215,8 +251,8 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
apk_error("%s: %s", *parg, apk_error_str(r));
errors++;
} else {
+ index_mark_package(db, pkg, rewrite_arch);
newpkgs++;
- if (rewrite_arch) pkg->arch = rewrite_arch;
}
apk_sign_ctx_free(&sctx);
}
@@ -235,7 +271,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
fi.mode = 0644 | S_IFREG;
fi.name = "APKINDEX";
counter = apk_ostream_counter(&fi.size);
- r = index_write(db, counter);
+ r = index_write(ictx, db, counter);
apk_ostream_close(counter);
if (r >= 0) {
@@ -250,13 +286,13 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
}
apk_tar_write_entry(os, &fi, NULL);
- r = index_write(db, os);
+ r = index_write(ictx, db, os);
apk_tar_write_padding(os, &fi);
apk_tar_write_entry(os, NULL, NULL);
}
} else {
- r = index_write(db, os);
+ r = index_write(ictx, db, os);
}
apk_ostream_close(os);