public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2016-02-22 20:37 Mike Frysinger
  0 siblings, 0 replies; 16+ messages in thread
From: Mike Frysinger @ 2016-02-22 20:37 UTC (permalink / raw
  To: gentoo-commits

commit:     dcec34fcf04c0399efc466adf770d60dc145129f
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Mon Feb 22 17:49:25 2016 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Mon Feb 22 17:49:25 2016 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=dcec34fc

qsize: change interface to operate on atoms

We also drop the --all flag as it's now the default behavior.
If no atoms are specified, we just check everything.

 man/qsize.1 |  5 +----
 qsize.c     | 49 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/man/qsize.1 b/man/qsize.1
index ca6a352..af32869 100644
--- a/man/qsize.1
+++ b/man/qsize.1
@@ -1,4 +1,4 @@
-.TH qsize "1" "Mar 2014" "Gentoo Foundation" "qsize"
+.TH qsize "1" "Feb 2016" "Gentoo Foundation" "qsize"
 .SH NAME
 qsize \- calculate size usage
 .SH SYNOPSIS
@@ -11,9 +11,6 @@ qsize \- calculate size usage
 \fB\-f\fR, \fB\-\-filesystem\fR
 Show size used on disk
 .TP
-\fB\-a\fR, \fB\-\-all\fR
-Size all installed packages
-.TP
 \fB\-s\fR, \fB\-\-sum\fR
 Include a summary
 .TP

diff --git a/qsize.c b/qsize.c
index 3a11842..7a40141 100644
--- a/qsize.c
+++ b/qsize.c
@@ -8,10 +8,9 @@
 
 #ifdef APPLET_qsize
 
-#define QSIZE_FLAGS "fasSmkbi:" COMMON_FLAGS
+#define QSIZE_FLAGS "fsSmkbi:" COMMON_FLAGS
 static struct option const qsize_long_opts[] = {
 	{"filesystem", no_argument, NULL, 'f'},
-	{"all",        no_argument, NULL, 'a'},
 	{"sum",        no_argument, NULL, 's'},
 	{"sum-only",   no_argument, NULL, 'S'},
 	{"megabytes",  no_argument, NULL, 'm'},
@@ -22,7 +21,6 @@ static struct option const qsize_long_opts[] = {
 };
 static const char * const qsize_opts_help[] = {
 	"Show size used on disk",
-	"Size all installed packages",
 	"Include a summary",
 	"Show just the summary",
 	"Display size in megabytes",
@@ -39,7 +37,6 @@ int qsize_main(int argc, char **argv)
 	q_vdb_cat_ctx *cat_ctx;
 	q_vdb_pkg_ctx *pkg_ctx;
 	size_t i;
-	char search_all = 0;
 	struct stat st;
 	char fs_size = 0, summary = 0, summary_only = 0;
 	size_t num_all_files, num_all_nonfiles, num_all_ignored;
@@ -50,13 +47,14 @@ int qsize_main(int argc, char **argv)
 	size_t buflen;
 	char *buf;
 	char filename[_Q_PATH_MAX], *filename_root;
+	depend_atom *atom;
+	DECLARE_ARRAY(atoms);
 	DECLARE_ARRAY(ignore_regexp);
 
 	while ((i = GETOPT_LONG(QSIZE, qsize, "")) != -1) {
 		switch (i) {
 		COMMON_GETOPTS_CASES(qsize)
 		case 'f': fs_size = 1; break;
-		case 'a': search_all = 1; break;
 		case 's': summary = 1; break;
 		case 'S': summary = summary_only = 1; break;
 		case 'm': disp_units = MEGABYTE; str_disp_units = "MiB"; break;
@@ -70,8 +68,16 @@ int qsize_main(int argc, char **argv)
 		}
 		}
 	}
-	if ((argc == optind) && !search_all)
-		qsize_usage(EXIT_FAILURE);
+
+	argc -= optind;
+	argv += optind;
+	for (i = 0; i < argc; ++i) {
+		atom = atom_explode(argv[i]);
+		if (!atom)
+			warn("invalid atom: %s", argv[i]);
+		else
+			xarraypush_ptr(atoms, atom);
+	}
 
 	num_all_bytes = num_all_files = num_all_nonfiles = num_all_ignored = 0;
 
@@ -91,18 +97,24 @@ int qsize_main(int argc, char **argv)
 		while ((pkg_ctx = q_vdb_next_pkg(cat_ctx))) {
 			const char *pkgname = pkg_ctx->name;
 			FILE *fp;
+			bool showit = false;
+
 			/* see if this cat/pkg is requested */
-			if (!search_all) {
-				for (i = optind; i < argc; ++i) {
-					snprintf(buf, buflen, "%s/%s", catname, pkgname);
-					if (rematch(argv[i], buf, REG_EXTENDED) == 0)
+			if (array_cnt(atoms)) {
+				depend_atom *qatom;
+
+				snprintf(buf, buflen, "%s/%s", catname, pkgname);
+				qatom = atom_explode(buf);
+				array_for_each(atoms, i, atom)
+					if (atom_compare(atom, qatom) == EQUAL) {
+						showit = true;
 						break;
-					if (rematch(argv[i], pkgname, REG_EXTENDED) == 0)
-						break;
-				}
-				if (i == argc)
-					goto next_pkg;
-			}
+					}
+				atom_implode(qatom);
+			} else
+				showit = true;
+			if (!showit)
+				goto next_pkg;
 
 			if ((fp = q_vdb_pkg_fopenat_ro(pkg_ctx, "CONTENTS")) == NULL)
 				goto next_pkg;
@@ -178,6 +190,9 @@ int qsize_main(int argc, char **argv)
 			       decimal_point,
 			       (unsigned long)(((num_all_bytes%MEGABYTE)*1000)/MEGABYTE));
 	}
+	array_for_each(atoms, i, atom)
+		atom_implode(atom);
+	xarrayfree_int(atoms);
 	xarrayfree(ignore_regexp);
 	return EXIT_SUCCESS;
 }


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2016-03-28  4:53 Mike Frysinger
  0 siblings, 0 replies; 16+ messages in thread
