2 files changed, 40 insertions(+) gnu/packages.scm | 1 + gnu/services/configuration.scm | 39 +++++++++++++++++++++++++++++++++++++++ modified gnu/packages.scm @@ -49,6 +49,7 @@ (define-module (gnu packages) #:export (search-patch search-patches search-auxiliary-file + %distro-root-directory %patch-path %auxiliary-files-path %package-module-path modified gnu/services/configuration.scm @@ -25,6 +25,9 @@ ;;; along with GNU Guix. If not, see . (define-module (gnu services configuration) + #:use-module (gnu packages) + #:use-module (guix discovery) + #:use-module (guix memoization) #:use-module (guix packages) #:use-module (guix records) #:use-module (guix gexp) @@ -34,6 +37,7 @@ (define-module (gnu services configuration) warning)) #:use-module ((guix modules) #:select (file-name->module-name)) #:use-module (guix i18n) + #:use-module ((guix ui) #:select (warn-about-load-error)) #:autoload (texinfo) (texi-fragment->stexi) #:autoload (texinfo serialize) (stexi->texi) #:use-module (ice-9 curried-definitions) @@ -588,3 +592,38 @@ (define (generic-serialize-alist combine serialize-field fields) @code{append} are usually good candidates for this." (apply combine (map (generic-serialize-alist-entry serialize-field) fields))) + + +;;; +;;; Configuration objects discovery. +;;; + +(define %default-service-module-path + ;; Default search path for service modules. + `((,%distro-root-directory . "gnu/services"))) + +(define (define-configuration? module symbol) + "Predicate to check if SYMBOL points to a `define-configuration'-generated +object in MODULE." + (let ((fields-variable-name (symbol-append symbol '-fields))) + (or (module-local-variable module fields-variable-name) ;private variable + (module-variable module fields-variable-name)))) ;public variable + +(define* (fold-configurations proc init + #:optional + (modules (all-modules %default-service-module-path + #:warn + warn-about-load-error)) + #:key (select? (const #t))) + "Call (PROC MODULE SYMBOL RESULT) for each service configuration defined via +`define-configuration' in the MODULES that matches SELECT?, using INIT as the +initial value of RESULT. SELECT? is called with two arguments, the module +object as well as the variable name (a symbol) of the configuration record +constructor, e.g. @code{'forgejo-configuration}." + (fold-module-public-variables* (lambda (module symbol _ result) + (if (and (define-configuration? module symbol) + (select? module symbol)) + (proc module symbol result) + result)) + init + modules)) [back]