Browse Source

Add scripts for exporting and diffing graphs

Allows for quick export<->import QA of more complex graphs
and any examples made in app
Gabriel Horner 7 months ago
parent
commit
ab9796ae60
3 changed files with 118 additions and 0 deletions
  1. 12 0
      bb.edn
  2. 46 0
      deps/db/script/diff_graphs.cljs
  3. 60 0
      deps/db/script/export_graph.cljs

+ 12 - 0
bb.edn

@@ -85,6 +85,18 @@
    :task (apply shell {:dir "deps/db" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
    :task (apply shell {:dir "deps/db" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
                 "yarn -s nbb-logseq -cp src:../outliner/src:script script/create_graph.cljs" *command-line-args*)}
                 "yarn -s nbb-logseq -cp src:../outliner/src:script script/create_graph.cljs" *command-line-args*)}
 
 
+  dev:db-export
+  {:doc "Export a DB graph to a sqlite.build EDN file"
+   :requires ([babashka.fs :as fs])
+   :task (apply shell {:dir "deps/db" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
+                "yarn -s nbb-logseq script/export_graph.cljs" *command-line-args*)}
+
+  dev:db-diff
+  {:doc "Diffs two DB graphs"
+   :requires ([babashka.fs :as fs])
+   :task (apply shell {:dir "deps/db" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
+                "yarn -s nbb-logseq script/diff_graphs.cljs" *command-line-args*)}
+
   dev:db-import
   dev:db-import
   {:doc "Import a file graph to db graph"
   {:doc "Import a file graph to db graph"
    :requires ([babashka.fs :as fs])
    :requires ([babashka.fs :as fs])

+ 46 - 0
deps/db/script/diff_graphs.cljs

@@ -0,0 +1,46 @@
+(ns diff-graphs
+  "A script that diffs two DB graphs through their sqlite.build EDN"
+  (:require ["os" :as os]
+            ["path" :as node-path]
+            [babashka.cli :as cli]
+            [clojure.data :as data]
+            [clojure.pprint :as pprint]
+            [clojure.string :as string]
+            #_:clj-kondo/ignore
+            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.sqlite.export :as sqlite-export]
+            [nbb.core :as nbb]))
+
+(defn- get-dir-and-db-name
+  "Gets dir and db name for use with open-db!"
+  [graph-dir]
+  (if (string/includes? graph-dir "/")
+    (let [graph-dir'
+          (node-path/join (or js/process.env.ORIGINAL_PWD ".") graph-dir)]
+      ((juxt node-path/dirname node-path/basename) graph-dir'))
+    [(node-path/join (os/homedir) "logseq" "graphs") graph-dir]))
+
+(def spec
+  "Options spec"
+  {:help {:alias :h
+          :desc "Print help"}
+   :timestamps {:alias :t
+                :desc "Include timestamps in export"}})
+
+(defn -main [args]
+  (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
+        [graph-dir graph-dir2] args'
+        _ (when (or (nil? graph-dir) (nil? graph-dir2) (:help options))
+            (println (str "Usage: $0 GRAPH-NAME GRAPH-NAME2 [& ARGS] [OPTIONS]\nOptions:\n"
+                          (cli/format-opts {:spec spec})))
+            (js/process.exit 1))
+        conn (apply sqlite-cli/open-db! (get-dir-and-db-name graph-dir))
+        conn2 (apply sqlite-cli/open-db! (get-dir-and-db-name graph-dir2))
+        export-options {:include-timestamps? (:timestamps options)}
+        export-map (sqlite-export/build-export @conn {:export-type :graph :graph-options export-options})
+        export-map2 (sqlite-export/build-export @conn2 {:export-type :graph :graph-options export-options})
+        diff (butlast (data/diff export-map export-map2))]
+    (pprint/pprint diff)))
+
+(when (= nbb/*file* (:file (meta #'-main)))
+  (-main *command-line-args*))

+ 60 - 0
deps/db/script/export_graph.cljs

@@ -0,0 +1,60 @@
+(ns export-graph
+  "A script that exports a graph to a sqlite.build EDN file"
+  (:require ["fs" :as fs]
+            ["os" :as os]
+            ["path" :as node-path]
+            [babashka.cli :as cli]
+            [clojure.edn :as edn]
+            [clojure.pprint :as pprint]
+            [clojure.string :as string]
+            #_:clj-kondo/ignore
+            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.sqlite.export :as sqlite-export]
+            [nbb.core :as nbb]))
+
+(defn- resolve-path
+  "If relative path, resolve with $ORIGINAL_PWD"
+  [path]
+  (if (node-path/isAbsolute path)
+    path
+    (node-path/join (or js/process.env.ORIGINAL_PWD ".") path)))
+
+(defn- get-dir-and-db-name
+  "Gets dir and db name for use with open-db!"
+  [graph-dir]
+  (if (string/includes? graph-dir "/")
+    (let [graph-dir'
+          (node-path/join (or js/process.env.ORIGINAL_PWD ".") graph-dir)]
+      ((juxt node-path/dirname node-path/basename) graph-dir'))
+    [(node-path/join (os/homedir) "logseq" "graphs") graph-dir]))
+
+(def spec
+  "Options spec"
+  {:help {:alias :h
+          :desc "Print help"}
+   :timestamps {:alias :t
+                :desc "Include timestamps in export"}
+   :file {:alias :f
+          :desc "Saves edn to file"}
+   :export-options {:alias :e
+                    :desc "Raw options map to pass to export"}})
+
+(defn -main [args]
+  (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
+        graph-dir (first args')
+        _ (when (or (nil? graph-dir) (:help options))
+            (println (str "Usage: $0 GRAPH-NAME [& ARGS] [OPTIONS]\nOptions:\n"
+                          (cli/format-opts {:spec spec})))
+            (js/process.exit 1))
+        [dir db-name] (get-dir-and-db-name graph-dir)
+        conn (sqlite-cli/open-db! dir db-name)
+        export-options (merge {:include-timestamps? (:timestamps options)}
+                              (edn/read-string (:export-options options)))
+        export-map (sqlite-export/build-export @conn {:export-type :graph :graph-options export-options})]
+    (when (:file options)
+      (fs/writeFileSync (resolve-path (:file options))
+                        (with-out-str (pprint/pprint export-map))))
+    (pprint/pprint export-map)))
+
+(when (= nbb/*file* (:file (meta #'-main)))
+  (-main *command-line-args*))