Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Really basic upgrade support
Baptiste Daroussin committed 14 years ago
commit 3a66d66c10cbcb61eeb3a8ee2890bf7927e7b5e5
parent b74d514
9 files changed +162 -32
modified libpkg/Makefile
@@ -20,6 +20,7 @@ SRCS= pkg.c \
		pkg_repo.c \
		pkg_create_repo.c \
		pkg_util.c \
+
		pkg_upgrade.c \
		pkg_version.c \
		pkgdb.c \
		dump.c \
modified libpkg/pkg.h
@@ -134,7 +134,8 @@ typedef enum _pkg_script_t {

typedef enum _pkg_jobs_t {
	PKG_JOBS_INSTALL,
-
	PKG_JOBS_DEINSTALL
+
	PKG_JOBS_DEINSTALL,
+
	PKG_JOBS_UPGRADE
} pkg_jobs_t;

/**
@@ -593,6 +594,7 @@ int pkgdb_compact(struct pkgdb *db);
 * @return An error code.
 */
int pkg_add(struct pkgdb *db, const char *path);
+
int pkg_add2(struct pkgdb *db, const char *path, int upgrade);

/**
 * Allocate a new pkg_jobs.
@@ -649,6 +651,9 @@ int pkg_create_fakeroot(const char *, pkg_formats, const char *, const char *);
 * @return An error code.
 */
int pkg_delete(struct pkg *pkg, struct pkgdb *db, int force);
+
int pkg_delete2(struct pkg *pkg, struct pkgdb *db, int force, int upgrade);
+

+
int pkg_upgrade(struct pkgdb *db, struct pkg *pkg, const char *path);

int pkg_repo_fetch(struct pkg *pkg);

@@ -696,6 +701,8 @@ typedef enum {
	PKG_EVENT_INSTALL_FINISHED,
	PKG_EVENT_DEINSTALL_BEGIN,
	PKG_EVENT_DEINSTALL_FINISHED,
+
	PKG_EVENT_UPGRADE_BEGIN,
+
	PKG_EVENT_UPGRADE_FINISHED,
	PKG_EVENT_FETCHING,
	/* errors */
	PKG_EVENT_ERROR,
@@ -740,6 +747,12 @@ struct pkg_event {
		} e_install_finished;
		struct {
			struct pkg *pkg;
+
		} e_upgrade_begin;
+
		struct {
+
			struct pkg *pkg;
+
		} e_upgrade_finished;
+
		struct {
+
			struct pkg *pkg;
		} e_install_end;
		struct {
			struct pkg *pkg;
modified libpkg/pkg_add.c
@@ -82,6 +82,12 @@ do_extract(struct archive *a, struct archive_entry *ae)
int
pkg_add(struct pkgdb *db, const char *path)
{
+
	return (pkg_add2(db, path, false));
+
}
+

+
int
+
pkg_add2(struct pkgdb *db, const char *path, int upgrade)
+
{
	struct archive *a;
	struct archive_entry *ae;
	struct pkgdb_it *it;
@@ -188,12 +194,14 @@ pkg_add(struct pkgdb *db, const char *path)
	if (retcode != EPKG_OK || pkgdb_has_flag(db, PKGDB_FLAG_IN_FLIGHT) == 0)
		goto cleanup_reg;

-
	EMIT_INSTALL_BEGIN(pkg);
+
	if (!upgrade)
+
		EMIT_INSTALL_BEGIN(pkg);

	/*
	 * Execute pre-install scripts
	 */
-
	pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);
+
	if (!upgrade)
+
		pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);

	/*
	 * Extract the files on disk.
@@ -208,9 +216,15 @@ pkg_add(struct pkgdb *db, const char *path)
	/*
	 * Execute post install scripts
	 */
-
	pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
-

-
	EMIT_INSTALL_FINISHED(pkg);
+
	if (upgrade)
+
		pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE);
+
	else
+
		pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
+

+
	if (upgrade)
+
		EMIT_UPGRADE_FINISHED(pkg);
+
	else
+
		EMIT_INSTALL_FINISHED(pkg);

	cleanup_reg:
	pkgdb_register_finale(db, retcode);
modified libpkg/pkg_delete.c
@@ -15,6 +15,12 @@
int
pkg_delete(struct pkg *pkg, struct pkgdb *db, int force)
{
+
	return (pkg_delete2(pkg, db, force, 0));
+
}
+

+
int
+
pkg_delete2(struct pkg *pkg, struct pkgdb *db, int force, int upgrade)
+
{
	struct pkg_dep *rdep = NULL;
	int ret;

@@ -41,7 +47,11 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int force)
	if ((ret = pkgdb_loadmtree(db, pkg)) != EPKG_OK)
		return (ret);

-
	EMIT_DEINSTALL_BEGIN(pkg);
+
	if (!upgrade)
+
		EMIT_DEINSTALL_BEGIN(pkg);
+
	else
+
		EMIT_UPGRADE_BEGIN(pkg);
+

	/* If there are dependencies */
	if (pkg_rdeps(pkg, &rdep) == EPKG_OK) {
		EMIT_REQUIRED(pkg, force);
@@ -49,19 +59,26 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int force)
			return (EPKG_REQUIRED);
	}

