Browse Source

Add nbb:watch task and example

Also update to latest clj-kondo
Gabriel Horner 3 years ago
parent
commit
70c0708f09

+ 10 - 2
bb.edn

@@ -2,9 +2,14 @@
  :deps
  {org.babashka/spec.alpha
   {:git/url "https://github.com/babashka/spec.alpha"
-   :sha "1a841c4cc1d4f6dab7505a98ed2d532dd9d56b78"}}
+   :sha "1a841c4cc1d4f6dab7505a98ed2d532dd9d56b78"}
+  logseq/bb-tasks
+  {:local/root "deps/bb-tasks"}
+  logseq/graph-parser
+  {:local/root "deps/graph-parser"}}
  :pods
- {clj-kondo/clj-kondo {:version "2022.02.09"}}
+ {clj-kondo/clj-kondo {:version "2022.02.09"}
+  org.babashka/fswatcher {:version "0.0.3"}}
  :tasks
  {dev:watch
   logseq.tasks.dev/watch
@@ -26,6 +31,9 @@
   dev:lint
   logseq.tasks.dev/lint
 
+  nbb:watch
+  logseq.bb-tasks.nbb.watch/watch-dir
+
   test:load-namespaces-with-nbb
   logseq.tasks.nbb/load-compatible-namespaces
 

+ 1 - 1
deps.edn

@@ -47,5 +47,5 @@
                   :main-opts   ["-m" "shadow.cljs.devtools.cli"]}
 
            ;; Use :replace-deps for tools. See https://github.com/clj-kondo/clj-kondo/issues/1536#issuecomment-1013006889
-           :clj-kondo {:replace-deps {clj-kondo/clj-kondo {:mvn/version "2022.05.27"}}
+           :clj-kondo {:replace-deps {clj-kondo/clj-kondo {:mvn/version "2022.05.28"}}
                        :main-opts  ["-m" "clj-kondo.main"]}}}

+ 33 - 0
deps/bb-tasks/README.md

@@ -0,0 +1,33 @@
+## Description
+
+Library of reusable https://github.com/babashka/babashka tasks
+
+## Install
+
+Add a git dependency to your `bb.edn`:
+
+```clojure
+:deps
+{logseq/bb-tasks
+{:git/url "https://github.com/logseq/logseq"
+ :git/sha "FILL IN"
+ :deps/root "deps/bb-tasks"}}
+```
+
+## Usage
+
+### nbb:watch
+
+Given a graph directory and an nbb script, the nbb script will run when either the
+script or a file in the directory is saved.
+
+For example, from root of logseq repo, run the following:
+
+```
+$ bb nbb:watch /path/to/graph deps/graph-parser/examples/parse_file.cljs
+Watching /path/to/graph ...
+```
+
+See [this demo
+clip](https://www.loom.com/share/20debb49fdd64e77ae83056289750b0f) to see it in
+action.

+ 6 - 0
deps/bb-tasks/bb.edn

@@ -0,0 +1,6 @@
+{:paths ["src"]
+ :pods
+ {org.babashka/fswatcher {:version "0.0.3"}}
+ :tasks
+ {nbb:watch
+  logseq.bb-tasks.nbb.watch/watch-dir}}

+ 2 - 0
deps/bb-tasks/deps.edn

@@ -0,0 +1,2 @@
+;; Allows for this lib to be pulled in as a gitlib
+{}

+ 35 - 0
deps/bb-tasks/src/logseq/bb_tasks/nbb/watch.clj

@@ -0,0 +1,35 @@
+(ns logseq.bb-tasks.nbb.watch
+  "To use tasks in this ns, first install nbb-logseq:
+`npm install -g @logseq/nbb-logseq`"
+  (:require [pod.babashka.fswatcher :as fw]
+            [babashka.tasks :refer [shell]]
+            [babashka.classpath :as classpath]))
+
+(def last-file (atom nil))
+
+(defn- run-script
+  [nbb-script dir file]
+  (shell "nbb-logseq -cp" (classpath/get-classpath) nbb-script dir file))
+
+(defn watch-dir
+  "Watch a graph dir and nbb script and run nbb script when either changes.
+Nbb takes graph dir and last modified graph file.
+NOTE: If the script fails, the watcher stops watching"
+  [& args]
+  (when-not (= 2 (count args))
+    (throw (ex-info "Usage: $0 DIR NBB-SCRIPT" {})))
+  (let [[dir nbb-script] args]
+    (println "Watching" dir "...")
+    (fw/watch dir
+              (fn [event]
+                ;; Don't use :chmod as it sometimes triggers twice on osx
+                (when (#{:write|chmod :write} (:type event))
+                  (run-script nbb-script dir (:path event))
+                  (reset! last-file (:path event))))
+              {:recursive true})
+    ;; Get live-editing experience by re-parsing last file
+    (fw/watch nbb-script
+              (fn [event]
+                (when (#{:write|chmod :write} (:type event))
+                  (run-script nbb-script dir @last-file))))
+    (deref (promise))))

+ 1 - 1
deps/graph-parser/deps.edn

@@ -19,5 +19,5 @@
                       org.clojure/clojurescript {:mvn/version "1.11.54"}}
          :main-opts ["-m" "cljs-test-runner.main"]}
 
-  :clj-kondo {:replace-deps {clj-kondo/clj-kondo {:mvn/version "2022.05.27"}}
+  :clj-kondo {:replace-deps {clj-kondo/clj-kondo {:mvn/version "2022.05.28"}}
               :main-opts  ["-m" "clj-kondo.main"]}}}

