summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2009-05-14 12:01:09 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2009-05-14 12:01:09 +0000
commitb91f9406dacb8585dd2f50548f72a36f378f5933 (patch)
tree85625267da7ee951c3ffd542783dfd0e4c08d244
parent6db3bbd790954ce2db241fd68f4b10e34c442893 (diff)
downloadapk-tools-b91f9406dacb8585dd2f50548f72a36f378f5933.tar.bz2
apk-tools-b91f9406dacb8585dd2f50548f72a36f378f5933.tar.xz
add: support for virtual meta packages
implements 'apk add --virutal metaname dep1 dep2...' where metaname will be an empy meta package with dep1 and dep2 as dependencies. This is useful to prevent abuild to add each makedepend to world which causes some headache when it comes to unintalling them after sucessful build.
-rw-r--r--src/add.c38
-rw-r--r--src/apk_database.h2
-rw-r--r--src/database.c81
3 files changed, 85 insertions, 36 deletions
diff --git a/src/add.c b/src/add.c
index cf518af..da83fe0 100644
--- a/src/add.c
+++ b/src/add.c
@@ -17,6 +17,7 @@
struct add_ctx {
unsigned int open_flags;
+ const char *virtpkg;
};
static int add_parse(void *ctx, int optch, int optindex, const char *optarg)
@@ -30,6 +31,9 @@ static int add_parse(void *ctx, int optch, int optindex, const char *optarg)
case 'u':
apk_flags |= APK_UPGRADE;
break;
+ case 't':
+ actx->virtpkg = optarg;
+ break;
default:
return -1;
}
@@ -41,12 +45,33 @@ static int add_main(void *ctx, int argc, char **argv)
struct add_ctx *actx = (struct add_ctx *) ctx;
struct apk_database db;
struct apk_state *state = NULL;
- struct apk_dependency_array *pkgs = NULL; /* list of pkgs to install */
+ struct apk_dependency_array *pkgs = NULL;
+ struct apk_package *virtpkg = NULL;
int i, r;
r = apk_db_open(&db, apk_root, actx->open_flags | APK_OPENF_WRITE);
if (r != 0)
return r;
+
+ if (actx->virtpkg) {
+ struct apk_dependency dep;
+ virtpkg = apk_pkg_new();
+ if (virtpkg == NULL) {
+ apk_error("Failed to allocate virtual meta package");
+ goto err;
+ }
+ virtpkg->name = apk_db_get_name(&db, APK_BLOB_STR(actx->virtpkg));
+ virtpkg->version = strdup("0");
+ virtpkg->description = strdup("virtual meta package");
+ dep = (struct apk_dependency) {
+ .name = virtpkg->name,
+ .version = virtpkg->version,
+ .result_mask = APK_VERSION_EQUAL,
+ };
+ dep.name->flags |= APK_NAME_TOPLEVEL | APK_NAME_VIRTUAL;
+ virtpkg = apk_db_pkg_add(&db, virtpkg);
+ apk_deps_add(&pkgs, &dep);
+ }
for (i = 0; i < argc; i++) {
struct apk_dependency dep;
@@ -71,8 +96,12 @@ static int add_main(void *ctx, int argc, char **argv)
.result_mask = APK_DEPMASK_REQUIRE,
};
}
- dep.name->flags |= APK_NAME_TOPLEVEL;
- apk_deps_add(&pkgs, &dep);
+ if (virtpkg) {
+ apk_deps_add(&virtpkg->depends, &dep);
+ } else {
+ dep.name->flags |= APK_NAME_TOPLEVEL;
+ apk_deps_add(&pkgs, &dep);
+ }
}
state = apk_state_new(&db);
@@ -95,11 +124,12 @@ err:
static struct option add_options[] = {
{ "initdb", no_argument, NULL, 0x10000 },
{ "upgrade", no_argument, NULL, 'u' },
+ { "virtual", required_argument, NULL, 't' },
};
static struct apk_applet apk_add = {
.name = "add",
- .usage = "[--initdb] [--upgrade|-u] apkname...",
+ .usage = "[--initdb] [--upgrade|-u] [--virtual metaname] apkname...",
.context_size = sizeof(struct add_ctx),
.num_options = ARRAY_SIZE(add_options),
.options = add_options,
diff --git a/src/apk_database.h b/src/apk_database.h
index 0a0e52d..523dab5 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -55,6 +55,7 @@ struct apk_db_dir_instance {
};
#define APK_NAME_TOPLEVEL 0x0001
+#define APK_NAME_VIRTUAL 0x0002
struct apk_name {
apk_hash_node hash_node;
@@ -120,6 +121,7 @@ int apk_db_write_config(struct apk_database *db);
void apk_db_close(struct apk_database *db);
struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file);
+struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg);
struct apk_package *apk_db_get_pkg(struct apk_database *db, csum_t sum);
struct apk_package *apk_db_get_file_owner(struct apk_database *db, apk_blob_t filename);
diff --git a/src/database.c b/src/database.c
index e91c64a..32ee3bd 100644
--- a/src/database.c
+++ b/src/database.c
@@ -349,7 +349,7 @@ static void apk_db_pkg_rdepends(struct apk_database *db, struct apk_package *pkg
}
}
-static struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg)
+struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg)
{
struct apk_package *idb;
@@ -1229,35 +1229,16 @@ static void apk_db_purge_pkg(struct apk_database *db,
apk_pkg_set_state(db, pkg, APK_PKG_NOT_INSTALLED);
}
-int apk_db_install_pkg(struct apk_database *db,
- struct apk_package *oldpkg,
- struct apk_package *newpkg,
- apk_progress_cb cb, void *cb_ctx)
+static int apk_db_unpack_pkg(struct apk_database *db,
+ struct apk_package *newpkg,
+ int upgrade, csum_t csum,
+ apk_progress_cb cb, void *cb_ctx)
{
- struct apk_bstream *bs;
struct install_ctx ctx;
- csum_t csum;
+ struct apk_bstream *bs;
char file[256];
- int r, i;
-
- if (fchdir(db->root_fd) < 0)
- return errno;
-
- /* Just purging? */
- if (oldpkg != NULL && newpkg == NULL) {
- r = apk_pkg_run_script(oldpkg, db->root_fd,
- APK_SCRIPT_PRE_DEINSTALL);
- if (r != 0)
- return r;
-
- apk_db_purge_pkg(db, oldpkg);
-
- r = apk_pkg_run_script(oldpkg, db->root_fd,
- APK_SCRIPT_POST_DEINSTALL);
- return r;
- }
+ int i;
- /* Install the new stuff */
if (newpkg->filename == NULL) {
for (i = 0; i < APK_MAX_REPOS; i++)
if (newpkg->repos & BIT(i))
@@ -1285,8 +1266,8 @@ int apk_db_install_pkg(struct apk_database *db,
ctx = (struct install_ctx) {
.db = db,
.pkg = newpkg,
- .script = (oldpkg == NULL) ?
- APK_SCRIPT_PRE_INSTALL : APK_SCRIPT_PRE_UPGRADE,
+ .script = upgrade ?
+ APK_SCRIPT_PRE_UPGRADE : APK_SCRIPT_PRE_INSTALL,
.cb = cb,
.cb_ctx = cb_ctx,
};
@@ -1294,10 +1275,49 @@ int apk_db_install_pkg(struct apk_database *db,
goto err_close;
bs->close(bs, csum, NULL);
+ return 0;
+err_close:
+ bs->close(bs, NULL, NULL);
+ return -1;
+}
+
+int apk_db_install_pkg(struct apk_database *db,
+ struct apk_package *oldpkg,
+ struct apk_package *newpkg,
+ apk_progress_cb cb, void *cb_ctx)
+{
+ csum_t csum;
+ int r;
+
+ if (fchdir(db->root_fd) < 0)
+ return errno;
+
+ /* Just purging? */
+ if (oldpkg != NULL && newpkg == NULL) {
+ r = apk_pkg_run_script(oldpkg, db->root_fd,
+ APK_SCRIPT_PRE_DEINSTALL);
+ if (r != 0)
+ return r;
+
+ apk_db_purge_pkg(db, oldpkg);
+
+ r = apk_pkg_run_script(oldpkg, db->root_fd,
+ APK_SCRIPT_POST_DEINSTALL);
+ return r;
+ }
+
+ /* Install the new stuff */
+ if (!(newpkg->name->flags & APK_NAME_VIRTUAL)) {
+ r = apk_db_unpack_pkg(db, newpkg, (oldpkg == NULL), csum,
+ cb, cb_ctx);
+ if (r != 0)
+ return r;
+ }
apk_pkg_set_state(db, newpkg, APK_PKG_INSTALLED);
- if (memcmp(csum, newpkg->csum, sizeof(csum)) != 0)
+ if (!(newpkg->name->flags & APK_NAME_VIRTUAL) &&
+ memcmp(csum, newpkg->csum, sizeof(csum)) != 0)
apk_warning("%s-%s: checksum does not match",
newpkg->name->name, newpkg->version);
@@ -1312,7 +1332,4 @@ int apk_db_install_pkg(struct apk_database *db,
newpkg->name->name, newpkg->version);
}
return r;
-err_close:
- bs->close(bs, NULL, NULL);
- return -1;
}