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.cute-signatures
parent
6db3bbd790
commit
b91f9406da
38
src/add.c
38
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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
int 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue