1 |
commit: f1cf942274c47dce50bbaff45d41a8a83102e3fd |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Jun 14 09:32:02 2021 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Jun 14 09:32:02 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=f1cf9422 |
7 |
|
8 |
qmerge: once over to make better/more use of libq/tree |
9 |
|
10 |
- unify best_version and grab_binpkg_info, into single function using |
11 |
tree_match_atom to benefit from cache and abstract any particulars |
12 |
- default to install action when no action given |
13 |
- unmerge previous package on merge upgrade again |
14 |
- possibly fix bug #792273 by exporting vars |
15 |
|
16 |
Bug: https://bugs.gentoo.org/792273 |
17 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
18 |
|
19 |
qmerge.c | 782 ++++++++------------- |
20 |
tests/qmerge/dotest | 52 +- |
21 |
tests/qmerge/packages/Packages | 13 + |
22 |
.../qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 | Bin 0 -> 7334 bytes |
23 |
4 files changed, 356 insertions(+), 491 deletions(-) |
24 |
|
25 |
diff --git a/qmerge.c b/qmerge.c |
26 |
index 8f1ca3d..f5386f2 100644 |
27 |
--- a/qmerge.c |
28 |
+++ b/qmerge.c |
29 |
@@ -49,8 +49,6 @@ |
30 |
/* #define BUSYBOX "/bin/busybox" */ |
31 |
#define BUSYBOX "" |
32 |
|
33 |
-int old_repo = 0; |
34 |
- |
35 |
#define QMERGE_FLAGS "fFsKUpuyO" COMMON_FLAGS |
36 |
static struct option const qmerge_long_opts[] = { |
37 |
{"fetch", no_argument, NULL, 'f'}, |
38 |
@@ -91,25 +89,6 @@ char update_only = 0; |
39 |
bool debug = false; |
40 |
const char Packages[] = "Packages"; |
41 |
|
42 |
-/* |
43 |
- "CHOST", "DEPEND", "DESCRIPTION", "EAPI", |
44 |
- "IUSE", "KEYWORDS", "LICENSE", "PDEPEND", |
45 |
- "PROVIDE", "RDEPEND", "SLOT", "USE" |
46 |
-*/ |
47 |
-struct pkg_t { |
48 |
- char PF[64]; |
49 |
- char CATEGORY[64]; |
50 |
- char DESC[126]; |
51 |
- char LICENSE[64]; |
52 |
- char RDEPEND[BUFSIZ]; |
53 |
- char MD5[34]; |
54 |
- char SHA1[42]; |
55 |
- char SLOT[64]; |
56 |
- size_t SIZE; |
57 |
- char USE[BUFSIZ]; |
58 |
- char REPO[64]; |
59 |
-}; |
60 |
- |
61 |
struct llist_char_t { |
62 |
char *data; |
63 |
struct llist_char_t *next; |
64 |
@@ -117,17 +96,16 @@ struct llist_char_t { |
65 |
|
66 |
typedef struct llist_char_t llist_char; |
67 |
|
68 |
-static void pkg_fetch(int, const depend_atom *, const struct pkg_t *); |
69 |
-static void pkg_merge(int, const depend_atom *, const struct pkg_t *); |
70 |
+static void pkg_fetch(int, const depend_atom *, const tree_match_ctx *); |
71 |
+static void pkg_merge(int, const depend_atom *, const tree_match_ctx *); |
72 |
static int pkg_unmerge(tree_pkg_ctx *, set *, int, char **, int, char **); |
73 |
-static struct pkg_t *grab_binpkg_info(depend_atom *); |
74 |
|
75 |
static bool |
76 |
-prompt(const char *p) |
77 |
+qmerge_prompt(const char *p) |
78 |
{ |
79 |
printf("%s? [Y/n] ", p); |
80 |
fflush(stdout); |
81 |
- switch (getc(stdin)) { |
82 |
+ switch (fgetc(stdin)) { |
83 |
case '\n': |
84 |
case 'y': |
85 |
case 'Y': |
86 |
@@ -143,8 +121,7 @@ fetch(const char *destdir, const char *src) |
87 |
if (!binhost[0]) |
88 |
return; |
89 |
|
90 |
- fflush(stdout); |
91 |
- fflush(stderr); |
92 |
+ fflush(NULL); |
93 |
|
94 |
#if 0 |
95 |
if (getenv("FETCHCOMMAND") != NULL) { |
96 |
@@ -161,18 +138,15 @@ fetch(const char *destdir, const char *src) |
97 |
|
98 |
xasprintf(&path, "%s/%s", binhost, src); |
99 |
|
100 |
+ /* wget -c -q -P <dir> <uri> */ |
101 |
char prog[] = "wget"; |
102 |
- char argv_c[] = "-c"; |
103 |
- char argv_P[] = "-P"; |
104 |
- char argv_q[] = "-q"; |
105 |
- char *argv_dir = xstrdup(destdir); |
106 |
- char *argv[] = { |
107 |
+ char *const argv[] = { |
108 |
prog, |
109 |
- argv_c, |
110 |
- argv_P, |
111 |
- argv_dir, |
112 |
+ (char *)"-c", |
113 |
+ (char *)"-P", |
114 |
+ (char *)destdir, |
115 |
path, |
116 |
- quiet ? argv_q : NULL, |
117 |
+ quiet ? (char *)"-q" : NULL, |
118 |
NULL, |
119 |
}; |
120 |
if (!(force_download || install) && pretend) |
121 |
@@ -187,7 +161,6 @@ fetch(const char *destdir, const char *src) |
122 |
} |
123 |
|
124 |
free(path); |
125 |
- free(argv_dir); |
126 |
|
127 |
waitpid(p, &status, 0); |
128 |
#if 0 |
129 |
@@ -205,7 +178,7 @@ qmerge_initialize(void) |
130 |
{ |
131 |
char *buf; |
132 |
|
133 |
- if (strlen(BUSYBOX)) |
134 |
+ if (strlen(BUSYBOX) > 0) |
135 |
if (access(BUSYBOX, X_OK) != 0) |
136 |
err(BUSYBOX " must be installed"); |
137 |
|
138 |
@@ -232,52 +205,78 @@ qmerge_initialize(void) |
139 |
free(buf); |
140 |
} |
141 |
|
142 |
-static char _best_version_retbuf[4096]; |
143 |
-static int |
144 |
-qmerge_best_version_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
145 |
+static tree_ctx *_qmerge_vdb_tree = NULL; |
146 |
+static tree_ctx *_qmerge_binpkg_tree = NULL; |
147 |
+#define BV_INSTALLED BV_VDB |
148 |
+#define BV_BINARY BV_BINPKG |
149 |
+#define BV_EBUILD (1<<0) /* not yet supported */ |
150 |
+#define BV_VDB (1<<1) |
151 |
+#define BV_BINPKG (1<<2) |
152 |
+static tree_match_ctx * |
153 |
+best_version(const depend_atom *atom, int mode) |
154 |
{ |
155 |
- depend_atom *sa = priv; |
156 |
- depend_atom *a = tree_get_atom(pkg_ctx, true); /* need SLOT */ |
157 |
- if (atom_compare(a, sa) == EQUAL) |
158 |
- snprintf(_best_version_retbuf, sizeof(_best_version_retbuf), |
159 |
- "%s/%s:%s", a->CATEGORY, a->PF, a->SLOT); |
160 |
- return 0; |
161 |
-} |
162 |
+ tree_ctx *vdb = _qmerge_vdb_tree; |
163 |
+ tree_ctx *binpkg = _qmerge_binpkg_tree; |
164 |
+ tree_match_ctx *tmv = NULL; |
165 |
+ tree_match_ctx *tmp = NULL; |
166 |
+ tree_match_ctx *ret; |
167 |
+ int r; |
168 |
+ |
169 |
+ if (mode & BV_EBUILD) { |
170 |
+ warn("BV_EBUILD not yet supported"); |
171 |
+ return NULL; |
172 |
+ } |
173 |
+ if (mode == 0) { |
174 |
+ warn("mode needs to be set"); |
175 |
+ return NULL; |
176 |
+ } |
177 |
|
178 |
-static char * |
179 |
-best_version(const char *catname, const char *pkgname, const char *slot) |
180 |
-{ |
181 |
- static int vdb_check = 1; |
182 |
- tree_ctx *vdb; |
183 |
- |
184 |
- /* Make sure these dirs exist before we try walking them */ |
185 |
- switch (vdb_check) { |
186 |
- case 1: { |
187 |
- int fd = open(portroot, O_RDONLY|O_CLOEXEC|O_PATH); |
188 |
- if (fd >= 0) { |
189 |
- /* skip leading slash */ |
190 |
- vdb_check = faccessat(fd, portvdb + 1, X_OK, 0); |
191 |
- close(fd); |
192 |
- } else |
193 |
- vdb_check = -1; |
194 |
+ if (mode & BV_VDB) { |
195 |
+ if (vdb == NULL) { |
196 |
+ vdb = tree_open_vdb(portroot, portvdb); |
197 |
+ if (vdb == NULL) |
198 |
+ return NULL; |
199 |
+ _qmerge_vdb_tree = vdb; |
200 |
+ } |
201 |
+ tmv = tree_match_atom(vdb, atom, |
202 |
+ TREE_MATCH_LATEST | TREE_MATCH_FIRST); |
203 |
} |
204 |
- if (vdb_check) |
205 |
- case -1: |
206 |
- goto done; |
207 |
+ |
208 |
+ if (mode & BV_BINPKG) { |
209 |
+ if (binpkg == NULL) { |
210 |
+ binpkg = tree_open_binpkg("/", pkgdir); |
211 |
+ if (binpkg == NULL) { |
212 |
+ if (tmv != NULL) |
213 |
+ tree_match_close(tmv); |
214 |
+ if (vdb != NULL) |
215 |
+ tree_close(vdb); |
216 |
+ return NULL; |
217 |
+ } |
218 |
+ _qmerge_binpkg_tree = binpkg; |
219 |
+ } |
220 |
+ tmp = tree_match_atom(binpkg, atom, |
221 |
+ TREE_MATCH_LATEST | TREE_MATCH_FIRST | TREE_MATCH_METADATA); |
222 |
} |
223 |
|
224 |
- snprintf(_best_version_retbuf, sizeof(_best_version_retbuf), |
225 |
- "%s%s%s:%s", catname ? : "", catname ? "/" : "", pkgname, slot); |
226 |
- vdb = tree_open_vdb(portroot, portvdb); |
227 |
- if (vdb != NULL) { |
228 |
- depend_atom *sa = atom_explode(_best_version_retbuf); |
229 |
- tree_foreach_pkg_fast(vdb, qmerge_best_version_cb, sa, sa); |
230 |
- tree_close(vdb); |
231 |
- atom_implode(sa); |
232 |
+ if (tmv == NULL && tmp == NULL) |
233 |
+ ret = NULL; |
234 |
+ else if (tmv == NULL && tmp != NULL) |
235 |
+ ret = tmp; |
236 |
+ else if (tmv != NULL && tmp == NULL) |
237 |
+ ret = tmv; |
238 |
+ else { |
239 |
+ if ((r = atom_compare(tmv->atom, tmp->atom)) == EQUAL || r == OLDER) |
240 |
+ ret = tmp; |
241 |
+ else |
242 |
+ ret = tmv; |
243 |
} |
244 |
|
245 |
- done: |
246 |
- return _best_version_retbuf; |
247 |
+ if (tmv != NULL && tmv != ret) |
248 |
+ tree_match_close(tmv); |
249 |
+ if (tmp != NULL && tmp != ret) |
250 |
+ tree_match_close(tmp); |
251 |
+ |
252 |
+ return ret; |
253 |
} |
254 |
|
255 |
static int |
256 |
@@ -557,50 +556,47 @@ install_mask_pwd(int iargc, char **iargv, const struct stat * const st, int fd) |
257 |
} |
258 |
|
259 |
static char |
260 |
-qprint_tree_node(int level, const depend_atom *atom, const struct pkg_t *pkg) |
261 |
+qprint_tree_node( |
262 |
+ int level, |
263 |
+ const tree_match_ctx *mpkg, |
264 |
+ const tree_match_ctx *bpkg, |
265 |
+ int replacing) |
266 |
{ |
267 |
- char buf[1024]; |
268 |
- char *p; |
269 |
- int i, ret; |
270 |
- |
271 |
- char install_ver[126] = ""; |
272 |
- char c = 'N'; |
273 |
- const char *color; |
274 |
+ char buf[1024]; |
275 |
+ int i; |
276 |
+ char install_ver[126] = ""; |
277 |
+ char c = 'N'; |
278 |
+ const char *color; |
279 |
|
280 |
if (!pretend) |
281 |
return 0; |
282 |
|
283 |
- p = best_version(pkg->CATEGORY, atom->PN, pkg->SLOT); |
284 |
- |
285 |
- if (strlen(p) < 1) { |
286 |
+ if (bpkg == NULL) { |
287 |
c = 'N'; |
288 |
snprintf(buf, sizeof(buf), "%sN%s", GREEN, NORM); |
289 |
} else { |
290 |
- depend_atom *subatom = atom_explode(p); |
291 |
- if (subatom != NULL) { |
292 |
- ret = atom_compare(subatom, atom); |
293 |
- switch (ret) { |
294 |
+ if (bpkg != NULL) { |
295 |
+ switch (replacing) { |
296 |
case EQUAL: c = 'R'; break; |
297 |
case NEWER: c = 'U'; break; |
298 |
case OLDER: c = 'D'; break; |
299 |
- default: c = '?'; break; |
300 |
+ default: c = '?'; break; |
301 |
} |
302 |
snprintf(install_ver, sizeof(install_ver), "[%s%.*s%s] ", |
303 |
DKBLUE, |
304 |
(int)(sizeof(install_ver) - 4 - |
305 |
sizeof(DKBLUE) - sizeof(NORM)), |
306 |
- subatom->P, NORM); |
307 |
- atom_implode(subatom); |
308 |
+ bpkg->atom->PVR, NORM); |
309 |
} |
310 |
if (update_only && c != 'U') |
311 |
return c; |
312 |
if ((c == 'R' || c == 'D') && update_only && level) |
313 |
return c; |
314 |
switch (c) { |
315 |
- case 'R': color = YELLOW; break; |
316 |
- case 'U': color = BLUE; break; |
317 |
- case 'D': color = DKBLUE; break; |
318 |
- default: color = RED; break; |
319 |
+ case 'R': color = YELLOW; break; |
320 |
+ case 'U': color = BLUE; break; |
321 |
+ case 'D': color = DKBLUE; break; |
322 |
+ default: color = RED; break; |
323 |
} |
324 |
snprintf(buf, sizeof(buf), "%s%c%s", color, c, NORM); |
325 |
#if 0 |
326 |
@@ -615,14 +611,19 @@ qprint_tree_node(int level, const depend_atom *atom, const struct pkg_t *pkg) |
327 |
} |
328 |
#endif |
329 |
} |
330 |
+ |
331 |
printf("[%s] ", buf); |
332 |
for (i = 0; i < level; ++i) |
333 |
putchar(' '); |
334 |
- if (verbose) |
335 |
- printf("%s%s/%s%s %s%s%s%s%s%s\n", DKGREEN, pkg->CATEGORY, pkg->PF, NORM, |
336 |
- install_ver, strlen(pkg->USE) > 0 ? "(" : "", RED, pkg->USE, NORM, strlen(pkg->USE) > 0 ? ")" : ""); |
337 |
- else |
338 |
- printf("%s%s/%s%s\n", DKGREEN, pkg->CATEGORY, pkg->PF, NORM); |
339 |
+ if (verbose) { |
340 |
+ char *use = mpkg->meta->Q_USE; /* TODO: compute difference */ |
341 |
+ printf("%s %s%s%s%s%s%s\n", |
342 |
+ atom_format("%[CAT]%[PF]", mpkg->atom), |
343 |
+ install_ver, use != NULL ? "(" : "", |
344 |
+ RED, use, NORM, use != NULL ? ")" : ""); |
345 |
+ } else { |
346 |
+ printf("%s\n", atom_format("%[CAT]%[PF]", mpkg->atom)); |
347 |
+ } |
348 |
return c; |
349 |
} |
350 |
|
351 |
@@ -641,7 +642,7 @@ pkg_run_func_at(int dirfd, const char *vdb_path, const char *phases, const char |
352 |
return; |
353 |
} |
354 |
|
355 |
- qprintf(">>> %s\n", func); |
356 |
+ qprintf("@@@ %s\n", func); |
357 |
|
358 |
xasprintf(&script, |
359 |
/* Provide funcs required by the PMS */ |
360 |
@@ -681,16 +682,16 @@ pkg_run_func_at(int dirfd, const char *vdb_path, const char *phases, const char |
361 |
/* Load the main env */ |
362 |
". '%1$s/environment'\n" |
363 |
/* Reload env vars that matter to us */ |
364 |
- "FILESDIR=/.does/not/exist/anywhere\n" |
365 |
- "MERGE_TYPE=binary\n" |
366 |
- "ROOT='%4$s'\n" |
367 |
- "EROOT=\"${ROOT%%/}${EPREFIX%%/}/\"\n" |
368 |
- "D=\"%5$s\"\n" |
369 |
- "ED=\"${D%%/}${EPREFIX%%/}/\"\n" |
370 |
- "T=\"%6$s\"\n" |
371 |
+ "export FILESDIR=/.does/not/exist/anywhere\n" |
372 |
+ "export MERGE_TYPE=binary\n" |
373 |
+ "export ROOT='%4$s'\n" |
374 |
+ "export EROOT=\"${ROOT%%/}${EPREFIX%%/}/\"\n" |
375 |
+ "export D=\"%5$s\"\n" |
376 |
+ "export ED=\"${D%%/}${EPREFIX%%/}/\"\n" |
377 |
+ "export T=\"%6$s\"\n" |
378 |
/* we do not support preserve-libs yet, so force |
379 |
* preserve_old_lib instead */ |
380 |
- "FEATURES=\"${FEATURES/preserve-libs/disabled}\"\n" |
381 |
+ "export FEATURES=\"${FEATURES/preserve-libs/disabled}\"\n" |
382 |
/* Finally run the func */ |
383 |
"%7$s%2$s\n" |
384 |
/* Ignore func return values (not exit values) */ |
385 |
@@ -778,7 +779,7 @@ merge_tree_at(int fd_src, const char *src, int fd_dst, const char *dst, |
386 |
if (!pretend) |
387 |
fprintf(contents, "dir %s\n", cpath); |
388 |
*objs = add_set(cpath, *objs); |
389 |
- qprintf("%s>>>%s %s%s%s/\n", GREEN, NORM, DKBLUE, cpath, NORM); |
390 |
+ qprintf("%s---%s %s%s%s/\n", GREEN, NORM, DKBLUE, cpath, NORM); |
391 |
|
392 |
/* Copy all of these contents */ |
393 |
merge_tree_at(subfd_src, name, |
394 |
@@ -973,67 +974,78 @@ pkg_extract_xpak_cb( |
395 |
} |
396 |
|
397 |
/* oh shit getting into pkg mgt here. FIXME: write a real dep resolver. */ |
398 |
+static char *pm_phases; |
399 |
+static size_t pm_phases_len; |
400 |
static void |
401 |
-pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
402 |
+pkg_merge(int level, const depend_atom *qatom, const tree_match_ctx *mpkg) |
403 |
{ |
404 |
- set *objs; |
405 |
- tree_ctx *vdb; |
406 |
- tree_cat_ctx *cat_ctx; |
407 |
- FILE *fp, *contents; |
408 |
- static char *phases; |
409 |
- static size_t phases_len; |
410 |
- char *eprefix = NULL; |
411 |
- size_t eprefix_len = 0; |
412 |
- char buf[1024]; |
413 |
- char *tbz2, *p, *D, *T; |
414 |
- int i; |
415 |
- char **ARGV; |
416 |
- int ARGC; |
417 |
- struct stat st; |
418 |
- char **iargv; |
419 |
- char c; |
420 |
- int iargc; |
421 |
- const char *compr; |
422 |
- int cp_argc; |
423 |
- int cpm_argc; |
424 |
- char **cp_argv; |
425 |
- char **cpm_argv; |
426 |
- int tbz2size; |
427 |
- |
428 |
- if (!install || !pkg || !atom) |
429 |
+ set *objs; |
430 |
+ tree_ctx *vdb; |
431 |
+ tree_cat_ctx *cat_ctx; |
432 |
+ tree_match_ctx *bpkg; |
433 |
+ tree_match_ctx *previnst; |
434 |
+ depend_atom *slotatom; |
435 |
+ FILE *fp; |
436 |
+ FILE *contents; |
437 |
+ char *eprefix = NULL; |
438 |
+ size_t eprefix_len = 0; |
439 |
+ char buf[1024]; |
440 |
+ char *p; |
441 |
+ char *D; |
442 |
+ char *T; |
443 |
+ int i; |
444 |
+ char **ARGV; |
445 |
+ int ARGC; |
446 |
+ struct stat st; |
447 |
+ char **iargv; |
448 |
+ int iargc; |
449 |
+ const char *compr; |
450 |
+ int cp_argc; |
451 |
+ int cpm_argc; |
452 |
+ char **cp_argv; |
453 |
+ char **cpm_argv; |
454 |
+ int tbz2size; |
455 |
+ int replacing = 0; |
456 |
+ |
457 |
+ if (!install || !mpkg || !qatom) |
458 |
return; |
459 |
|
460 |
- if (!pkg->PF[0] || !pkg->CATEGORY[0]) { |
461 |
- if (verbose) warn("CPF is really NULL at level %d", level); |
462 |
- return; |
463 |
- } |
464 |
+ /* create atom of the installed mpkg without version, with this |
465 |
+ * SLOT (without SUBSLOT) */ |
466 |
+ snprintf(buf, sizeof(buf), "%s/%s:%s", |
467 |
+ mpkg->atom->CATEGORY, |
468 |
+ mpkg->atom->PN, |
469 |
+ mpkg->atom->SLOT != NULL ? "0" : mpkg->atom->SLOT); |
470 |
+ slotatom = atom_explode(buf); |
471 |
|
472 |
- c = qprint_tree_node(level, atom, pkg); |
473 |
+ previnst = best_version(slotatom, BV_INSTALLED); |
474 |
+ if (previnst != NULL) |
475 |
+ replacing = atom_compare(mpkg->atom, slotatom); |
476 |
|
477 |
- if (0) |
478 |
- if (((c == 'R') || (c == 'D')) && update_only) |
479 |
- return; |
480 |
+ (void)qprint_tree_node(level, mpkg, previnst, replacing); |
481 |
|
482 |
- if (pkg->RDEPEND[0] != '\0' && follow_rdepends) { |
483 |
- const char *rdepend; |
484 |
+ if (mpkg->meta->Q_RDEPEND != NULL && |
485 |
+ mpkg->meta->Q_RDEPEND[0] != '\0' && |
486 |
+ follow_rdepends) |
487 |
+ { |
488 |
+ const char *rdepend = mpkg->meta->Q_RDEPEND; |
489 |
|
490 |
- IF_DEBUG(fprintf(stderr, "\n+Parent: %s/%s\n", pkg->CATEGORY, pkg->PF)); |
491 |
- IF_DEBUG(fprintf(stderr, "+Depstring: %s\n", pkg->RDEPEND)); |
492 |
+ IF_DEBUG(fprintf(stderr, "\n+Parent: %s\n+Depstring: %s\n", |
493 |
+ atom_to_string(mpkg->atom), rdepend)); |
494 |
|
495 |
/* <hack> */ |
496 |
- if (strncmp(pkg->RDEPEND, "|| ", 3) == 0) { |
497 |
+ if (strncmp(rdepend, "|| ", 3) == 0) { |
498 |
if (verbose) |
499 |
- qfprintf(stderr, "fix this rdepend hack %s\n", pkg->RDEPEND); |
500 |
+ qfprintf(stderr, "fix this rdepend hack %s\n", rdepend); |
501 |
rdepend = ""; |
502 |
- } else |
503 |
- rdepend = pkg->RDEPEND; |
504 |
+ } |
505 |
/* </hack> */ |
506 |
|
507 |
makeargv(rdepend, &ARGC, &ARGV); |
508 |
/* Walk the rdepends here. Merging what need be. */ |
509 |
for (i = 1; i < ARGC; i++) { |
510 |
- depend_atom *subatom, *ratom; |
511 |
- char *name = ARGV[i]; |
512 |
+ depend_atom *subatom; |
513 |
+ char *name = ARGV[i]; |
514 |
switch (*name) { |
515 |
case '|': |
516 |
case '!': |
517 |
@@ -1046,41 +1058,19 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
518 |
break; |
519 |
default: |
520 |
if ((subatom = atom_explode(name)) != NULL) { |
521 |
- struct pkg_t *subpkg; |
522 |
- |
523 |
- subpkg = grab_binpkg_info(subatom); /* free me later */ |
524 |
- if (subpkg == NULL) { |
525 |
- warn("Cannot find a binpkg for %s from rdepend(%s)", |
526 |
- name, pkg->RDEPEND); |
527 |
+ bpkg = best_version(subatom, BV_INSTALLED | BV_BINPKG); |
528 |
+ if (bpkg == NULL) { |
529 |
+ warn("cannot resolve %s from rdepend(%s)", |
530 |
+ name, rdepend); |
531 |
atom_implode(subatom); |
532 |
continue; |
533 |
} |
534 |
|
535 |
- assert(subpkg != NULL); |
536 |
- IF_DEBUG(fprintf(stderr, "+Subpkg: %s/%s\n", |
537 |
- subpkg->CATEGORY, subpkg->PF)); |
538 |
- |
539 |
- /* look at installed versions now. |
540 |
- * If NULL or < merge this pkg */ |
541 |
- snprintf(buf, sizeof(buf), "%s/%s", |
542 |
- subpkg->CATEGORY, subpkg->PF); |
543 |
- |
544 |
- ratom = atom_explode(buf); |
545 |
- |
546 |
- p = best_version(subpkg->CATEGORY, |
547 |
- subpkg->PF, subpkg->SLOT); |
548 |
- |
549 |
- /* we dont want to remerge equal versions here */ |
550 |
- IF_DEBUG(fprintf(stderr, "+Installed: %s\n", p)); |
551 |
- if (strlen(p) < 1) |
552 |
- if (!((strcmp(pkg->PF, subpkg->PF) == 0) && |
553 |
- (strcmp(pkg->CATEGORY, |
554 |
- subpkg->CATEGORY) == 0))) |
555 |
- pkg_fetch(level+1, ratom, subpkg); |
556 |
+ if (bpkg->pkg->cat_ctx->ctx->cachetype != CACHE_VDB) |
557 |
+ pkg_fetch(level + 1, subatom, bpkg); |
558 |
|
559 |
+ tree_match_close(bpkg); |
560 |
atom_implode(subatom); |
561 |
- atom_implode(ratom); |
562 |
- free(subpkg); |
563 |
} else { |
564 |
qfprintf(stderr, "Cant explode atom %s\n", name); |
565 |
} |
566 |
@@ -1103,22 +1093,22 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
567 |
} |
568 |
if (vdb == NULL) |
569 |
errf("need access to root, check permissions to access %s", portroot); |
570 |
- cat_ctx = tree_open_cat(vdb, pkg->CATEGORY); |
571 |
+ cat_ctx = tree_open_cat(vdb, mpkg->atom->CATEGORY); |
572 |
if (!cat_ctx) { |
573 |
if (errno != ENOENT) { |
574 |
tree_close(vdb); |
575 |
return; |
576 |
} |
577 |
- mkdirat(vdb->tree_fd, pkg->CATEGORY, 0755); |
578 |
- cat_ctx = tree_open_cat(vdb, pkg->CATEGORY); |
579 |
+ mkdirat(vdb->tree_fd, mpkg->atom->CATEGORY, 0755); |
580 |
+ cat_ctx = tree_open_cat(vdb, mpkg->atom->CATEGORY); |
581 |
if (!cat_ctx) { |
582 |
tree_close(vdb); |
583 |
return; |
584 |
} |
585 |
} |
586 |
|
587 |
- /* Set up our temp dir to unpack this stuff */ |
588 |
- xasprintf(&p, "%s/qmerge/%s/%s", port_tmpdir, pkg->CATEGORY, pkg->PF); |
589 |
+ /* Set up our temp dir to unpack this stuff FIXME p -> builddir */ |
590 |
+ xasprintf(&p, "%s/qmerge/%s", port_tmpdir, atom_to_string(mpkg->atom)); |
591 |
mkdir_p(p, 0755); |
592 |
xchdir(p); |
593 |
xasprintf(&D, "%s/image", p); |
594 |
@@ -1131,7 +1121,6 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
595 |
mkdir("temp", 0755); |
596 |
mkdir_p(portroot, 0755); |
597 |
|
598 |
- xasprintf(&tbz2, "%s/%s/%s.tbz2", pkgdir, pkg->CATEGORY, pkg->PF); |
599 |
tbz2size = 0; |
600 |
|
601 |
mkdir("vdb", 0755); |
602 |
@@ -1139,10 +1128,10 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
603 |
int vdbfd = open("vdb", O_RDONLY); |
604 |
if (vdbfd == -1) |
605 |
err("failed to open vdb extraction directory"); |
606 |
- tbz2size = xpak_extract(tbz2, &vdbfd, pkg_extract_xpak_cb); |
607 |
+ tbz2size = xpak_extract(mpkg->path, &vdbfd, pkg_extract_xpak_cb); |
608 |
} |
609 |
if (tbz2size <= 0) |
610 |
- err("%s appears not to be a valid tbz2 file", tbz2); |
611 |
+ err("%s appears not to be a valid tbz2 file", mpkg->path); |
612 |
|
613 |
/* figure out if the data is compressed differently from what the |
614 |
* name suggests, bug #660508, usage of BINPKG_COMPRESS, |
615 |
@@ -1162,7 +1151,7 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
616 |
FILE *mfd; |
617 |
|
618 |
compr = "brotli -dc"; /* default: brotli; has no magic header */ |
619 |
- mfd = fopen(tbz2, "r"); |
620 |
+ mfd = fopen(mpkg->path, "r"); |
621 |
if (mfd != NULL) { |
622 |
size_t mlen = fread(magic, 1, sizeof(magic), mfd); |
623 |
fclose(mfd); |
624 |
@@ -1261,18 +1250,18 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
625 |
if ((tarpipe = popen(buf, "w")) == NULL) |
626 |
errp("failed to start %s", buf); |
627 |
|
628 |
- if ((tbz2f = fopen(tbz2, "r")) == NULL) |
629 |
- errp("failed to open %s for reading", tbz2); |
630 |
+ if ((tbz2f = fopen(mpkg->path, "r")) == NULL) |
631 |
+ errp("failed to open %s for reading", mpkg->path); |
632 |
|
633 |
for (piped = wr = 0; piped < tbz2size; piped += wr) { |
634 |
n = MIN(tbz2size - piped, (ssize_t)sizeof iobuf); |
635 |
rd = fread(iobuf, 1, n, tbz2f); |
636 |
if (0 == rd) { |
637 |
if ((err = ferror(tbz2f)) != 0) |
638 |
- err("reading %s failed: %s", tbz2, strerror(err)); |
639 |
+ err("reading %s failed: %s", mpkg->path, strerror(err)); |
640 |
|
641 |
if (feof(tbz2f)) |
642 |
- err("unexpected EOF in %s: corrupted binpkg", tbz2); |
643 |
+ err("unexpected EOF in %s: corrupted binpkg", mpkg->path); |
644 |
} |
645 |
|
646 |
for (wr = n = 0; wr < rd; wr += n) { |
647 |
@@ -1296,13 +1285,12 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
648 |
errp("finishing unpack binpkg unsuccessful"); |
649 |
} |
650 |
|
651 |
- free(tbz2); |
652 |
fflush(stdout); |
653 |
|
654 |
- eat_file("vdb/DEFINED_PHASES", &phases, &phases_len); |
655 |
- pkg_run_func("vdb", phases, "pkg_pretend", D, T); |
656 |
- pkg_run_func("vdb", phases, "pkg_setup", D, T); |
657 |
- pkg_run_func("vdb", phases, "pkg_preinst", D, T); |
658 |
+ eat_file("vdb/DEFINED_PHASES", &pm_phases, &pm_phases_len); |
659 |
+ pkg_run_func("vdb", pm_phases, "pkg_pretend", D, T); |
660 |
+ pkg_run_func("vdb", pm_phases, "pkg_setup", D, T); |
661 |
+ pkg_run_func("vdb", pm_phases, "pkg_preinst", D, T); |
662 |
|
663 |
if (!eat_file("vdb/EPREFIX", &eprefix, &eprefix_len)) |
664 |
eprefix_len = 0; |
665 |
@@ -1379,7 +1367,7 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
666 |
|
667 |
/* run postinst */ |
668 |
if (!pretend) |
669 |
- pkg_run_func("vdb", phases, "pkg_postinst", D, T); |
670 |
+ pkg_run_func("vdb", pm_phases, "pkg_postinst", D, T); |
671 |
|
672 |
/* XXX: hmm, maybe we'll want to strip more ? */ |
673 |
unlink("vdb/environment"); |
674 |
@@ -1387,43 +1375,24 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
675 |
/* Unmerge any stray pieces from the older version which we didn't |
676 |
* replace */ |
677 |
/* TODO: Should see about merging with unmerge_packages() */ |
678 |
- while (1) { |
679 |
- int ret; |
680 |
- tree_pkg_ctx *pkg_ctx; |
681 |
- depend_atom *old_atom; |
682 |
- |
683 |
- pkg_ctx = tree_next_pkg(cat_ctx); |
684 |
- if (!pkg_ctx) |
685 |
+ switch (replacing) { |
686 |
+ case NEWER: |
687 |
+ case OLDER: |
688 |
+ case EQUAL: |
689 |
+ /* We need to really set this unmerge pending after we |
690 |
+ * look at contents of the new pkg */ |
691 |
+ pkg_unmerge(previnst->pkg, objs, |
692 |
+ cp_argc, cp_argv, cpm_argc, cpm_argv); |
693 |
+ break; |
694 |
+ default: |
695 |
+ warn("no idea how we reached here."); |
696 |
+ case ERROR: |
697 |
+ case NOT_EQUAL: |
698 |
break; |
699 |
- old_atom = tree_get_atom(pkg_ctx, 1); /* retrieve SLOT */ |
700 |
- if (!old_atom) |
701 |
- goto next_pkg; |
702 |
- old_atom->SUBSLOT = NULL; /* just match SLOT */ |
703 |
- old_atom->REPO = NULL; /* REPO never matters, TODO atom_compare */ |
704 |
- ret = atom_compare(atom, old_atom); |
705 |
- switch (ret) { |
706 |
- case NEWER: |
707 |
- case OLDER: |
708 |
- case EQUAL: |
709 |
- /* We need to really set this unmerge pending after we |
710 |
- * look at contents of the new pkg */ |
711 |
- break; |
712 |
- default: |
713 |
- warn("no idea how we reached here."); |
714 |
- case ERROR: |
715 |
- case NOT_EQUAL: |
716 |
- goto next_pkg; |
717 |
- } |
718 |
- |
719 |
- printf("%s+++%s %s/%s %s %s/%s\n", |
720 |
- GREEN, NORM, atom->CATEGORY, pkg->PF, |
721 |
- booga[ret], cat_ctx->name, pkg_ctx->name); |
722 |
- |
723 |
- pkg_unmerge(pkg_ctx, objs, cp_argc, cp_argv, cpm_argc, cpm_argv); |
724 |
- next_pkg: |
725 |
- tree_close_pkg(pkg_ctx); |
726 |
} |
727 |
|
728 |
+ tree_match_close(previnst); |
729 |
+ |
730 |
freeargv(cp_argc, cp_argv); |
731 |
freeargv(cpm_argc, cpm_argv); |
732 |
|
733 |
@@ -1442,9 +1411,9 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
734 |
if (!pretend) { |
735 |
/* move the local vdb copy to the final place */ |
736 |
snprintf(buf, sizeof(buf), "%s%s/%s/", |
737 |
- portroot, portvdb, pkg->CATEGORY); |
738 |
+ portroot, portvdb, mpkg->atom->CATEGORY); |
739 |
mkdir_p(buf, 0755); |
740 |
- strcat(buf, pkg->PF); |
741 |
+ strcat(buf, mpkg->atom->PF); |
742 |
rm_rf(buf); /* get rid of existing dir, empty dir is fine */ |
743 |
if (rename("vdb", buf) != 0) |
744 |
warn("failed to move 'vdb' to '%s': %s", buf, strerror(errno)); |
745 |
@@ -1452,12 +1421,12 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
746 |
|
747 |
/* clean up our local temp dir */ |
748 |
xchdir(".."); |
749 |
- rm_rf(pkg->PF); |
750 |
+ rm_rf(mpkg->atom->PF); |
751 |
/* don't care about return */ |
752 |
rmdir("../qmerge"); |
753 |
|
754 |
- printf("%s>>>%s %s%s%s/%s%s%s\n", |
755 |
- YELLOW, NORM, WHITE, pkg->CATEGORY, NORM, CYAN, pkg->PF, NORM); |
756 |
+ printf("%s>>>%s %s\n", |
757 |
+ YELLOW, NORM, atom_format("%[CAT]%[PF]", mpkg->atom)); |
758 |
|
759 |
tree_close_cat(cat_ctx); |
760 |
tree_close(vdb); |
761 |
@@ -1481,7 +1450,7 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep, |
762 |
buf = phases = NULL; |
763 |
T = "${PWD}/temp"; |
764 |
|
765 |
- printf("%s<<<%s %s\n", YELLOW, NORM, |
766 |
+ printf("%s***%s unmerging %s\n", YELLOW, NORM, |
767 |
atom_format("%[CATEGORY]%[PF]", tree_get_atom(pkg_ctx, false))); |
768 |
|
769 |
if (pretend == 100) |
770 |
@@ -1513,11 +1482,11 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep, |
771 |
strstr(features, "config-protect-if-modified") != NULL; |
772 |
|
773 |
for (; (buf = strtok_r(buf, "\n", &savep)) != NULL; buf = NULL) { |
774 |
- bool del; |
775 |
+ bool del; |
776 |
contents_entry *e; |
777 |
- char zing[20]; |
778 |
- int protected = 0; |
779 |
- struct stat st; |
780 |
+ char zing[20]; |
781 |
+ int protected = 0; |
782 |
+ struct stat st; |
783 |
|
784 |
e = contents_parse_line(buf); |
785 |
if (!e) |
786 |
@@ -1657,55 +1626,58 @@ unlink_empty(const char *buf) |
787 |
|
788 |
static int |
789 |
pkg_verify_checksums( |
790 |
- char *fname, |
791 |
- const struct pkg_t *pkg, |
792 |
- int strict, |
793 |
- int display) |
794 |
+ const tree_match_ctx *pkg, |
795 |
+ int strict, |
796 |
+ int display) |
797 |
{ |
798 |
- int ret = 0; |
799 |
- char md5[32+1]; |
800 |
- char sha1[40+1]; |
801 |
+ int ret = 0; |
802 |
+ char md5[32+1]; |
803 |
+ char sha1[40+1]; |
804 |
size_t flen; |
805 |
+ int mlen; |
806 |
|
807 |
- if (hash_multiple_file(fname, md5, sha1, NULL, NULL, NULL, NULL, |
808 |
+ if (hash_multiple_file(pkg->path, md5, sha1, NULL, NULL, NULL, NULL, |
809 |
&flen, HASH_MD5 | HASH_SHA1) == -1) |
810 |
- errf("failed to compute hashes for %s/%s: %s\n", |
811 |
- pkg->CATEGORY, pkg->PF, strerror(errno)); |
812 |
+ errf("failed to compute hashes for %s: %s\n", |
813 |
+ atom_to_string(pkg->atom), strerror(errno)); |
814 |
|
815 |
- if (flen != pkg->SIZE) { |
816 |
- warn("filesize %zu doesn't match requested size %zu for %s/%s\n", |
817 |
- flen, pkg->SIZE, pkg->CATEGORY, pkg->PF); |
818 |
+ mlen = atoi(pkg->meta->Q_SIZE); |
819 |
+ if (flen != (size_t)mlen) { |
820 |
+ warn("filesize %zu doesn't match requested size %d for %s\n", |
821 |
+ flen, mlen, atom_to_string(pkg->atom)); |
822 |
ret++; |
823 |
} |
824 |
|
825 |
- if (pkg->MD5[0]) { |
826 |
- if (strcmp(md5, pkg->MD5) == 0) { |
827 |
+ if (pkg->meta->Q_MD5 != NULL) { |
828 |
+ if (strcmp(md5, pkg->meta->Q_MD5) == 0) { |
829 |
if (display) |
830 |
- printf("MD5: [%sOK%s] %s %s/%s\n", |
831 |
- GREEN, NORM, md5, pkg->CATEGORY, pkg->PF); |
832 |
+ printf("MD5: [%sOK%s] %s %s\n", |
833 |
+ GREEN, NORM, md5, atom_to_string(pkg->atom)); |
834 |
} else { |
835 |
if (display) |
836 |
- warn("MD5: [%sER%s] (%s) != (%s) %s/%s", |
837 |
- RED, NORM, md5, pkg->MD5, pkg->CATEGORY, pkg->PF); |
838 |
+ warn("MD5: [%sER%s] (%s) != (%s) %s", |
839 |
+ RED, NORM, md5, pkg->meta->Q_MD5, |
840 |
+ atom_to_string(pkg->atom)); |
841 |
ret++; |
842 |
} |
843 |
} |
844 |
|
845 |
- if (pkg->SHA1[0]) { |
846 |
- if (strcmp(sha1, pkg->SHA1) == 0) { |
847 |
+ if (pkg->meta->Q_SHA1 != NULL) { |
848 |
+ if (strcmp(sha1, pkg->meta->Q_SHA1) == 0) { |
849 |
if (display) |
850 |
- qprintf("SHA1: [%sOK%s] %s %s/%s\n", |
851 |
- GREEN, NORM, sha1, pkg->CATEGORY, pkg->PF); |
852 |
+ qprintf("SHA1: [%sOK%s] %s %s\n", |
853 |
+ GREEN, NORM, sha1, atom_to_string(pkg->atom)); |
854 |
} else { |
855 |
if (display) |
856 |
- warn("SHA1: [%sER%s] (%s) != (%s) %s/%s", |
857 |
- RED, NORM, sha1, pkg->SHA1, pkg->CATEGORY, pkg->PF); |
858 |
+ warn("SHA1: [%sER%s] (%s) != (%s) %s", |
859 |
+ RED, NORM, sha1, pkg->meta->Q_SHA1, |
860 |
+ atom_to_string(pkg->atom)); |
861 |
ret++; |
862 |
} |
863 |
} |
864 |
|
865 |
- if (!pkg->SHA1[0] && !pkg->MD5[0]) |
866 |
- return 1; |
867 |
+ if (pkg->meta->Q_MD5 == NULL && pkg->meta->Q_SHA1 == NULL) |
868 |
+ return -1; |
869 |
|
870 |
if (strict && ret) |
871 |
errf("strict is set in features"); |
872 |
@@ -1714,140 +1686,69 @@ pkg_verify_checksums( |
873 |
} |
874 |
|
875 |
static void |
876 |
-pkg_fetch(int level, const depend_atom *atom, const struct pkg_t *pkg) |
877 |
+pkg_fetch(int level, const depend_atom *qatom, const tree_match_ctx *mpkg) |
878 |
{ |
879 |
- char buf[_Q_PATH_MAX], str[_Q_PATH_MAX]; |
880 |
+ int verifyret; |
881 |
+ char buf[_Q_PATH_MAX]; |
882 |
|
883 |
/* qmerge -pv patch */ |
884 |
if (pretend) { |
885 |
if (!install) |
886 |
install++; |
887 |
- /* qprint_tree_node(level, atom, pkg); */ |
888 |
- pkg_merge(level, atom, pkg); |
889 |
+ /* qprint_tree_node(level, qatom, mpkg); */ |
890 |
+ pkg_merge(level, qatom, mpkg); |
891 |
return; |
892 |
} |
893 |
|
894 |
- /* check to see if file exists and it's checksum matches */ |
895 |
- snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", pkgdir, pkg->CATEGORY, pkg->PF); |
896 |
- unlink_empty(buf); |
897 |
+ unlink_empty(mpkg->path); |
898 |
|
899 |
- snprintf(str, sizeof(str), "%s/%s", pkgdir, pkg->CATEGORY); |
900 |
- if (mkdir(str, 0755) == -1 && errno != EEXIST) { |
901 |
- warn("Failed to create %s", str); |
902 |
+ if (mkdir(mpkg->pkg->cat_ctx->ctx->path, 0755) == -1 && errno != EEXIST) { |
903 |
+ warn("Failed to create %s", mpkg->pkg->cat_ctx->ctx->path); |
904 |
return; |
905 |
} |
906 |
|
907 |
- if (force_download && (access(buf, R_OK) == 0) && |
908 |
- (pkg->SHA1[0] || pkg->MD5[0])) |
909 |
+ if (force_download && (access(mpkg->path, R_OK) == 0) && |
910 |
+ (mpkg->meta->Q_SHA1 != NULL || mpkg->meta->Q_MD5 != NULL)) |
911 |
{ |
912 |
- if (pkg_verify_checksums(buf, pkg, 0, 0) != 0) |
913 |
+ if (pkg_verify_checksums(mpkg, 0, 0) != 0) |
914 |
if (getenv("QMERGE") == NULL) |
915 |
- unlink(buf); |
916 |
- } |
917 |
- if (access(buf, R_OK) == 0) { |
918 |
- if (!pkg->SHA1[0] && !pkg->MD5[0]) { |
919 |
- warn("No checksum data for %s (try `emaint binhost --fix`)", buf); |
920 |
- return; |
921 |
- } else { |
922 |
- if (pkg_verify_checksums(buf, pkg, qmerge_strict, !quiet) |
923 |
- == 0) |
924 |
- { |
925 |
- pkg_merge(0, atom, pkg); |
926 |
- return; |
927 |
- } |
928 |
- } |
929 |
- } |
930 |
- if (verbose) |
931 |
- printf("Fetching %s/%s.tbz2\n", atom->CATEGORY, pkg->PF); |
932 |
- |
933 |
- /* fetch the package */ |
934 |
- /* Check CATEGORY first */ |
935 |
- if (!old_repo) { |
936 |
- snprintf(buf, sizeof(buf), "%s/%s.tbz2", atom->CATEGORY, pkg->PF); |
937 |
- fetch(str, buf); |
938 |
- } |
939 |
- snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", |
940 |
- pkgdir, atom->CATEGORY, pkg->PF); |
941 |
- if (access(buf, R_OK) != 0) { |
942 |
- snprintf(buf, sizeof(buf), "%s.tbz2", pkg->PF); |
943 |
- fetch(str, buf); |
944 |
- old_repo = 1; |
945 |
+ unlink(mpkg->path); |
946 |
} |
947 |
|
948 |
- /* verify the pkg exists now. unlink if zero bytes */ |
949 |
- snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", |
950 |
- pkgdir, atom->CATEGORY, pkg->PF); |
951 |
- unlink_empty(buf); |
952 |
+ if (access(mpkg->path, R_OK) != 0) { |
953 |
+ if (verbose) |
954 |
+ printf("Fetching %s\n", atom_to_string(mpkg->atom)); |
955 |
|
956 |
- if (access(buf, R_OK) != 0) { |
957 |
- warn("Failed to fetch %s.tbz2 from %s", pkg->PF, binhost); |
958 |
- fflush(stderr); |
959 |
- return; |
960 |
+ /* fetch the package */ |
961 |
+ snprintf(buf, sizeof(buf), "%s/%s.tbz2", |
962 |
+ mpkg->atom->CATEGORY, mpkg->atom->PF); |
963 |
+ fetch(mpkg->pkg->cat_ctx->ctx->path, buf); |
964 |
+ |
965 |
+ /* verify the pkg exists now. unlink if zero bytes */ |
966 |
+ unlink_empty(mpkg->path); |
967 |
} |
968 |
|
969 |
- snprintf(buf, sizeof(buf), "%s/%s/%s.tbz2", |
970 |
- pkgdir, atom->CATEGORY, pkg->PF); |
971 |
- if (pkg_verify_checksums(buf, pkg, qmerge_strict, !quiet) == 0) { |
972 |
- pkg_merge(0, atom, pkg); |
973 |
+ if (access(mpkg->path, R_OK) != 0) { |
974 |
+ warn("Failed to fetch %s.tbz2 from %s", mpkg->atom->PF, binhost); |
975 |
+ fflush(stderr); |
976 |
return; |
977 |
} |
978 |
-} |
979 |
- |
980 |
-static void |
981 |
-print_Pkg(int full, const depend_atom *atom, const struct pkg_t *pkg) |
982 |
-{ |
983 |
- char *p = NULL; |
984 |
- char buf[512]; |
985 |
- |
986 |
- printf("%s%s%s%s\n", atom_format("%[CAT]%[PF]%[SLOT]", atom), |
987 |
- !quiet ? " [" : "", |
988 |
- !quiet ? make_human_readable_str(pkg->SIZE, 1, KILOBYTE) : "", |
989 |
- !quiet ? " KiB]" : ""); |
990 |
|
991 |
- if (full == 0) |
992 |
+ /* check to see if checksum matches */ |
993 |
+ verifyret = pkg_verify_checksums(mpkg, qmerge_strict, !quiet); |
994 |
+ if (verifyret == -1) { |
995 |
+ warn("No checksum data for %s (try `emaint binhost --fix`)", |
996 |
+ mpkg->path); |
997 |
+ return; |
998 |
+ } else if (verifyret == 0) { |
999 |
+ pkg_merge(0, qatom, mpkg); |
1000 |
return; |
1001 |
- |
1002 |
- if (pkg->DESC[0]) |
1003 |
- printf(" %sDesc%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->DESC); |
1004 |
- if (pkg->SHA1[0]) |
1005 |
- printf(" %sSha1%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->SHA1); |
1006 |
- if (pkg->MD5[0]) |
1007 |
- printf(" %sMd5%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->MD5); |
1008 |
- if (!pkg->MD5[0] && !pkg->SHA1[0]) |
1009 |
- printf(" %sSums%s:%s %s(MISSING!)%s\n", |
1010 |
- DKGREEN, YELLOW, NORM, RED, NORM); |
1011 |
- if (pkg->SLOT[0]) |
1012 |
- printf(" %sSlot%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->SLOT); |
1013 |
- if (pkg->LICENSE[0]) |
1014 |
- printf(" %sLicense%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->LICENSE); |
1015 |
- if (pkg->RDEPEND[0]) |
1016 |
- printf(" %sRdepend%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->RDEPEND); |
1017 |
- if (pkg->USE[0]) |
1018 |
- printf(" %sUse%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->USE); |
1019 |
- if (pkg->REPO[0]) |
1020 |
- if (strcmp(pkg->REPO, "gentoo") != 0) |
1021 |
- printf(" %sRepo%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->REPO); |
1022 |
- |
1023 |
- if ((p = best_version(pkg->CATEGORY, atom->PN, pkg->SLOT)) != NULL) { |
1024 |
- if (*p) { |
1025 |
- int ret; |
1026 |
- const char *icolor = RED; |
1027 |
- ret = atom_compare_str(buf, p); |
1028 |
- switch (ret) { |
1029 |
- case EQUAL: icolor = RED; break; |
1030 |
- case NEWER: icolor = YELLOW; break; |
1031 |
- case OLDER: icolor = BLUE; break; |
1032 |
- default: icolor = NORM; break; |
1033 |
- } |
1034 |
- printf(" %sInstalled%s:%s %s%s%s\n", |
1035 |
- DKGREEN, YELLOW, NORM, icolor, p, NORM); |
1036 |
- } |
1037 |
} |
1038 |
} |
1039 |
|
1040 |
/* HACK: pull this in, knowing that qlist will be in the final link, we |
1041 |
* should however figure out how to do what match does here from e.g. |
1042 |
- * atom */ |
1043 |
+ * atom FIXME use tree_match_atom instead */ |
1044 |
extern bool qlist_match( |
1045 |
tree_pkg_ctx *pkg_ctx, |
1046 |
const char *name, |
1047 |
@@ -1893,71 +1794,6 @@ unmerge_packages(set *todo) |
1048 |
return ret; |
1049 |
} |
1050 |
|
1051 |
-static tree_ctx *_grab_binpkg_info_tree = NULL; |
1052 |
-static struct pkg_t * |
1053 |
-grab_binpkg_info(depend_atom *atom) |
1054 |
-{ |
1055 |
- tree_ctx *tree = _grab_binpkg_info_tree; |
1056 |
- tree_match_ctx *tpkg; |
1057 |
- struct pkg_t *pkg = NULL; |
1058 |
- char path[BUFSIZ]; |
1059 |
- FILE *d; |
1060 |
- |
1061 |
- /* reuse previously opened tree, so we really employ the cache |
1062 |
- * from libq/tree */ |
1063 |
- if (tree == NULL) { |
1064 |
- snprintf(path, sizeof(path), "%s/portage/%s", port_tmpdir, Packages); |
1065 |
- /* we don't use ROOT on package tree here, operating on ROOT |
1066 |
- * should be for package merges/unmerges, but be able to pull |
1067 |
- * binpkgs from current system */ |
1068 |
- if ((d = fopen(path, "r")) != NULL) { |
1069 |
- fclose(d); |
1070 |
- snprintf(path, sizeof(path), "%s/portage", port_tmpdir); |
1071 |
- tree = tree_open_binpkg("/", path); |
1072 |
- } else { |
1073 |
- tree = tree_open_binpkg("/", pkgdir); |
1074 |
- } |
1075 |
- _grab_binpkg_info_tree = tree; |
1076 |
- |
1077 |
- /* if opening the tree failed somehow, we can't return anything */ |
1078 |
- if (tree == NULL) |
1079 |
- return NULL; |
1080 |
- } |
1081 |
- |
1082 |
- tpkg = tree_match_atom(tree, atom, |
1083 |
- TREE_MATCH_FIRST | TREE_MATCH_VIRTUAL | TREE_MATCH_METADATA); |
1084 |
- if (tpkg != NULL) { |
1085 |
- depend_atom *tatom = tpkg->atom; |
1086 |
- tree_pkg_meta *meta = tpkg->meta; |
1087 |
- pkg = xzalloc(sizeof(struct pkg_t)); |
1088 |
- |
1089 |
- snprintf(pkg->PF, sizeof(pkg->PF), "%s", tatom->PF); |
1090 |
- snprintf(pkg->CATEGORY, sizeof(pkg->CATEGORY), "%s", tatom->CATEGORY); |
1091 |
- if (meta->Q_DESCRIPTION != NULL) |
1092 |
- snprintf(pkg->DESC, sizeof(pkg->DESC), "%s", meta->Q_DESCRIPTION); |
1093 |
- if (meta->Q_LICENSE != NULL) |
1094 |
- snprintf(pkg->LICENSE, sizeof(pkg->LICENSE), "%s", meta->Q_LICENSE); |
1095 |
- if (meta->Q_RDEPEND != NULL) |
1096 |
- snprintf(pkg->RDEPEND, sizeof(pkg->RDEPEND), "%s", meta->Q_RDEPEND); |
1097 |
- if (meta->Q_MD5 != NULL) |
1098 |
- snprintf(pkg->MD5, sizeof(pkg->MD5), "%s", meta->Q_MD5); |
1099 |
- if (meta->Q_SHA1 != NULL) |
1100 |
- snprintf(pkg->SHA1, sizeof(pkg->SHA1), "%s", meta->Q_SHA1); |
1101 |
- if (meta->Q_USE != NULL) |
1102 |
- snprintf(pkg->USE, sizeof(pkg->USE), "%s", meta->Q_USE); |
1103 |
- if (meta->Q_repository != NULL) |
1104 |
- snprintf(pkg->REPO, sizeof(pkg->REPO), "%s", meta->Q_repository); |
1105 |
- if (meta->Q_SLOT != NULL) |
1106 |
- snprintf(pkg->REPO, sizeof(pkg->REPO), "%s", meta->Q_SLOT); |
1107 |
- if (meta->Q_SIZE != NULL) |
1108 |
- pkg->SIZE = atoi(meta->Q_SIZE); |
1109 |
- |
1110 |
- tree_match_close(tpkg); |
1111 |
- } |
1112 |
- |
1113 |
- return pkg; |
1114 |
-} |
1115 |
- |
1116 |
static set * |
1117 |
qmerge_add_set_file(const char *pfx, const char *dir, const char *file, set *q) |
1118 |
{ |
1119 |
@@ -2046,8 +1882,7 @@ qmerge_run(set *todo) |
1120 |
return unmerge_packages(todo); |
1121 |
} else { |
1122 |
if (todo == NULL || search_pkgs) { |
1123 |
- /* disputable, this should be qlist -kIv or something */ |
1124 |
- warn("please use qlist -kI"); |
1125 |
+ warn("please use qlist -kIv"); |
1126 |
|
1127 |
return EXIT_SUCCESS; |
1128 |
} else { |
1129 |
@@ -2055,19 +1890,18 @@ qmerge_run(set *todo) |
1130 |
size_t todo_cnt = list_set(todo, &todo_strs); |
1131 |
size_t i; |
1132 |
depend_atom *atom; |
1133 |
- struct pkg_t *pkg; |
1134 |
+ tree_match_ctx *bpkg; |
1135 |
int ret = EXIT_FAILURE; |
1136 |
|
1137 |
for (i = 0; i < todo_cnt; i++) { |
1138 |
atom = atom_explode(todo_strs[i]); |
1139 |
- pkg = grab_binpkg_info(atom); |
1140 |
- if (pkg != NULL) { |
1141 |
- if (search_pkgs) |
1142 |
- print_Pkg(verbose, atom, pkg); |
1143 |
- else |
1144 |
- pkg_fetch(0, atom, pkg); |
1145 |
- free(pkg); |
1146 |
+ bpkg = best_version(atom, BV_BINPKG); |
1147 |
+ if (bpkg != NULL) { |
1148 |
+ pkg_fetch(0, atom, bpkg); |
1149 |
+ tree_match_close(bpkg); |
1150 |
ret = EXIT_SUCCESS; |
1151 |
+ } else { |
1152 |
+ warn("nothing found for %s", atom_to_string(atom)); |
1153 |
} |
1154 |
atom_implode(atom); |
1155 |
} |
1156 |
@@ -2088,23 +1922,27 @@ int qmerge_main(int argc, char **argv) |
1157 |
|
1158 |
while ((i = GETOPT_LONG(QMERGE, qmerge, "")) != -1) { |
1159 |
switch (i) { |
1160 |
- case 'f': force_download = 1; break; |
1161 |
- case 'F': force_download = 2; break; |
1162 |
- case 's': search_pkgs = 1; interactive = 0; break; |
1163 |
+ case 'f': force_download = 1; break; |
1164 |
+ case 'F': force_download = 2; break; |
1165 |
+ case 's': search_pkgs = 1; |
1166 |
+ interactive = 0; break; |
1167 |
/* case 'i': case 'g': */ |
1168 |
- case 'K': install = 1; break; |
1169 |
- case 'U': uninstall = 1; break; |
1170 |
- case 'p': pretend = 1; break; |
1171 |
- case 'u': |
1172 |
- update_only = 1; |
1173 |
- /* fall through */ |
1174 |
- case 'y': interactive = 0; break; |
1175 |
+ case 'K': install = 1; break; |
1176 |
+ case 'U': uninstall = 1; break; |
1177 |
+ case 'p': pretend = 1; break; |
1178 |
+ case 'u': update_only = 1; |
1179 |
+ install = 1; break; |
1180 |
+ case 'y': interactive = 0; break; |
1181 |
case 'O': follow_rdepends = 0; break; |
1182 |
- case 128: debug = true; break; |
1183 |
+ case 128: debug = true; break; |
1184 |
COMMON_GETOPTS_CASES(qmerge) |
1185 |
} |
1186 |
} |
1187 |
|
1188 |
+ /* default to install if no action given */ |
1189 |
+ if (!install && !uninstall) |
1190 |
+ install = 1; |
1191 |
+ |
1192 |
qmerge_strict = (strstr("strict", features) == 0) ? 1 : 0; |
1193 |
|
1194 |
/* Short circut this. */ |
1195 |
@@ -2140,14 +1978,14 @@ int qmerge_main(int argc, char **argv) |
1196 |
verbose = 0; |
1197 |
quiet = 1; |
1198 |
ret = qmerge_run(todo); |
1199 |
- if (ret || save_pretend) |
1200 |
+ if (ret != EXIT_SUCCESS || save_pretend) |
1201 |
return ret; |
1202 |
|
1203 |
if (uninstall) { |
1204 |
- if (!prompt("OK to unmerge these packages")) |
1205 |
+ if (!qmerge_prompt("OK to unmerge these packages")) |
1206 |
return EXIT_FAILURE; |
1207 |
} else { |
1208 |
- if (!prompt("OK to merge these packages")) |
1209 |
+ if (!qmerge_prompt("OK to merge these packages")) |
1210 |
return EXIT_FAILURE; |
1211 |
} |
1212 |
|
1213 |
|
1214 |
diff --git a/tests/qmerge/dotest b/tests/qmerge/dotest |
1215 |
index 59f249d..0f870ef 100755 |
1216 |
--- a/tests/qmerge/dotest |
1217 |
+++ b/tests/qmerge/dotest |
1218 |
@@ -22,16 +22,17 @@ set +e |
1219 |
|
1220 |
# sanity check on environment |
1221 |
q -Cev |
1222 |
+qlist -kIv |
1223 |
|
1224 |
# Do a merge into an empty tree. |
1225 |
|
1226 |
-out=$(yes | qmerge -F qmerge-test) |
1227 |
+out=$(yes | qmerge -F qmerge-test-1.3) |
1228 |
tend $? "qmerge-test: [N] basic merge" || die "${out}" |
1229 |
|
1230 |
[[ ${out} != *"FAIL"* ]] |
1231 |
tend $? "qmerge-test: [N] no FAIL messages" || die "${out}" |
1232 |
|
1233 |
-order=$(echo "${out}" | awk '$1 == ">>>" && $2 ~ /^pkg_/ { printf "%s ", $NF }') |
1234 |
+order=$(echo "${out}" | awk '$1 == "@@@" && $2 ~ /^pkg_/ { printf "%s ", $NF }') |
1235 |
[[ ${order} == "pkg_pretend pkg_setup pkg_preinst pkg_postinst " ]] |
1236 |
tend $? "qmerge-test: [N] pkg_* order of execution" || die "$(printf '%s\n' "${order}" "${out}")" |
1237 |
|
1238 |
@@ -45,14 +46,14 @@ tend $? "qmerge-test: [N] installed expected files" || die "$(treedir "${ROOT}") |
1239 |
|
1240 |
# Now do a re-emerge. |
1241 |
|
1242 |
-out=$(yes | qmerge -F qmerge-test) |
1243 |
+out=$(yes | qmerge -F "<qmerge-test-2") |
1244 |
tend $? "qmerge-test: [R] re-emerge" || die "${out}" |
1245 |
|
1246 |
[[ -x ${ROOT}/usr/bin/qmerge-test ]] |
1247 |
tend $? "qmerge-test: [R] installed expected files" || die "$(treedir "${ROOT}")" |
1248 |
|
1249 |
-order=$(echo "${out}" | awk '$1 == ">>>" && $2 ~ /^pkg_/ { printf "%s ", $NF }') |
1250 |
-[[ ${order} == "pkg_pretend pkg_setup pkg_preinst pkg_postinst " ]] |
1251 |
+order=$(echo "${out}" | awk '$1 == "@@@" && $2 ~ /^pkg_/ { printf "%s ", $NF }') |
1252 |
+[[ ${order} == "pkg_pretend pkg_setup pkg_preinst pkg_postinst pkg_prerm pkg_postrm " ]] |
1253 |
tend $? "qmerge-test: [R] pkg_* order of execution" || die "$(printf '%s\n' "${order}" "${out}")" |
1254 |
|
1255 |
[[ -x ${ROOT}/usr/bin/qmerge-test && \ |
1256 |
@@ -61,6 +62,19 @@ tend $? "qmerge-test: [R] pkg_* order of execution" || die "$(printf '%s\n' "${o |
1257 |
-f ${ROOT}/etc/._cfg0000_some.conf ]] |
1258 |
tend $? "qmerge-test: [R] re-installed expected files" || die "$(treedir "${ROOT}")" |
1259 |
|
1260 |
+# upgrade to latest version |
1261 |
+ |
1262 |
+out=$(yes | qmerge -F qmerge-test) |
1263 |
+tend $? "qmerge-test: [U] update" || die "${out}" |
1264 |
+ |
1265 |
+[[ $(qlist -Iv qmerge-test) == "sys-devel/qmerge-test-2.0" ]] |
1266 |
+tend $? "qmerge-test: qlist does not report version 2.0 installed" || die "$(qlist -Iv qmerge-test;qlist -kIv) ${out}" |
1267 |
+ |
1268 |
+[[ ! -x ${ROOT}/usr/bin/qmerge-test ]] |
1269 |
+tend $? "qmerge-test: binary from version 1 does not exist" || die "$(treedir "${ROOT}")" |
1270 |
+[[ -x ${ROOT}/usr/bin/qmerge-test2 ]] |
1271 |
+tend $? "qmerge-test: binary from version 2 exists" || die "$(treedir "${ROOT}")" |
1272 |
+ |
1273 |
# Finally do an unmerge. |
1274 |
|
1275 |
echo alkdsjfalksdf > "${ROOT}/etc/some.conf" |
1276 |
@@ -69,7 +83,7 @@ rm -f "${ROOT}/etc/._cfg0000_some.conf" |
1277 |
out=$(yes | qmerge -FU qmerge-test) |
1278 |
tend $? "qmerge-test: [C] uninstall" || die "${out}" |
1279 |
|
1280 |
-order=$(echo "${out}" | awk '$1 == ">>>" { printf "%s ", $NF }') |
1281 |
+order=$(echo "${out}" | awk '$1 == "@@@" { printf "%s ", $NF }') |
1282 |
[[ ${order} == "pkg_prerm pkg_postrm " ]] |
1283 |
tend $? "qmerge-test: [C] pkg_* order of execution" || die "$(printf '%s\n' "${order}" "${out}")" |
1284 |
|
1285 |
@@ -90,9 +104,9 @@ tend $? "qmerge-test: [M] install no /etc" || die "${out}" |
1286 |
tend $? "qmerge-test: [M] found no /etc" || die "$(treedir "${ROOT}")" |
1287 |
|
1288 |
out=$(yes | qmerge -FU qmerge-test) |
1289 |
-tend $? "qmerge-test: [M] uninstall" || die "${out}" |
1290 |
+tend $? "qmerge-test: [U] uninstall" || die "${out}" |
1291 |
[[ ! -e ${ROOT}/etc ]] |
1292 |
-tend $? "qmerge-test: [M] /etc removed" || die "$(treedir "${ROOT}")" |
1293 |
+tend $? "qmerge-test: [U] /etc removed" || die "$(treedir "${ROOT}")" |
1294 |
|
1295 |
export INSTALL_MASK="/etc -/etc/some.conf" |
1296 |
out=$(yes | qmerge -F qmerge-test) |
1297 |
@@ -101,9 +115,9 @@ tend $? "qmerge-test: [M] install only /etc/some.conf" || die "${out}" |
1298 |
tend $? "qmerge-test: [M] found /etc/another.conf" || die "$(treedir "${ROOT}")" |
1299 |
|
1300 |
out=$(yes | qmerge -FU qmerge-test) |
1301 |
-tend $? "qmerge-test: [M] uninstall" || die "${out}" |
1302 |
+tend $? "qmerge-test: [U] uninstall" || die "${out}" |
1303 |
[[ ! -e ${ROOT}/etc ]] |
1304 |
-tend $? "qmerge-test: [M] /etc removed" || die "$(treedir "${ROOT}")" |
1305 |
+tend $? "qmerge-test: [U] /etc removed" || die "$(treedir "${ROOT}")" |
1306 |
|
1307 |
export INSTALL_MASK="/usr -/usr/bin/dummy" |
1308 |
out=$(yes | qmerge -F qmerge-test) |
1309 |
@@ -114,22 +128,22 @@ tend $? "qmerge-test: [M] found /usr/bin/dummy" || die "$(treedir "${ROOT}")" |
1310 |
tend $? "qmerge-test: [M] /usr/bin/qmerge-test absent" || die "$(treedir "${ROOT}")" |
1311 |
|
1312 |
out=$(yes | qmerge -FU qmerge-test) |
1313 |
-tend $? "qmerge-test: [M] uninstall" || die "${out}" |
1314 |
+tend $? "qmerge-test: [U] uninstall" || die "${out}" |
1315 |
[[ ! -e ${ROOT}/usr/bin/dummy ]] |
1316 |
-tend $? "qmerge-test: [M] /usr/bin/dummy removed" || die "$(treedir "${ROOT}")" |
1317 |
+tend $? "qmerge-test: [U] /usr/bin/dummy removed" || die "$(treedir "${ROOT}")" |
1318 |
|
1319 |
export INSTALL_MASK="/usr -/usr/bin /usr/bin/dummy" |
1320 |
out=$(yes | qmerge -F qmerge-test) |
1321 |
tend $? "qmerge-test: [M] install except /usr/bin/dummy" || die "${out}" |
1322 |
[[ ! -e ${ROOT}/usr/bin/dummy ]] |
1323 |
tend $? "qmerge-test: [M] found no /usr/bin/dummy" || die "$(treedir "${ROOT}")" |
1324 |
-[[ -e ${ROOT}/usr/bin/qmerge-test ]] |
1325 |
-tend $? "qmerge-test: [M] found /usr/bin/qmerge-test" || die "$(treedir "${ROOT}")" |
1326 |
+[[ -e ${ROOT}/usr/bin/qmerge-test2 ]] |
1327 |
+tend $? "qmerge-test: [M] found /usr/bin/qmerge-test2" || die "$(treedir "${ROOT}")" |
1328 |
|
1329 |
out=$(yes | qmerge -FU qmerge-test) |
1330 |
-tend $? "qmerge-test: [M] uninstall" || die "${out}" |
1331 |
-[[ ! -e ${ROOT}/usr/bin/qmerge-test ]] |
1332 |
-tend $? "qmerge-test: [M] /usr/bin/qmerge-test removed" || die "$(treedir "${ROOT}")" |
1333 |
+tend $? "qmerge-test: [U] uninstall" || die "${out}" |
1334 |
+[[ ! -e ${ROOT}/usr/bin/qmerge-test2 ]] |
1335 |
+tend $? "qmerge-test: [U] /usr/bin/qmerge-test2 removed" || die "$(treedir "${ROOT}")" |
1336 |
|
1337 |
# try all compressions we know to see if we handle them properly |
1338 |
pkgver=qmerge-test-1.3 |
1339 |
@@ -152,10 +166,10 @@ for compr in "" brotli gzip bzip2 xz lz4 zstd lzip lzop ; do |
1340 |
: $((rev++)) |
1341 |
qtbz2 -j ${f} ${pkgver}.xpak pkgs/sys-devel/${pkgver}-r${rev}.tbz2 |
1342 |
ls -l pkgs/sys-devel/${pkgver}-r${rev}.tbz2 |
1343 |
- ROOT=/ qlist -kIv | tee /dev/stderr | wc -l |
1344 |
+ qlist -kIv | tee /dev/stderr | wc -l |
1345 |
|
1346 |
# see if we can install this package |
1347 |
- out=$(yes | qmerge -Fv qmerge-test) |
1348 |
+ out=$(yes | qmerge -Fv =${pkgver}-r${rev}) |
1349 |
tend $? "qmerge-test: [X] install ${pkgver}-r${rev}" || die "${out}" |
1350 |
qlist -Iv |
1351 |
out=$(yes | qmerge -FU qmerge-test) |
1352 |
|
1353 |
diff --git a/tests/qmerge/packages/Packages b/tests/qmerge/packages/Packages |
1354 |
index e6fa3a2..cd34d8d 100644 |
1355 |
--- a/tests/qmerge/packages/Packages |
1356 |
+++ b/tests/qmerge/packages/Packages |
1357 |
@@ -28,3 +28,16 @@ SHA1: 47f731ce30149f5ab15f0c47dc19b46e4b189d60 |
1358 |
SIZE: 7289 |
1359 |
REPO: local |
1360 |
|
1361 |
+BUILD_TIME: 1367285976 |
1362 |
+CPV: sys-devel/qmerge-test-2.0 |
1363 |
+DEFINED_PHASES: install postinst postrm preinst prerm pretend setup |
1364 |
+DESC: my desc |
1365 |
+EAPI: 6 |
1366 |
+KEYWORDS: ~amd64 ~x86 |
1367 |
+LICENSE: GPL-2 |
1368 |
+MD5: 100f6c414b1dc980fc73cf70178c2190 |
1369 |
+MTIME: 1367290147 |
1370 |
+SHA1: 5ba9c5db40a1b9be5e0e98b19b2cff5d2c197808 |
1371 |
+SIZE: 7334 |
1372 |
+REPO: local |
1373 |
+ |
1374 |
|
1375 |
diff --git a/tests/qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 b/tests/qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 |
1376 |
new file mode 100644 |
1377 |
index 0000000..1fac801 |
1378 |
Binary files /dev/null and b/tests/qmerge/packages/sys-devel/qmerge-test-2.0.tbz2 differ |