#!txr --lisp ;; ;; This program is intended to be installed as .git/hooks/post-checkout. ;; It caches the build configuration for the current commit, and restores ;; it for the new commit, if possible. ;; ;; People have git hook directories which are shared among different ;; repos; we only want to fire for txr. (unless (ends-with "txr" (pwd)) (exit)) (defvarl %files% '#"reconfigure config.h config.make") (defvarl %cachedir% ".config-cache") (defun hash-config-inputs (sha) (let ((s (sha256-begin)) (makefile-conftest-parts (flow `git cat-file -p @sha:Makefile` command-get-lines (member-if (op starts-with "conftest:")) (join-with "\n")))) (sha256-hash s (command-get-string `git cat-file -p @sha:configure`)) (sha256-hash s makefile-conftest-parts) (tostringp (sha256-end s)))) (defun try-save-current-config (key) (when [all %files% path-exists-p] (let* ((dir (path-cat %cachedir% key))) (ensure-dir dir) (copy-files %files% dir t)))) (defun try-restore-new-config (key) (let* ((dir (path-cat %cachedir% key)) (files [map (op path-cat dir) %files%])) (when [all files path-exists-p] (copy-files files "." t) t))) (match-case *args* (("hash" @sha) (flow sha hash-config-inputs put-line)) (@(require (@prevsha @newsha @nil) (nequal prevsha newsha)) (let ((prevkey (hash-config-inputs prevsha)) (newkey (hash-config-inputs newsha))) (cond ((equal prevkey newkey) (put-line `current configuration valid for @newsha`)) (t (try-save-current-config prevkey) (if (try-restore-new-config newkey) (put-line `retrieved cached configuration for @newsha`) (put-line `no cached configuration for @newsha - run ./configure`)))))))