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
  :deps
  {org.babashka/spec.alpha
  {org.babashka/spec.alpha
   {:git/url "https://github.com/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
  :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
  :tasks
  {dev:watch
  {dev:watch
   logseq.tasks.dev/watch
   logseq.tasks.dev/watch
@@ -26,6 +31,9 @@
   dev:lint
   dev:lint
   logseq.tasks.dev/lint
   logseq.tasks.dev/lint
 
 
+  nbb:watch
+  logseq.bb-tasks.nbb.watch/watch-dir
+
   test:load-namespaces-with-nbb
   test:load-namespaces-with-nbb
   logseq.tasks.nbb/load-compatible-namespaces
   logseq.tasks.nbb/load-compatible-namespaces
 
 

+ 1 - 1
deps.edn

@@ -47,5 +47,5 @@
                   :main-opts   ["-m" "shadow.cljs.devtools.cli"]}
                   :main-opts   ["-m" "shadow.cljs.devtools.cli"]}
 
 
            ;; Use :replace-deps for tools. See https://github.com/clj-kondo/clj-kondo/issues/1536#issuecomment-1013006889
            ;; 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"]}}}
                        :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"}}
                       org.clojure/clojurescript {:mvn/version "1.11.54"}}
          :main-opts ["-m" "cljs-test-runner.main"]}
          :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"]}}}
               :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.config :as gp-config]
             [logseq.graph-parser.db :as gp-db]))
             [logseq.graph-parser.db :as gp-db]))
 
 
-(defn- slurp
-  "Like clojure.core/slurp"
+(defn slurp
+  "Return file contents like clojure.core/slurp"
   [file]
   [file]
   (str (fs/readFileSync file)))
   (str (fs/readFileSync file)))
 
 
-(defn- sh
+(defn sh
   "Run shell cmd synchronously and print to inherited streams by default. Aims
   "Run shell cmd synchronously and print to inherited streams by default. Aims
     to be similar to babashka.tasks/shell
     to be similar to babashka.tasks/shell
 TODO: Fail fast when process exits 1"
 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
   "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
   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
   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]
   ([dir]
    (parse-graph dir {}))
    (parse-graph dir {}))
   ([dir options]
   ([dir options]
-   (let [files (build-graph-files dir)
+   (let [files (or (:files options) (build-graph-files dir))
          conn (gp-db/start-conn)
          conn (gp-db/start-conn)
          config (read-config dir)]
          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}))
      (parse-files conn files (merge options {:config config}))
      {:conn conn
      {:conn conn
       :files (map :file/path files)})))
       :files (map :file/path files)})))