(zilch core nixpkgs): allow evaluating arbitrary Nix code

This commit is contained in:
puck 2025-03-01 15:41:18 +00:00
parent 5306246cdd
commit 16b2064fc6
4 changed files with 60 additions and 17 deletions

View file

@ -18,6 +18,7 @@
srfi-152 srfi-152
srfi-180 srfi-180
trace trace
json
libsodium # TODO(puck): don't propagate this libsodium # TODO(puck): don't propagate this
]; ];

View file

@ -99,17 +99,20 @@
(cached-data derivation-cached-data)) (cached-data derivation-cached-data))
(define is-printing-drv (make-parameter #f))
(define-record-printer (<derivation> drv out) (define-record-printer (<derivation> drv out)
(fprintf out "#<derivation ~s ~s inputs: ~s ~s, ~s ~s ~s ~s, cached data ~S>" (define was-printing-drv (is-printing-drv))
(derivation-name drv) (parameterize ((is-printing-drv #t))
(derivation-outputs drv) (fprintf out "#<derivation ~s ~s inputs: ~s ~s, ~s ~s ~s ~s, cached data ~S>"
(derivation-input-drvs drv) (derivation-name drv)
(derivation-input-src drv) (derivation-outputs drv)
(derivation-system drv) (if was-printing-drv (map derivation-name (derivation-input-drvs)) (derivation-input-drvs drv))
(derivation-builder drv) (derivation-input-src drv)
(derivation-args drv) (derivation-system drv)
(derivation-env drv) (derivation-builder drv)
(derivation-cached-data drv))) (derivation-args drv)
(derivation-env drv)
(derivation-cached-data drv))))
(define (write-delim-list start end fn val port) (define (write-delim-list start end fn val port)
(write-char start port) (write-char start port)

View file

@ -1,10 +1,12 @@
(define-library (zilch nixpkgs) (define-library (zilch nixpkgs)
(import (import
(scheme base) (scheme base) (scheme lazy)
(zilch magic) (zilch nix drv) (zilch nix hash) (zilch magic) (zilch nix drv) (zilch nix hash)
(srfi 18) (zilch zexpr)
(chicken process)) (srfi 18) (srfi 128) (srfi 146)
(export nix-prefetch-url nixpkgs) (chicken format) (chicken process)
json)
(export nix-prefetch-url nixpkgs nix-eval)
(begin (begin
(define (run-stderr-thread prefix port) (define (run-stderr-thread prefix port)
@ -23,6 +25,15 @@
(define-values (_ _ _) (process-wait pid #t)) (define-values (_ _ _) (process-wait pid #t))
(close-port stdout) (close-port stdout)
drvpath) drvpath)
(define (read-from-eval code)
(define-values (stdout stdin pid stderr) (process* "nix-instantiate" `("--json" "--eval" "--strict" "--read-write-mode" "-E" ,code)))
(define thread (thread-start! (make-thread (lambda () (run-stderr-thread (string-append "eval `" code "`") stderr)) "read-from-eval stderr passthrough")))
(close-port stdin)
(define output (json-read stdout))
(close-port stdout)
(define-values (_ _ _) (process-wait pid #t))
output)
;; Returns the hash (as bytevector) of prefetching the specified URL. ;; Returns the hash (as bytevector) of prefetching the specified URL.
(define (nix-prefetch-url name url) (define (nix-prefetch-url name url)
@ -45,4 +56,32 @@
(drv (read-drv-path drv-path)) (drv (read-drv-path drv-path))
(data (map (lambda (l) (cons (car l) (make-store-path drv (car l) #t))) (derivation-outputs drv)))) (data (map (lambda (l) (cons (car l) (make-store-path drv (car l) #t))) (derivation-outputs drv))))
(set! eval-cache (cons (cons path data) eval-cache)) (set! eval-cache (cons (cons path data) eval-cache))
data))))) data)))
(define (nix-eval-inner code)
(define response (read-from-eval (string-append "(v: [(builtins.getContext (builtins.toJSON v)) v]) (" code ")")))
; Format: key is drv,
; path = true (always true if set, matches Opaque)
; allOutputs = true (if set, matches DrvDeep, aka the .drv and its entire fucking closure)
; outputs = [ ...output-name output-name-2 ] (matches Built)
(define drvs '())
(define paths '())
(vector-for-each
(lambda (item)
(define pairs (vector->list (cdr item)))
(when (assoc "path" pairs)
(set! paths (cons (car item) paths)))
(when (assoc "allOutputs" pairs)
(error "Context of evaluation output uses allOutputs; this is unsupported"))
(define outputs (let ((p (assoc "outputs" pairs))) (and p (cdr p))))
(when outputs
(let ((drv (read-drv-path (car item))))
(set! drvs (cons (cons drv outputs) drvs)))))
(car response))
(values drvs paths (cadr response)))
;; Parse an arbitrary Nix expression and return it as a zexpr.
(define (nix-eval code)
(define data (delay (nix-eval-inner code)))
(make-zexp (lambda () (let-values (((drvs paths out) (force data))) (zexp-context-register-items drvs paths) out))
(lambda (p) (fprintf p "nix`~A`" code))))))

View file

@ -1,7 +1,7 @@
((version "0.0.1") ((version "0.0.1")
(synopsis "Nix. Noppes. Nada.") (synopsis "Nix. Noppes. Nada.")
(author "puck") (author "puck")
(dependencies socket r7rs vector-lib srfi-60 srfi-113 srfi-128 srfi-132 srfi-146 srfi-151 srfi-152 srfi-180 trace) (dependencies socket r7rs vector-lib srfi-60 srfi-113 srfi-128 srfi-132 srfi-146 srfi-151 srfi-152 srfi-180 trace json)
(component-options (component-options
(csc-options "-X" "r7rs" "-R" "r7rs" "-optimize-level" "3")) (csc-options "-X" "r7rs" "-R" "r7rs" "-optimize-level" "3"))
(components (components
@ -27,7 +27,7 @@
(component-dependencies zilch.magic zilch.nix.binproto zilch.nix.daemon zilch.nix.drv zilch.zexpr)) (component-dependencies zilch.magic zilch.nix.binproto zilch.nix.daemon zilch.nix.drv zilch.zexpr))
(extension zilch.nixpkgs (extension zilch.nixpkgs
(source "src/nixpkgs.sld") (source "src/nixpkgs.sld")
(component-dependencies zilch.magic zilch.nix.drv zilch.nix.hash)) (component-dependencies zilch.magic zilch.nix.drv zilch.nix.hash zilch.zexpr))
(extension zilch.nix.daemon (extension zilch.nix.daemon
(source "src/nix/daemon.sld") (source "src/nix/daemon.sld")
(component-dependencies zilch.lib.hash zilch.nix.binproto)) (component-dependencies zilch.lib.hash zilch.nix.binproto))