Gentoo Archives: gentoo-commits

From: Mike Frysinger <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage-utils:master commit in: /, man/, tests/qlop/
Date: Mon, 28 Mar 2016 04:53:59
Message-Id: 1459137122.79ae531435cf37e50676c25e794f335a6587c7d3.vapier@gentoo
1 commit: 79ae531435cf37e50676c25e794f335a6587c7d3
2 Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
3 AuthorDate: Mon Mar 28 03:52:02 2016 +0000
4 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
5 CommitDate: Mon Mar 28 03:52:02 2016 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=79ae5314
7
8 qlop: add --date option to filter output
9
10 Allow people to filter results by start & end dates.
11
12 URL: https://bugs.gentoo.org/192918
13 Reported-by: Laurento Frittella <laurento.frittella <AT> gmail.com>
14
15 man/qlop.1 | 5 +-
16 qlop.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++---
17 tests/qlop/dotest | 5 ++
18 tests/qlop/list06.good | 2 +
19 tests/qlop/list07.good | 2 +
20 tests/qlop/list08.good | 2 +
21 6 files changed, 139 insertions(+), 8 deletions(-)
22
23 diff --git a/man/qlop.1 b/man/qlop.1
24 index 6e645a8..77cf5ef 100644
25 --- a/man/qlop.1
26 +++ b/man/qlop.1
27 @@ -1,4 +1,4 @@
28 -.TH qlop "1" "Feb 2016" "Gentoo Foundation" "qlop"
29 +.TH qlop "1" "Mar 2016" "Gentoo Foundation" "qlop"
30 .SH NAME
31 qlop \- emerge log analyzer
32 .SH SYNOPSIS
33 @@ -29,6 +29,9 @@ Show sync history
34 \fB\-c\fR, \fB\-\-current\fR
35 Show current emerging packages
36 .TP
37 +\fB\-d\fR \fI<arg>\fR, \fB\-\-date\fR \fI<arg>\fR
38 +Limit selection to this time (1st -d is start, 2nd -d is end)
39 +.TP
40 \fB\-f\fR \fI<arg>\fR, \fB\-\-logfile\fR \fI<arg>\fR
41 Read emerge logfile instead of $EMERGE_LOG_DIR/emerge.log
42 .TP
43
44 diff --git a/qlop.c b/qlop.c
45 index 319d767..0da636a 100644
46 --- a/qlop.c
47 +++ b/qlop.c
48 @@ -10,7 +10,7 @@
49
50 #define QLOP_DEFAULT_LOGFILE "emerge.log"
51
52 -#define QLOP_FLAGS "gtHluscf:" COMMON_FLAGS
53 +#define QLOP_FLAGS "gtHluscd:f:" COMMON_FLAGS
54 static struct option const qlop_long_opts[] = {
55 {"gauge", no_argument, NULL, 'g'},
56 {"time", no_argument, NULL, 't'},
57 @@ -19,6 +19,7 @@ static struct option const qlop_long_opts[] = {
58 {"unlist", no_argument, NULL, 'u'},
59 {"sync", no_argument, NULL, 's'},
60 {"current", no_argument, NULL, 'c'},
61 + {"date", a_argument, NULL, 'd'},
62 {"logfile", a_argument, NULL, 'f'},
63 COMMON_LONG_OPTS
64 };
65 @@ -30,6 +31,7 @@ static const char * const qlop_opts_help[] = {
66 "Show unmerge history",
67 "Show sync history",
68 "Show current emerging packages",
69 + "Limit selection to this time (1st -d is start, 2nd -d is end)",
70 "Read emerge logfile instead of $EMERGE_LOG_DIR/" QLOP_DEFAULT_LOGFILE,
71 COMMON_OPTS_HELP
72 };
73 @@ -64,7 +66,8 @@ chop_ctime(time_t t)
74 }
75
76 _q_static unsigned long
77 -show_merge_times(char *package, const char *logfile, int average, char human_readable)
78 +show_merge_times(char *package, const char *logfile, int average, char human_readable,
79 + time_t start_time, time_t end_time)
80 {
81 FILE *fp;
82 char cat[126], buf[2][BUFSIZ];
83 @@ -103,6 +106,8 @@ show_merge_times(char *package, const char *logfile, int average, char human_rea
84 continue;
85 *p = 0;
86 t[0] = atol(buf[0]);
87 + if (t[0] < start_time || t[0] > end_time)
88 + continue;
89 strcpy(buf[1], p + 1);
90 rmspace(buf[1]);
91 if (strncmp(buf[1], ">>> emerge (", 12) == 0) {
92 @@ -216,7 +221,8 @@ show_merge_times(char *package, const char *logfile, int average, char human_rea
93 }
94
95 _q_static void
96 -show_emerge_history(int listflag, array_t *atoms, const char *logfile)
97 +show_emerge_history(int listflag, array_t *atoms, const char *logfile,
98 + time_t start_time, time_t end_time)
99 {
100 FILE *fp;
101 size_t buflen, linelen;
102 @@ -247,6 +253,8 @@ show_emerge_history(int listflag, array_t *atoms, const char *logfile)
103 continue;
104
105 t = (time_t) atol(buf);
106 + if (t < start_time || t > end_time)
107 + continue;
108
109 if ((listflag & QLOP_LIST) && !strncmp(q, "::: completed emerge (", 22)) {
110 merged = 1;
111 @@ -313,7 +321,7 @@ New format:
112 1431764493: *** terminating.
113 */
114 _q_static void
115 -show_sync_history(const char *logfile)
116 +show_sync_history(const char *logfile, time_t start_time, time_t end_time)
117 {
118 FILE *fp;
119 size_t buflen, linelen;
120 @@ -344,6 +352,8 @@ show_sync_history(const char *logfile)
121 rmspace_len(buf, linelen);
122
123 t = (time_t)atol(buf);
124 + if (t < start_time || t > end_time)
125 + continue;
126
127 if (!strncmp(p, "with ", 5))
128 p += 5;
129 @@ -635,16 +645,112 @@ void show_current_emerge(void)
130 }
131 #endif
132
133 +_q_static
134 +bool parse_date(const char *sdate, time_t *t)
135 +{
136 + struct tm tm;
137 + const char *s;
138 +
139 + memset(&tm, 0, sizeof(tm));
140 +
141 + s = strchr(sdate, '|');
142 + if (s) {
143 + /* Handle custom format like "%Y|2012". */
144 + size_t fmtlen = s - sdate;
145 + char fmt[fmtlen + 1];
146 + memcpy(fmt, sdate, fmtlen);
147 + fmt[fmtlen] = '\0';
148 + sdate = s + 1;
149 + s = strptime(sdate, fmt, &tm);
150 + if (s == NULL || s[0] != '\0')
151 + return false;
152 + } else {
153 + /* Handle automatic formats:
154 + * - "12315128" -> %s
155 + * - "2015-12-24" -> %F (same as %Y-%m-%d
156 + * - human readable format (see below)
157 + */
158 + size_t len = strspn(sdate, "0123456789-");
159 + if (sdate[len] == '\0') {
160 + const char *fmt;
161 + if (strchr(sdate, '-') == NULL)
162 + fmt = "%s";
163 + else
164 + fmt = "%F";
165 +
166 + s = strptime(sdate, fmt, &tm);
167 + if (s == NULL || s[0] != '\0')
168 + return false;
169 + } else {
170 + /* Handle the formats:
171 + * <#> <day|week|month|year>[s] [ago]
172 + */
173 + len = strlen(sdate);
174 +
175 + unsigned long num;
176 + char dur[len];
177 + char ago[len];
178 + int ret = sscanf(sdate, "%lu %s %s", &num, dur, ago);
179 +
180 + if (ret < 2)
181 + return false;
182 + if (ret == 3 && strcmp(ago, "ago") != 0)
183 + return false;
184 +
185 + if (time(t) == -1)
186 + return false;
187 + if (localtime_r(t, &tm) == NULL)
188 + return false;
189 +
190 + /* Chop and trailing "s" sizes. */
191 + len = strlen(dur);
192 + if (dur[len - 1] == 's')
193 + dur[len - 1] = '\0';
194 +
195 + /* Step down the current time. */
196 + if (!strcmp(dur, "year")) {
197 + tm.tm_year -= num;
198 + } else if (!strcmp(dur, "month")) {
199 + if (num >= 12) {
200 + tm.tm_year -= (num / 12);
201 + num %= 12;
202 + }
203 + tm.tm_mon -= num;
204 + if (tm.tm_mon < 0) {
205 + tm.tm_mon += 12;
206 + tm.tm_year -= 1;
207 + }
208 + } else if (!strcmp(dur, "week")) {
209 + num *= 7;
210 + goto days;
211 + } else if (!strcmp(dur, "day")) {
212 + days:
213 + /* This is in seconds, so scale w/that. */
214 + *t -= (num * 24 * 60 * 60);
215 + if (localtime_r(t, &tm) == NULL)
216 + return false;
217 + } else
218 + return false;
219 + }
220 + }
221 +
222 + *t = mktime(&tm);
223 + return (*t == -1) ? false : true;
224 +}
225 +
226 int qlop_main(int argc, char **argv)
227 {
228 size_t i;
229 int average = 1;
230 + time_t start_time, end_time;
231 char do_time, do_list, do_unlist, do_sync, do_current, do_human_readable = 0;
232 char *logfile = NULL;
233 int flags;
234 depend_atom *atom;
235 DECLARE_ARRAY(atoms);
236
237 + start_time = 0;
238 + end_time = LONG_MAX;
239 do_time = do_list = do_unlist = do_sync = do_current = 0;
240
241 while ((i = GETOPT_LONG(QLOP, qlop, "")) != -1) {
242 @@ -658,6 +764,16 @@ int qlop_main(int argc, char **argv)
243 case 'c': do_current = 1; break;
244 case 'g': do_time = 1; average = 0; break;
245 case 'H': do_human_readable = 1; break;
246 + case 'd':
247 + if (start_time == 0) {
248 + if (!parse_date(optarg, &start_time))
249 + err("invalid date: %s", optarg);
250 + } else if (end_time == LONG_MAX) {
251 + if (!parse_date(optarg, &end_time))
252 + err("invalid date: %s", optarg);
253 + } else
254 + err("too many -d options");
255 + break;
256 case 'f':
257 if (logfile) err("Only use -f once");
258 logfile = xstrdup(optarg);
259 @@ -685,16 +801,17 @@ int qlop_main(int argc, char **argv)
260 if (do_unlist)
261 flags |= QLOP_UNLIST;
262 if (flags)
263 - show_emerge_history(flags, atoms, logfile);
264 + show_emerge_history(flags, atoms, logfile, start_time, end_time);
265
266 if (do_current)
267 show_current_emerge();
268 if (do_sync)
269 - show_sync_history(logfile);
270 + show_sync_history(logfile, start_time, end_time);
271
272 if (do_time) {
273 for (i = 0; i < argc; ++i)
274 - show_merge_times(argv[i], logfile, average, do_human_readable);
275 + show_merge_times(argv[i], logfile, average, do_human_readable,
276 + start_time, end_time);
277 }
278
279 array_for_each(atoms, i, atom)
280
281 diff --git a/tests/qlop/dotest b/tests/qlop/dotest
282 index fad6011..0275d45 100755
283 --- a/tests/qlop/dotest
284 +++ b/tests/qlop/dotest
285 @@ -37,6 +37,11 @@ test 04 0 "qlop -l gcc -f ${as}/sync.log"
286 # verify atom version parsing works
287 test 05 0 "qlop -l '<gcc-5' -f ${as}/sync.log"
288
289 +# check date time parser
290 +test 06 0 "qlop -l -f ${as}/sync.log -d 2005-01-01"
291 +test 07 0 "qlop -l -f ${as}/sync.log -d '%d%Y%m|01200501'"
292 +test 08 0 "qlop -l -f ${as}/sync.log -d 1104898893"
293 +
294 cleantmpdir
295
296 end
297
298 diff --git a/tests/qlop/list06.good b/tests/qlop/list06.good
299 new file mode 100644
300 index 0000000..e9fccc3
301 --- /dev/null
302 +++ b/tests/qlop/list06.good
303 @@ -0,0 +1,2 @@
304 +Thu Jan 27 05:56:39 2005 >>> sys-devel/gcc-config-1.3.9
305 +Thu Jan 27 06:17:10 2005 >>> sys-devel/gcc-3.4.3-r1
306
307 diff --git a/tests/qlop/list07.good b/tests/qlop/list07.good
308 new file mode 100644
309 index 0000000..e9fccc3
310 --- /dev/null
311 +++ b/tests/qlop/list07.good
312 @@ -0,0 +1,2 @@
313 +Thu Jan 27 05:56:39 2005 >>> sys-devel/gcc-config-1.3.9
314 +Thu Jan 27 06:17:10 2005 >>> sys-devel/gcc-3.4.3-r1
315
316 diff --git a/tests/qlop/list08.good b/tests/qlop/list08.good
317 new file mode 100644
318 index 0000000..e9fccc3
319 --- /dev/null
320 +++ b/tests/qlop/list08.good
321 @@ -0,0 +1,2 @@
322 +Thu Jan 27 05:56:39 2005 >>> sys-devel/gcc-config-1.3.9
323 +Thu Jan 27 06:17:10 2005 >>> sys-devel/gcc-3.4.3-r1