+ 52 - 0
deps/graph-parser/examples/parse_file.cljs

@@ -0,0 +1,52 @@
+(ns parse-file
+  (:require [logseq.graph-parser.cli :as gp-cli]
+            [clojure.pprint :as pprint]
+            [datascript.core :as d]))
+
+(defn- colorize-or-pretty-print
+  [results]
+  (if (zero? (.-status (gp-cli/sh ["which" "puget"] {})))
+    (gp-cli/sh ["puget"] {:input (pr-str results)
+                          :stdio ["pipe" "inherit" "inherit"]})
+    (pprint/pprint results)))
+
+(defn- get-all-page-properties
+  [db]
+  (->> (d/q '[:find (pull ?b [*])
+              :where
+              [?b :block/properties]]
+            db)
+       (map first)
+       (map (fn [m] (zipmap (keys (:block/properties m)) (repeat 1))))
+       (apply merge-with +)
+       (into {})))
+
+(defn- analyze-file
+  [db file]
+  (let [results (map first
+                     (d/q '[:find (pull ?b [:db/id :block/content])
+                            :in $ ?path
+                            :where
+                            [?b :block/page ?page]
+                            [?page :block/file ?file]
+                            [?file :file/path ?path]]
+                          db
+                          file))]
+    (colorize-or-pretty-print results)
+    (println "Block count:" (count results))
+    (println "Properties count:" (get-all-page-properties db))))
+
+(defn -main
+  "Prints blocks for given file along with basic file stats"
+  [& args]
+  (when-not (= 2 (count args))
+    (throw (ex-info "Usage: $0 DIR FILE" {})))
+  (println "Parsing...")
+  (let [[dir file] args
+        {:keys [conn]} (gp-cli/parse-graph dir
+                                           {:verbose false
+                                            :files [{:file/path file
+                                                     :file/content (gp-cli/slurp file)}]})]
+    (analyze-file @conn file)))
+
+(apply -main *command-line-args*)

+ 8 - 6
deps/graph-parser/src/logseq/graph_parser/cli.cljs

@@ -8,12 +8,12 @@
             [logseq.graph-parser.config :as gp-config]
             [logseq.graph-parser.db :as gp-db]))
 
-(defn- slurp
-  "Like clojure.core/slurp"
+(defn slurp
+  "Return file contents like clojure.core/slurp"
   [file]
   (str (fs/readFileSync file)))
 
-(defn- sh
+(defn sh
   "Run shell cmd synchronously and print to inherited streams by default. Aims
     to be similar to babashka.tasks/shell
 TODO: Fail fast when process exits 1"
@@ -53,14 +53,16 @@ TODO: Fail fast when process exits 1"
   "Parses a given graph directory and returns a datascript connection and all
   files that were processed. The directory is parsed as if it were a new graph
   as it can't assume that the metadata in logseq/ is up to date. Directory is
-  assumed to be using git"
+  assumed to be using git. This fn takes the following options:
+* :verbose - When enabled prints more information during parsing. Defaults to true
+* :files - Specific files to parse instead of parsing the whole directory"
   ([dir]
    (parse-graph dir {}))
   ([dir options]
-   (let [files (build-graph-files dir)
+   (let [files (or (:files options) (build-graph-files dir))
          conn (gp-db/start-conn)
          config (read-config dir)]
-     (println "Parsing" (count files) "files...")
+     (when-not (:files options) (println "Parsing" (count files) "files..."))
      (parse-files conn files (merge options {:config config}))
      {:conn conn
       :files (map :file/path files)})))