diff options
author | 2021-06-14 11:32:02 +0200 | |
---|---|---|
committer | 2021-06-14 11:32:02 +0200 | |
commit | f1cf942274c47dce50bbaff45d41a8a83102e3fd (patch) | |
tree | a0e4866f868474903503077880fbfed09afa0211 | |
parent | libq/tree: make tree_match_atom produce valid meta for binpkgs (diff) | |
download | portage-utils-f1cf942274c47dce50bbaff45d41a8a83102e3fd.tar.gz portage-utils-f1cf942274c47dce50bbaff45d41a8a83102e3fd.tar.bz2 portage-utils-f1cf942274c47dce50bbaff45d41a8a83102e3fd.zip |
qmerge: once over to make better/more use of libq/tree
- unify best_version and grab_binpkg_info, into single function using
tree_match_atom to benefit from cache and abstract any particulars
- default to install action when no action given
- unmerge previous package on merge upgrade again
- possibly fix bug #792273 by exporting vars
Bug: https://bugs.gentoo.org/792273
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
-rw-r--r-- | qmerge.c | 782 | ||||
-rwxr-xr-x | tests/qmerge/dotest | 52 | ||||
-rw-r--r-- | tests/qmerge/packages/Packages | 13 | ||||
-rw-r--r-- | tests/qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 | bin | 0 -> 7334 bytes |
4 files changed, 356 insertions, 491 deletions
@@ -49,8 +49,6 @@ /* #define BUSYBOX "/bin/busybox" */ #define BUSYBOX "" -int old_repo = 0; - #define QMERGE_FLAGS "fFsKUpuyO" COMMON_FLAGS static struct option const qmerge_long_opts[] = { {"fetch", no_argument, NULL, 'f'}, @@ -91,25 +89,6 @@ char update_only = 0; bool debug = false; const char Packages[] = "Packages"; -/* - "CHOST", "DEPEND", "DESCRIPTION", "EAPI", - "IUSE", "KEYWORDS", "LICENSE", "PDEPEND", - "PROVIDE", "RDEPEND", "SLOT", "USE" -*/ -struct pkg_t { - char PF[64]; - char CATEGORY[64]; - char DESC[126]; - char LICENSE[64]; - char RDEPEND[BUFSIZ]; - char MD5[34]; - char SHA1[42]; - char SLOT[64]; - size_t SIZE; - char USE[BUFSIZ]; - char REPO[64]; -}; - struct llist_char_t { char *data; struct llist_char_t *next; @@ -117,17 +96,16 @@ struct llist_char_t { typedef struct llist_char_t llist_char; -static void pkg_fetch(int, const depend_atom *, const struct pkg_t *); -static void pkg_merge(int, const depend_atom *, const struct pkg_t *); +static void pkg_fetch(int, const depend_atom *, const tree_match_ctx *); +static void pkg_merge(int, const depend_atom *, const tree_match_ctx *); static int pkg_unmerge(tree_pkg_ctx *, set *, int, char **, int, char **); -static struct pkg_t *grab_binpkg_info(depend_atom *); static bool -prompt(const char *p) +qmerge_prompt(const char *p) { printf("%s? [Y/n] ", p); fflush(stdout); - switch (getc(stdin)) { + switch (fgetc(stdin)) { case '\n': case 'y': case 'Y': @@ -143,8 +121,7 @@ fetch(const char *destdir, const char *src) if (!binhost[0]) return; - fflush(stdout); - fflush(stderr); + fflush(NULL); #if 0 if (getenv("FETCHCOMMAND") != NULL) { @@ -161,18 +138,15 @@ fetch(const char *destdir, const char *src) xasprintf(&path, "%s/%s", binhost, src); + /* wget -c -q -P <dir> <uri> */ char prog[] = "wget"; - char argv_c[] = "-c"; - char argv_P[] = "-P"; - char argv_q[] = "-q"; - char *argv_dir = xstrdup(destdir); - char *argv[] = { + char *const argv[] = { prog, - argv_c, - argv_P, - argv_dir, + (char *)"-c", + (char *)"-P", + (char *)destdir, path, - quiet ? argv_q : NULL, + quiet ? (char *)"-q" : NULL, NULL, }; if (!(force_download || install) && pretend) @@ -187,7 +161,6 @@ fetch(const char *destdir, const char *src) } free(path); - free(argv_dir); waitpid(p, &status, 0); #if 0 @@ -205,7 +178,7 @@ qmerge_initialize(void) { char *buf; - if (strlen(BUSYBOX)) + if (strlen(BUSYBOX) > 0) if (access(BUSYBOX, X_OK) != 0) err(BUSYBOX " must be installed"); @@ -232,52 +205,78 @@ qmerge_initialize(void) free(buf); } -static char _best_version_retbuf[4096]; -static int -qmerge_best_version_cb(tree_pkg_ctx *pkg_ctx, void *priv) +static tree_ctx *_qmerge_vdb_tree = NULL; +static tree_ctx *_qmerge_binpkg_tree = NULL; +#define BV_INSTALLED BV_VDB +#define BV_BINARY BV_BINPKG +#define BV_EBUILD (1<<0) /* not yet supported */ +#define BV_VDB (1<<1) +#define BV_BINPKG (1<<2) +static tree_match_ctx * +best_version(const depend_atom *atom, int mode) { - depend_atom *sa = priv; - depend_atom *a = tree_get_atom(pkg_ctx, true); /* need SLOT */ - if (atom_compare(a, sa) == EQUAL) - snprintf(_best_version_retbuf, sizeof(_best_version_retbuf), - "%s/%s:%s", a->CATEGORY, a->PF, a->SLOT); - return 0; -} + tree_ctx *vdb = _qmerge_vdb_tree; + tree_ctx *binpkg = _qmerge_binpkg_tree; + tree_match_ctx *tmv = NULL; + tree_match_ctx *tmp = NULL; + tree_match_ctx *ret; + int r; + + if (mode & BV_EBUILD) { + warn("BV_EBUILD not yet supported"); + return NULL; + } + if (mode == 0) { + warn("mode needs to be set"); + return NULL; + } -static char * -best_version(const char *catname, const char *pkgname, const char *slot) -{ - static int vdb_check = 1; - tree_ctx *vdb; - - /* Make sure these dirs exist before we try walking them */ - switch (vdb_check) { - case 1: { - int fd = open(portroot, O_RDONLY|O_CLOEXEC|O_PATH); - if (fd >= 0) { - /* skip leading slash */ - vdb_check = faccessat(fd, portvdb + 1, X_OK, 0); - close(fd); - } else - vdb_check = -1; + if (mode & BV_VDB) { + if (vdb == NULL) { + vdb = tree_open_vdb(portroot, portvdb); + if (vdb == NULL) + return NULL; + _qmerge_vdb_tree = vdb; + } + tmv = tree_match_atom(vdb, atom, + TREE_MATCH_LATEST | TREE_MATCH_FIRST); } - if (vdb_check) - case -1: - goto done; + + if (mode & BV_BINPKG) { + if (binpkg == NULL) { + binpkg = tree_open_binpkg("/", pkgdir); + if (binpkg == NULL) { + if (tmv != NULL) + tree_match_close(tmv); + if (vdb != NULL) + tree_close(vdb); + return NULL; + } + _qmerge_binpkg_tree = binpkg; + } + tmp = tree_match_atom(binpkg, atom, + TREE_MATCH_LATEST | TREE_MATCH_FIRST | TREE_MATCH_METADATA); } - snprintf(_best_version_retbuf, sizeof(_best_version_retbuf), - "%s%s%s:%s", catname ? : "", catname ? "/" : "", pkgname, slot); - vdb = tree_open_vdb(portroot, portvdb); - if (vdb != NULL) { - depend_atom *sa = atom_explode(_best_version_retbuf); - tree_foreach_pkg_fast(vdb, qmerge_best_version_cb, sa, sa); - tree_close(vdb); - atom_implode(sa); + if (tmv == NULL && tmp == NULL) + ret = NULL; + else if (tmv == NULL && tmp != NULL) + ret = tmp; + else if (tmv != NULL && tmp == NULL) + ret = tmv; + else { + if ((r = atom_compare(tmv->atom, tmp->atom)) == EQUAL || r == OLDER) + ret = tmp; + else + ret = tmv; } - done: - return _best_version_retbuf; + if (tmv != NULL && tmv != ret) + tree_match_close(tmv); + if (tmp != NULL && tmp != ret) + tree_match_close(tmp); + + return ret; } static int @@ -557,50 +556,47 @@ install_mask_pwd(int iargc, char **iargv, const struct stat * const st, int fd) } static char -qprint_tree_node(int level, const depend_atom *atom, const struct pkg_t *pkg) +qprint_tree_node( + int level, + const tree_match_ctx *mpkg, + const tree_match_ctx *bpkg, + int replacing) { - char buf[1024]; - char *p; - int i, ret; - - char install_ver[126] = ""; - char c = 'N'; - const char *color; + char buf[1024]; + int i; + char install_ver[126] = ""; + char c = 'N'; + const char *color; if (!pretend) return 0; - p = best_version(pkg->CATEGORY, atom->PN, pkg->SLOT); - - if (strlen(p) < 1) { + if (bpkg == NULL) { c = 'N'; snprintf(buf, sizeof(buf), "%sN%s", GREEN, NORM); } else { - depend_atom *subatom = atom_explode(p); - if (subatom != NULL) { - ret = atom_compare(subatom, atom); - switch (ret) { + if (bpkg != NULL) { + switch (replacing) { case EQUAL: c = 'R'; break; case NEWER: c = 'U'; break; case OLDER: c = 'D'; break; - default: c = '?'; break; + default: c = '?'; break; } snprintf(install_ver, sizeof(install_ver), "[%s%.*s%s] ", DKBLUE, (int)(sizeof(install_ver) - 4 - sizeof(DKBLUE) - sizeof(NORM)), - subatom->P, NORM); - atom_implode(subatom); + bpkg->atom->PVR, NORM); } if (update_only && c != 'U') return c; if ((c == 'R' || c == 'D') && update_only && level) return c; switch (c) { - case 'R': color = YELLOW; break; - case 'U': color = BLUE; break; - case 'D': color = DKBLUE; break; - default: color = RED; break; + case 'R': color = YELLOW; break; + case 'U': color = BLUE; break; + case 'D': color = DKBLUE; break; + default: color = RED; break; } snprintf(buf, sizeof(buf), "%s%c%s", color, c, NORM); #if 0 @@ -615,14 +611,19 @@ qprint_tree_node(int level, const depend_atom *atom, const struct pkg_t *pkg) } #endif } + printf("[%s] ", buf); for (i = 0; i < level; ++i) putchar(' '); - if (verbose) - printf("%s%s/%s%s %s%s%s%s%s%s\n", DKGREEN, pkg->CATEGORY, pkg->PF, NORM, - install_ver, strlen(pkg->USE) > 0 ? "(" : "", RED, pkg->USE, NORM, strlen(pkg->USE) > 0 ? ")" : ""); - else - printf("%s%s/%s%s\n", DKGREEN, pkg->CATEGORY, pkg->PF, NORM); + if (verbose) { + char *use = mpkg->meta->Q_USE; /* TODO: compute difference */ + printf("%s %s%s%s%s%s%s\n", + atom_format("%[CAT]%[PF]", mpkg->atom), + install_ver, use != NULL ? "(" : "", + RED, use, NORM, use != NULL ? ")" : ""); + } else { + printf("%s\n", atom_format("%[CAT]%[PF]", mpkg->atom)); + } return c; } @@ -641,7 +642,7 @@ pkg_run_func_at(int dirfd, const char *vdb_path, const char *phases, const char return; } - qprintf(">>> %s\n", func); + qprintf("@@@ %s\n", func); xasprintf(&script, /* Provide funcs required by the PMS */ @@ -681,16 +682,16 @@ pkg_run_func_at(int dirfd, const char *vdb_path, const char *phases, const char /* Load the main env */ ". '%1$s/environment'\n" /* Reload env vars that matter to us */ - "FILESDIR=/.does/not/exist/anywhere\n" - "MERGE_TYPE=binary\n" - "ROOT='%4$s'\n" - "EROOT=\"${ROOT%%/}${EPREFIX%%/}/\"\n" - "D=\"%5$s\"\n" - "ED=\"${D%%/}${EPREFIX%%/}/\"\n" - "T=\"%6$s\"\n" + "export FILESDIR=/.does/not/exist/anywhere\n" + "export MERGE_TYPE=binary\n" + "export ROOT='%4$s'\n" + "export EROOT=\"${ROOT%%/}${EPREFIX%%/}/\"\n" + "export D=\"%5$s\"\n" + "export ED=\"${D%%/}${EPREFIX%%/}/\"\n" + "export T=\"%6$s\"\n" /* we do not support preserve-libs yet, so force * preserve_old_lib instead */ - "FEATURES=\"${FEATURES/preserve-libs/disabled}\"\n" + "export FEATURES=\"${FEATURES/preserve-libs/disabled}\"\n" /* Finally run the func */ "%7$s%2$s\n" /* Ignore func return values (not exit values) */ @@ -778,7 +779,7 @@ merge_tree_at(int fd_src, const char *src, int fd_dst, const char *dst, if (!pretend) fprintf(contents, "dir %s\n", cpath); *objs = add_set(cpath, *objs); - qprintf("%s>>>%s %s%s%s/\n", GREEN, NORM, DKBLUE, cpath, NORM); + qprintf("%s---%s %s%s%s/\n", GREEN, NORM, DKBLUE, cpath, NORM); /* Copy all of these contents */ merge_tree_at(subfd_src, name, @@ -973,67 +974,78 @@ pkg_extract_xpak_cb( } /* oh shit getting into pkg mgt here. FIXME: write a real dep resolver. */ +static char *pm_phases; +static size_t pm_phases_len; static void -pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) +pkg_merge(int level, const depend_atom *qatom, const tree_match_ctx *mpkg) { - set *objs; - tree_ctx *vdb; - tree_cat_ctx *cat_ctx; - FILE *fp, *contents; - static char *phases; - static size_t phases_len; - char *eprefix = NULL; - size_t eprefix_len = 0; - char buf[1024]; - char *tbz2, *p, *D, *T; - int i; - char **ARGV; - int ARGC; - struct stat st; - char **iargv; - char c; - int iargc; - const char *compr; - int cp_argc; - int cpm_argc; - char **cp_argv; - char **cpm_argv; - int tbz2size; - - if (!install || !pkg || !atom) + set *objs; + tree_ctx *vdb; + tree_cat_ctx *cat_ctx; + tree_match_ctx *bpkg; + tree_match_ctx *previnst; + depend_atom *slotatom; + FILE *fp; + FILE *contents; + char *eprefix = NULL; + size_t eprefix_len = 0; + char buf[1024]; + char *p; + char *D; + char *T; + int i; + char **ARGV; + int ARGC; + struct stat st; + char **iargv; + int iargc; + const char *compr; + int cp_argc; + int cpm_argc; + char **cp_argv; + char **cpm_argv; + int tbz2size; + int replacing = 0; + + if (!install || !mpkg || !qatom) return; - if (!pkg->PF[0] || !pkg->CATEGORY[0]) { - if (verbose) warn("CPF is really NULL at level %d", level); - return; - } + /* create atom of the installed mpkg without version, with this + * SLOT (without SUBSLOT) */ + snprintf(buf, sizeof(buf), "%s/%s:%s", + mpkg->atom->CATEGORY, + mpkg->atom->PN, + mpkg->atom->SLOT != NULL ? "0" : mpkg->atom->SLOT); + slotatom = atom_explode(buf); - c = qprint_tree_node(level, atom, pkg); + previnst = best_version(slotatom, BV_INSTALLED); + if (previnst != NULL) + replacing = atom_compare(mpkg->atom, slotatom); - if (0) - if (((c == 'R') || (c == 'D')) && update_only) - return; + (void)qprint_tree_node(level, mpkg, previnst, replacing); - if (pkg->RDEPEND[0] != '\0' && follow_rdepends) { - const char *rdepend; + if (mpkg->meta->Q_RDEPEND != NULL && + mpkg->meta->Q_RDEPEND[0] != '\0' && + follow_rdepends) + { + const char *rdepend = mpkg->meta->Q_RDEPEND; - IF_DEBUG(fprintf(stderr, "\n+Parent: %s/%s\n", pkg->CATEGORY, pkg->PF)); - IF_DEBUG(fprintf(stderr, "+Depstring: %s\n", pkg->RDEPEND)); + IF_DEBUG(fprintf(stderr, "\n+Parent: %s\n+Depstring: %s\n", + atom_to_string(mpkg->atom), rdepend)); /* <hack> */ - if (strncmp(pkg->RDEPEND, "|| ", 3) == 0) { + if (strncmp(rdepend, "|| ", 3) == 0) { if (verbose) - qfprintf(stderr, "fix this rdepend hack %s\n", pkg->RDEPEND); + qfprintf(stderr, "fix this rdepend hack %s\n", rdepend); rdepend = ""; - } else - rdepend = pkg->RDEPEND; + } /* </hack> */ makeargv(rdepend, &ARGC, &ARGV); /* Walk the rdepends here. Merging what need be. */ for (i = 1; i < ARGC; i++) { - depend_atom *subatom, *ratom; - char *name = ARGV[i]; + depend_atom *subatom; + char *name = ARGV[i]; switch (*name) { case '|': case '!': @@ -1046,41 +1058,19 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) break; default: if ((subatom = atom_explode(name)) != NULL) { - struct pkg_t *subpkg; - - subpkg = grab_binpkg_info(subatom); /* free me later */ - if (subpkg == NULL) { - warn("Cannot find a binpkg for %s from rdepend(%s)", - name, pkg->RDEPEND); + bpkg = best_version(subatom, BV_INSTALLED | BV_BINPKG); + if (bpkg == NULL) { + warn("cannot resolve %s from rdepend(%s)", + name, rdepend); atom_implode(subatom); continue; } - assert(subpkg != NULL); - IF_DEBUG(fprintf(stderr, "+Subpkg: %s/%s\n", - subpkg->CATEGORY, subpkg->PF)); - - /* look at installed versions now. - * If NULL or < merge this pkg */ - snprintf(buf, sizeof(buf), "%s/%s", - subpkg->CATEGORY, subpkg->PF); - - ratom = atom_explode(buf); - - p = best_version(subpkg->CATEGORY, - subpkg->PF, subpkg->SLOT); - - /* we dont want to remerge equal versions here */ - IF_DEBUG(fprintf(stderr, "+Installed: %s\n", p)); - if (strlen(p) < 1) - if (!((strcmp(pkg->PF, subpkg->PF) == 0) && - (strcmp(pkg->CATEGORY, - subpkg->CATEGORY) == 0))) - pkg_fetch(level+1, ratom, subpkg); + if (bpkg->pkg->cat_ctx->ctx->cachetype != CACHE_VDB) + pkg_fetch(level + 1, subatom, bpkg); + tree_match_close(bpkg); atom_implode(subatom); - atom_implode(ratom); - free(subpkg); } else { qfprintf(stderr, "Cant explode atom %s\n", name); } @@ -1103,22 +1093,22 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) } if (vdb == NULL) errf("need access to root, check permissions to access %s", portroot); - cat_ctx = tree_open_cat(vdb, pkg->CATEGORY); + cat_ctx = tree_open_cat(vdb, mpkg->atom->CATEGORY); if (!cat_ctx) { if (errno != ENOENT) { tree_close(vdb); return; } - mkdirat(vdb->tree_fd, pkg->CATEGORY, 0755); - cat_ctx = tree_open_cat(vdb, pkg->CATEGORY); + mkdirat(vdb->tree_fd, mpkg->atom->CATEGORY, 0755); + cat_ctx = tree_open_cat(vdb, mpkg->atom->CATEGORY); if (!cat_ctx) { tree_close(vdb); return; } } - /* Set up our temp dir to unpack this stuff */ - xasprintf(&p, "%s/qmerge/%s/%s", port_tmpdir, pkg->CATEGORY, pkg->PF); + /* Set up our temp dir to unpack this stuff FIXME p -> builddir */ + xasprintf(&p, "%s/qmerge/%s", port_tmpdir, atom_to_string(mpkg->atom)); mkdir_p(p, 0755); xchdir(p); xasprintf(&D, "%s/image", p); @@ -1131,7 +1121,6 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) mkdir("temp", 0755); mkdir_p(portroot, 0755); - xasprintf(&tbz2, "%s/%s/%s.tbz2", pkgdir, pkg->CATEGORY, pkg->PF); tbz2size = 0; mkdir("vdb", 0755); @@ -1139,10 +1128,10 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) int vdbfd = open("vdb", O_RDONLY); if (vdbfd == -1) err("failed to open vdb extraction directory"); - tbz2size = xpak_extract(tbz2, &vdbfd, pkg_extract_xpak_cb); + tbz2size = xpak_extract(mpkg->path, &vdbfd, pkg_extract_xpak_cb); } if (tbz2size <= 0) - err("%s appears not to be a valid tbz2 file", tbz2); + err("%s appears not to be a valid tbz2 file", mpkg->path); /* figure out if the data is compressed differently from what the * name suggests, bug #660508, usage of BINPKG_COMPRESS, @@ -1162,7 +1151,7 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) FILE *mfd; compr = "brotli -dc"; /* default: brotli; has no magic header */ - mfd = fopen(tbz2, "r"); + mfd = fopen(mpkg->path, "r"); if (mfd != NULL) { size_t mlen = fread(magic, 1, sizeof(magic), mfd); fclose(mfd); @@ -1261,18 +1250,18 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) if ((tarpipe = popen(buf, "w")) == NULL) errp("failed to start %s", buf); - if ((tbz2f = fopen(tbz2, "r")) == NULL) - errp("failed to open %s for reading", tbz2); + if ((tbz2f = fopen(mpkg->path, "r")) == NULL) + errp("failed to open %s for reading", mpkg->path); for (piped = wr = 0; piped < tbz2size; piped += wr) { n = MIN(tbz2size - piped, (ssize_t)sizeof iobuf); rd = fread(iobuf, 1, n, tbz2f); if (0 == rd) { if ((err = ferror(tbz2f)) != 0) - err("reading %s failed: %s", tbz2, strerror(err)); + err("reading %s failed: %s", mpkg->path, strerror(err)); if (feof(tbz2f)) - err("unexpected EOF in %s: corrupted binpkg", tbz2); + err("unexpected EOF in %s: corrupted binpkg", mpkg->path); } for (wr = n = 0; wr < rd; wr += n) { @@ -1296,13 +1285,12 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) errp("finishing unpack binpkg unsuccessful"); } - free(tbz2); fflush(stdout); - eat_file("vdb/DEFINED_PHASES", &phases, &phases_len); - pkg_run_func("vdb", phases, "pkg_pretend", D, T); - pkg_run_func("vdb", phases, "pkg_setup", D, T); - pkg_run_func("vdb", phases, "pkg_preinst", D, T); + eat_file("vdb/DEFINED_PHASES", &pm_phases, &pm_phases_len); + pkg_run_func("vdb", pm_phases, "pkg_pretend", D, T); + pkg_run_func("vdb", pm_phases, "pkg_setup", D, T); + pkg_run_func("vdb", pm_phases, "pkg_preinst", D, T); if (!eat_file("vdb/EPREFIX", &eprefix, &eprefix_len)) eprefix_len = 0; @@ -1379,7 +1367,7 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) /* run postinst */ if (!pretend) - pkg_run_func("vdb", phases, "pkg_postinst", D, T); + pkg_run_func("vdb", pm_phases, "pkg_postinst", D, T); /* XXX: hmm, maybe we'll want to strip more ? */ unlink("vdb/environment"); @@ -1387,43 +1375,24 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) /* Unmerge any stray pieces from the older version which we didn't * replace */ /* TODO: Should see about merging with unmerge_packages() */ - while (1) { - int ret; - tree_pkg_ctx *pkg_ctx; - depend_atom *old_atom; - - pkg_ctx = tree_next_pkg(cat_ctx); - if (!pkg_ctx) + switch (replacing) { + case NEWER: + case OLDER: + case EQUAL: + /* We need to really set this unmerge pending after we + * look at contents of the new pkg */ + pkg_unmerge(previnst->pkg, objs, + cp_argc, cp_argv, cpm_argc, cpm_argv); + break; + default: + warn("no idea how we reached here."); + case ERROR: + case NOT_EQUAL: break; - old_atom = tree_get_atom(pkg_ctx, 1); /* retrieve SLOT */ - if (!old_atom) - goto next_pkg; - old_atom->SUBSLOT = NULL; /* just match SLOT */ - old_atom->REPO = NULL; /* REPO never matters, TODO atom_compare */ - ret = atom_compare(atom, old_atom); - switch (ret) { - case NEWER: - case OLDER: - case EQUAL: - /* We need to really set this unmerge pending after we - * look at contents of the new pkg */ - break; - default: - warn("no idea how we reached here."); - case ERROR: - case NOT_EQUAL: - goto next_pkg; - } - - printf("%s+++%s %s/%s %s %s/%s\n", - GREEN, NORM, atom->CATEGORY, pkg->PF, - booga[ret], cat_ctx->name, pkg_ctx->name); - - pkg_unmerge(pkg_ctx, objs, cp_argc, cp_argv, cpm_argc, cpm_argv); - next_pkg: - tree_close_pkg(pkg_ctx); } + tree_match_close(previnst); + freeargv(cp_argc, cp_argv); freeargv(cpm_argc, cpm_argv); @@ -1442,9 +1411,9 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) if (!pretend) { /* move the local vdb copy to the final place */ snprintf(buf, sizeof(buf), "%s%s/%s/", - portroot, portvdb, pkg->CATEGORY); + portroot, portvdb, mpkg->atom->CATEGORY); mkdir_p(buf, 0755); - strcat(buf, pkg->PF); + strcat(buf, mpkg->atom->PF); rm_rf(buf); /* get rid of existing dir, empty dir is fine */ if (rename("vdb", buf) != 0) warn("failed to move 'vdb' to '%s': %s", buf, strerror(errno)); @@ -1452,12 +1421,12 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) /* clean up our local temp dir */ xchdir(".."); - rm_rf(pkg->PF); + rm_rf(mpkg->atom->PF); /* don't care about return */ rmdir("../qmerge"); - printf("%s>>>%s %s%s%s/%s%s%s\n", - YELLOW, NORM, WHITE, pkg->CATEGORY, NORM, CYAN, pkg->PF, NORM); + printf("%s>>>%s %s\n", + YELLOW, NORM, atom_format("%[CAT]%[PF]", mpkg->atom)); tree_close_cat(cat_ctx); tree_close(vdb); @@ -1481,7 +1450,7 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep, buf = phases = NULL; T = "${PWD}/temp"; - printf("%s<<<%s %s\n", YELLOW, NORM, + printf("%s***%s unmerging %s\n", YELLOW, NORM, atom_format("%[CATEGORY]%[PF]", tree_get_atom(pkg_ctx, false))); if (pretend == 100) @@ -1513,11 +1482,11 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep, strstr(features, "config-protect-if-modified") != NULL; for (; (buf = strtok_r(buf, "\n", &savep)) != NULL; buf = NULL) { - bool del; + bool del; contents_entry *e; - char zing[20]; - int protected = 0; - struct stat st; + char zing[20]; + int protected = 0; + struct stat st; e = contents_parse_line(buf); if (!e) @@ -1657,55 +1626,58 @@ unlink_empty(const char *buf) static int pkg_verify_checksums( - char *fname, - const struct pkg_t *pkg, - int strict, - int display) + const tree_match_ctx *pkg, + int strict, + int display) { - int ret = 0; - char md5[32+1]; - char sha1[40+1]; + int ret = 0; + char md5[32+1]; + char sha1[40+1]; size_t flen; + int mlen; - if (hash_multiple_file(fname, md5, sha1, NULL, NULL, NULL, NULL, + if (hash_multiple_file(pkg->path, md5, sha1, NULL, NULL, NULL, NULL, &flen, HASH_MD5 | HASH_SHA1) == -1) - errf("failed to compute hashes for %s/%s: %s\n", - pkg->CATEGORY, pkg->PF, strerror(errno)); + errf("failed to compute hashes for %s: %s\n", + atom_to_string(pkg->atom), strerror(errno)); - if (flen != pkg->SIZE) { - warn("filesize %zu doesn't match requested size %zu for %s/%s\n", - flen, pkg->SIZE, pkg->CATEGORY, pkg->PF); + mlen = atoi(pkg->meta->Q_SIZE); + if (flen != (size_t)mlen) { + warn("filesize %zu doesn't match requested size %d for %s\n", + flen, mlen, atom_to_string(pkg->atom)); ret++; } - if (pkg->MD5[0]) { - if (strcmp(md5, pkg->MD5) == 0) { + if (pkg->meta->Q_MD5 != NULL) { + if (strcmp(md5, pkg->meta->Q_MD5) == 0) { if (display) - printf("MD5: [%sOK%s] %s %s/%s\n", - GREEN, NORM, md5, pkg->CATEGORY, pkg->PF); + printf("MD5: [%sOK%s] %s %s\n", + GREEN, NORM, md5, atom_to_string(pkg->atom)); } else { if (display) - warn("MD5: [%sER%s] (%s) != (%s) %s/%s", - RED, NORM, md5, pkg->MD5, pkg->CATEGORY, pkg->PF); + warn("MD5: [%sER%s] (%s) != (%s) %s", + RED, NORM, md5, pkg->meta->Q_MD5, + atom_to_string(pkg->atom)); ret++; } } - if (pkg->SHA1[0]) { - if (strcmp(sha1, pkg->SHA1) == 0) { + if (pkg->meta->Q_SHA1 != NULL) { + if (strcmp(sha1, pkg->meta->Q_SHA1) == 0) { if (display) - qprintf("SHA1: [%sOK%s] %s %s/%s\n", - GREEN, NORM, sha1, pkg->CATEGORY, pkg->PF); + qprintf("SHA1: [%sOK%s] %s %s\n", + GREEN, NORM, sha1, atom_to_string(pkg->atom)); } else { if (display) - warn("SHA1: [%sER%s] (%s) != (%s) %s/%s", - RED, NORM, sha1, pkg->SHA1, pkg->CATEGORY, pkg->PF); + warn("SHA1: [%sER%s] (%s) != (%s) %s", + RED, NORM, sha1, pkg->meta->Q_SHA1, + atom_to_string(pkg->atom)); ret++; } } - if (!pkg->SHA1[0] && !pkg->MD5[0]) - return 1; + if (pkg->meta->Q_MD5 == NULL && pkg->meta->Q_SHA1 == NULL) + return -1; if (strict && ret) errf("strict is set in features"); @@ -1714,140 +1686,69 @@ pkg_verify_checksums( } static void -pkg_fetch(int level, const depend_atom *atom, const struct pkg_t *pkg) +pkg_fetch(int level, const depend_atom *qatom, const tree_match_ctx *mpkg) { - char buf[_Q_PATH_MAX], str[_Q_PATH_MAX]; + int verifyret; + char buf[_Q_PATH_MAX]; /* qmerge -pv patch */ if (pretend) { if (!install) install++; - /* qprint_tree_node(level, atom, pkg); */ - pkg_merge(level, atom, pkg); + /* qprint_tree_node(level, qatom, mpkg); */ + pkg_merge(level, qatom, mpkg); return; } - /* check to see if file exists and it's checksum matches */ - snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", pkgdir, pkg->CATEGORY, pkg->PF); - unlink_empty(buf); + unlink_empty(mpkg->path); - snprintf(str, sizeof(str), "%s/%s", pkgdir, pkg->CATEGORY); - if (mkdir(str, 0755) == -1 && errno != EEXIST) { - warn("Failed to create %s", str); + if (mkdir(mpkg->pkg->cat_ctx->ctx->path, 0755) == -1 && errno != EEXIST) { + warn("Failed to create %s", mpkg->pkg->cat_ctx->ctx->path); return; } - if (force_download && (access(buf, R_OK) == 0) && - (pkg->SHA1[0] || pkg->MD5[0])) + if (force_download && (access(mpkg->path, R_OK) == 0) && + (mpkg->meta->Q_SHA1 != NULL || mpkg->meta->Q_MD5 != NULL)) { - if (pkg_verify_checksums(buf, pkg, 0, 0) != 0) + if (pkg_verify_checksums(mpkg, 0, 0) != 0) if (getenv("QMERGE") == NULL) - unlink(buf); - } - if (access(buf, R_OK) == 0) { - if (!pkg->SHA1[0] && !pkg->MD5[0]) { - warn("No checksum data for %s (try `emaint binhost --fix`)", buf); - return; - } else { - if (pkg_verify_checksums(buf, pkg, qmerge_strict, !quiet) - == 0) - { - pkg_merge(0, atom, pkg); - return; - } - } - } - if (verbose) - printf("Fetching %s/%s.tbz2\n", atom->CATEGORY, pkg->PF); - - /* fetch the package */ - /* Check CATEGORY first */ - if (!old_repo) { - snprintf(buf, sizeof(buf), "%s/%s.tbz2", atom->CATEGORY, pkg->PF); - fetch(str, buf); - } - snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", - pkgdir, atom->CATEGORY, pkg->PF); - if (access(buf, R_OK) != 0) { - snprintf(buf, sizeof(buf), "%s.tbz2", pkg->PF); - fetch(str, buf); - old_repo = 1; + unlink(mpkg->path); } - /* verify the pkg exists now. unlink if zero bytes */ - snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", - pkgdir, atom->CATEGORY, pkg->PF); - unlink_empty(buf); + if (access(mpkg->path, R_OK) != 0) { + if (verbose) + printf("Fetching %s\n", atom_to_string(mpkg->atom)); - if (access(buf, R_OK) != 0) { - warn("Failed to fetch %s.tbz2 from %s", pkg->PF, binhost); - fflush(stderr); - return; + /* fetch the package */ + snprintf(buf, sizeof(buf), "%s/%s.tbz2", + mpkg->atom->CATEGORY, mpkg->atom->PF); + fetch(mpkg->pkg->cat_ctx->ctx->path, buf); + + /* verify the pkg exists now. unlink if zero bytes */ + unlink_empty(mpkg->path); } - snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", - pkgdir, atom->CATEGORY, pkg->PF); - if (pkg_verify_checksums(buf, pkg, qmerge_strict, !quiet) == 0) { - pkg_merge(0, atom, pkg); + if (access(mpkg->path, R_OK) != 0) { + warn("Failed to fetch %s.tbz2 from %s", mpkg->atom->PF, binhost); + fflush(stderr); return; } -} - -static void -print_Pkg(int full, const depend_atom *atom, const struct pkg_t *pkg) -{ - char *p = NULL; - char buf[512]; - - printf("%s%s%s%s\n", atom_format("%[CAT]%[PF]%[SLOT]", atom), - !quiet ? " [" : "", - !quiet ? make_human_readable_str(pkg->SIZE, 1, KILOBYTE) : "", - !quiet ? " KiB]" : ""); - if (full == 0) + /* check to see if checksum matches */ + verifyret = pkg_verify_checksums(mpkg, qmerge_strict, !quiet); + if (verifyret == -1) { + warn("No checksum data for %s (try `emaint binhost --fix`)", + mpkg->path); + return; + } else if (verifyret == 0) { + pkg_merge(0, qatom, mpkg); return; - - if (pkg->DESC[0]) - printf(" %sDesc%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->DESC); - if (pkg->SHA1[0]) - printf(" %sSha1%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->SHA1); - if (pkg->MD5[0]) - printf(" %sMd5%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->MD5); - if (!pkg->MD5[0] && !pkg->SHA1[0]) - printf(" %sSums%s:%s %s(MISSING!)%s\n", - DKGREEN, YELLOW, NORM, RED, NORM); - if (pkg->SLOT[0]) - printf(" %sSlot%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->SLOT); - if (pkg->LICENSE[0]) - printf(" %sLicense%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->LICENSE); - if (pkg->RDEPEND[0]) - printf(" %sRdepend%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->RDEPEND); - if (pkg->USE[0]) - printf(" %sUse%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->USE); - if (pkg->REPO[0]) - if (strcmp(pkg->REPO, "gentoo") != 0) - printf(" %sRepo%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->REPO); - - if ((p = best_version(pkg->CATEGORY, atom->PN, pkg->SLOT)) != NULL) { - if (*p) { - int ret; - const char *icolor = RED; - ret = atom_compare_str(buf, p); - switch (ret) { - case EQUAL: icolor = RED; break; - case NEWER: icolor = YELLOW; break; - case OLDER: icolor = BLUE; break; - default: icolor = NORM; break; - } - printf(" %sInstalled%s:%s %s%s%s\n", - DKGREEN, YELLOW, NORM, icolor, p, NORM); - } } } /* HACK: pull this in, knowing that qlist will be in the final link, we * should however figure out how to do what match does here from e.g. - * atom */ + * atom FIXME use tree_match_atom instead */ extern bool qlist_match( tree_pkg_ctx *pkg_ctx, const char *name, @@ -1893,71 +1794,6 @@ unmerge_packages(set *todo) return ret; } -static tree_ctx *_grab_binpkg_info_tree = NULL; -static struct pkg_t * -grab_binpkg_info(depend_atom *atom) -{ - tree_ctx *tree = _grab_binpkg_info_tree; - tree_match_ctx *tpkg; - struct pkg_t *pkg = NULL; - char path[BUFSIZ]; - FILE *d; - - /* reuse previously opened tree, so we really employ the cache - * from libq/tree */ - if (tree == NULL) { - snprintf(path, sizeof(path), "%s/portage/%s", port_tmpdir, Packages); - /* we don't use ROOT on package tree here, operating on ROOT - * should be for package merges/unmerges, but be able to pull - * binpkgs from current system */ - if ((d = fopen(path, "r")) != NULL) { - fclose(d); - snprintf(path, sizeof(path), "%s/portage", port_tmpdir); - tree = tree_open_binpkg("/", path); - } else { - tree = tree_open_binpkg("/", pkgdir); - } - _grab_binpkg_info_tree = tree; - - /* if opening the tree failed somehow, we can't return anything */ - if (tree == NULL) - return NULL; - } - - tpkg = tree_match_atom(tree, atom, - TREE_MATCH_FIRST | TREE_MATCH_VIRTUAL | TREE_MATCH_METADATA); - if (tpkg != NULL) { - depend_atom *tatom = tpkg->atom; - tree_pkg_meta *meta = tpkg->meta; - pkg = xzalloc(sizeof(struct pkg_t)); - - snprintf(pkg->PF, sizeof(pkg->PF), "%s", tatom->PF); - snprintf(pkg->CATEGORY, sizeof(pkg->CATEGORY), "%s", tatom->CATEGORY); - if (meta->Q_DESCRIPTION != NULL) - snprintf(pkg->DESC, sizeof(pkg->DESC), "%s", meta->Q_DESCRIPTION); - if (meta->Q_LICENSE != NULL) - snprintf(pkg->LICENSE, sizeof(pkg->LICENSE), "%s", meta->Q_LICENSE); - if (meta->Q_RDEPEND != NULL) - snprintf(pkg->RDEPEND, sizeof(pkg->RDEPEND), "%s", meta->Q_RDEPEND); - if (meta->Q_MD5 != NULL) - snprintf(pkg->MD5, sizeof(pkg->MD5), "%s", meta->Q_MD5); - if (meta->Q_SHA1 != NULL) - snprintf(pkg->SHA1, sizeof(pkg->SHA1), "%s", meta->Q_SHA1); - if (meta->Q_USE != NULL) - snprintf(pkg->USE, sizeof(pkg->USE), "%s", meta->Q_USE); - if (meta->Q_repository != NULL) - snprintf(pkg->REPO, sizeof(pkg->REPO), "%s", meta->Q_repository); - if (meta->Q_SLOT != NULL) - snprintf(pkg->REPO, sizeof(pkg->REPO), "%s", meta->Q_SLOT); - if (meta->Q_SIZE != NULL) - pkg->SIZE = atoi(meta->Q_SIZE); - - tree_match_close(tpkg); - } - - return pkg; -} - static set * qmerge_add_set_file(const char *pfx, const char *dir, const char *file, set *q) { @@ -2046,8 +1882,7 @@ qmerge_run(set *todo) return unmerge_packages(todo); } else { if (todo == NULL || search_pkgs) { - /* disputable, this should be qlist -kIv or something */ - warn("please use qlist -kI"); + warn("please use qlist -kIv"); return EXIT_SUCCESS; } else { @@ -2055,19 +1890,18 @@ qmerge_run(set *todo) size_t todo_cnt = list_set(todo, &todo_strs); size_t i; depend_atom *atom; - struct pkg_t *pkg; + tree_match_ctx *bpkg; int ret = EXIT_FAILURE; for (i = 0; i < todo_cnt; i++) { atom = atom_explode(todo_strs[i]); - pkg = grab_binpkg_info(atom); - if (pkg != NULL) { - if (search_pkgs) - print_Pkg(verbose, atom, pkg); - else - pkg_fetch(0, atom, pkg); - free(pkg); + bpkg = best_version(atom, BV_BINPKG); + if (bpkg != NULL) { + pkg_fetch(0, atom, bpkg); + tree_match_close(bpkg); ret = EXIT_SUCCESS; + } else { + warn("nothing found for %s", atom_to_string(atom)); } atom_implode(atom); } @@ -2088,23 +1922,27 @@ int qmerge_main(int argc, char **argv) while ((i = GETOPT_LONG(QMERGE, qmerge, "")) != -1) { switch (i) { - case 'f': force_download = 1; break; - case 'F': force_download = 2; break; - case 's': search_pkgs = 1; interactive = 0; break; + case 'f': force_download = 1; break; + case 'F': force_download = 2; break; + case 's': search_pkgs = 1; + interactive = 0; break; /* case 'i': case 'g': */ - case 'K': install = 1; break; - case 'U': uninstall = 1; break; - case 'p': pretend = 1; break; - case 'u': - update_only = 1; - /* fall through */ - case 'y': interactive = 0; break; + case 'K': install = 1; break; + case 'U': uninstall = 1; break; + case 'p': pretend = 1; break; + case 'u': update_only = 1; + install = 1; break; + case 'y': interactive = 0; break; case 'O': follow_rdepends = 0; break; - case 128: debug = true; break; + case 128: debug = true; break; COMMON_GETOPTS_CASES(qmerge) } } + /* default to install if no action given */ + if (!install && !uninstall) + install = 1; + qmerge_strict = (strstr("strict", features) == 0) ? 1 : 0; /* Short circut this. */ @@ -2140,14 +1978,14 @@ int qmerge_main(int argc, char **argv) verbose = 0; quiet = 1; ret = qmerge_run(todo); - if (ret || save_pretend) + if (ret != EXIT_SUCCESS || save_pretend) return ret; if (uninstall) { - if (!prompt("OK to unmerge these packages")) + if (!qmerge_prompt("OK to unmerge these packages")) return EXIT_FAILURE; } else { - if (!prompt("OK to merge these packages")) + if (!qmerge_prompt("OK to merge these packages")) return EXIT_FAILURE; } diff --git a/tests/qmerge/dotest b/tests/qmerge/dotest index 59f249d4..0f870efb 100755 --- a/tests/qmerge/dotest +++ b/tests/qmerge/dotest @@ -22,16 +22,17 @@ set +e # sanity check on environment q -Cev +qlist -kIv # Do a merge into an empty tree. -out=$(yes | qmerge -F qmerge-test) +out=$(yes | qmerge -F qmerge-test-1.3) tend $? "qmerge-test: [N] basic merge" || die "${out}" [[ ${out} != *"FAIL"* ]] tend $? "qmerge-test: [N] no FAIL messages" || die "${out}" -order=$(echo "${out}" | awk '$1 == ">>>" && $2 ~ /^pkg_/ { printf "%s ", $NF }') +order=$(echo "${out}" | awk '$1 == "@@@" && $2 ~ /^pkg_/ { printf "%s ", $NF }') [[ ${order} == "pkg_pretend pkg_setup pkg_preinst pkg_postinst " ]] tend $? "qmerge-test: [N] pkg_* order of execution" || die "$(printf '%s\n' "${order}" "${out}")" @@ -45,14 +46,14 @@ tend $? "qmerge-test: [N] installed expected files" || die "$(treedir "${ROOT}") # Now do a re-emerge. -out=$(yes | qmerge -F qmerge-test) +out=$(yes | qmerge -F "<qmerge-test-2") tend $? "qmerge-test: [R] re-emerge" || die "${out}" [[ -x ${ROOT}/usr/bin/qmerge-test ]] tend $? "qmerge-test: [R] installed expected files" || die "$(treedir "${ROOT}")" -order=$(echo "${out}" | awk '$1 == ">>>" && $2 ~ /^pkg_/ { printf "%s ", $NF }') -[[ ${order} == "pkg_pretend pkg_setup pkg_preinst pkg_postinst " ]] +order=$(echo "${out}" | awk '$1 == "@@@" && $2 ~ /^pkg_/ { printf "%s ", $NF }') +[[ ${order} == "pkg_pretend pkg_setup pkg_preinst pkg_postinst pkg_prerm pkg_postrm " ]] tend $? "qmerge-test: [R] pkg_* order of execution" || die "$(printf '%s\n' "${order}" "${out}")" [[ -x ${ROOT}/usr/bin/qmerge-test && \ @@ -61,6 +62,19 @@ tend $? "qmerge-test: [R] pkg_* order of execution" || die "$(printf '%s\n' "${o -f ${ROOT}/etc/._cfg0000_some.conf ]] tend $? "qmerge-test: [R] re-installed expected files" || die "$(treedir "${ROOT}")" +# upgrade to latest version + +out=$(yes | qmerge -F qmerge-test) +tend $? "qmerge-test: [U] update" || die "${out}" + +[[ $(qlist -Iv qmerge-test) == "sys-devel/qmerge-test-2.0" ]] +tend $? "qmerge-test: qlist does not report version 2.0 installed" || die "$(qlist -Iv qmerge-test;qlist -kIv) ${out}" + +[[ ! -x ${ROOT}/usr/bin/qmerge-test ]] +tend $? "qmerge-test: binary from version 1 does not exist" || die "$(treedir "${ROOT}")" +[[ -x ${ROOT}/usr/bin/qmerge-test2 ]] +tend $? "qmerge-test: binary from version 2 exists" || die "$(treedir "${ROOT}")" + # Finally do an unmerge. echo alkdsjfalksdf > "${ROOT}/etc/some.conf" @@ -69,7 +83,7 @@ rm -f "${ROOT}/etc/._cfg0000_some.conf" out=$(yes | qmerge -FU qmerge-test) tend $? "qmerge-test: [C] uninstall" || die "${out}" -order=$(echo "${out}" | awk '$1 == ">>>" { printf "%s ", $NF }') +order=$(echo "${out}" | awk '$1 == "@@@" { printf "%s ", $NF }') [[ ${order} == "pkg_prerm pkg_postrm " ]] tend $? "qmerge-test: [C] pkg_* order of execution" || die "$(printf '%s\n' "${order}" "${out}")" @@ -90,9 +104,9 @@ tend $? "qmerge-test: [M] install no /etc" || die "${out}" tend $? "qmerge-test: [M] found no /etc" || die "$(treedir "${ROOT}")" out=$(yes | qmerge -FU qmerge-test) -tend $? "qmerge-test: [M] uninstall" || die "${out}" +tend $? "qmerge-test: [U] uninstall" || die "${out}" [[ ! -e ${ROOT}/etc ]] -tend $? "qmerge-test: [M] /etc removed" || die "$(treedir "${ROOT}")" +tend $? "qmerge-test: [U] /etc removed" || die "$(treedir "${ROOT}")" export INSTALL_MASK="/etc -/etc/some.conf" out=$(yes | qmerge -F qmerge-test) @@ -101,9 +115,9 @@ tend $? "qmerge-test: [M] install only /etc/some.conf" || die "${out}" tend $? "qmerge-test: [M] found /etc/another.conf" || die "$(treedir "${ROOT}")" out=$(yes | qmerge -FU qmerge-test) -tend $? "qmerge-test: [M] uninstall" || die "${out}" +tend $? "qmerge-test: [U] uninstall" || die "${out}" [[ ! -e ${ROOT}/etc ]] -tend $? "qmerge-test: [M] /etc removed" || die "$(treedir "${ROOT}")" +tend $? "qmerge-test: [U] /etc removed" || die "$(treedir "${ROOT}")" export INSTALL_MASK="/usr -/usr/bin/dummy" out=$(yes | qmerge -F qmerge-test) @@ -114,22 +128,22 @@ tend $? "qmerge-test: [M] found /usr/bin/dummy" || die "$(treedir "${ROOT}")" tend $? "qmerge-test: [M] /usr/bin/qmerge-test absent" || die "$(treedir "${ROOT}")" out=$(yes | qmerge -FU qmerge-test) -tend $? "qmerge-test: [M] uninstall" || die "${out}" +tend $? "qmerge-test: [U] uninstall" || die "${out}" [[ ! -e ${ROOT}/usr/bin/dummy ]] -tend $? "qmerge-test: [M] /usr/bin/dummy removed" || die "$(treedir "${ROOT}")" +tend $? "qmerge-test: [U] /usr/bin/dummy removed" || die "$(treedir "${ROOT}")" export INSTALL_MASK="/usr -/usr/bin /usr/bin/dummy" out=$(yes | qmerge -F qmerge-test) tend $? "qmerge-test: [M] install except /usr/bin/dummy" || die "${out}" [[ ! -e ${ROOT}/usr/bin/dummy ]] tend $? "qmerge-test: [M] found no /usr/bin/dummy" || die "$(treedir "${ROOT}")" -[[ -e ${ROOT}/usr/bin/qmerge-test ]] -tend $? "qmerge-test: [M] found /usr/bin/qmerge-test" || die "$(treedir "${ROOT}")" +[[ -e ${ROOT}/usr/bin/qmerge-test2 ]] +tend $? "qmerge-test: [M] found /usr/bin/qmerge-test2" || die "$(treedir "${ROOT}")" out=$(yes | qmerge -FU qmerge-test) -tend $? "qmerge-test: [M] uninstall" || die "${out}" -[[ ! -e ${ROOT}/usr/bin/qmerge-test ]] -tend $? "qmerge-test: [M] /usr/bin/qmerge-test removed" || die "$(treedir "${ROOT}")" +tend $? "qmerge-test: [U] uninstall" || die "${out}" +[[ ! -e ${ROOT}/usr/bin/qmerge-test2 ]] +tend $? "qmerge-test: [U] /usr/bin/qmerge-test2 removed" || die "$(treedir "${ROOT}")" # try all compressions we know to see if we handle them properly pkgver=qmerge-test-1.3 @@ -152,10 +166,10 @@ for compr in "" brotli gzip bzip2 xz lz4 zstd lzip lzop ; do : $((rev++)) qtbz2 -j ${f} ${pkgver}.xpak pkgs/sys-devel/${pkgver}-r${rev}.tbz2 ls -l pkgs/sys-devel/${pkgver}-r${rev}.tbz2 - ROOT=/ qlist -kIv | tee /dev/stderr | wc -l + qlist -kIv | tee /dev/stderr | wc -l # see if we can install this package - out=$(yes | qmerge -Fv qmerge-test) + out=$(yes | qmerge -Fv =${pkgver}-r${rev}) tend $? "qmerge-test: [X] install ${pkgver}-r${rev}" || die "${out}" qlist -Iv out=$(yes | qmerge -FU qmerge-test) diff --git a/tests/qmerge/packages/Packages b/tests/qmerge/packages/Packages index e6fa3a28..cd34d8db 100644 --- a/tests/qmerge/packages/Packages +++ b/tests/qmerge/packages/Packages @@ -28,3 +28,16 @@ SHA1: 47f731ce30149f5ab15f0c47dc19b46e4b189d60 SIZE: 7289 REPO: local +BUILD_TIME: 1367285976 +CPV: sys-devel/qmerge-test-2.0 +DEFINED_PHASES: install postinst postrm preinst prerm pretend setup +DESC: my desc +EAPI: 6 +KEYWORDS: ~amd64 ~x86 +LICENSE: GPL-2 +MD5: 100f6c414b1dc980fc73cf70178c2190 +MTIME: 1367290147 +SHA1: 5ba9c5db40a1b9be5e0e98b19b2cff5d2c197808 +SIZE: 7334 +REPO: local + diff --git a/tests/qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 b/tests/qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 Binary files differnew file mode 100644 index 00000000..1fac8012 --- /dev/null +++ b/tests/qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 |