From 7b6ae322e729216a8622bacca326bf9c7531735c Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Mon, 9 Oct 2023 14:35:23 -0400 Subject: [PATCH] lib: add ability to template repo urls with {arch} {arch} will be replaced with XBPS_TARGET_ARCH (if set) or XBPS_ARCH --- data/xbps.d.5 | 12 +++++++-- include/xbps_api_impl.h | 1 + lib/initend.c | 9 +++++++ lib/repo.c | 60 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/data/xbps.d.5 b/data/xbps.d.5 index 6e671847..6a8f787f 100644 --- a/data/xbps.d.5 +++ b/data/xbps.d.5 @@ -111,12 +111,20 @@ argument accepts local and remote repositories. A complete url or absolute path to the directory that stores the .Em -repodata archive is expected. +If the +.Ar url +contains +.Ar {arch} , +.Ar {arch} +will be replaced by the current target XBPS architecture at runtime. +If the target architecture is not set, the native architecture will be used. Note that remote repositories must be signed using .Xr xbps-rindex 1 , example: .Pp -.Bl -tag -compact -width repository=https://a-hel-fi.m.voidlinux.org/current -.It Sy repository=https://a-hel-fi.m.voidlinux.org/current +.Bl -tag -compact -width repository=https://repo-default.voidlinux.org/current +.It Sy repository=https://repo-default.voidlinux.org/current +.It Sy repository=https://repo-default.voidlinux.org/{arch} .It Sy repository=/hostdir/binpkgs .El .It Sy rootdir=path diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h index 66ffc3c1..fc354aa6 100644 --- a/include/xbps_api_impl.h +++ b/include/xbps_api_impl.h @@ -104,6 +104,7 @@ int HIDDEN xbps_transaction_fetch(struct xbps_handle *, int HIDDEN xbps_transaction_pkg_deps(struct xbps_handle *, xbps_array_t, xbps_dictionary_t); int HIDDEN xbps_transaction_internalize(struct xbps_handle *, xbps_object_iterator_t); +char HIDDEN *repo_format(struct xbps_handle *, const char *); char HIDDEN *xbps_get_remote_repo_string(const char *); int HIDDEN xbps_repo_sync(struct xbps_handle *, const char *); int HIDDEN xbps_file_hash_check_dictionary(struct xbps_handle *, diff --git a/lib/initend.c b/lib/initend.c index 70ee26cb..31ba3ded 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -163,6 +163,15 @@ xbps_init(struct xbps_handle *xhp) xhp->flags |= XBPS_FLAG_DISABLE_SYSLOG; } + for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) { + const char *url = NULL; + xbps_array_get_cstring_nocopy(xhp->repositories, i, &url); + xbps_array_set_cstring_nocopy(xhp->repositories, i, repo_format(xhp, url)); + } + + xbps_dbg_printf("Native architecture is %s\n", xhp->native_arch); + xbps_dbg_printf("Target architecture is %s\n", xhp->target_arch); + if (xhp->flags & XBPS_FLAG_DEBUG) { const char *repodir; for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) { diff --git a/lib/repo.c b/lib/repo.c index 95acd906..2391233a 100644 --- a/lib/repo.c +++ b/lib/repo.c @@ -37,6 +37,7 @@ #include #include +#include "xbps/fmt.h" #include "xbps_api_impl.h" /** @@ -193,6 +194,65 @@ repo_open_remote(struct xbps_repo *repo) return rv; } +static int +repo_fmt(FILE *fp, const struct xbps_fmt_var *var, void *data) +{ + struct xbps_handle *xhp = data; + const char *arch; + + if (xhp->target_arch) + arch = xhp->target_arch; + else + arch = xhp->native_arch; + + if (strcmp(var->name, "arch") == 0) { + return xbps_fmt_print_string(var, arch, 0, fp); + } + return 0; +} + +char * +repo_format(struct xbps_handle *xhp, const char *url) +{ + struct xbps_fmt *fmt = NULL; + FILE *fmt_stream; + char *fmt_buf; + size_t len; + int r; + + assert(xhp); + assert(url); + + if (!strstr(url, "{arch}")) + return strdup(url); + + xbps_dbg_printf("Processing templated repository: %s\n", url); + + fmt_stream = open_memstream(&fmt_buf, &len); + if (!fmt_stream) { + xbps_error_printf("failed to open buffer: %s\n", strerror(errno)); + goto fmtout; + } + fmt = xbps_fmt_parse(url); + if (!fmt) { + xbps_error_printf("failed to parse format for repo '%s': %s\n", url, strerror(errno)); + goto fmtout; + } + r = xbps_fmt(fmt, repo_fmt, xhp, fmt_stream); + if (r < 0) { + xbps_error_printf("failed to format repo '%s': %s\n", url, strerror(-r)); + goto fmtout; + } + fflush(fmt_stream); + return fmt_buf; + +fmtout: + fclose(fmt_stream); + xbps_fmt_free(fmt); + free(fmt_buf); + return NULL; +} + static struct xbps_repo * repo_open_with_type(struct xbps_handle *xhp, const char *url, const char *name) {