From dd691b1bd388a2f8923c28280f11a15293282f3b Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 27 Apr 2022 16:10:52 +0200 Subject: feat(magrathea): add flag passthru for arguments to nix-build in some cases, users might want to pass through flags for nix-build (such as `-j`). magrathea now accepts these as arguments to `mg build`, as long as they are separated by `--`. the arguments passed to `mg build` are parsed into a proper record, which enables us to show users very clear error messages in case they forget to use the `--` separator and keeping us future-compatible with more potential arguments to magrathea itself. Change-Id: I81f5d9db52779a5cc3b8bbdd975316274fffe5fc Reviewed-on: https://cl.tvl.fyi/c/depot/+/5507 Tested-by: BuildkiteCI Reviewed-by: ezemtsov Reviewed-by: asmundo --- tools/magrathea/mg.scm | 69 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'tools/magrathea') diff --git a/tools/magrathea/mg.scm b/tools/magrathea/mg.scm index a453da2ccd28..cbbcfc69dd57 100644 --- a/tools/magrathea/mg.scm +++ b/tools/magrathea/mg.scm @@ -215,22 +215,65 @@ USAGE [('error . message) (mg-error message)] [_ value])) -(define (execute-build t) - (let ((expr (nix-expr-for t))) - (fprintf (current-error-port) "[mg] building target ~A~%" t) - (process-execute "nix-build" (list "-E" expr "--show-trace")))) - -(define (build args) +(define-record build-args target passthru unknown) +(define (execute-build args) + (let ((expr (nix-expr-for (build-args-target args)))) + (fprintf (current-error-port) "[mg] building target ~A~%" (build-args-target args)) + (process-execute "nix-build" (append (list "-E" expr "--show-trace") + (or (build-args-passthru args) '()))))) + +;; split the arguments used for builds into target/unknown args/nix +;; args, where the latter occur after '--' +(define (parse-build-args acc args) (match args - ;; simplest case: plain mg build with no target spec -> build - ;; the current folder's main target. - [() (execute-build (empty-target))] + ;; no arguments remaining, return accumulator as is + [() acc] + + ;; next argument is '--' separator, split off passthru and + ;; return + [("--" . passthru) + (begin + (build-args-passthru-set! acc passthru) + acc)] + + [(arg . rest) + ;; set target if not already known (and if the first + ;; argument does not look like an accidental unknown + ;; parameter) + (if (and (not (build-args-target acc)) + (not (substring=? "-" arg))) + (begin + (build-args-target-set! acc (guarantee-success (parse-target arg))) + (parse-build-args acc rest)) + + ;; otherwise, collect unknown arguments + (begin + (build-args-unknown-set! acc (append (or (build-args-unknown acc) '()) + (list arg))) + (parse-build-args acc rest)))])) + +;; parse the passed build args, applying sanity checks and defaulting +;; the target if necessary, then execute the build +(define (build args) + (let ((parsed (parse-build-args (make-build-args #f #f #f) args))) + ;; fail if there are unknown arguments present + (when (build-args-unknown parsed) + (let ((unknown (string-intersperse (build-args-unknown parsed)))) + (mg-error (sprintf "unknown arguments: ~a - ;; single argument should be a target spec - [(arg) (execute-build - (guarantee-success (parse-target arg)))] +if you meant to pass these arguments to nix, please separate them with +'--' like so: - [other (print "not yet implemented")])) + mg build ~a -- ~a" + unknown + (or (build-args-target parsed) "") + unknown)))) + + ;; default the target to the current folder's main target + (unless (build-args-target parsed) + (build-args-target-set! parsed (empty-target))) + + (execute-build parsed))) (define (execute-shell t) (let ((expr (nix-expr-for t)) -- cgit 1.4.1