From c1d34a07f45cd6e8d6ddc98e40390e86c7268201 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Tue, 21 Mar 2023 13:05:39 +0200
Subject: [PATCH] fetch: implement --built-after

ref #10873
---
 doc/apk-fetch.8.scd |  4 ++++
 src/app_fetch.c     | 23 +++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/doc/apk-fetch.8.scd b/doc/apk-fetch.8.scd
index dd86ce4e..7bbbc907 100644
--- a/doc/apk-fetch.8.scd
+++ b/doc/apk-fetch.8.scd
@@ -17,6 +17,10 @@ specified.
 
 # OPTIONS
 
+*--built-after* _TIMESPEC_
+	Only fetch packages that have buildtime more recent than TIMESPEC.
+	TIMESPEC can be a "YYYY-MM-DD HH:MM:SS" date, or seconds since epoch.
+
 *-L, --link*
 	Create hard links if possible.
 
diff --git a/src/app_fetch.c b/src/app_fetch.c
index 54f3e474..1f05a80f 100644
--- a/src/app_fetch.c
+++ b/src/app_fetch.c
@@ -29,6 +29,7 @@
 struct fetch_ctx {
 	unsigned int flags;
 	int outdir_fd, errors;
+	time_t built_after;
 	struct apk_database *db;
 	struct apk_progress prog;
 	size_t done, total;
@@ -70,6 +71,7 @@ static int cup(void)
 }
 
 #define FETCH_OPTIONS(OPT) \
+	OPT(OPT_FETCH_built_after,	APK_OPT_ARG "built-after") \
 	OPT(OPT_FETCH_link,		APK_OPT_SH("l") "link") \
 	OPT(OPT_FETCH_recursive,	APK_OPT_SH("R") "recursive") \
 	OPT(OPT_FETCH_output,		APK_OPT_ARG APK_OPT_SH("o") "output") \
@@ -80,11 +82,30 @@ static int cup(void)
 
 APK_OPT_APPLET(option_desc, FETCH_OPTIONS);
 
+static time_t parse_time(const char *timestr)
+{
+	struct tm tm;
+	char *p;
+	time_t t;
+
+	p = strptime(optarg, "%Y-%m-%d %H:%M:%S", &tm);
+	if (p && *p == 0) return mktime(&tm);
+
+	t = strtoul(optarg, &p, 10);
+	if (p && *p == 0) return t;
+
+	return 0;
+}
+
 static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
 {
 	struct fetch_ctx *fctx = (struct fetch_ctx *) ctx;
 
 	switch (opt) {
+	case OPT_FETCH_built_after:
+		fctx->built_after = parse_time(optarg);
+		if (!fctx->built_after) return -EINVAL;
+		break;
 	case OPT_FETCH_simulate:
 		ac->flags |= APK_SIMULATE;
 		break;
@@ -207,6 +228,8 @@ static void mark_package(struct fetch_ctx *ctx, struct apk_package *pkg)
 {
 	if (pkg == NULL || pkg->marked)
 		return;
+	if (ctx->built_after && pkg->build_time && ctx->built_after >= pkg->build_time)
+		return;
 	ctx->total += pkg->size;
 	pkg->marked = 1;
 }
-- 
GitLab