summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2022-05-02 11:22:43 +0300
committerTimo Teräs <timo.teras@iki.fi>2022-06-03 14:41:11 +0300
commit892425381682008463b7528bdc994fb2bf6f5c71 (patch)
treea634e471879e5df3e6a8edc61b57518ee6339882
parent1be0510c4e2dc806e5989d49884f5a626b132ec4 (diff)
downloadapk-tools-892425381682008463b7528bdc994fb2bf6f5c71.tar.gz
apk-tools-892425381682008463b7528bdc994fb2bf6f5c71.tar.bz2
apk-tools-892425381682008463b7528bdc994fb2bf6f5c71.tar.xz
apk-tools-892425381682008463b7528bdc994fb2bf6f5c71.zip
add: allow specifying a version for --virtual package
fixes #10835
-rw-r--r--doc/apk-add.8.scd4
-rw-r--r--src/app_add.c49
-rw-r--r--test/basic8.test1
3 files changed, 36 insertions, 18 deletions
diff --git a/doc/apk-add.8.scd b/doc/apk-add.8.scd
index 1586f7e..db6214e 100644
--- a/doc/apk-add.8.scd
+++ b/doc/apk-add.8.scd
@@ -42,7 +42,9 @@ following options:
*-t, --virtual* _NAME_
Create virtual package _NAME_ with given dependencies. This new package
will get the _packages_ as dependencies instead of _world_. Finally the
- _NAME_ is added to _world_.
+ _NAME_ is added to _world_. An optional version specifier for the virtual
+ package can be given via syntax _NAME_=_VERSION_. The version defaults
+ to synthesized version based on time.
One can use this to ensure that selected set of packages are installed,
and later the temporary modification be undone with *apk-del*(8) _NAME_
diff --git a/src/app_add.c b/src/app_add.c
index 1472506..dac85c9 100644
--- a/src/app_add.c
+++ b/src/app_add.c
@@ -77,32 +77,26 @@ static int non_repository_check(struct apk_database *db)
return 1;
}
-static struct apk_package *create_virtual_package(struct apk_database *db, struct apk_name *name)
+static struct apk_package *create_virtual_package(struct apk_database *db, struct apk_dependency *dep)
{
- char ver[32];
struct apk_package *virtpkg;
- struct tm tm;
EVP_MD_CTX *mdctx;
- time_t now = time(NULL);
pid_t pid = getpid();
- gmtime_r(&now, &tm);
- strftime(ver, sizeof ver, "%Y%m%d.%H%M%S", &tm);
-
virtpkg = apk_pkg_new();
if (virtpkg == NULL) return 0;
- virtpkg->name = name;
- virtpkg->version = apk_atomize_dup(&db->atoms, APK_BLOB_STR(ver));
+ virtpkg->name = dep->name;
+ virtpkg->version = dep->version;
virtpkg->description = strdup("virtual meta package");
virtpkg->arch = apk_atomize(&db->atoms, APK_BLOB_STR("noarch"));
virtpkg->repos |= BIT(APK_REPOSITORY_CACHED);
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, apk_checksum_default(), NULL);
- EVP_DigestUpdate(mdctx, &tm, sizeof tm);
EVP_DigestUpdate(mdctx, &pid, sizeof pid);
EVP_DigestUpdate(mdctx, virtpkg->name->name, strlen(virtpkg->name->name) + 1);
+ EVP_DigestUpdate(mdctx, dep->version->ptr, dep->version->len);
virtpkg->csum.type = EVP_MD_CTX_size(mdctx);
EVP_DigestFinal_ex(mdctx, virtpkg->csum.data, NULL);
EVP_MD_CTX_free(mdctx);
@@ -110,6 +104,17 @@ static struct apk_package *create_virtual_package(struct apk_database *db, struc
return virtpkg;
}
+static apk_blob_t *generate_version(struct apk_database *db)
+{
+ char ver[32];
+ struct tm tm;
+ time_t now = time(NULL);
+
+ gmtime_r(&now, &tm);
+ strftime(ver, sizeof ver, "%Y%m%d.%H%M%S", &tm);
+ return apk_atomize_dup(&db->atoms, APK_BLOB_STR(ver));
+}
+
static int add_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
struct add_ctx *actx = (struct add_ctx *) ctx;
@@ -127,23 +132,33 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array
if (actx->virtpkg) {
apk_blob_t b = APK_BLOB_STR(actx->virtpkg);
apk_blob_pull_dep(&b, db, &virtdep);
+
if (APK_BLOB_IS_NULL(b) || virtdep.conflict ||
- virtdep.result_mask != APK_DEPMASK_ANY ||
- virtdep.version != &apk_atom_null) {
+ (virtdep.name->name[0] != '.' && non_repository_check(db)))
+ goto bad_spec;
+
+ switch (virtdep.result_mask) {
+ case APK_DEPMASK_ANY:
+ if (virtdep.version != &apk_atom_null) goto bad_spec;
+ virtdep.result_mask = APK_VERSION_EQUAL;
+ virtdep.version = generate_version(db);
+ break;
+ case APK_VERSION_EQUAL:
+ if (virtdep.version == &apk_atom_null) goto bad_spec;
+ break;
+ default:
+ bad_spec:
apk_error("%s: bad package specifier", actx->virtpkg);
return -1;
}
- if (virtdep.name->name[0] != '.' && non_repository_check(db))
- return -1;
- virtpkg = create_virtual_package(db, virtdep.name);
+ virtpkg = create_virtual_package(db, &virtdep);
if (!virtpkg) {
apk_error("Failed to allocate virtual meta package");
return -1;
}
- virtdep.result_mask = APK_VERSION_EQUAL;
- virtdep.version = virtpkg->version;
+ if (!args->num) apk_warning("creating empty virtual package");
}
foreach_array_item(parg, args) {
diff --git a/test/basic8.test b/test/basic8.test
index 19d3964..0042371 100644
--- a/test/basic8.test
+++ b/test/basic8.test
@@ -2,5 +2,6 @@
--no-network
add -t .virtual
@EXPECT
+WARNING: creating empty virtual package
(1/1) Installing .virtual (20190603.131426)
OK: 0 MiB in 0 packages