From d7161980ffed183f385b6430df0f55f2c3916249 Mon Sep 17 00:00:00 2001 From: Jacob O'Bryant Date: Mon, 1 Aug 2022 14:45:53 -0700 Subject: [PATCH] Add use-beholder component, deprecate use-hawk --- deps.edn | 6 ++++-- src/com/biffweb.clj | 33 ++++++++++++++++++++++++++------- src/com/biffweb/impl/misc.clj | 21 +++++++++++++++++++++ src/com/biffweb/impl/util.clj | 8 ++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/deps.edn b/deps.edn index e999d9cc..ca8852a0 100644 --- a/deps.edn +++ b/deps.edn @@ -2,10 +2,10 @@ buddy/buddy-sign {:mvn/version "3.4.333"} cider/cider-nrepl {:mvn/version "0.28.2"} clj-http/clj-http {:mvn/version "3.12.3"} + com.nextjournal/beholder {:mvn/version "1.0.0"} com.xtdb/xtdb-core {:mvn/version "1.21.0-beta2"} com.xtdb/xtdb-jdbc {:mvn/version "1.21.0-beta2"} com.xtdb/xtdb-rocksdb {:mvn/version "1.21.0-beta2"} - hawk/hawk {:mvn/version "0.2.11"} info.sunng/ring-jetty9-adapter {:mvn/version "0.17.2"} jarohen/chime {:mvn/version "0.3.3"} lambdaisland/uri {:mvn/version "1.13.95"} @@ -18,7 +18,9 @@ org.postgresql/postgresql {:mvn/version "42.3.2"} ring/ring-defaults {:mvn/version "0.3.3"} rum/rum {:mvn/version "0.12.8" - :exclusions [cljsjs/react cljsjs/react-dom]}} + :exclusions [cljsjs/react cljsjs/react-dom]} + ;; deprecated + hawk/hawk {:mvn/version "0.2.11"}} :aliases {:dev {:extra-deps {org.slf4j/slf4j-simple {:mvn/version "2.0.0-alpha5"}} :main-opts ["-m" "nrepl.cmdline"]} :format {:extra-deps {cljfmt/cljfmt {:mvn/version "0.8.2"}} diff --git a/src/com/biffweb.clj b/src/com/biffweb.clj index 4408a772..b1e77feb 100644 --- a/src/com/biffweb.clj +++ b/src/com/biffweb.clj @@ -1,5 +1,6 @@ (ns com.biffweb - (:require [clojure.string :as str] + (:require [clojure.stacktrace :as st] + [clojure.string :as str] [com.biffweb.impl.middleware :as middle] [com.biffweb.impl.misc :as misc] [com.biffweb.impl.rum :as brum] @@ -131,6 +132,14 @@ [& body] `(try ~@body (catch Exception ~'_ nil))) +(defmacro catchall-verbose + [& body] + "Like catchall, but prints exceptions." + `(try + ~@body + (catch Exception e# + (st/print-stack-trace e#)))) + (defmacro letd "Like let, but transparently wraps all bindings with delay. @@ -177,20 +186,30 @@ ;;;; misc (defn use-hawk - "A Biff component that runs code when files are changed, via Hawk. + "Deprecated. Use use-beholder instead. + + use-beholder is a drop-in replacement for use-hawk, except that keys must be + prefixed with :biff.beholder/ instead of :biff.hawk/" + [{:biff.hawk/keys [on-save exts paths] + :or {paths ["src" "resources"]} + :as sys}] + (misc/use-hawk sys)) + +(defn use-beholder + "A Biff component that runs code when files are changed, via Beholder. - See (https://github.com/wkf/hawk). + See https://github.com/nextjournal/beholder. on-save: A single-argument function to call whenever a file is saved. - Receives the system map as a parameter. The function is called no - more than once every 500 milliseconds. + Receives the system map as a parameter. Subsequent file saves + that occur within one second are ignored. paths: A collection of root directories to monitor for file changes. exts: If exts is non-empty, files that don't end in one of the extensions will be ignored." - [{:biff.hawk/keys [on-save exts paths] + [{:biff.beholder/keys [on-save exts paths] :or {paths ["src" "resources"]} :as sys}] - (misc/use-hawk sys)) + (misc/use-beholder sys)) (defn reitit-handler "Convenience wrapper for reitit.ring/ring-handler. diff --git a/src/com/biffweb/impl/misc.clj b/src/com/biffweb/impl/misc.clj index 48214470..bd1f185f 100644 --- a/src/com/biffweb/impl/misc.clj +++ b/src/com/biffweb/impl/misc.clj @@ -3,14 +3,35 @@ [buddy.sign.jwt :as jwt] [chime.core :as chime] [clj-http.client :as http] + [clojure.stacktrace :as st] [clojure.string :as str] [clojure.tools.logging :as log] [com.biffweb.impl.time :as time] [com.biffweb.impl.util :as util] [hawk.core :as hawk] + [nextjournal.beholder :as beholder] [reitit.ring :as reitit-ring] [ring.adapter.jetty9 :as jetty])) +(defn use-beholder [{:biff.beholder/keys [on-save exts paths] + :or {paths ["src" "resources"]} + :as sys}] + (let [;; Poor man's debouncer -- don't want to pull in core.async just for + ;; this, and don't want to spend time figuring out how else to do it. + last-called (atom #inst "1970") + watch (apply beholder/watch + (fn [{:keys [path]}] + (when (and (or (empty? exts) + (some #(str/ends-with? path %) exts)) + (time/elapsed? @last-called :now 1 :seconds)) + ;; Give all the files some time to get written before invoking the callback. + (Thread/sleep 100) + (util/catchall-verbose (on-save sys)) + (reset! last-called (java.util.Date.)))) + paths)] + (update sys :biff/stop conj #(beholder/stop watch)))) + +;; Deprecated (defn use-hawk [{:biff.hawk/keys [on-save exts paths] :or {paths ["src" "resources"]} :as sys}] diff --git a/src/com/biffweb/impl/util.clj b/src/com/biffweb/impl/util.clj index d8c8b2bf..6075e84b 100644 --- a/src/com/biffweb/impl/util.clj +++ b/src/com/biffweb/impl/util.clj @@ -3,11 +3,19 @@ [clojure.java.shell :as shell] [clojure.pprint :as pp] [clojure.spec.alpha :as spec] + [clojure.stacktrace :as st] [clojure.string :as str] [clojure.tools.logging :refer [info]] [clojure.tools.namespace.repl :as tn-repl] [clojure.walk :as walk])) +(defmacro catchall-verbose + [& body] + `(try + ~@body + (catch Exception e# + (st/print-stack-trace e#)))) + (defn start-system [system-atom init] (reset! system-atom (merge {:biff/stop '()} init)) (loop [{[f & components] :biff/components :as sys} init]