From: Mike Frysinger @ 2016-03-28  4:53 UTC (permalink / raw
  To: gentoo-commits

commit:     f27b1c430a13ed45dba638f2390e6a22f7199f8f
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 27 16:42:58 2016 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Sun Mar 27 16:42:58 2016 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=f27b1c43

usage: handle optional args, and auto-align display

Since --help is not performance sensitive, add a bit of logic to auto
align the width of the help columns.

 main.c       | 24 ++++++++++++++++++++----
 man/mkman.py |  4 ++--
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/main.c b/main.c
index d366bef..e9bacda 100644
--- a/main.c
+++ b/main.c
@@ -117,7 +117,11 @@ void no_colors(void)
 static void usage(int status, const char *flags, struct option const opts[],
                   const char * const help[], int blabber)
 {
-	unsigned long i;
+	const char opt_arg[] = "[arg]";
+	const char a_arg[] = "<arg>";
+	size_t a_arg_len = strlen(a_arg) + 1;
+	size_t i, optlen;
+
 	if (status != EXIT_SUCCESS)
 		dup2(STDERR_FILENO, STDOUT_FILENO);
 	if (blabber == 0) {
@@ -140,6 +144,15 @@ static void usage(int status, const char *flags, struct option const opts[],
 	if (module_name != NULL)
 		printf("%sLoaded module:%s\n%s%8s%s %s<args>%s\n", GREEN, NORM, YELLOW, module_name, NORM, DKBLUE, NORM);
 
+	/* Prescan the --long opt length to auto-align. */
+	optlen = 0;
+	for (i = 0; opts[i].name; ++i) {
+		size_t l = strlen(opts[i].name);
+		if (opts[i].has_arg != no_argument)
+			l += a_arg_len;
+		optlen = MAX(l, optlen);
+	}
+
 	printf("\n%sOptions:%s -[%s]\n", GREEN, NORM, flags);
 	for (i = 0; opts[i].name; ++i) {
 		/* this assert is a life saver when adding new applets. */
@@ -153,11 +166,14 @@ static void usage(int status, const char *flags, struct option const opts[],
 
 		/* then the long flag + help text */
 		if (opts[i].has_arg == no_argument)
-			printf("--%-15s%s*%s %s\n", opts[i].name,
+			printf("--%-*s %s*%s %s\n", (int)optlen, opts[i].name,
 				RED, NORM, _(help[i]));
 		else
-			printf("--%-8s %s<arg>%s %s*%s %s\n", opts[i].name,
-				DKBLUE, NORM, RED, NORM, _(help[i]));
+			printf("--%s %s%s%s%*s %s*%s %s\n",
+				opts[i].name,
+				DKBLUE, (opts[i].has_arg == a_argument ? a_arg : opt_arg), NORM,
+				(int)(optlen - strlen(opts[i].name) - a_arg_len), "",
+				RED, NORM, _(help[i]));
 	}
 	exit(status);
 }

diff --git a/man/mkman.py b/man/mkman.py
index 1ec8584..0751b92 100755
--- a/man/mkman.py
+++ b/man/mkman.py
@@ -89,8 +89,8 @@ def MkMan(applets, applet, output):
                 flags += [option[0].rstrip(',')]
                 option.pop(0)
 
-            if option[0] == '<arg>':
-                flags = [r'\fB%s\fR \fI<arg>\fR' % x for x in flags]
+            if option[0] in ('<arg>', '[arg]'):
+                flags = [r'\fB%s\fR \fI%s\fR' % (x, option[0]) for x in flags]
                 option.pop(0)
             else:
                 flags = [r'\fB%s\fR' % x for x in flags]


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-05-20 10:46 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-05-20 10:46 UTC (permalink / raw
  To: gentoo-commits

commit:     861d52c3d5fe82d4ca07ba7159f3232c215af28e
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon May 20 08:40:58 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon May 20 08:43:57 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=861d52c3

q: remove -M (modpath) option

modpath is never used in the code, remove its option

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 applets.h | 1 -
 main.c    | 1 -
 man/q.1   | 3 ---
 q.c       | 5 +----
 4 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/applets.h b/applets.h
index 8cb537a..f183dca 100644
--- a/applets.h
+++ b/applets.h
@@ -137,7 +137,6 @@ static const struct applet_t {
 	case 'C': no_colors(); break; \
 	default: applet ## _usage(EXIT_FAILURE); break;
 
-extern char *modpath;
 extern char *portroot;
 extern int verbose;
 extern int quiet;

diff --git a/main.c b/main.c
index 944950e..bf86c49 100644
--- a/main.c
+++ b/main.c
@@ -24,7 +24,6 @@
 
 /* variables to control runtime behavior */
 char *module_name = NULL;
-char *modpath = NULL;
 int verbose = 0;
 int quiet = 0;
 char pretend = 0;

diff --git a/man/q.1 b/man/q.1
index 92794a2..4d0b352 100644
--- a/man/q.1
+++ b/man/q.1
@@ -19,9 +19,6 @@ no longer necessary to initialise the cache at any time.
 \fB\-i\fR, \fB\-\-install\fR
 Install symlinks for applets.
 .TP
-\fB\-M\fR \fI<arg>\fR, \fB\-\-modpath\fR \fI<arg>\fR
-Module path.
-.TP
 \fB\-\-root\fR \fI<arg>\fR
 Set the ROOT env var.
 .TP

diff --git a/q.c b/q.c
index b6486ee..6307658 100644
--- a/q.c
+++ b/q.c
@@ -21,15 +21,13 @@
 
 #include "basename.h"
 
-#define Q_FLAGS "iM:" COMMON_FLAGS
+#define Q_FLAGS "i" COMMON_FLAGS
 static struct option const q_long_opts[] = {
 	{"install",       no_argument, NULL, 'i'},
-	{"modpath",        a_argument, NULL, 'M'},
 	COMMON_LONG_OPTS
 };
 static const char * const q_opts_help[] = {
 	"Install symlinks for applets",
-	"Module path",
 	COMMON_OPTS_HELP
 };
 #define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, NULL, lookup_applet_idx("q"))
@@ -95,7 +93,6 @@ int q_main(int argc, char **argv)
 	while ((i = GETOPT_LONG(Q, q, "+")) != -1) {
 		switch (i) {
 		COMMON_GETOPTS_CASES(q)
-		case 'M': modpath = optarg; break;
 		case 'i': install = 1; break;
 		}
 	}


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-07-14 10:21 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-07-14 10:21 UTC (permalink / raw
  To: gentoo-commits

commit:     ccfa1c152556ee6080731e2d1d51d92e5cd0b278
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 14 10:17:20 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Jul 14 10:17:20 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=ccfa1c15

qlop: add -F argument

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/qlop.1 |  3 +++
 qlop.c     | 43 ++++++++++++++++++++++++++-----------------
 2 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/man/qlop.1 b/man/qlop.1
index 3fb9c7a..10eaa27 100644
--- a/man/qlop.1
+++ b/man/qlop.1
@@ -109,6 +109,9 @@ Read emerge logfile instead of $EMERGE_LOG_DIR/emerge.log.
 \fB\-w\fR \fI<arg>\fR, \fB\-\-atoms\fR \fI<arg>\fR
 Read package atoms to report from file.
 .TP
+\fB\-F\fR \fI<arg>\fR, \fB\-\-format\fR \fI<arg>\fR
+Print matched atom using given format string.
+.TP
 \fB\-\-root\fR \fI<arg>\fR
 Set the ROOT env var.
 .TP

diff --git a/qlop.c b/qlop.c
index bd16018..e20c97b 100644
--- a/qlop.c
+++ b/qlop.c
@@ -24,7 +24,7 @@
 
 #define QLOP_DEFAULT_LOGFILE "emerge.log"
 
-#define QLOP_FLAGS "ctaHMmuUslerd:f:w:" COMMON_FLAGS
+#define QLOP_FLAGS "ctaHMmuUslerd:f:w:F:" COMMON_FLAGS
 static struct option const qlop_long_opts[] = {
 	{"summary",   no_argument, NULL, 'c'},
 	{"time",      no_argument, NULL, 't'},
@@ -41,6 +41,7 @@ static struct option const qlop_long_opts[] = {
 	{"lastmerge", no_argument, NULL, 'l'},
 	{"logfile",    a_argument, NULL, 'f'},
 	{"atoms",      a_argument, NULL, 'w'},
+	{"format",     a_argument, NULL, 'F'},
 	COMMON_LONG_OPTS
 };
 static const char * const qlop_opts_help[] = {
@@ -59,6 +60,7 @@ static const char * const qlop_opts_help[] = {
 	"Limit selection to last Portage emerge action",
 	"Read emerge logfile instead of $EMERGE_LOG_DIR/" QLOP_DEFAULT_LOGFILE,
 	"Read package atoms to report from file",
+	"Print matched atom using given format string",
 	COMMON_OPTS_HELP
 };
 static const char qlop_desc[] =
@@ -83,6 +85,7 @@ struct qlop_mode {
 	char do_machine:1;
 	char do_endtime:1;
 	char show_lastmerge:1;
+	const char *fmt;
 };
 
 static bool
@@ -347,10 +350,6 @@ static int do_emerge_log(
 	};
 	struct pkg_match *pkg;
 	struct pkg_match *pkgw;
-	const char *afmt = "%[CATEGORY]%[PN]";
-
-	if (verbose)
-		afmt = "%[CATEGORY]%[PF]";
 
 	if ((fp = fopen(log, "r")) == NULL) {
 		warnp("Could not open logfile '%s'", log);
@@ -621,19 +620,19 @@ static int do_emerge_log(
 					}
 					if (quiet && !flags->do_average) {
 						printf("%s%s%s\n",
-								atom_format(afmt, pkgw->atom),
+								atom_format(flags->fmt, pkgw->atom),
 								flags->do_time ? ": " : "",
 								flags->do_time ?
 									fmt_elapsedtime(flags, elapsed) : "");
 					} else if (flags->do_time) {
 						printf("%s >>> %s: %s\n",
 								fmt_date(flags, pkgw->tbegin, tstart),
-								atom_format(afmt, pkgw->atom),
+								atom_format(flags->fmt, pkgw->atom),
 								fmt_elapsedtime(flags, elapsed));
 					} else if (!flags->do_average) {
 						printf("%s >>> %s\n",
 								fmt_date(flags, pkgw->tbegin, tstart),
-								atom_format(afmt, pkgw->atom));
+								atom_format(flags->fmt, pkgw->atom));
 					}
 					atom_implode(pkgw->atom);
 					xarraydelete(merge_matches, i);
@@ -726,19 +725,19 @@ static int do_emerge_log(
 					}
 					if (quiet && !flags->do_average) {
 						printf("%s%s%s\n",
-								atom_format(afmt, pkgw->atom),
+								atom_format(flags->fmt, pkgw->atom),
 								flags->do_time ? ": " : "",
 								flags->do_time ?
 									fmt_elapsedtime(flags, elapsed) : "");
 					} else if (flags->do_time) {
 						printf("%s <<< %s: %s\n",
 								fmt_date(flags, pkgw->tbegin, tstart),
-								atom_format(afmt, pkgw->atom),
+								atom_format(flags->fmt, pkgw->atom),
 								fmt_elapsedtime(flags, elapsed));
 					} else if (!flags->do_average) {
 						printf("%s <<< %s\n",
 								fmt_date(flags, pkgw->tbegin, tstart),
-								atom_format(afmt, pkgw->atom));
+								atom_format(flags->fmt, pkgw->atom));
 					}
 					atom_implode(pkgw->atom);
 					xarraydelete(unmerge_matches, i);
@@ -800,7 +799,7 @@ static int do_emerge_log(
 			if (flags->do_time) {
 				printf("%s >>> %s: %s...%s ETA: %s\n",
 						fmt_date(flags, pkgw->tbegin, 0),
-						atom_format(afmt, pkgw->atom),
+						atom_format(flags->fmt, pkgw->atom),
 						fmt_elapsedtime(flags, elapsed),
 						p == NULL ? "" : p,
 						maxtime == 0 ? "unknown" :
@@ -808,7 +807,7 @@ static int do_emerge_log(
 			} else {
 				printf("%s >>> %s...%s ETA: %s\n",
 						fmt_date(flags, pkgw->tbegin, 0),
-						atom_format(afmt, pkgw->atom),
+						atom_format(flags->fmt, pkgw->atom),
 						p == NULL ? "" : p,
 						maxtime == 0 ? "unknown" :
 							fmt_elapsedtime(flags, maxtime - elapsed));
@@ -833,14 +832,14 @@ static int do_emerge_log(
 			if (flags->do_time) {
 				printf("%s <<< %s: %s... ETA: %s\n",
 						fmt_date(flags, pkgw->tbegin, 0),
-						atom_format(afmt, pkgw->atom),
+						atom_format(flags->fmt, pkgw->atom),
 						fmt_elapsedtime(flags, elapsed),
 						maxtime == 0 ? "unknown" :
 							fmt_elapsedtime(flags, maxtime - elapsed));
 			} else {
 				printf("%s <<< %s... ETA: %s\n",
 						fmt_date(flags, pkgw->tbegin, 0),
-						atom_format(afmt, pkgw->atom),
+						atom_format(flags->fmt, pkgw->atom),
 						maxtime == 0 ? "unknown" :
 							fmt_elapsedtime(flags, maxtime - elapsed));
 			}
@@ -852,7 +851,7 @@ static int do_emerge_log(
 
 		array_for_each(merge_averages, i, pkg) {
 			printf("%s: %s average for %s%zd%s merge%s\n",
-					atom_format(afmt, pkg->atom),
+					atom_format(flags->fmt, pkg->atom),
 					fmt_elapsedtime(flags, pkg->time / pkg->cnt),
 					GREEN, pkg->cnt, NORM, pkg->cnt == 1 ? "" : "s");
 			total_merges += pkg->cnt;
@@ -860,7 +859,7 @@ static int do_emerge_log(
 		}
 		array_for_each(unmerge_averages, i, pkg) {
 			printf("%s: %s average for %s%zd%s unmerge%s\n",
-					atom_format(afmt, pkg->atom),
+					atom_format(flags->fmt, pkg->atom),
 					fmt_elapsedtime(flags, pkg->time / pkg->cnt),
 					GREEN, pkg->cnt, NORM, pkg->cnt == 1 ? "" : "s");
 			total_unmerges += pkg->cnt;
@@ -922,6 +921,7 @@ int qlop_main(int argc, char **argv)
 	m.do_machine = 0;
 	m.do_endtime = 0;
 	m.show_lastmerge = 0;
+	m.fmt = NULL;
 
 	while ((ret = GETOPT_LONG(QLOP, qlop, "")) != -1) {
 		switch (ret) {
@@ -939,6 +939,7 @@ int qlop_main(int argc, char **argv)
 			case 'M': m.do_machine = 1;     break;
 			case 'e': m.do_endtime = 1;     break;
 			case 'l': m.show_lastmerge = 1; break;
+			case 'F': m.fmt = optarg;       break;
 			case 'd':
 				if (start_time == 0) {
 					if (!parse_date(optarg, &start_time))
@@ -1059,6 +1060,14 @@ int qlop_main(int argc, char **argv)
 			m.do_sync = 1;
 	}
 
+	/* set format if none given */
+	if (m.fmt == NULL) {
+		if (verbose)
+			m.fmt = "%[CATEGORY]%[PF]";
+		else
+			m.fmt = "%[CATEGORY]%[PN]";
+	}
+
 	do_emerge_log(logfile, &m, atoms, start_time, end_time);
 
 	array_for_each(atoms, i, atom)


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-07-14 10:21 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-07-14 10:21 UTC (permalink / raw
  To: gentoo-commits

commit:     eadd293b14379b5f8f49dd000fed18139d90dc94
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 14 09:26:26 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Jul 14 09:26:26 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=eadd293b

qfile add -F argument

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/qcheck.1 |  5 ++++-
 man/qfile.1  |  5 ++++-
 qfile.c      | 49 ++++++++++++++++++++++++-------------------------
 3 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/man/qcheck.1 b/man/qcheck.1
index 9e4d873..f48fa63 100644
--- a/man/qcheck.1
+++ b/man/qcheck.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qcheck "1" "May 2019" "Gentoo Foundation" "qcheck"
+.TH qcheck "1" "Jul 2019" "Gentoo Foundation" "qcheck"
 .SH NAME
 qcheck \- verify integrity of installed packages
 .SH SYNOPSIS
@@ -9,6 +9,9 @@ qcheck \- verify integrity of installed packages
 
 .SH OPTIONS
 .TP
+\fB\-F\fR \fI<arg>\fR, \fB\-\-format\fR \fI<arg>\fR
+Custom output format (default: %[CATEGORY]%[PN]).
+.TP
 \fB\-s\fR \fI<arg>\fR, \fB\-\-skip\fR \fI<arg>\fR
 Ignore files matching the regular expression <arg>.
 .TP

diff --git a/man/qfile.1 b/man/qfile.1
index 6dedef2..33dfbee 100644
--- a/man/qfile.1
+++ b/man/qfile.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qfile "1" "May 2019" "Gentoo Foundation" "qfile"
+.TH qfile "1" "Jul 2019" "Gentoo Foundation" "qfile"
 .SH NAME
 qfile \- list all pkgs owning files
 .SH SYNOPSIS
@@ -35,6 +35,9 @@ After version \fB0.74\fR of portage-utils, the \fB-b\fR option was
 renamed to \fB-d\fR.
 .SH OPTIONS
 .TP
+\fB\-F\fR \fI<arg>\fR, \fB\-\-format\fR \fI<arg>\fR
+Print matched atom using given format string.
+.TP
 \fB\-S\fR, \fB\-\-slots\fR
 Display installed packages with slots.
 .TP

diff --git a/qfile.c b/qfile.c
index 1a6b470..bc5c9ac 100644
--- a/qfile.c
+++ b/qfile.c
@@ -20,8 +20,9 @@
 #include "rmspace.h"
 #include "tree.h"
 
-#define QFILE_FLAGS "doRx:S" COMMON_FLAGS
+#define QFILE_FLAGS "F:doRx:S" COMMON_FLAGS
 static struct option const qfile_long_opts[] = {
+	{"format",       a_argument, NULL, 'F'},
 	{"slots",       no_argument, NULL, 'S'},
 	{"root-prefix", no_argument, NULL, 'R'},
 	{"dir",         no_argument, NULL, 'd'},
@@ -30,6 +31,7 @@ static struct option const qfile_long_opts[] = {
 	COMMON_LONG_OPTS
 };
 static const char * const qfile_opts_help[] = {
+	"Print matched atom using given format string",
 	"Display installed packages with slots",
 	"Assume arguments are already prefixed by $ROOT",
 	"Also match directories for single component arguments",
@@ -64,16 +66,13 @@ struct qfile_opt_state {
 	char *exclude_pkg;
 	char *exclude_slot;
 	depend_atom *exclude_atom;
-	bool slotted;
 	bool basename;
 	bool orphans;
 	bool assume_root_prefix;
+	const char *format;
+	bool need_full_atom;
 };
 
-/*
- * We assume the people calling us have chdir(/var/db/pkg) and so
- * we use relative paths throughout here.
- */
 static int qfile_cb(tree_pkg_ctx *pkg_ctx, void *priv)
 {
 	struct qfile_opt_state *state = priv;
@@ -215,24 +214,9 @@ static int qfile_cb(tree_pkg_ctx *pkg_ctx, void *priv)
 				continue;
 
 			if (non_orphans == NULL) {
-				const char *fmt;
-
-				atom = tree_get_atom(pkg_ctx, true);
+				atom = tree_get_atom(pkg_ctx, state->need_full_atom);
 
-				if (state->slotted) {
-					if (verbose) {
-						fmt = "%[CATEGORY]%[PF]%[SLOT]";
-					} else {
-						fmt = "%[CATEGORY]%[PN]%[SLOT]";
-					}
-				} else {
-					if (verbose) {
-						fmt = "%[CATEGORY]%[PF]";
-					} else {
-						fmt = "%[CATEGORY]%[PN]";
-					}
-				}
-				printf("%s", atom_format(fmt, atom));
+				printf("%s", atom_format(state->format, atom));
 				if (quiet)
 					puts("");
 				else
@@ -402,10 +386,11 @@ int qfile_main(int argc, char **argv)
 {
 	struct qfile_opt_state state = {
 		.buflen = _Q_PATH_MAX,
-		.slotted = false,
+		.need_full_atom = false,
 		.basename = false,
 		.orphans = false,
 		.assume_root_prefix = false,
+		.format = NULL,
 	};
 	int i, nb_of_queries, found = 0;
 	char *p;
@@ -413,7 +398,8 @@ int qfile_main(int argc, char **argv)
 	while ((i = GETOPT_LONG(QFILE, qfile, "")) != -1) {
 		switch (i) {
 			COMMON_GETOPTS_CASES(qfile)
-			case 'S': state.slotted = true;             break;
+			case 'F': state.format = optarg;            /* fall through */
+			case 'S': state.need_full_atom = true;      break;
 			case 'd': state.basename = true;            break;
 			case 'o': state.orphans = true;             break;
 			case 'R': state.assume_root_prefix = true;  break;
@@ -436,6 +422,19 @@ int qfile_main(int argc, char **argv)
 	argc -= optind;
 	argv += optind;
 
+	if (state.format == NULL) {
+		if (state.need_full_atom)
+			if (verbose)
+				state.format = "%[CATEGORY]%[PF]%[SLOT]";
+			else
+				state.format = "%[CATEGORY]%[PN]%[SLOT]";
+		else
+			if (verbose)
+				state.format = "%[CATEGORY]%[PF]";
+			else
+				state.format = "%[CATEGORY]%[PN]";
+	}
+
 	state.buf = xmalloc(state.buflen);
 	if (state.assume_root_prefix) {
 		/* Get a copy of $ROOT, with no trailing slash


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-07-14 10:21 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-07-14 10:21 UTC (permalink / raw
  To: gentoo-commits

commit:     ee8c746db135320fe41c1dc830bda1617216b916
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 14 10:14:39 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Jul 14 10:14:39 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=ee8c746d

main: nicely format/wrap help arguments in -h output

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 main.c       | 51 +++++++++++++++++++++++++++++++++++++++------------
 man/mkman.py |  8 ++++----
 2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/main.c b/main.c
index bdbb2a7..5d4c4cd 100644
--- a/main.c
+++ b/main.c
@@ -92,14 +92,18 @@ usage(int status, const char *flags, struct option const opts[],
 	const char opt_arg[] = "[arg]";
 	const char a_arg[] = "<arg>";
 	size_t a_arg_len = strlen(a_arg) + 1;
-	size_t i, optlen;
+	size_t i;
+	size_t optlen;
+	size_t l;
+	size_t prefixlen;
+	const char *hstr;
 	FILE *fp = status == EXIT_SUCCESS ? stdout : warnout;
 
 	if (blabber == 0) {
-		fprintf(fp, "%sUsage:%s %sq%s %s<applet> <args>%s  : %s"
+		fprintf(fp, "%susage:%s %sq%s %s<applet> <args>%s  : %s"
 			"invoke a portage utility applet\n\n", GREEN,
 			NORM, YELLOW, NORM, DKBLUE, RED, NORM);
-		fprintf(fp, "%sCurrently defined applets:%s\n", GREEN, NORM);
+		fprintf(fp, "%scurrently defined applets:%s\n", GREEN, NORM);
 		for (i = 0; applets[i].desc; ++i)
 			if (applets[i].func)
 				fprintf(fp, " %s%8s%s %s%-16s%s%s:%s %s\n",
@@ -107,7 +111,7 @@ usage(int status, const char *flags, struct option const opts[],
 					DKBLUE, applets[i].opts, NORM,
 					RED, NORM, _(applets[i].desc));
 	} else if (blabber > 0) {
-		fprintf(fp, "%sUsage:%s %s%s%s [opts] %s%s%s %s:%s %s\n",
+		fprintf(fp, "%susage:%s %s%s%s [opts] %s%s%s %s:%s %s\n",
 			GREEN, NORM,
 			YELLOW, applets[blabber].name, NORM,
 			DKBLUE, applets[blabber].opts, NORM,
@@ -116,19 +120,19 @@ usage(int status, const char *flags, struct option const opts[],
 			fprintf(fp, "\n%s\n", desc);
 	}
 	if (module_name != NULL)
-		fprintf(fp, "%sLoaded module:%s\n%s%8s%s %s<args>%s\n",
+		fprintf(fp, "%sloaded module:%s\n%s%8s%s %s<args>%s\n",
 			GREEN, NORM, YELLOW, module_name, NORM, DKBLUE, NORM);
 
 	/* Prescan the --long opt length to auto-align. */
 	optlen = 0;
 	for (i = 0; opts[i].name; ++i) {
-		size_t l = strlen(opts[i].name);
+		l = strlen(opts[i].name);
 		if (opts[i].has_arg != no_argument)
 			l += a_arg_len;
 		optlen = MAX(l, optlen);
 	}
 
-	fprintf(fp, "\n%sOptions:%s -[%s]\n", GREEN, NORM, flags);
+	fprintf(fp, "\n%soptions:%s -[%s]\n", GREEN, NORM, flags);
 	for (i = 0; opts[i].name; ++i) {
 		/* this assert is a life saver when adding new applets. */
 		assert(help[i] != NULL);
@@ -139,16 +143,39 @@ usage(int status, const char *flags, struct option const opts[],
 		else
 			fprintf(fp, "  -%c, ", opts[i].val);
 
-		/* then the long flag + help text */
+		/* then the long flag */
 		if (opts[i].has_arg == no_argument)
-			fprintf(fp, "--%-*s %s*%s %s\n", (int)optlen, opts[i].name,
-				RED, NORM, _(help[i]));
+			fprintf(fp, "--%-*s %s*%s ", (int)optlen, opts[i].name,
+				RED, NORM);
 		else
-			fprintf(fp, "--%s %s%s%s%*s %s*%s %s\n",
+			fprintf(fp, "--%s %s%s%s%*s %s*%s ",
 				opts[i].name,
 				DKBLUE, (opts[i].has_arg == a_argument ? a_arg : opt_arg), NORM,
 				(int)(optlen - strlen(opts[i].name) - a_arg_len), "",
-				RED, NORM, _(help[i]));
+				RED, NORM);
+
+		/* then wrap the help text, if necessary */
+		prefixlen = 6 + 2 + optlen + 1 + 1 + 1;
+		if ((size_t)twidth < prefixlen + 10) {
+			fprintf(fp, "%s\n", _(help[i]));
+		} else {
+			const char *t;
+			hstr = _(help[i]);
+			l = strlen(hstr);
+			while (twidth - prefixlen < l) {
+				/* search backwards for a space */
+				t = &hstr[twidth - prefixlen];
+				while (t > hstr && !isspace((int)*t))
+					t--;
+				if (t == hstr)
+					break;
+				fprintf(fp, "%.*s\n%*s",
+						(int)(t - hstr), hstr, (int)prefixlen, "");
+				l -= t + 1 - hstr;
+				hstr = t + 1;  /* skip space */
+			}
+			fprintf(fp, "%s\n", hstr);
+		}
 	}
 	exit(status);
 }

diff --git a/man/mkman.py b/man/mkman.py
index a1b68a7..13cd1c9 100755
--- a/man/mkman.py
+++ b/man/mkman.py
@@ -69,7 +69,7 @@ def MkMan(applets, applet, output):
     except:
         return
     lines = ahelp.splitlines()
-    m = re.search(r'^Usage: %s (.*) : (.*)' % applet, ahelp)
+    m = re.search(r'^usage: %s (.*) : (.*)' % applet, ahelp)
     usage = m.group(1)
     short_desc = m.group(2)
 
@@ -92,7 +92,7 @@ def MkMan(applets, applet, output):
     # Extract all the options
     options = []
     for line, i in zip(lines, range(len(lines))):
-        if not line.startswith('Options: '):
+        if not line.startswith('options: '):
             continue
 
         for option in [x.strip().split() for x in lines[i + 1:]]:
@@ -128,8 +128,8 @@ def MkMan(applets, applet, output):
 
     # Handle applets that have applets
     extra_sections = []
-    if 'Currently defined applets:' in ahelp:
-        alines = lines[lines.index('Currently defined applets:') + 1:]
+    if 'currently defined applets:' in ahelp:
+        alines = lines[lines.index('currently defined applets:') + 1:]
         alines = alines[:alines.index('')]
         extra_sections += (
             ['.SH APPLETS', '.nf',


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-07-14 10:21 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-07-14 10:21 UTC (permalink / raw
  To: gentoo-commits

commit:     47087590e69be3b84c299d4e69d028d8c783b14e
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 14 09:31:21 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Jul 14 09:31:21 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=47087590

applets: reword -v help description into what it really is

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 applets.h       | 2 +-
 man/q.1         | 4 ++--
 man/qatom.1     | 2 +-
 man/qcheck.1    | 2 +-
 man/qdepends.1  | 2 +-
 man/qgrep.1     | 2 +-
 man/qkeyword.1  | 4 ++--
 man/qlist.1     | 2 +-
 man/qlop.1      | 2 +-
 man/qmanifest.1 | 4 ++--
 man/qmerge.1    | 4 ++--
 man/qpkg.1      | 2 +-
 man/qsearch.1   | 2 +-
 man/qsize.1     | 2 +-
 man/qtbz2.1     | 2 +-
 man/qtegrity.1  | 4 ++--
 man/quse.1      | 2 +-
 man/qxpak.1     | 4 ++--
 18 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/applets.h b/applets.h
index acc85da..999cf7a 100644
--- a/applets.h
+++ b/applets.h
@@ -133,7 +133,7 @@ static const struct applet_t {
 	{NULL,        no_argument, NULL, 0x0}
 #define COMMON_OPTS_HELP \
 	"Set the ROOT env var", \
-	"Make a lot of noise", \
+	"Report full package versions, emit more elaborate output", \
 	"Tighter output; suppress warnings", \
 	"Don't output color", \
 	"Print this help and exit", \

diff --git a/man/q.1 b/man/q.1
index 0546ab1..4e6264c 100644
--- a/man/q.1
+++ b/man/q.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH q "1" "May 2019" "Gentoo Foundation" "q"
+.TH q "1" "Jul 2019" "Gentoo Foundation" "q"
 .SH NAME
 q \- invoke a portage utility applet
 .SH SYNOPSIS
@@ -26,7 +26,7 @@ Print available overlays (read from repos.conf).
 Set the ROOT env var.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Make a lot of noise.
+Report full package versions, emit more elaborate output.
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Tighter output; suppress warnings.

diff --git a/man/qatom.1 b/man/qatom.1
index 968e1af..ab6cfb3 100644
--- a/man/qatom.1
+++ b/man/qatom.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qatom "1" "Jun 2019" "Gentoo Foundation" "qatom"
+.TH qatom "1" "Jul 2019" "Gentoo Foundation" "qatom"
 .SH NAME
 qatom \- split atom strings
 .SH SYNOPSIS

diff --git a/man/qcheck.1 b/man/qcheck.1
index f48fa63..fce6b42 100644
--- a/man/qcheck.1
+++ b/man/qcheck.1
@@ -40,7 +40,7 @@ Undo prelink when calculating checksums.
 Set the ROOT env var.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Make a lot of noise.
+Report full package versions, emit more elaborate output.
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Tighter output; suppress warnings.

diff --git a/man/qdepends.1 b/man/qdepends.1
index 7898e3d..8b0ad69 100644
--- a/man/qdepends.1
+++ b/man/qdepends.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qdepends "1" "Jun 2019" "Gentoo Foundation" "qdepends"
+.TH qdepends "1" "Jul 2019" "Gentoo Foundation" "qdepends"
 .SH NAME
 qdepends \- show dependency info
 .SH SYNOPSIS

diff --git a/man/qgrep.1 b/man/qgrep.1
index fbde702..f3a5c2d 100644
--- a/man/qgrep.1
+++ b/man/qgrep.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qgrep "1" "Jun 2019" "Gentoo Foundation" "qgrep"
+.TH qgrep "1" "Jul 2019" "Gentoo Foundation" "qgrep"
 .SH NAME
 qgrep \- grep in ebuilds
 .SH SYNOPSIS

diff --git a/man/qkeyword.1 b/man/qkeyword.1
index 483c608..a191d72 100644
--- a/man/qkeyword.1
+++ b/man/qkeyword.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qkeyword "1" "May 2019" "Gentoo Foundation" "qkeyword"
+.TH qkeyword "1" "Jul 2019" "Gentoo Foundation" "qkeyword"
 .SH NAME
 qkeyword \- list packages based on keywords
 .SH SYNOPSIS
@@ -53,7 +53,7 @@ list packages that aren't keyworded on a given arch.
 Set the ROOT env var.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Make a lot of noise.
+Report full package versions, emit more elaborate output.
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Tighter output; suppress warnings.

diff --git a/man/qlist.1 b/man/qlist.1
index cd1e8bb..8f9cf56 100644
--- a/man/qlist.1
+++ b/man/qlist.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qlist "1" "May 2019" "Gentoo Foundation" "qlist"
+.TH qlist "1" "Jul 2019" "Gentoo Foundation" "qlist"
 .SH NAME
 qlist \- list files owned by pkgname
 .SH SYNOPSIS

diff --git a/man/qlop.1 b/man/qlop.1
index f42a853..3fb9c7a 100644
--- a/man/qlop.1
+++ b/man/qlop.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qlop "1" "May 2019" "Gentoo Foundation" "qlop"
+.TH qlop "1" "Jul 2019" "Gentoo Foundation" "qlop"
 .SH NAME
 qlop \- emerge log analyzer
 .SH SYNOPSIS

diff --git a/man/qmanifest.1 b/man/qmanifest.1
index 15027f6..5d00bd3 100644
--- a/man/qmanifest.1
+++ b/man/qmanifest.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qmanifest "1" "May 2019" "Gentoo Foundation" "qmanifest"
+.TH qmanifest "1" "Jul 2019" "Gentoo Foundation" "qmanifest"
 .SH NAME
 qmanifest \- verify or generate thick Manifest files
 .SH SYNOPSIS
@@ -60,7 +60,7 @@ Treat arguments as overlay names.
 Set the ROOT env var.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Make a lot of noise.
+Report full package versions, emit more elaborate output.
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Tighter output; suppress warnings.

diff --git a/man/qmerge.1 b/man/qmerge.1
index d31ae1c..a4f09e2 100644
--- a/man/qmerge.1
+++ b/man/qmerge.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qmerge "1" "May 2019" "Gentoo Foundation" "qmerge"
+.TH qmerge "1" "Jul 2019" "Gentoo Foundation" "qmerge"
 .SH NAME
 qmerge \- fetch and merge binary package
 .SH SYNOPSIS
@@ -48,7 +48,7 @@ Run shell funcs with `set -x`.
 Set the ROOT env var.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Make a lot of noise.
+Report full package versions, emit more elaborate output.
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Tighter output; suppress warnings.

diff --git a/man/qpkg.1 b/man/qpkg.1
index c4a6868..c471ea1 100644
--- a/man/qpkg.1
+++ b/man/qpkg.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qpkg "1" "May 2019" "Gentoo Foundation" "qpkg"
+.TH qpkg "1" "Jul 2019" "Gentoo Foundation" "qpkg"
 .SH NAME
 qpkg \- manipulate Gentoo binpkgs
 .SH SYNOPSIS

diff --git a/man/qsearch.1 b/man/qsearch.1
index ce389e6..f6b9baf 100644
--- a/man/qsearch.1
+++ b/man/qsearch.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qsearch "1" "May 2019" "Gentoo Foundation" "qsearch"
+.TH qsearch "1" "Jul 2019" "Gentoo Foundation" "qsearch"
 .SH NAME
 qsearch \- search pkgname/desc
 .SH SYNOPSIS

diff --git a/man/qsize.1 b/man/qsize.1
index 28f4445..3a359e4 100644
--- a/man/qsize.1
+++ b/man/qsize.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qsize "1" "May 2019" "Gentoo Foundation" "qsize"
+.TH qsize "1" "Jul 2019" "Gentoo Foundation" "qsize"
 .SH NAME
 qsize \- calculate size usage
 .SH SYNOPSIS

diff --git a/man/qtbz2.1 b/man/qtbz2.1
index cfe9b71..cf63fd8 100644
--- a/man/qtbz2.1
+++ b/man/qtbz2.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qtbz2 "1" "May 2019" "Gentoo Foundation" "qtbz2"
+.TH qtbz2 "1" "Jul 2019" "Gentoo Foundation" "qtbz2"
 .SH NAME
 qtbz2 \- manipulate tbz2 packages
 .SH SYNOPSIS

diff --git a/man/qtegrity.1 b/man/qtegrity.1
index 8ac89ee..f1df5e7 100644
--- a/man/qtegrity.1
+++ b/man/qtegrity.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qtegrity "1" "May 2019" "Gentoo Foundation" "qtegrity"
+.TH qtegrity "1" "Jul 2019" "Gentoo Foundation" "qtegrity"
 .SH NAME
 qtegrity \- verify files with IMA
 .SH SYNOPSIS
@@ -29,7 +29,7 @@ Show recorded digests that match with known-good digests.
 Set the ROOT env var.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Make a lot of noise.
+Report full package versions, emit more elaborate output.
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Tighter output; suppress warnings.

diff --git a/man/quse.1 b/man/quse.1
index 0a031ba..a30e189 100644
--- a/man/quse.1
+++ b/man/quse.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH quse "1" "Jun 2019" "Gentoo Foundation" "quse"
+.TH quse "1" "Jul 2019" "Gentoo Foundation" "quse"
 .SH NAME
 quse \- find pkgs using useflags
 .SH SYNOPSIS

diff --git a/man/qxpak.1 b/man/qxpak.1
index f090ee5..d212671 100644
--- a/man/qxpak.1
+++ b/man/qxpak.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qxpak "1" "May 2019" "Gentoo Foundation" "qxpak"
+.TH qxpak "1" "Jul 2019" "Gentoo Foundation" "qxpak"
 .SH NAME
 qxpak \- manipulate xpak archives
 .SH SYNOPSIS
@@ -28,7 +28,7 @@ Write files to stdout.
 Set the ROOT env var.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Make a lot of noise.
+Report full package versions, emit more elaborate output.
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Tighter output; suppress warnings.


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-07-14 13:09 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-07-14 13:09 UTC (permalink / raw
  To: gentoo-commits

commit:     44b67c2d685a763c3f8aee1ecffc8d3f5ababe4c
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 14 11:55:07 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Jul 14 11:55:07 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=44b67c2d

qsize: add -F argument, changed default format to match other applets

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/qsize.1 |  3 +++
 qsize.c     | 36 +++++++++++++++++++++++++++---------
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/man/qsize.1 b/man/qsize.1
index 3a359e4..df85970 100644
--- a/man/qsize.1
+++ b/man/qsize.1
@@ -33,6 +33,9 @@ Display all sizes in bytes.
 Filter out entries matching \fI<arg>\fR, which is a regular
 expression, before calculating size.
 .TP
+\fB\-F\fR \fI<arg>\fR, \fB\-\-format\fR \fI<arg>\fR
+Print matched atom using given format string.
+.TP
 \fB\-\-root\fR \fI<arg>\fR
 Set the ROOT env var.
 .TP

diff --git a/qsize.c b/qsize.c
index 10aadc8..1f1dfc9 100644
--- a/qsize.c
+++ b/qsize.c
@@ -55,7 +55,7 @@
 #include "xarray.h"
 #include "xregex.h"
 
-#define QSIZE_FLAGS "fsSmkbi:" COMMON_FLAGS
+#define QSIZE_FLAGS "fsSmkbi:F:" COMMON_FLAGS
 static struct option const qsize_long_opts[] = {
 	{"filesystem", no_argument, NULL, 'f'},
 	{"sum",        no_argument, NULL, 's'},
@@ -64,6 +64,7 @@ static struct option const qsize_long_opts[] = {
 	{"kilobytes",  no_argument, NULL, 'k'},
 	{"bytes",      no_argument, NULL, 'b'},
 	{"ignore",      a_argument, NULL, 'i'},
+	{"format",      a_argument, NULL, 'F'},
 	COMMON_LONG_OPTS
 };
 static const char * const qsize_opts_help[] = {
@@ -74,6 +75,7 @@ static const char * const qsize_opts_help[] = {
 	"Display all sizes in kilobytes",
 	"Display all sizes in bytes",
 	"Ignore regexp string",
+	"Print matched atom using given format string",
 	COMMON_OPTS_HELP
 };
 #define qsize_usage(ret) usage(ret, QSIZE_FLAGS, qsize_long_opts, qsize_opts_help, NULL, lookup_applet_idx("qsize"))
@@ -88,6 +90,8 @@ struct qsize_opt_state {
 	size_t disp_units;
 	const char *str_disp_units;
 	array_t *ignore_regexp;
+	const char *fmt;
+	bool need_full_atom:1;
 
 	size_t buflen;
 	char *buf;
@@ -160,9 +164,9 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv)
 	state->num_all_ignored += num_ignored;
 
 	if (!state->summary_only) {
-		atom = tree_get_atom(pkg_ctx, 0);
+		atom = tree_get_atom(pkg_ctx, state->need_full_atom);
 		printf("%s: %'zu files, %'zu non-files, ",
-				atom_format("%[CATEGORY]%[PF]", atom),
+				atom_format(state->fmt, atom),
 				num_files, num_nonfiles);
 		if (num_ignored)
 			printf("%'zu names-ignored, ", num_ignored);
@@ -195,17 +199,24 @@ int qsize_main(int argc, char **argv)
 		.num_all_files = 0,
 		.num_all_nonfiles = 0,
 		.num_all_ignored = 0,
+		.need_full_atom = false,
+		.fmt = NULL,
 	};
 
 	while ((ret = GETOPT_LONG(QSIZE, qsize, "")) != -1) {
 		switch (ret) {
 		COMMON_GETOPTS_CASES(qsize)
-		case 'f': state.fs_size = 1; break;
-		case 's': state.summary = 1; break;
-		case 'S': state.summary = state.summary_only = 1; break;
-		case 'm': state.disp_units = MEGABYTE; state.str_disp_units = "MiB"; break;
-		case 'k': state.disp_units = KILOBYTE; state.str_disp_units = "KiB"; break;
-		case 'b': state.disp_units = 1; state.str_disp_units = "bytes"; break;
+		case 'f': state.fs_size = 1;                       break;
+		case 's': state.summary = 1;                       break;
+		case 'S': state.summary = state.summary_only = 1;  break;
+		case 'm': state.disp_units = MEGABYTE;
+				  state.str_disp_units = "MiB";            break;
+		case 'k': state.disp_units = KILOBYTE;
+				  state.str_disp_units = "KiB";            break;
+		case 'b': state.disp_units = 1;
+				  state.str_disp_units = "bytes";          break;
+		case 'F': state.fmt = optarg;
+				  state.need_full_atom = true;             break;
 		case 'i': {
 			regex_t regex;
 			xregcomp(&regex, optarg, REG_EXTENDED|REG_NOSUB);
@@ -225,6 +236,13 @@ int qsize_main(int argc, char **argv)
 			xarraypush_ptr(state.atoms, atom);
 	}
 
+	if (state.fmt == NULL) {
+		if (verbose)
+			state.fmt = "%[CATEGORY]%[PF]";
+		else
+			state.fmt = "%[CATEGORY]%[PN]";
+	}
+
 	state.buflen = _Q_PATH_MAX;
 	state.buf = xmalloc(state.buflen);
 


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-09-10 18:25 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-09-10 18:25 UTC (permalink / raw
  To: gentoo-commits

commit:     3dc607a8a6cfd3bafbc2f10d9a7c3aae90c3a757
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 10 18:21:51 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Sep 10 18:21:51 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=3dc607a8

qlop: add mode to print last run in a similar way like emerge(1) does

For example, the output could be like this, showing upgrade information:

% ./qlop -E -t
  U  app-shells/bash-5.0_p11 [5.0_p9-r0]: 2′38″
  U  app-admin/eselect-1.4.15 [1.4.14-r0]: 19s
  U  sys-libs/talloc-2.3.0 [2.2.0-r0]: 1′56″
  U  app-portage/prefix-toolkit-5 [4-r0]: 10s
  U  dev-python/cryptography-2.7 [2.6.1-r0]: 1′59″
  U  net-dns/bind-tools-9.14.5 [9.14.4-r0]: 4′17″
 R   dev-python/sphinxcontrib-applehelp-1.0.1: 28s
 R   dev-python/sphinxcontrib-devhelp-1.0.1: 27s
 R   dev-python/sphinxcontrib-jsmath-1.0.1: 25s
 R   dev-python/sphinxcontrib-htmlhelp-1.0.2: 28s
 R   dev-python/sphinxcontrib-serializinghtml-1.1.3: 28s
 R   dev-python/sphinxcontrib-qthelp-1.0.2: 28s
  U  dev-python/sphinx-2.0.1 [1.7.5-r1]: 1′13″
  U  net-mail/notmuch-0.29.1-r1 [0.28.4-r0]: 1′00″

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/qlop.1 |  5 ++++-
 qlop.c     | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/man/qlop.1 b/man/qlop.1
index baa5bf5..de1e525 100644
--- a/man/qlop.1
+++ b/man/qlop.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qlop "1" "Jul 2019" "Gentoo Foundation" "qlop"
+.TH qlop "1" "Sep 2019" "Gentoo Foundation" "qlop"
 .SH NAME
 qlop \- emerge log analyzer
 .SH SYNOPSIS
@@ -65,6 +65,9 @@ Show autoclean unmerge history.
 \fB\-s\fR, \fB\-\-sync\fR
 Show sync history.
 .TP
+\fB\-E\fR, \fB\-\-emerge\fR
+Show last merge like how emerge(1) -v would show it.
+.TP
 \fB\-e\fR, \fB\-\-endtime\fR
 Report time at which the operation finished (iso started).
 .TP

diff --git a/qlop.c b/qlop.c
index 243c8b6..3cc3367 100644
--- a/qlop.c
+++ b/qlop.c
@@ -24,7 +24,7 @@
 
 #define QLOP_DEFAULT_LOGFILE "emerge.log"
 
-#define QLOP_FLAGS "ctaHMmuUslerd:f:w:F:" COMMON_FLAGS
+#define QLOP_FLAGS "ctaHMmuUsElerd:f:w:F:" COMMON_FLAGS
 static struct option const qlop_long_opts[] = {
 	{"summary",   no_argument, NULL, 'c'},
 	{"time",      no_argument, NULL, 't'},
@@ -35,6 +35,7 @@ static struct option const qlop_long_opts[] = {
 	{"unmerge",   no_argument, NULL, 'u'},
 	{"autoclean", no_argument, NULL, 'U'},
 	{"sync",      no_argument, NULL, 's'},
+	{"emerge",    no_argument, NULL, 'E'},
 	{"endtime",   no_argument, NULL, 'e'},
 	{"running",   no_argument, NULL, 'r'},
 	{"date",       a_argument, NULL, 'd'},
@@ -54,6 +55,7 @@ static const char * const qlop_opts_help[] = {
 	"Show unmerge history",
 	"Show autoclean unmerge history",
 	"Show sync history",
+	"Show last merge like how emerge(1) -v would show it",
 	"Report time at which the operation finished (iso started)",
 	"Show current emerging packages",
 	"Limit selection to this time (1st -d is start, 2nd -d is end)",
@@ -85,6 +87,7 @@ struct qlop_mode {
 	char do_machine:1;
 	char do_endtime:1;
 	char show_lastmerge:1;
+	char show_emerge:1;
 	const char *fmt;
 };
 
@@ -334,6 +337,7 @@ static int do_emerge_log(
 	time_t elapsed;
 	depend_atom *atom;
 	depend_atom *atomw;
+	depend_atom *upgrade_atom = NULL;
 	DECLARE_ARRAY(merge_matches);
 	DECLARE_ARRAY(merge_averages);
 	DECLARE_ARRAY(unmerge_matches);
@@ -638,6 +642,34 @@ static int do_emerge_log(
 								flags->do_time ? ": " : "",
 								flags->do_time ?
 									fmt_elapsedtime(flags, elapsed) : "");
+					} else if (flags->show_emerge) {
+						int state = NOT_EQUAL;
+						if (upgrade_atom != NULL)
+							state = atom_compare(pkgw->atom, upgrade_atom);
+						switch (state) {
+							/*         "NRUD " */
+							case EQUAL:
+								printf(" %sR%s   ", YELLOW, NORM);
+								break;
+							case NOT_EQUAL:
+								printf("%sN%s    ", GREEN, NORM);
+								break;
+							case NEWER:
+								printf("  %sU%s  ", BLUE, NORM);
+								break;
+							case OLDER:
+								printf("  %sU%sD%s ", BLUE, DKBLUE, NORM);
+								break;
+						}
+						printf("%s", atom_format(flags->fmt, pkgw->atom));
+						if (state == NEWER || state == OLDER)
+							printf(" %s[%s%s%s]%s", DKBLUE, NORM,
+									atom_format("%[PVR]", upgrade_atom),
+									DKBLUE, NORM);
+						if (flags->do_time)
+							printf(": %s\n", fmt_elapsedtime(flags, elapsed));
+						else
+							printf("\n");
 					} else if (flags->do_time) {
 						printf("%s >>> %s: %s\n",
 								fmt_date(flags, pkgw->tbegin, tstart),
@@ -675,6 +707,14 @@ static int do_emerge_log(
 				if (atom == NULL)
 					continue;
 
+				if (p[-20] == ' ' && flags->show_emerge)
+				{
+					if (upgrade_atom != NULL)
+						atom_implode(upgrade_atom);
+					upgrade_atom = atom;
+					continue;
+				}
+
 				/* see if we need this atom */
 				atomw = NULL;
 				array_for_each(atoms, i, atomw) {
@@ -942,6 +982,7 @@ int qlop_main(int argc, char **argv)
 	m.do_machine = 0;
 	m.do_endtime = 0;
 	m.show_lastmerge = 0;
+	m.show_emerge = 0;
 	m.fmt = NULL;
 
 	while ((ret = GETOPT_LONG(QLOP, qlop, "")) != -1) {
@@ -953,6 +994,12 @@ int qlop_main(int argc, char **argv)
 			case 'u': m.do_unmerge = 1;     break;
 			case 'U': m.do_autoclean = 1;   break;
 			case 's': m.do_sync = 1;        break;
+			case 'E': m.do_merge = 1;
+					  m.do_unmerge = 1;
+					  m.do_autoclean = 1;
+					  m.show_lastmerge = 1;
+					  m.show_emerge = 1;
+					  verbose = 1;          break;
 			case 'r': m.do_running = 1;     break;
 			case 'a': m.do_average = 1;     break;
 			case 'c': m.do_summary = 1;     break;


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-09-28 13:19 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-09-28 13:19 UTC (permalink / raw
  To: gentoo-commits

commit:     ea7f00529fa689a6624f6b26b5d3b7197f4fbfd5
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat Sep 28 13:18:31 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat Sep 28 13:18:31 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=ea7f0052

qpkg: don't emit hypothetical messages when real work has been done

drop the "would be" part of how many bytes were freed when we're not
pretending

Bug: https://bugs.gentoo.org/695586
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 applets.h  | 2 +-
 man/qpkg.1 | 4 ++--
 qpkg.c     | 8 +++++---
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/applets.h b/applets.h
index 520ff23..364f457 100644
--- a/applets.h
+++ b/applets.h
@@ -82,7 +82,7 @@ static const struct applet_t {
 	{"qmanifest", qmanifest_main, "<misc args>",     "verify or generate thick Manifest files"},
 #endif
 	{"qmerge",    qmerge_main,    "<pkgnames>",      "fetch and merge binary package"},
-	{"qpkg",      qpkg_main,      "<misc args>",     "manipulate Gentoo binpkgs"},
+	{"qpkg",      qpkg_main,      "<misc args>",     "create or manipulate Gentoo binpkgs"},
 	{"qsearch",   qsearch_main,   "<regex>",         "search pkgname/desc"},
 	{"qsize",     qsize_main,     "<pkgname>",       "calculate size usage"},
 	{"qtbz2",     qtbz2_main,     "<misc args>",     "manipulate tbz2 packages"},

diff --git a/man/qpkg.1 b/man/qpkg.1
index c471ea1..161a8bb 100644
--- a/man/qpkg.1
+++ b/man/qpkg.1
@@ -1,7 +1,7 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qpkg "1" "Jul 2019" "Gentoo Foundation" "qpkg"
+.TH qpkg "1" "Sep 2019" "Gentoo Foundation" "qpkg"
 .SH NAME
-qpkg \- manipulate Gentoo binpkgs
+qpkg \- create or manipulate Gentoo binpkgs
 .SH SYNOPSIS
 .B qpkg
 \fI[opts] <misc args>\fR

diff --git a/qpkg.c b/qpkg.c
index 0ac6e92..947ff84 100644
--- a/qpkg.c
+++ b/qpkg.c
@@ -171,8 +171,9 @@ qpkg_clean(char *dirp)
 	disp_units = KILOBYTE;
 	if ((num_all_bytes / KILOBYTE) > 1000)
 		disp_units = MEGABYTE;
-	qprintf(" %s*%s Total space that would be freed in packages "
-			"directory: %s%s %ciB%s\n", GREEN, NORM, RED,
+	qprintf(" %s*%s Total space %sfreed in packages "
+			"directory: %s%s %ciB%s\n", GREEN, NORM,
+			pretend ? "that would be " : "", RED,
 			make_human_readable_str(num_all_bytes, 1, disp_units),
 			disp_units == MEGABYTE ? 'M' : 'K', NORM);
 
@@ -297,10 +298,11 @@ qpkg_make(depend_atom *atom)
 	xpak_create(AT_FDCWD, tbz2, 1, xpak_argv, 1, verbose);
 
 	stat(tbz2, &st);
+	xpaksize = st.st_size - xpaksize;
 
 	/* save tbz2 tail: OOOOSTOP */
 	fp = fopen(tbz2, "a");
-	WRITE_BE_INT32(buf, st.st_size - xpaksize);
+	WRITE_BE_INT32(buf, xpaksize);
 	fwrite(buf, 1, 4, fp);
 	fwrite("STOP", 1, 4, fp);
 	fclose(fp);


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-10-27 12:22 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-10-27 12:22 UTC (permalink / raw
  To: gentoo-commits

commit:     c9d7b9de78f1488827cb516bf61a54df28a750ab
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 27 12:19:06 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Oct 27 12:19:06 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=c9d7b9de

qlop: take two at implementing currently running merges

Probe /proc filesystem for running merges, and use the atoms found there
to select the packages to list.  In addition, prune any operations that
started > 10 days ago so there will be some sort of convergence.

Bug: https://bugs.gentoo.org/698196
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 main.c     |   3 +-
 man/qlop.1 |   4 +-
 qlop.c     | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 173 insertions(+), 9 deletions(-)

diff --git a/main.c b/main.c
index 5d4c4cd..0b827fc 100644
--- a/main.c
+++ b/main.c
@@ -501,7 +501,8 @@ read_portage_env_file(const char *configroot, const char *file, env_vars vars[])
 				source_len = strlen(sfile);
 
 				if (buflen <= source_len + file_path_len)
-					buf = xrealloc(buf, buflen = source_len + file_path_len + 1);
+					buf = xrealloc(buf,
+							buflen = source_len + file_path_len + 1);
 				memmove(buf + file_path_len, buf + 7, source_len + 1);
 				memcpy(buf, file, file_path_len);
 				sfile = buf;

diff --git a/man/qlop.1 b/man/qlop.1
index de1e525..58efd09 100644
--- a/man/qlop.1
+++ b/man/qlop.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qlop "1" "Sep 2019" "Gentoo Foundation" "qlop"
+.TH qlop "1" "Oct 2019" "Gentoo Foundation" "qlop"
 .SH NAME
 qlop \- emerge log analyzer
 .SH SYNOPSIS
@@ -51,7 +51,7 @@ Print elapssed time in human readable format.  This form uses
 minutes, hours and days instead of just seconds.
 .TP
 \fB\-M\fR, \fB\-\-machine\fR
-Print elapsed time as seconds with no formatting.
+Print start/elapsed time as seconds with no formatting.
 .TP
 \fB\-m\fR, \fB\-\-merge\fR
 Show merge history.

diff --git a/qlop.c b/qlop.c
index 7a93656..6cb2c04 100644
--- a/qlop.c
+++ b/qlop.c
@@ -16,9 +16,11 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <limits.h>
+#include <sys/stat.h>
 
 #include "atom.h"
 #include "eat_file.h"
+#include "scandirat.h"
 #include "set.h"
 #include "xarray.h"
 #include "xasprintf.h"
@@ -51,7 +53,7 @@ static const char * const qlop_opts_help[] = {
 	"Print time taken to complete action",
 	"Print average time taken to complete action",
 	"Print elapsed time in human readable format (use with -t or -a)",
-	"Print elapsed time as seconds with no formatting",
+	"Print start/elapsed time as seconds with no formatting",
 	"Show merge history",
 	"Show unmerge history",
 	"Show autoclean unmerge history",
@@ -201,10 +203,15 @@ parse_date(const char *sdate, time_t *t)
 static char _date_buf[48];
 static char *fmt_date(struct qlop_mode *flags, time_t ts, time_t te)
 {
-	time_t t;
+	time_t t = flags->do_endtime ? te : ts;
+
+	if (flags->do_machine)
+		snprintf(_date_buf, sizeof(_date_buf),
+				"%zd", (size_t)t);
+	else
+		strftime(_date_buf, sizeof(_date_buf),
+				"%Y-%m-%dT%H:%M:%S", localtime(&t));
 
-	t = flags->do_endtime ? te : ts;
-	strftime(_date_buf, sizeof(_date_buf), "%Y-%m-%dT%H:%M:%S", localtime(&t));
 	return _date_buf;
 }
 
@@ -336,6 +343,21 @@ New format:
 1550953125:  >>> unmerge success: app-admin/pwgen-2.08
 1550953125:  *** exiting successfully.
 1550953125:  *** terminating.
+
+
+Currently running merges can be found in the /proc filesystem:
+- Linux: readlink(/proc/<pid>/fd/X)
+- Solaris: readlink(/proc/<pid>/path/X)
+from here a file should be there that points to the build.log file
+$CAT/$P/work/build.log.  If so, it's running for $CAT/$P.
+This requires being the portage user though, or root.
+
+Should there be no /proc, we can deduce from the log whether a package
+is being emerged, if and only if, there are no parallel merges, and
+portage never got interrupted in a way where it could not write its
+interruption to the log.  Unfortunately these scenarios happen a lot.
+As such, we can try to remedy this somewhat by using a rule of thumb
+that currently merging packages need to be withinin the last 10 days.
 */
 static int do_emerge_log(
 		const char *log,
@@ -463,6 +485,7 @@ static int do_emerge_log(
 		tbegin = last_merge;
 		tend = tstart;
 	}
+
 	/* loop over lines searching for atoms */
 	while (fgets(buf, sizeof(buf), fp) != NULL) {
 		if ((p = strchr(buf, ':')) == NULL)
@@ -821,11 +844,19 @@ static int do_emerge_log(
 	}
 	fclose(fp);
 	if (flags->do_running) {
+		time_t cutofftime;
+
+		/* emerge.log can be interrupted, incorrect and hopelessly lost,
+		 * so to eliminate some unfinished crap from there, we just
+		 * ignore anything that's > cutofftime, 10 days for now. */
+		cutofftime = 10 * 24 * 60 * 60;  /* when we consider entries stale */
+
 		/* can't report endtime for non-finished operations */
 		flags->do_endtime = 0;
 		tstart = time(NULL);
 		sync_time /= sync_cnt;
-		if (sync_start > 0) {
+		if (sync_start >= tstart - cutofftime) {
+			elapsed = tstart - sync_start;
 			if (elapsed >= sync_time)
 				sync_time = 0;
 			if (flags->do_time) {
@@ -847,6 +878,9 @@ static int do_emerge_log(
 			time_t maxtime = 0;
 			bool isMax = false;
 
+			if (pkgw->tbegin < tstart - cutofftime)
+				continue;
+
 			snprintf(afmt, sizeof(afmt), "%s/%s",
 					pkgw->atom->CATEGORY, pkgw->atom->PN);
 
@@ -891,6 +925,9 @@ static int do_emerge_log(
 			time_t maxtime = 0;
 			bool isMax = false;
 
+			if (pkgw->tbegin < tstart - cutofftime)
+				continue;
+
 			snprintf(afmt, sizeof(afmt), "%s/%s",
 					pkgw->atom->CATEGORY, pkgw->atom->PN);
 
@@ -978,6 +1015,118 @@ static int do_emerge_log(
 	return 0;
 }
 
+/* scan through /proc for running merges, this requires portage user
+ * or root */
+static array_t *probe_proc(array_t *atoms)
+{
+	struct dirent **procs;
+	int procslen;
+	int pi;
+	struct dirent **links;
+	int linkslen;
+	int li;
+	struct dirent *d;
+	char npath[_Q_PATH_MAX * 2];
+	char rpath[_Q_PATH_MAX];
+	const char *subdir = NULL;
+	const char *pid;
+	ssize_t rpathlen;
+	char *p;
+	depend_atom *atom;
+	DECLARE_ARRAY(ret_atoms);
+	size_t i;
+
+	/* /proc/<pid>/path/<[0-9]+link>
+	 * /proc/<pid>/fd/<[0-9]+link> */
+	if ((procslen = scandir("/proc", &procs, NULL, NULL)) > 0) {
+		for (pi = 0; pi < procslen; pi++) {
+			d = procs[pi];
+			/* must be [0-9]+ */
+			if (d->d_name[0] < '0' || d->d_name[0] > '9')
+				continue;
+
+			if (subdir == NULL) {
+				struct stat st;
+
+				snprintf(npath, sizeof(npath), "/proc/%s/path", d->d_name);
+				if (stat(npath, &st) < 0)
+					subdir = "fd";
+				else
+					subdir = "path";
+			}
+
+			pid = d->d_name;
+			snprintf(npath, sizeof(npath), "/proc/%s/%s", pid, subdir);
+			if ((linkslen = scandir(npath, &links, NULL, NULL)) > 0) {
+				for (li = 0; li < linkslen; li++) {
+					d = links[li];
+					/* must be [0-9]+ */
+					if (d->d_name[0] < '0' || d->d_name[0] > '9')
+						continue;
+					snprintf(npath, sizeof(npath), "/proc/%s/%s/%s",
+							pid, subdir, d->d_name);
+					rpathlen = readlink(npath, rpath, sizeof(rpath));
+					if (rpathlen <= 0)
+						continue;
+					rpath[rpathlen] = '\0';
+					/* check if this points to a portage build:
+					 * <somepath>/portage/<cat>/<pf>/temp/build.log */
+					if (strcmp(rpath + rpathlen -
+								(sizeof("/temp/build.log") - 1),
+								"/temp/build.log") == 0 &&
+							(p = strstr(rpath, "/portage/")) != NULL)
+					{
+						p += sizeof("/portage/") - 1;
+						rpath[rpathlen - (sizeof("/temp/build.log") - 1)] =
+							'\0';
+						atom = atom_explode(p);
+						if (atom == NULL ||
+								atom->CATEGORY == NULL || atom->P == NULL)
+						{
+							if (atom != NULL)
+								atom_implode(atom);
+							continue;
+						}
+						xarraypush_ptr(ret_atoms, atom);
+					}
+				}
+				scandir_free(links, linkslen);
+			}
+		}
+		scandir_free(procs, procslen);
+	} else {
+		/* flag /proc doesn't exist */
+		return NULL;
+	}
+
+	if (array_cnt(atoms) > 0) {
+		size_t j;
+		depend_atom *atomr;
+
+		/* calculate intersection */
+		array_for_each(atoms, i, atom) {
+			array_for_each(ret_atoms, j, atomr) {
+				if (atom_compare(atomr, atom) != EQUAL) {
+					xarraydelete_ptr(ret_atoms, j);
+					atom_implode(atomr);
+					break;
+				}
+			}
+			atom_implode(atom);
+		}
+		xarrayfree_int(atoms);
+	}
+
+	/* ret_atoms is allocated on the stack, so copy into atoms which is
+	 * empty at this point */
+	array_for_each(ret_atoms, i, atom)
+		xarraypush_ptr(atoms, atom);
+
+	xarrayfree_int(ret_atoms);
+
+	return atoms;
+}
+
 int qlop_main(int argc, char **argv)
 {
 	size_t i;
@@ -1160,7 +1309,21 @@ int qlop_main(int argc, char **argv)
 			m.fmt = "%[CATEGORY]%[PN]";
 	}
 
-	do_emerge_log(logfile, &m, atoms, start_time, end_time);
+	if (m.do_running) {
+		array_t *new_atoms = probe_proc(atoms);
+
+		if (new_atoms != NULL && array_cnt(new_atoms) == 0) {
+			/* proc supported, found nothing running */
+			start_time = LONG_MAX;
+		} else {
+			warn("/proc not available, deducing running "
+					"merges from emerge.log");
+		}
+
+	}
+
+	if (start_time < LONG_MAX)
+		do_emerge_log(logfile, &m, atoms, start_time, end_time);
 
 	array_for_each(atoms, i, atom)
 		atom_implode(atom);


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-11-09 10:13 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-11-09 10:13 UTC (permalink / raw
  To: gentoo-commits

commit:     57e49de5c210c8def6f4957a6f94a62c60f98e52
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat Nov  9 10:11:04 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat Nov  9 10:11:04 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=57e49de5

q: add option to print envvars, much like portageq envvar

Option -e to q will dump the env variables used by portage-utils.

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 main.c  | 86 +++++++++++++++++++++++++++--------------------------------------
 main.h  | 23 +++++++++++++++---
 man/q.1 |  7 ++++--
 q.c     | 59 +++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 118 insertions(+), 57 deletions(-)

diff --git a/main.c b/main.c
index 0b827fc..f8ba7af 100644
--- a/main.c
+++ b/main.c
@@ -393,19 +393,6 @@ strincr_var(const char *name, const char *s, char **value, size_t *value_len)
 	/* we should sort here */
 }
 
-typedef enum { _Q_BOOL, _Q_STR, _Q_ISTR } var_types;
-typedef struct {
-	const char *name;
-	const size_t name_len;
-	const var_types type;
-	union {
-		char **s;
-		bool *b;
-	} value;
-	size_t value_len;
-	const char *default_value;
-} env_vars;
-
 static env_vars *
 get_portage_env_var(env_vars *vars, const char *name)
 {
@@ -619,49 +606,48 @@ read_portage_profile(const char *configroot, const char *profile, env_vars vars[
 	free(profile_file);
 }
 
-static void
-initialize_portage_env(void)
-{
-	size_t i;
-	const char *s;
-
-	bool nocolor = 0;
-
-	env_vars *var;
-	env_vars vars_to_read[] = {
+static bool nocolor = 0;
+env_vars vars_to_read[] = {
 #define _Q_EV(t, V, set, lset, d) \
-	{ \
-		.name = #V, \
-		.name_len = strlen(#V), \
-		.type = _Q_##t, \
-		set, \
-		lset, \
-		.default_value = d, \
-	},
+{ \
+	.name = #V, \
+	.name_len = strlen(#V), \
+	.type = _Q_##t, \
+	set, \
+	lset, \
+	.default_value = d, \
+},
 #define _Q_EVS(t, V, v, d) _Q_EV(t, V, .value.s = &v, .value_len = strlen(d), d)
 #define _Q_EVB(t, V, v, d) _Q_EV(t, V, .value.b = &v, .value_len = 0, d)
 
-		_Q_EVS(STR,  ROOT,                portroot,            "/")
-		_Q_EVS(STR,  ACCEPT_LICENSE,      accept_license,      "")
-		_Q_EVS(ISTR, INSTALL_MASK,        install_mask,        "")
-		_Q_EVS(ISTR, PKG_INSTALL_MASK,    pkg_install_mask,    "")
-		_Q_EVS(STR,  ARCH,                portarch,            "")
-		_Q_EVS(ISTR, CONFIG_PROTECT,      config_protect,      "/etc")
-		_Q_EVS(ISTR, CONFIG_PROTECT_MASK, config_protect_mask, "")
-		_Q_EVB(BOOL, NOCOLOR,             nocolor,             0)
-		_Q_EVS(ISTR, FEATURES,            features,            "")
-		_Q_EVS(STR,  EPREFIX,             eprefix,             CONFIG_EPREFIX)
-		_Q_EVS(STR,  EMERGE_LOG_DIR,      portlogdir,          CONFIG_EPREFIX "var/log")
-		_Q_EVS(STR,  PORTDIR,             main_overlay,        CONFIG_EPREFIX "var/db/repos/gentoo")
-		_Q_EVS(STR,  PORTAGE_BINHOST,     binhost,             DEFAULT_PORTAGE_BINHOST)
-		_Q_EVS(STR,  PORTAGE_TMPDIR,      port_tmpdir,         CONFIG_EPREFIX "var/tmp/portage/")
-		_Q_EVS(STR,  PKGDIR,              pkgdir,              CONFIG_EPREFIX "var/cache/binpkgs/")
-		_Q_EVS(STR,  Q_VDB,               portvdb,             CONFIG_EPREFIX "var/db/pkg")
-		_Q_EVS(STR,  Q_EDB,               portedb,             CONFIG_EPREFIX "var/cache/edb")
-		{ NULL, 0, _Q_BOOL, { NULL }, 0, NULL, }
+	_Q_EVS(STR,  ROOT,                portroot,            "/")
+	_Q_EVS(STR,  ACCEPT_LICENSE,      accept_license,      "")
+	_Q_EVS(ISTR, INSTALL_MASK,        install_mask,        "")
+	_Q_EVS(ISTR, PKG_INSTALL_MASK,    pkg_install_mask,    "")
+	_Q_EVS(STR,  ARCH,                portarch,            "")
+	_Q_EVS(ISTR, CONFIG_PROTECT,      config_protect,      "/etc")
+	_Q_EVS(ISTR, CONFIG_PROTECT_MASK, config_protect_mask, "")
+	_Q_EVB(BOOL, NOCOLOR,             nocolor,             0)
+	_Q_EVS(ISTR, FEATURES,            features,            "")
+	_Q_EVS(STR,  EPREFIX,             eprefix,             CONFIG_EPREFIX)
+	_Q_EVS(STR,  EMERGE_LOG_DIR,      portlogdir,          CONFIG_EPREFIX "var/log")
+	_Q_EVS(STR,  PORTDIR,             main_overlay,        CONFIG_EPREFIX "var/db/repos/gentoo")
+	_Q_EVS(STR,  PORTAGE_BINHOST,     binhost,             DEFAULT_PORTAGE_BINHOST)
+	_Q_EVS(STR,  PORTAGE_TMPDIR,      port_tmpdir,         CONFIG_EPREFIX "var/tmp/portage/")
+	_Q_EVS(STR,  PKGDIR,              pkgdir,              CONFIG_EPREFIX "var/cache/binpkgs/")
+	_Q_EVS(STR,  Q_VDB,               portvdb,             CONFIG_EPREFIX "var/db/pkg")
+	_Q_EVS(STR,  Q_EDB,               portedb,             CONFIG_EPREFIX "var/cache/edb")
+	{ NULL, 0, _Q_BOOL, { NULL }, 0, NULL, }
 
 #undef _Q_EV
-	};
+};
+
+static void
+initialize_portage_env(void)
+{
+	size_t i;
+	const char *s;
+	env_vars *var;
 
 	/* initialize all the strings with their default value */
 	for (i = 0; vars_to_read[i].name; ++i) {

diff --git a/main.h b/main.h
index 88412a8..ad1467b 100644
--- a/main.h
+++ b/main.h
@@ -14,15 +14,16 @@
 # include "config.h"  /* make sure we have EPREFIX, if set */
 #endif
 
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <errno.h>
-#include <stdint.h>
-#include <limits.h>
 
-#include "i18n.h"
 #include "colors.h"
+#include "i18n.h"
 
 extern const char *argv0;
 
@@ -134,4 +135,18 @@ extern FILE *warnout;
 #define errp(fmt, args...) _err(warnp, fmt , ## args)
 #define errfp(fmt, args...) _err(warnfp, fmt, ## args)
 
+typedef enum { _Q_BOOL, _Q_STR, _Q_ISTR } var_types;
+typedef struct {
+	const char *name;
+	const size_t name_len;
+	const var_types type;
+	union {
+		char **s;
+		bool *b;
+	} value;
+	size_t value_len;
+	const char *default_value;
+} env_vars;
+extern env_vars vars_to_read[];
+
 #endif

diff --git a/man/q.1 b/man/q.1
index 4e6264c..95caf56 100644
--- a/man/q.1
+++ b/man/q.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH q "1" "Jul 2019" "Gentoo Foundation" "q"
+.TH q "1" "Nov 2019" "Gentoo Foundation" "q"
 .SH NAME
 q \- invoke a portage utility applet
 .SH SYNOPSIS
@@ -22,6 +22,9 @@ Install symlinks for applets.
 \fB\-o\fR, \fB\-\-overlays\fR
 Print available overlays (read from repos.conf).
 .TP
+\fB\-e\fR, \fB\-\-envvar\fR
+Print found environment variables and their values.
+.TP
 \fB\-\-root\fR \fI<arg>\fR
 Set the ROOT env var.
 .TP
@@ -53,7 +56,7 @@ Print version and exit.
      qlop <pkgname>       : emerge log analyzer
  qmanifest <misc args>     : verify or generate thick Manifest files
    qmerge <pkgnames>      : fetch and merge binary package
-     qpkg <misc args>     : manipulate Gentoo binpkgs
+     qpkg <misc args>     : create or manipulate Gentoo binpkgs
   qsearch <regex>         : search pkgname/desc
     qsize <pkgname>       : calculate size usage
     qtbz2 <misc args>     : manipulate tbz2 packages

diff --git a/q.c b/q.c
index c03fd66..2fb406f 100644
--- a/q.c
+++ b/q.c
@@ -23,15 +23,17 @@
 #include "eat_file.h"
 #include "rmspace.h"
 
-#define Q_FLAGS "io" COMMON_FLAGS
+#define Q_FLAGS "ioe" COMMON_FLAGS
 static struct option const q_long_opts[] = {
 	{"install",       no_argument, NULL, 'i'},
 	{"overlays",      no_argument, NULL, 'o'},
+	{"envvar",        no_argument, NULL, 'e'},
 	COMMON_LONG_OPTS
 };
 static const char * const q_opts_help[] = {
 	"Install symlinks for applets",
 	"Print available overlays (read from repos.conf)",
+	"Print found environment variables and their values",
 	COMMON_OPTS_HELP
 };
 #define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, NULL, lookup_applet_idx("q"))
@@ -78,6 +80,7 @@ int q_main(int argc, char **argv)
 	int i;
 	bool install;
 	bool print_overlays;
+	bool print_vars;
 	const char *p;
 	APPLET func;
 
@@ -96,11 +99,13 @@ int q_main(int argc, char **argv)
 
 	install = false;
 	print_overlays = false;
+	print_vars = false;
 	while ((i = GETOPT_LONG(Q, q, "+")) != -1) {
 		switch (i) {
 		COMMON_GETOPTS_CASES(q)
 		case 'i': install = true;        break;
 		case 'o': print_overlays = true; break;
+		case 'e': print_vars = true;     break;
 		}
 	}
 
@@ -187,6 +192,58 @@ int q_main(int argc, char **argv)
 		return 0;
 	}
 
+	if (print_vars) {
+		env_vars *var;
+		int j;
+
+		if (argc == optind || argc - optind > 1) {
+			for (i = 0; vars_to_read[i].name; i++) {
+				var = &vars_to_read[i];
+
+				/* check if we want this variable */
+				for (j = optind; j < argc; j++)
+					if (strcmp(var->name, argv[j]) == 0)
+						break;
+				if (j == argc && optind != argc)
+					continue;
+
+				printf("%s%s%s=", BLUE, var->name, NORM);
+				switch (var->type) {
+					case _Q_BOOL:
+						printf("%s%s%s\n",
+								YELLOW, *var->value.b ? "1" : "0", NORM);
+						break;
+				case _Q_STR:
+				case _Q_ISTR:
+						printf("%s\"%s\"%s\n", RED, *var->value.s, NORM);
+						break;
+				}
+			}
+		} else {
+			/* single envvar printing, just output the value, like
+			 * portageq envvar does */
+			for (i = 0; vars_to_read[i].name; i++) {
+				var = &vars_to_read[i];
+
+				if (strcmp(var->name, argv[optind]) != 0)
+					continue;
+
+				switch (var->type) {
+					case _Q_BOOL:
+						printf("%s%s%s\n",
+								YELLOW, *var->value.b ? "1" : "0", NORM);
+						break;
+				case _Q_STR:
+				case _Q_ISTR:
+						printf("%s%s%s\n", RED, *var->value.s, NORM);
+						break;
+				}
+			}
+		}
+
+		return 0;
+	}
+
 	if (argc == optind)
 		q_usage(EXIT_FAILURE);
 	if ((func = lookup_applet(argv[optind])) == NULL)


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-11-24 12:29 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-11-24 12:29 UTC (permalink / raw
  To: gentoo-commits

commit:     abbfff8553d8e99d71d71054e81a7f21d6479221
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Nov 24 12:26:47 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Nov 24 12:26:47 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=abbfff85

main: overhaul profile/config reading somewhat

- track where values come from, expose using -v (with q -[oe])
- follow repo-prefixed profiles in parent files (non-PMS feature?)
- read usr/share/portage/config/repos.conf for repo defaults

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 applets.h |   1 +
 main.c    | 397 ++++++++++++++++++++++++++++++++++++--------------------------
 main.h    |   1 +
 man/q.1   |   6 +-
 q.c       |  20 +++-
 5 files changed, 254 insertions(+), 171 deletions(-)

diff --git a/applets.h b/applets.h
index 364f457..e7b81f4 100644
--- a/applets.h
+++ b/applets.h
@@ -168,6 +168,7 @@ extern char *features;
 extern char *install_mask;
 extern DEFINE_ARRAY(overlays);
 extern DEFINE_ARRAY(overlay_names);
+extern DEFINE_ARRAY(overlay_src);
 extern char *main_overlay;
 extern int twidth;
 

diff --git a/main.c b/main.c
index e236934..081d72a 100644
--- a/main.c
+++ b/main.c
@@ -44,6 +44,7 @@ char *features;
 char *install_mask;
 DECLARE_ARRAY(overlays);
 DECLARE_ARRAY(overlay_names);
+DECLARE_ARRAY(overlay_src);
 
 static char *portarch;
 static char *portedb;
@@ -248,96 +249,6 @@ makeargv(const char *string, int *argc, char ***argv)
 	free(q);
 }
 
-/* Handle a single file in the repos.conf format. */
-static void
-read_one_repos_conf(const char *repos_conf)
-{
-	int nsec;
-	char *conf;
-	const char *main_repo, *repo, *path;
-	dictionary *dict;
-
-	if (getenv("DEBUG"))
-		fprintf(stderr, "  parse %s\n", repos_conf);
-
-	dict = iniparser_load(repos_conf);
-
-	main_repo = iniparser_getstring(dict, "DEFAULT:main-repo", NULL);
-
-	nsec = iniparser_getnsec(dict);
-	while (nsec-- > 0) {
-		repo = iniparser_getsecname(dict, nsec);
-		if (!strcmp(repo, "DEFAULT"))
-			continue;
-
-		xasprintf(&conf, "%s:location", repo);
-		path = iniparser_getstring(dict, conf, NULL);
-		if (path) {
-			void *ele = xarraypush_str(overlays, path);
-			xarraypush_str(overlay_names, repo);
-			if (main_repo && !strcmp(repo, main_repo))
-				main_overlay = ele;
-		}
-		free(conf);
-	}
-
-	iniparser_freedict(dict);
-}
-
-/* Handle a possible directory of files. */
-static void
-read_repos_conf(const char *configroot, const char *repos_conf)
-{
-	char *top_conf, *sub_conf;
-	int i, count;
-	struct dirent **confs;
-
-	xasprintf(&top_conf, "%s%s", configroot, repos_conf);
-	if (getenv("DEBUG"))
-		fprintf(stderr, "repos.conf.d scanner %s\n", top_conf);
-	count = scandir(top_conf, &confs, NULL, alphasort);
-	if (count == -1) {
-		if (errno == ENOTDIR)
-			read_one_repos_conf(top_conf);
-	} else {
-		for (i = 0; i < count; ++i) {
-			const char *name = confs[i]->d_name;
-
-			if (name[0] == '.' || name[0] == '\0')
-				continue;
-
-			/* Exclude backup files (aka files with ~ as postfix). */
-			if (name[strlen(name) - 1] == '~')
-				continue;
-
-#ifdef DT_UNKNOWN
-			if (confs[i]->d_type != DT_UNKNOWN &&
-			    confs[i]->d_type != DT_REG &&
-			    confs[i]->d_type != DT_LNK)
-				continue;
-#endif
-
-			xasprintf(&sub_conf, "%s/%s", top_conf, name);
-
-#ifdef DT_UNKNOWN
-			if (confs[i]->d_type != DT_REG)
-#endif
-			{
-				struct stat st;
-				if (stat(sub_conf, &st) || !S_ISREG(st.st_mode)) {
-					free(sub_conf);
-					continue;
-				}
-			}
-
-			read_one_repos_conf(sub_conf);
-			free(sub_conf);
-		}
-		scandir_free(confs, count);
-	}
-	free(top_conf);
-}
-
 static void
 strincr_var(const char *name, const char *s, char **value, size_t *value_len)
 {
@@ -406,19 +317,33 @@ get_portage_env_var(env_vars *vars, const char *name)
 }
 
 static void
-set_portage_env_var(env_vars *var, const char *value)
+set_portage_env_var(env_vars *var, const char *value, const char *src)
 {
 	switch (var->type) {
 	case _Q_BOOL:
 		*var->value.b = 1;
+		free(var->src);
+		var->src = xstrdup(src);
 		break;
 	case _Q_STR:
 		free(*var->value.s);
 		*var->value.s = xstrdup(value);
 		var->value_len = strlen(value);
+		free(var->src);
+		var->src = xstrdup(src);
 		break;
 	case _Q_ISTR:
 		strincr_var(var->name, value, var->value.s, &var->value_len);
+		if (strcmp(var->src, "built-in default") == 0) {
+			free(var->src);
+			var->src = xstrdup(src);
+		} else {
+			size_t l = strlen(var->src) + 2 + strlen(src) + 1;
+			char *p = xmalloc(sizeof(char) * l);
+			snprintf(p, l, "%s, %s", var->src, src);
+			free(var->src);
+			var->src = p;
+		}
 		break;
 	}
 }
@@ -426,27 +351,22 @@ set_portage_env_var(env_vars *var, const char *value)
 /* Helper to read a portage env file (e.g. make.conf), or recursively if
  * it points to a directory */
 static void
-read_portage_env_file(const char *configroot, const char *file, env_vars vars[])
+read_portage_env_file(const char *file, env_vars vars[])
 {
-	size_t i, buflen, line, configroot_len, file_len;
 	FILE *fp;
 	struct dirent **dents;
 	int dentslen;
-	char *buf, *s, *p;
+	char *s;
+	char *p;
+	char *buf = NULL;
+	size_t buflen = 0;
+	size_t line;
+	int i;
 
 	if (getenv("DEBUG"))
-		fprintf(stderr, "profile %s/%s\n", configroot, file);
-
-	configroot_len = strlen(configroot);
-	file_len = strlen(file);
-	buflen = configroot_len + file_len + 1;
-	buf = xmalloc(buflen);
-
-	memcpy(buf, configroot, configroot_len);
-	memcpy(buf + configroot_len, file, file_len);
-	buf[buflen - 1] = '\0';
+		fprintf(stderr, "profile %s\n", file);
 
-	if ((dentslen = scandir(buf, &dents, NULL, alphasort)) > 0) {
+	if ((dentslen = scandir(file, &dents, NULL, alphasort)) > 0) {
 		int di;
 		struct dirent *d;
 		char npath[_Q_PATH_MAX * 2];
@@ -458,44 +378,41 @@ read_portage_env_file(const char *configroot, const char *file, env_vars vars[])
 					d->d_name[strlen(d->d_name) - 1] == '~')
 				continue;
 			snprintf(npath, sizeof(npath), "%s/%s", file, d->d_name);
-			read_portage_env_file(configroot, npath, vars);
+			read_portage_env_file(npath, vars);
 		}
 		scandir_free(dents, dentslen);
 		goto done;
 	}
 
-	fp = fopen(buf, "r");
+	fp = fopen(file, "r");
 	if (fp == NULL)
 		goto done;
 
 	line = 0;
 	while (getline(&buf, &buflen, fp) != -1) {
-		++line;
+		line++;
 		rmspace(buf);
 		if (*buf == '#' || *buf == '\0')
 			continue;
 
 		/* Handle "source" keyword */
-		if (!strncmp(buf, "source ", 7)) {
+		if (strncmp(buf, "source ", 7) == 0) {
 			const char *sfile = buf + 7;
+			char npath[_Q_PATH_MAX * 2];
 
 			if (sfile[0] != '/') {
 				/* handle relative paths */
-				size_t file_path_len, source_len;
+				size_t file_path_len;
 
 				s = strrchr(file, '/');
 				file_path_len = s - file + 1;
-				source_len = strlen(sfile);
-
-				if (buflen <= source_len + file_path_len)
-					buf = xrealloc(buf,
-							buflen = source_len + file_path_len + 1);
-				memmove(buf + file_path_len, buf + 7, source_len + 1);
-				memcpy(buf, file, file_path_len);
-				sfile = buf;
+
+				snprintf(npath, sizeof(npath), "%.*s/%s",
+						(int)file_path_len, file, sfile);
+				sfile = npath;
 			}
 
-			read_portage_env_file(configroot, sfile, vars);
+			read_portage_env_file(sfile, vars);
 			continue;
 		}
 
@@ -506,7 +423,8 @@ read_portage_env_file(const char *configroot, const char *file, env_vars vars[])
 			if (strncmp(buf, vars[i].name, vars[i].name_len))
 				continue;
 
-			/* make sure we handle spaces between the varname, the =, and the value:
+			/* make sure we handle spaces between the varname, the =,
+			 * and the value:
 			 * VAR=val   VAR = val   VAR="val"
 			 */
 			s = buf + vars[i].name_len;
@@ -541,7 +459,8 @@ read_portage_env_file(const char *configroot, const char *file, env_vars vars[])
 					free(abuf);
 
 					if (!endq)
-						warn("%s:%zu: %s: quote mismatch", file, line, vars[i].name);
+						warn("%s:%zu: %s: quote mismatch",
+								file, line, vars[i].name);
 
 					s = buf + vars[i].name_len + 2;
 				} else {
@@ -554,7 +473,7 @@ read_portage_env_file(const char *configroot, const char *file, env_vars vars[])
 				s[off] = '\0';
 			}
 
-			set_portage_env_var(&vars[i], s);
+			set_portage_env_var(&vars[i], s, file);
 		}
 	}
 
@@ -565,47 +484,74 @@ read_portage_env_file(const char *configroot, const char *file, env_vars vars[])
 
 /* Helper to recursively read stacked make.defaults in profiles */
 static void
-read_portage_profile(const char *configroot, const char *profile, env_vars vars[])
+read_portage_profile(const char *profile, env_vars vars[])
 {
-	size_t configroot_len, profile_len, sub_len;
-	char *profile_file, *sub_file;
+	char profile_file[_Q_PATH_MAX * 3];
+	size_t profile_len;
 	char *s;
+	char *p;
 	char *buf = NULL;
 	size_t buf_len = 0;
 	char *saveptr;
 
 	if (getenv("DEBUG"))
-		fprintf(stderr, "profile %s/%s\n", configroot, profile);
+		fprintf(stderr, "profile %s\n", profile);
 
-	/* initialize the base profile path */
-	configroot_len = strlen(configroot);
-	profile_len = strlen(profile);
-	sub_len = 1024;	/* should be big enough for longest line in "parent" */
-	profile_file = xmalloc(configroot_len + profile_len + sub_len + 2);
+	/* create mutable/appendable copy */
+	profile_len = snprintf(profile_file, sizeof(profile_file), "%s/", profile);
 
-	memcpy(profile_file, configroot, configroot_len);
-	memcpy(profile_file + configroot_len, profile, profile_len);
-	sub_file = profile_file + configroot_len + profile_len + 1;
-	sub_file[-1] = '/';
+	/* check if we have enough space (should always be the case) */
+	if (sizeof(profile_file) - profile_len < sizeof("make.defaults"))
+		return;
 
 	/* first consume the profile's make.defaults */
-	strcpy(sub_file, "make.defaults");
-	read_portage_env_file("", profile_file, vars);
+	strcpy(profile_file + profile_len, "make.defaults");
+	read_portage_env_file(profile_file, vars);
 
 	/* now walk all the parents */
-	strcpy(sub_file, "parent");
+	strcpy(profile_file + profile_len, "parent");
 	if (eat_file(profile_file, &buf, &buf_len) == 0)
-		goto done;
+		return;
 
 	s = strtok_r(buf, "\n", &saveptr);
 	while (s) {
-		strncpy(sub_file, s, sub_len);
-		read_portage_profile("", profile_file, vars);
+		/* handle repo: notation (not in PMS, referenced in Wiki only?) */
+		if ((p = strchr(s, ':')) != NULL) {
+			char *overlay;
+			char *repo_name;
+			size_t n;
+
+			/* split repo from target */
+			*p++ = '\0';
+
+			/* match the repo */
+			repo_name = NULL;
+			array_for_each(overlays, n, overlay) {
+				repo_name = xarrayget(overlay_names, n);
+				if (strcmp(repo_name, s) == 0) {
+					snprintf(profile_file, sizeof(profile_file),
+							"%s/profiles/%s/", overlay, p);
+					break;
+				}
+				repo_name = NULL;
+			}
+			if (repo_name == NULL) {
+				warn("ignoring parent with unknown repo in profile: %s", s);
+				s = strtok_r(NULL, "\n", &saveptr);
+				continue;
+			}
+		} else {
+			snprintf(profile_file + profile_len,
+					sizeof(profile_file) - profile_len, "%s", s);
+		}
+		read_portage_profile(profile_file, vars);
+		/* restore original path in case we were repointed by profile */
+		if (p != NULL)
+			snprintf(profile_file, sizeof(profile_file), "%s/", profile);
 		s = strtok_r(NULL, "\n", &saveptr);
 	}
 
- done:
-	free(profile_file);
+	free(buf);
 }
 
 static bool nocolor = 0;
@@ -618,6 +564,7 @@ env_vars vars_to_read[] = {
 	set, \
 	lset, \
 	.default_value = d, \
+	.src = NULL, \
 },
 #define _Q_EVS(t, V, v, d) _Q_EV(t, V, .value.s = &v, .value_len = strlen(d), d)
 #define _Q_EVB(t, V, v, d) _Q_EV(t, V, .value.b = &v, .value_len = 0, d)
@@ -639,45 +586,176 @@ env_vars vars_to_read[] = {
 	_Q_EVS(STR,  PKGDIR,              pkgdir,              CONFIG_EPREFIX "var/cache/binpkgs/")
 	_Q_EVS(STR,  Q_VDB,               portvdb,             CONFIG_EPREFIX "var/db/pkg")
 	_Q_EVS(STR,  Q_EDB,               portedb,             CONFIG_EPREFIX "var/cache/edb")
-	{ NULL, 0, _Q_BOOL, { NULL }, 0, NULL, }
+	{ NULL, 0, _Q_BOOL, { NULL }, 0, NULL, NULL, }
 
 #undef _Q_EV
 };
 
+/* Handle a single file in the repos.conf format. */
+static void
+read_one_repos_conf(const char *repos_conf)
+{
+	int nsec;
+	char *conf;
+	const char *main_repo, *repo, *path;
+	dictionary *dict;
+
+	if (getenv("DEBUG"))
+		fprintf(stderr, "  parse %s\n", repos_conf);
+
+	dict = iniparser_load(repos_conf);
+
+	main_repo = iniparser_getstring(dict, "DEFAULT:main-repo", NULL);
+
+	nsec = iniparser_getnsec(dict);
+	while (nsec-- > 0) {
+		repo = iniparser_getsecname(dict, nsec);
+		if (!strcmp(repo, "DEFAULT"))
+			continue;
+
+		xasprintf(&conf, "%s:location", repo);
+		path = iniparser_getstring(dict, conf, NULL);
+		if (path) {
+			void *ele = xarraypush_str(overlays, path);
+			xarraypush_str(overlay_names, repo);
+			xarraypush_str(overlay_src, repos_conf);
+			if (main_repo && !strcmp(repo, main_repo)) {
+				main_overlay = ele;
+				set_portage_env_var(&vars_to_read[11] /* PORTDIR */,
+						main_overlay, repos_conf);
+			}
+		}
+		free(conf);
+	}
+
+	iniparser_freedict(dict);
+}
+
+/* Handle a possible directory of files. */
+static void
+read_repos_conf(const char *configroot, const char *repos_conf)
+{
+	char *top_conf, *sub_conf;
+	int i, count;
+	struct dirent **confs;
+
+	xasprintf(&top_conf, "%s%s", configroot, repos_conf);
+	if (getenv("DEBUG"))
+		fprintf(stderr, "repos.conf.d scanner %s\n", top_conf);
+	count = scandir(top_conf, &confs, NULL, alphasort);
+	if (count == -1) {
+		if (errno == ENOTDIR)
+			read_one_repos_conf(top_conf);
+	} else {
+		for (i = 0; i < count; ++i) {
+			const char *name = confs[i]->d_name;
+
+			if (name[0] == '.' || name[0] == '\0')
+				continue;
+
+			/* Exclude backup files (aka files with ~ as postfix). */
+			if (name[strlen(name) - 1] == '~')
+				continue;
+
+#ifdef DT_UNKNOWN
+			if (confs[i]->d_type != DT_UNKNOWN &&
+			    confs[i]->d_type != DT_REG &&
+			    confs[i]->d_type != DT_LNK)
+				continue;
+#endif
+
+			xasprintf(&sub_conf, "%s/%s", top_conf, name);
+
+#ifdef DT_UNKNOWN
+			if (confs[i]->d_type != DT_REG)
+#endif
+			{
+				struct stat st;
+				if (stat(sub_conf, &st) || !S_ISREG(st.st_mode)) {
+					free(sub_conf);
+					continue;
+				}
+			}
+
+			read_one_repos_conf(sub_conf);
+			free(sub_conf);
+		}
+		scandir_free(confs, count);
+	}
+	free(top_conf);
+}
+
 static void
 initialize_portage_env(void)
 {
 	size_t i;
 	const char *s;
 	env_vars *var;
+	char pathbuf[_Q_PATH_MAX];
+	const char *configroot = getenv("PORTAGE_CONFIGROOT");
+	char *orig_main_overlay = main_overlay;
 
 	/* initialize all the strings with their default value */
 	for (i = 0; vars_to_read[i].name; ++i) {
 		var = &vars_to_read[i];
 		if (var->type != _Q_BOOL)
 			*var->value.s = xstrdup(var->default_value);
+		var->src = xstrdup("built-in default");
 	}
 
 	/* figure out where to find our config files */
-	const char *configroot = getenv("PORTAGE_CONFIGROOT");
 	if (!configroot)
-		configroot = CONFIG_EPREFIX "/";
+		configroot = CONFIG_EPREFIX;
+
+	/* rstrip /-es */
+	i = strlen(configroot);
+	while (i > 0 && configroot[i - 1] == '/')
+		i--;
+
+	/* read overlays first so we can resolve repo references in profile
+	 * parent files */
+	snprintf(pathbuf, sizeof(pathbuf), "%.*s", (int)i, configroot);
+	read_repos_conf(pathbuf, "/usr/share/portage/config/repos.conf");
+	read_repos_conf(pathbuf, "/etc/portage/repos.conf");
+	if (orig_main_overlay != main_overlay)
+		free(orig_main_overlay);
+	if (array_cnt(overlays) == 0) {
+		xarraypush_ptr(overlays, main_overlay);
+		xarraypush_str(overlay_names, "<PORTDIR>");
+		xarraypush_str(overlay_src, "built-in default");
+	} else if (orig_main_overlay == main_overlay) {
+		/* if no explicit overlay was flagged as main, take the first one */
+		main_overlay = array_get_elem(overlays, 0);
+		set_portage_env_var(&vars_to_read[11] /* PORTDIR */, main_overlay,
+				(char *)array_get_elem(overlay_src, 0));
+	}
 
 	/* walk all the stacked profiles */
-	read_portage_profile(configroot, "/etc/make.profile", vars_to_read);
-	read_portage_profile(configroot, "/etc/portage/make.profile", vars_to_read);
+	snprintf(pathbuf, sizeof(pathbuf), "%.*s/etc/make.profile",
+			(int)i, configroot);
+	read_portage_profile(pathbuf, vars_to_read);
+	snprintf(pathbuf, sizeof(pathbuf), "%.*s/etc/portage/make.profile",
+			(int)i, configroot);
+	read_portage_profile(pathbuf, vars_to_read);
 
 	/* now read all the config files */
-	read_portage_env_file("", CONFIG_EPREFIX "usr/share/portage/config/make.globals", vars_to_read);
-	read_portage_env_file(configroot, "/etc/make.conf", vars_to_read);
-	read_portage_env_file(configroot, "/etc/portage/make.conf", vars_to_read);
+	snprintf(pathbuf, sizeof(pathbuf),
+			"%.*s/usr/share/portage/config/make.globals",
+			(int)i, configroot);
+	read_portage_env_file(pathbuf, vars_to_read);
+	snprintf(pathbuf, sizeof(pathbuf), "%.*s/etc/make.conf",
+			(int)i, configroot);
+	read_portage_env_file(pathbuf, vars_to_read);
+	snprintf(pathbuf, sizeof(pathbuf), "%.*s/etc/portage/make.conf",
+			(int)i, configroot);
+	read_portage_env_file(pathbuf, vars_to_read);
 
 	/* finally, check the env */
 	for (i = 0; vars_to_read[i].name; ++i) {
 		var = &vars_to_read[i];
 		s = getenv(var->name);
 		if (s != NULL)
-			set_portage_env_var(var, s);
+			set_portage_env_var(var, s, var->name);
 	}
 
 	/* expand any nested variables e.g. PORTDIR=${EPREFIX}/usr/portage */
@@ -734,7 +812,8 @@ initialize_portage_env(void)
 			*svar = byte;
 			slen = strlen(sval);
 			post_len = strlen(svar + !!brace);
-			*var->value.s = xrealloc(*var->value.s, pre_len + MAX(var_len, slen) + post_len + 1);
+			*var->value.s = xrealloc(*var->value.s,
+					pre_len + MAX(var_len, slen) + post_len + 1);
 
 			/*
 			 * VAR=XxXxX	(slen = 5)
@@ -758,18 +837,6 @@ initialize_portage_env(void)
 		portroot[var->value_len + 1] = '\0';
 	}
 
-	char *orig_main_overlay = main_overlay;
-	read_repos_conf(configroot, "/etc/portage/repos.conf");
-	if (orig_main_overlay != main_overlay)
-		free(orig_main_overlay);
-	if (array_cnt(overlays) == 0) {
-		xarraypush_ptr(overlays, main_overlay);
-		xarraypush_str(overlay_names, "<PORTDIR>");
-	} else if (orig_main_overlay == main_overlay) {
-		/* if no explicit overlay was flagged as main, take the first one */
-		main_overlay = array_get_elem(overlays, 0);
-	}
-
 	if (getenv("DEBUG")) {
 		for (i = 0; vars_to_read[i].name; ++i) {
 			var = &vars_to_read[i];

diff --git a/main.h b/main.h
index 03c3bd2..98e5cbb 100644
--- a/main.h
+++ b/main.h
@@ -149,6 +149,7 @@ typedef struct {
 	} value;
 	size_t value_len;
 	const char *default_value;
+	char *src;
 } env_vars;
 extern env_vars vars_to_read[];
 

diff --git a/man/q.1 b/man/q.1
index 95caf56..886b00f 100644
--- a/man/q.1
+++ b/man/q.1
@@ -20,10 +20,12 @@ no longer necessary to initialise the cache at any time.
 Install symlinks for applets.
 .TP
 \fB\-o\fR, \fB\-\-overlays\fR
-Print available overlays (read from repos.conf).
+Print available overlays (read from repos.conf).  Use \fI-v\fR to
+see the source (file) where the overlay was declared.
 .TP
 \fB\-e\fR, \fB\-\-envvar\fR
-Print found environment variables and their values.
+Print used environment variables and found values.  Use \fI-v\fR to
+see the source (file, environment) where the variable was declared.
 .TP
 \fB\-\-root\fR \fI<arg>\fR
 Set the ROOT env var.

diff --git a/q.c b/q.c
index 2fb406f..40cdc2a 100644
--- a/q.c
+++ b/q.c
@@ -33,7 +33,7 @@ static struct option const q_long_opts[] = {
 static const char * const q_opts_help[] = {
 	"Install symlinks for applets",
 	"Print available overlays (read from repos.conf)",
-	"Print found environment variables and their values",
+	"Print used variables and their found values",
 	COMMON_OPTS_HELP
 };
 #define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, NULL, lookup_applet_idx("q"))
@@ -179,10 +179,14 @@ int q_main(int argc, char **argv)
 				if (repo_name != NULL)
 					rmspace(repo_name);
 			}
-			printf("%s%s%s: %s%s%s%s\n",
+			printf("%s%s%s: %s%s%s%s",
 					GREEN, repo_name == NULL ? "?unknown?" : repo_name,
 					NORM, overlay,
 					YELLOW, main_overlay == overlay ? " (main)" : "", NORM);
+			if (verbose)
+				printf(" [%s]\n", (char *)xarrayget(overlay_src, n));
+			else
+				printf("\n");
 			if (repo_name_len != 0) {
 				free(repo_name);
 				repo_name_len = 0;
@@ -210,14 +214,18 @@ int q_main(int argc, char **argv)
 				printf("%s%s%s=", BLUE, var->name, NORM);
 				switch (var->type) {
 					case _Q_BOOL:
-						printf("%s%s%s\n",
+						printf("%s%s%s",
 								YELLOW, *var->value.b ? "1" : "0", NORM);
 						break;
 				case _Q_STR:
 				case _Q_ISTR:
-						printf("%s\"%s\"%s\n", RED, *var->value.s, NORM);
+						printf("%s\"%s\"%s", RED, *var->value.s, NORM);
 						break;
 				}
+				if (verbose)
+					printf(" [%s]\n", var->src);
+				else
+					printf("\n");
 			}
 		} else {
 			/* single envvar printing, just output the value, like
@@ -238,6 +246,10 @@ int q_main(int argc, char **argv)
 						printf("%s%s%s\n", RED, *var->value.s, NORM);
 						break;
 				}
+				if (verbose)
+					printf(" [%s]\n", var->src);
+				else
+					printf("\n");
 			}
 		}
 


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2019-12-14 17:01 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2019-12-14 17:01 UTC (permalink / raw
  To: gentoo-commits

commit:     e5ff6caad2f4b848f77e6de82c866fa42aba30ae
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 14 16:56:39 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat Dec 14 16:56:39 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=e5ff6caa

qkeyword: add modes to list just list latest stable/testing

This functionality combined with -F allows usage with e.g. Puppet
providers.

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/qkeyword.1 | 23 +++++++++++-----
 qkeyword.c     | 84 +++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 81 insertions(+), 26 deletions(-)

diff --git a/man/qkeyword.1 b/man/qkeyword.1
index c43fa61..34beb18 100644
--- a/man/qkeyword.1
+++ b/man/qkeyword.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qkeyword "1" "Nov 2019" "Gentoo Foundation" "qkeyword"
+.TH qkeyword "1" "Dec 2019" "Gentoo Foundation" "qkeyword"
 .SH NAME
 qkeyword \- list packages based on keywords
 .SH SYNOPSIS
@@ -32,22 +32,31 @@ match catname.
 match maintainer email from metadata.xml (slow).
 .TP
 \fB\-i\fR, \fB\-\-imlate\fR
-list packages that can be marked stable on a given arch.
+list packages that can be marked stable for <arch>.
 .TP
 \fB\-d\fR, \fB\-\-dropped\fR
-list packages that have dropped keywords on a version bump on a given arch.
+list packages that have dropped keywords for <arch>.
 .TP
-\fB\-t\fR, \fB\-\-testing\fR
-list packages that have ~arch versions, but no stable versions on a given arch.
+\fB\-t\fR, \fB\-\-needsstable\fR
+list packages that have ~arch versions, but no stable versions for <arch>.
 .TP
 \fB\-s\fR, \fB\-\-stats\fR
 display statistics about the portage tree.
 .TP
 \fB\-a\fR, \fB\-\-all\fR
-list packages that have at least one version keyworded for on a given arch.
+list packages that have at least one version keyworded for <arch>.
 .TP
 \fB\-n\fR, \fB\-\-not\fR
-list packages that aren't keyworded on a given arch.
+list packages that aren't keyworded for <arch>.
+.TP
+\fB\-S\fR, \fB\-\-stable\fR
+list latest stable version per package for <arch>.
+.TP
+\fB\-T\fR, \fB\-\-testing\fR
+list latest testing version per package for <arch>.
+.TP
+\fB\-F\fR \fI<arg>\fR, \fB\-\-format\fR \fI<arg>\fR
+Print latest atom using given format string.
 .TP
 \fB\-\-root\fR \fI<arg>\fR
 Set the ROOT env var.

diff --git a/qkeyword.c b/qkeyword.c
index 4c6c759..4a55b6a 100644
--- a/qkeyword.c
+++ b/qkeyword.c
@@ -28,29 +28,35 @@
 /* Required portage-utils stuff                                     */
 /********************************************************************/
 
-#define QKEYWORD_FLAGS "p:c:m:idtans" COMMON_FLAGS
+#define QKEYWORD_FLAGS "p:c:m:idtsanSTF:" COMMON_FLAGS
 static struct option const qkeyword_long_opts[] = {
-	{"matchpkg", a_argument, NULL, 'p'},
-	{"matchcat", a_argument, NULL, 'c'},
-	{"matchmaint", a_argument, NULL, 'm'},
-	{"imlate",  no_argument, NULL, 'i'},
-	{"dropped", no_argument, NULL, 'd'},
-	{"testing", no_argument, NULL, 't'},
-	{"stats",   no_argument, NULL, 's'},
-	{"all",     no_argument, NULL, 'a'},
-	{"not",     no_argument, NULL, 'n'},
+	{"matchpkg",     a_argument, NULL, 'p'},
+	{"matchcat",     a_argument, NULL, 'c'},
+	{"matchmaint",   a_argument, NULL, 'm'},
+	{"imlate",      no_argument, NULL, 'i'},
+	{"dropped",     no_argument, NULL, 'd'},
+	{"needsstable", no_argument, NULL, 't'},
+	{"stats",       no_argument, NULL, 's'},
+	{"all",         no_argument, NULL, 'a'},
+	{"not",         no_argument, NULL, 'n'},
+	{"stable",      no_argument, NULL, 'S'},
+	{"testing",     no_argument, NULL, 'T'},
+	{"format",       a_argument, NULL, 'F'},
 	COMMON_LONG_OPTS
 };
 static const char * const qkeyword_opts_help[] = {
 	"match pkgname",
 	"match catname",
 	"match maintainer email from metadata.xml (slow)",
-	"list packages that can be marked stable on a given arch",
-	"list packages that have dropped keywords on a version bump on a given arch",
-	"list packages that have ~arch versions, but no stable versions on a given arch",
+	"list packages that can be marked stable for <arch>",
+	"list packages that have dropped keywords for <arch>",
+	"list packages that have ~arch versions, but no stable versions for <arch>",
 	"display statistics about the portage tree",
-	"list packages that have at least one version keyworded for on a given arch",
-	"list packages that aren't keyworded on a given arch.",
+	"list packages that have at least one version keyworded for <arch>",
+	"list packages that aren't keyworded for <arch>",
+	"list latest stable version per package for <arch>",
+	"list latest testing version per package for <arch>",
+	"Print latest atom using given format string",
 	COMMON_OPTS_HELP
 };
 #define qkeyword_usage(ret) usage(ret, QKEYWORD_FLAGS, qkeyword_long_opts, qkeyword_opts_help, NULL, lookup_applet_idx("qkeyword"))
@@ -63,6 +69,7 @@ typedef struct {
 	size_t keywordsbuflen;
 	const char *arch;
 	tree_pkg_cb *runfunc;
+	const char *fmt;
 } qkeyword_data;
 
 static set *archs = NULL;
@@ -218,6 +225,34 @@ qkeyword_imlate(tree_pkg_ctx *pkg_ctx, void *priv)
 	return EXIT_FAILURE;
 }
 
+static int
+qkeyword_lstable(tree_pkg_ctx *pkg_ctx, void *priv)
+{
+	qkeyword_data *data = (qkeyword_data *)priv;
+
+	if (data->keywordsbuf[qkeyword_test_arch] == stable)
+	{
+		printf("%s", atom_format(data->fmt, tree_get_atom(pkg_ctx, true)));
+		return EXIT_SUCCESS;
+	}
+
+	return EXIT_FAILURE;
+}
+
+static int
+qkeyword_ltesting(tree_pkg_ctx *pkg_ctx, void *priv)
+{
+	qkeyword_data *data = (qkeyword_data *)priv;
+
+	if (data->keywordsbuf[qkeyword_test_arch] == testing)
+	{
+		printf("%s\n", atom_format(data->fmt, tree_get_atom(pkg_ctx, true)));
+		return EXIT_SUCCESS;
+	}
+
+	return EXIT_FAILURE;
+}
+
 static int
 qkeyword_not(tree_pkg_ctx *pkg_ctx, void *priv)
 {
@@ -658,7 +693,6 @@ keyword_sort(const void *l, const void *r)
 	char *ld = strchr(*ls, '-');
 	char *rd = strchr(*rs, '-');
 
-	printf("%s vs %s\n", *ls, *rs);
 	if (ld == NULL && rd != NULL)
 		return -1;
 	else if (ld != NULL && rd == NULL)
@@ -729,7 +763,7 @@ qkeyword_traverse(tree_pkg_cb func, void *priv)
 	const char *overlay;
 	qkeyword_data *data = (qkeyword_data *)priv;
 
-	/* Preload all the arches. Not entirely correctly (as arches are bound
+	/* Preload all the arches. Not entirely correct (as arches are bound
 	 * to overlays if set), but oh well. */
 	array_for_each(overlays, n, overlay)
 		qkeyword_load_arches(overlay);
@@ -767,6 +801,7 @@ int qkeyword_main(int argc, char **argv)
 	char *cat = NULL;
 	char *maint = NULL;
 
+	data.fmt = NULL;
 	while ((i = GETOPT_LONG(QKEYWORD, qkeyword, "")) != -1) {
 		switch (i) {
 			case 'p': pkg = optarg; break;
@@ -778,11 +813,16 @@ int qkeyword_main(int argc, char **argv)
 			case 's':
 			case 'a':
 			case 'n':
-				if (action)
+			case 'S':
+			case 'T':
+				/* trying to use more than 1 action */
+				if (action != '\0')
 					qkeyword_usage(EXIT_FAILURE);
-					/* trying to use more than 1 action */
 				action = i;
 				break;
+			case 'F':
+				data.fmt = optarg;
+				break;
 
 			COMMON_GETOPTS_CASES(qkeyword)
 		}
@@ -815,6 +855,10 @@ int qkeyword_main(int argc, char **argv)
 		data.qatom = NULL;
 	}
 
+	/* set format if none given */
+	if ((action == 'S' || action == 'T') && data.fmt == NULL)
+		data.fmt = "%[CATEGORY]%[PF]";
+
 	archs = create_set();
 	archlist_count = 0;
 	arch_longest_len = 0;
@@ -834,6 +878,8 @@ int qkeyword_main(int argc, char **argv)
 				  i = qkeyword_stats(NULL, NULL);                       break;
 		case 'a': i = qkeyword_traverse(qkeyword_all, &data);           break;
 		case 'n': i = qkeyword_traverse(qkeyword_not, &data);           break;
+		case 'S': i = qkeyword_traverse(qkeyword_lstable, &data);       break;
+		case 'T': i = qkeyword_traverse(qkeyword_ltesting, &data);      break;
 		default:  i = -2;                                               break;
 	}
 


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2020-01-06 15:03 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2020-01-06 15:03 UTC (permalink / raw
  To: gentoo-commits

commit:     88bd510b4bd83123cd8c1c4920a8e655584ea2db
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon Jan  6 15:03:07 2020 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon Jan  6 15:03:07 2020 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=88bd510b

qgrep: fix description for -N

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/qgrep.1 | 6 +++---
 qgrep.c     | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/man/qgrep.1 b/man/qgrep.1
index e414ba4..2d73f4c 100644
--- a/man/qgrep.1
+++ b/man/qgrep.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qgrep "1" "Nov 2019" "Gentoo Foundation" "qgrep"
+.TH qgrep "1" "Jan 2020" "Gentoo Foundation" "qgrep"
 .SH NAME
 qgrep \- grep in ebuilds
 .SH SYNOPSIS
@@ -20,8 +20,8 @@ Select non-matching lines.
 \fB\-i\fR, \fB\-\-ignore\-case\fR
 Ignore case distinctions.
 .TP
-\fB\-N\fR, \fB\-\-with\-name\fR
-Print the filename for each match.
+\fB\-N\fR, \fB\-\-atom\-name\fR
+Print the atom instead of filename for each match.
 .TP
 \fB\-c\fR, \fB\-\-count\fR
 Only print a count of matching lines per FILE.

diff --git a/qgrep.c b/qgrep.c
index 4d8c27f..019b0b6 100644
--- a/qgrep.c
+++ b/qgrep.c
@@ -28,7 +28,7 @@
 static struct option const qgrep_long_opts[] = {
 	{"invert-match",  no_argument, NULL, 'I'},
 	{"ignore-case",   no_argument, NULL, 'i'},
-	{"with-name",     no_argument, NULL, 'N'},
+	{"atom-name",     no_argument, NULL, 'N'},
 	{"count",         no_argument, NULL, 'c'},
 	{"list",          no_argument, NULL, 'l'},
 	{"invert-list",   no_argument, NULL, 'L'},
@@ -46,7 +46,7 @@ static struct option const qgrep_long_opts[] = {
 static const char * const qgrep_opts_help[] = {
 	"Select non-matching lines",
 	"Ignore case distinctions",
-	"Print the filename for each match",
+	"Print the atom instead of filename for each match",
 	"Only print a count of matching lines per FILE",
 	"Only print FILE names containing matches",
 	"Only print FILE names containing no match",


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/portage-utils:master commit in: /, man/
@ 2020-05-02  8:45 Fabian Groffen
  0 siblings, 0 replies; 16+ messages in thread
From: Fabian Groffen @ 2020-05-02  8:45 UTC (permalink / raw
  To: gentoo-commits

commit:     20844dc943700cca72bbb6896f42adcd30de41e3
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat May  2 08:13:29 2020 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat May  2 08:45:40 2020 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=20844dc9

qlop: silently drop -l when -d is used with -E

While -E defaults to -l (last merge), silently drop it when -d is used.

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/qlop.1 | 4 ++--
 qlop.c     | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/man/qlop.1 b/man/qlop.1
index 1b63edd..7027f14 100644
--- a/man/qlop.1
+++ b/man/qlop.1
@@ -1,5 +1,5 @@
 .\" generated by mkman.py, please do NOT edit!
-.TH qlop "1" "Nov 2019" "Gentoo Foundation" "qlop"
+.TH qlop "1" "May 2020" "Gentoo Foundation" "qlop"
 .SH NAME
 qlop \- emerge log analyzer
 .SH SYNOPSIS
@@ -66,7 +66,7 @@ Show autoclean unmerge history.
 Show sync history.
 .TP
 \fB\-E\fR, \fB\-\-emerge\fR
-Show last merge like how emerge(1) -v would show it.
+Show last merge similar to how emerge(1) -v would show it.
 .TP
 \fB\-e\fR, \fB\-\-endtime\fR
 Report time at which the operation finished (iso started).

diff --git a/qlop.c b/qlop.c
index cbe3b58..3e38adf 100644
--- a/qlop.c
+++ b/qlop.c
@@ -58,7 +58,7 @@ static const char * const qlop_opts_help[] = {
 	"Show unmerge history",
 	"Show autoclean unmerge history",
 	"Show sync history",
-	"Show last merge like how emerge(1) -v would show it",
+	"Show last merge similar to how emerge(1) -v would show it",
 	"Report time at which the operation finished (iso started)",
 	"Show current emerging packages",
 	"Limit selection to this time (1st -d is start, 2nd -d is end)",
@@ -1367,7 +1367,8 @@ int qlop_main(int argc, char **argv)
 
 	/* handle -l / -d conflict */
 	if (start_time != 0 && m.show_lastmerge) {
-		warn("-l and -d cannot be used together, dropping -l");
+		if (m.show_emerge)
+			warn("-l and -d cannot be used together, dropping -l");
 		m.show_lastmerge = 0;
 	}
 


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-05-02  8:45 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-07-14 10:21 [gentoo-commits] proj/portage-utils:master commit in: /, man/ Fabian Groffen
  -- strict thread matches above, loose matches on Subject: below --
2020-05-02  8:45 Fabian Groffen
2020-01-06 15:03 Fabian Groffen
2019-12-14 17:01 Fabian Groffen
2019-11-24 12:29 Fabian Groffen
2019-11-09 10:13 Fabian Groffen
2019-10-27 12:22 Fabian Groffen
2019-09-28 13:19 Fabian Groffen
2019-09-10 18:25 Fabian Groffen
2019-07-14 13:09 Fabian Groffen
2019-07-14 10:21 Fabian Groffen
2019-07-14 10:21 Fabian Groffen
2019-07-14 10:21 Fabian Groffen
2019-05-20 10:46 Fabian Groffen
2016-03-28  4:53 Mike Frysinger
2016-02-22 20:37 Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox