home: hub: zuo

Download patch

ref: d73ec321266e06ad3dd472d38553a2a99e337a1c
parent: 8e5889465ef96d4675107dfe54cfabbc46b9d8f0
author: Matthew Flatt <mflatt@racket-lang.org>
date: Wed Sep 14 09:47:24 CDT 2022

zuo: arrange for target name to appear in a stack trace

--- a/lib/zuo/build.zuo
+++ b/lib/zuo/build.zuo
@@ -318,7 +318,11 @@
      (define sha256 (or (rule-sha256 r) (file-sha256/state (target-path t) state)))
      (when (equal? sha256 no-sha256) ((rule-build r)))
      (update-target-state state t (list sha256))]
-    [else (build-unbuilt t state seen top?)]))
+    [else (call-with-name+stack
+           (target-name t)
+           seen
+           (lambda ()
+             (build-unbuilt t state seen top?)))]))
 
 ;; Starts a build for a specific target
 (define (build-unbuilt t state seen top?)
@@ -328,7 +332,9 @@
                          '()))
   (define alert-top? (and top? (not (hash-ref (target-options t) 'quiet? #f))))
   (define dep-top? (and alert-top? (symbol? path)))
-  (define new-seen (hash-set seen (target-key t) #t))
+  (define new-seen (hash-set (hash-set seen (target-key t) #t)
+                             stack-key
+                             (cons path (hash-ref seen stack-key '()))))
 
   ;; delete a target file if we don't finish:
   (define path-handle (and (path-string? path)
@@ -810,6 +816,29 @@
   (let ([a (assoc "ZUO_JOBS" (hash-ref (runtime-env) 'env '()))])
     (or (and a (string->integer (cdr a)))
         1)))
+
+;; creates a non-tail call labelled "target <name>" so that
+;; it shows up in a stack trace
+(define (call-with-name name thunk)
+  ((kernel-eval `(lambda (proc)
+                   ,(~a "target " name)
+                   (let ([result (proc)])
+                     result)))
+   thunk))
+
+(define stack-key (string->uninterned-symbol "stack"))
+
+(define (call-with-name+stack name seen thunk)
+  (let loop ([stack (if (> (hash-count seen) 16)
+                        ;; avoid quadratic behavior in the unlikely
+                        ;; event that dependencies get deep:
+                        '()
+                        (reverse (hash-ref seen stack-key '())))])
+    (if (null? stack)
+        (call-with-name name thunk)
+        (call-with-name (car stack)
+                        (lambda ()
+                          (loop (cdr stack)))))))
 
 ;; ------------------------------------------------------------
 ;; `make`-like target and dependency declaration