-
	if ((ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_DEINSTALL)) != EPKG_OK)
-
		return (ret);
+
	if (upgrade) {
+
		if (( ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_UPGRADE)) != EPKG_OK )
+
			return (ret);
+
	} else {
+
		if ((ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_DEINSTALL)) != EPKG_OK)
+
			return (ret);
+
	}

	if ((ret = pkg_delete_files(pkg, force)) != EPKG_OK)
		return (ret);

-
	if ((ret = pkg_script_run(pkg, PKG_SCRIPT_POST_DEINSTALL)) != EPKG_OK)
-
		return (ret);
+
	if (!upgrade)
+
		if ((ret = pkg_script_run(pkg, PKG_SCRIPT_POST_DEINSTALL)) != EPKG_OK)
+
			return (ret);

	if ((ret = pkg_delete_dirs(db, pkg, force)) != EPKG_OK)
		return (ret);

-
	EMIT_DEINSTALL_FINISHED(pkg);
+
	if (!upgrade)
+
		EMIT_DEINSTALL_FINISHED(pkg);

	return (pkgdb_unregister_pkg(db, pkg_get(pkg, PKG_ORIGIN)));
}
modified libpkg/pkg_event.h
@@ -72,6 +72,20 @@
	_EV_EMIT; \
	_EV_END

+
#define EMIT_UPGRADE_BEGIN(p) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_UPGRADE_BEGIN; \
+
	ev.e_upgrade_begin.pkg = p; \
+
	_EV_EMIT; \
+
	_EV_END
+

+
#define EMIT_UPGRADE_FINISHED(p) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_UPGRADE_FINISHED; \
+
	ev.e_upgrade_finished.pkg = p; \
+
	_EV_EMIT; \
+
	_EV_END
+

#define EMIT_MISSING_DEP(p, d) \
	_EV_START; \
	ev.type = PKG_EVENT_MISSING_DEP; \
modified libpkg/pkg_jobs.c
@@ -100,6 +100,41 @@ pkg_jobs_install(struct pkg_jobs *j)
}

static int
+
pkg_jobs_upgrade(struct pkg_jobs *j)
+
{
+
	struct pkg *p = NULL;
+
	struct pkg *oldpkg = NULL;
+
	struct pkgdb_it *it;
+
	const char *cachedir;
+
	char path[MAXPATHLEN];
+
	int retcode;
+

+
	/* Fetch */
+
	while (pkg_jobs(j, &p) == EPKG_OK) {
+
		if (pkg_repo_fetch(p) != EPKG_OK)
+
			return (EPKG_FATAL);
+
	}
+

+
	cachedir = pkg_config("PKG_CACHEDIR");
+
	p = NULL;
+
	while (pkg_jobs(j, &p) == EPKG_OK) {
+
		/* get the installed pkg */
+
		it = pkgdb_query(j->db, pkg_get(p, PKG_ORIGIN), MATCH_EXACT);
+
		pkgdb_it_next(it, &oldpkg, PKG_LOAD_BASIC);
+
		snprintf(path, sizeof(path), "%s/%s", cachedir,
+
				pkg_get(p, PKG_REPOPATH));
+

+
		retcode = pkg_upgrade(j->db, oldpkg, path);
+
		if (retcode != EPKG_OK)
+
			return (retcode);
+
	}
+

+
	pkgdb_it_free(it);
+
	pkg_free(oldpkg);
+
	return (EPKG_OK);
+
}
+

+
static int
pkg_jobs_deinstall(struct pkg_jobs *j, int force)
{
	struct pkg *p = NULL;
@@ -121,6 +156,8 @@ pkg_jobs_apply(struct pkg_jobs *j, int force)
		return (pkg_jobs_install(j));
	if (j->type == PKG_JOBS_DEINSTALL)
		return (pkg_jobs_deinstall(j, force));
+
	if (j->type == PKG_JOBS_UPGRADE)
+
		return (pkg_jobs_upgrade(j));

	EMIT_PKG_ERROR("%s", "bad jobs argument");
	return (EPKG_FATAL);
added libpkg/pkg_upgrade.c
@@ -0,0 +1,16 @@
+
#include "pkg.h"
+
#include "pkg_event.h"
+
#include "pkg_private.h"
+

+
int
+
pkg_upgrade(struct pkgdb *db, struct pkg *pkg, const char *path)
+
{
+
	int ret;
+

+
	if ((ret = pkg_delete2(pkg, db, 1, 0)) != EPKG_OK)
+
		return (ret);
+
	if ((ret = pkg_add2(db, path, 0)) != EPKG_OK)
+
		return (ret);
+

+
	return (EPKG_OK);
+
}
modified pkg/event.c
@@ -44,6 +44,12 @@ event_callback(void *data __unused, struct pkg_event *ev)
	case PKG_EVENT_DEINSTALL_FINISHED:
		printf(" done\n");
		break;
+
	case PKG_EVENT_UPGRADE_BEGIN:
+
		printf("Upgrading %s from %s to %s...",
+
				pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME),
+
				pkg_get(ev->e_upgrade_finished.pkg, PKG_VERSION),
+
				pkg_get(ev->e_upgrade_finished.pkg, PKG_NEWVERSION));
+
		break;
	case PKG_EVENT_REQUIRED:
		pkg = ev->e_required.pkg;
		fprintf(stderr, "%s-%s is required by:", pkg_get(pkg, PKG_NAME),
modified pkg/upgrade.c
@@ -13,11 +13,12 @@
#include <pkg.h>

#include "upgrade.h"
+
#include "utils.h"

void
usage_upgrade(void)
{
-
	fprintf(stderr, "usage pkg upgrade\n\n");
+
	fprintf(stderr, "usage pkg upgrade [-y]\n");
	fprintf(stderr, "For more information see 'pkg help upgrade'.\n");
}

@@ -27,13 +28,15 @@ exec_upgrade(int argc, char **argv)
	struct pkgdb *db = NULL;
	struct pkgdb_it *it;
	struct pkg *pkg = NULL;
+
	struct pkg_jobs *jobs = NULL;
	int retcode = EPKG_OK;
	int64_t oldsize = 0, newsize = 0;
	int64_t dlsize = 0;
	char size[7];
+
	int ch, yes = 0;

	(void) argv;
-
	if (argc != 1) {
+
	if (argc < 2) {
		usage_upgrade();
		return (EX_USAGE);
	}
@@ -43,53 +46,62 @@ exec_upgrade(int argc, char **argv)
		return (EX_NOPERM);
	}

+
	while ((ch = getopt(argc, argv, "y")) != -1) {
+
		switch (ch) {
+
			case 'y':
+
				yes = 1;
+
				break;
+
			default:
+
				break;
+
		}
+
	}
+
	argc -= optind;
+
	argv += optind;
+

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
		return (EX_IOERR);
	}

-
	if ((it = pkgdb_query_upgrades(db)) == NULL) {
+
	if (pkg_jobs_new(&jobs, PKG_JOBS_UPGRADE, db) != EPKG_OK) {
		retcode = EPKG_FATAL;
		goto cleanup;
	}

-
	printf("Packages to be upgraded: \n");
-
	while ((retcode = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
-
		oldsize += pkg_flatsize(pkg);
-
		newsize += pkg_new_flatsize(pkg);
-
		dlsize += pkg_new_pkgsize(pkg);
-
		printf("\t%s: %s -> %s\n", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION), pkg_get(pkg,PKG_NEWVERSION));
-
	}
-
	printf("\n");
-
	pkgdb_it_free(it);
-

-
	if ((it = pkgdb_query_downgrades(db)) == NULL) {
+
	if ((it = pkgdb_query_upgrades(db)) == NULL) {
		retcode = EPKG_FATAL;
		goto cleanup;
	}

-
	printf("Packages to be downgraded: \n");
+
	printf("The following packages will be upgraded: \n");
	while ((retcode = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
+
		pkg_jobs_add(jobs, pkgdb_query_remote(db, pkg_get(pkg, PKG_ORIGIN)));
		oldsize += pkg_flatsize(pkg);
		newsize += pkg_new_flatsize(pkg);
		dlsize += pkg_new_pkgsize(pkg);
-
		printf("\t%s: %s -> %s\n", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION), pkg_get(pkg, PKG_NEWVERSION));
+
		printf("\t%s: %s -> %s\n", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION), pkg_get(pkg,PKG_NEWVERSION));
	}
-
	printf("\n");
-
	pkgdb_it_free(it);

	if (oldsize > newsize) {
		newsize *= -1;
		humanize_number(size, sizeof(size), oldsize - newsize, "B", HN_AUTOSCALE, 0);
-
		printf("the upgrade will save %s\n", size);
+
		printf("\nthe upgrade will save %s\n", size);
	} else {
		humanize_number(size, sizeof(size), newsize - oldsize, "B", HN_AUTOSCALE, 0);
-
		printf("the upgrade will require %s more space\n", size);
+
		printf("\nthe upgrade will require %s more space\n", size);
	}
	humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0);
	printf("%s to be downloaded\n", size);

+
	if (yes == 0)
+
		yes = query_yesno("\nProceed with upgrading packages [y/N]: ");
+

+
	if (yes == 1)
+
		retcode = pkg_jobs_apply(jobs, 0);

	cleanup:
+

+
	pkgdb_it_free(it);
+
	pkg_jobs_free(jobs);
	pkgdb_close(db);

	return (retcode);