瀏覽代碼

Fix more bugs, move plugins.edn and add enabled

- Move plugins.edn to config/ as it is user configuration
- Add plugin-config enabled flag and moved plugin enabled
- Fixed bugs with manual install
- Refactored plugin-config component to have its own listener
- Split out shared plugin fns to a common ns - plugin-config shouldn't
  need to depend on a component like plugin-handler
- Bump rewrite-edn to include upstream fix and avoid tons of cljs
  warnings with earlier versions
- Fix react warning introduced outside this PR in ui/icon
Gabriel Horner 3 年之前
父節點
當前提交
0c570a0300

+ 3 - 0
.clj-kondo/config.edn

@@ -43,12 +43,15 @@
              frontend.handler.extract extract
              frontend.handler.extract extract
              frontend.handler.common common-handler
              frontend.handler.common common-handler
              frontend.handler.common.file file-common-handler
              frontend.handler.common.file file-common-handler
+             frontend.handler.common.plugin plugin-common-handler
              frontend.handler.config config-handler
              frontend.handler.config config-handler
              frontend.handler.events events
              frontend.handler.events events
              frontend.handler.global-config global-config-handler
              frontend.handler.global-config global-config-handler
              frontend.handler.ui ui-handler
              frontend.handler.ui ui-handler
              frontend.handler.notification notification
              frontend.handler.notification notification
              frontend.handler.page page-handler
              frontend.handler.page page-handler
+             frontend.handler.plugin plugin-handler
+             frontend.handler.plugin-config plugin-config-handler
              frontend.handler.repo repo-handler
              frontend.handler.repo repo-handler
              frontend.handler.repo-config repo-config-handler
              frontend.handler.repo-config repo-config-handler
              frontend.handler.search search-handler
              frontend.handler.search search-handler

+ 3 - 1
deps.edn

@@ -4,7 +4,9 @@
   rum/rum                               {:mvn/version "0.12.9"}
   rum/rum                               {:mvn/version "0.12.9"}
   datascript/datascript                 {:mvn/version "1.3.8"}
   datascript/datascript                 {:mvn/version "1.3.8"}
   datascript-transit/datascript-transit {:mvn/version "0.3.0"}
   datascript-transit/datascript-transit {:mvn/version "0.3.0"}
-  borkdude/rewrite-edn                  {:mvn/version "0.1.0"}
+  ;; TODO: bump to mvn/version when released
+  borkdude/rewrite-edn                  {:git/url "https://github.com/borkdude/rewrite-edn"
+                                         :sha "80f246139b1a43b6f2cbab329521d060ee7c1b7b"}
   funcool/promesa                       {:mvn/version "4.0.2"}
   funcool/promesa                       {:mvn/version "4.0.2"}
   medley/medley                         {:mvn/version "1.4.0"}
   medley/medley                         {:mvn/version "1.4.0"}
   metosin/reitit-frontend               {:mvn/version "0.3.10"}
   metosin/reitit-frontend               {:mvn/version "0.3.10"}

+ 1 - 1
src/main/frontend/components/block.cljs

@@ -1503,7 +1503,7 @@
       (= name "embed")
       (= name "embed")
       (macro-embed-cp config arguments)
       (macro-embed-cp config arguments)
 
 
-      (and plugin-handler/lsp-enabled? (= name "renderer"))
+      (and config/lsp-enabled? (= name "renderer"))
       (when-let [block-uuid (str (:block/uuid config))]
       (when-let [block-uuid (str (:block/uuid config))]
         (plugins/hook-ui-slot :macro-renderer-slotted (assoc options :uuid block-uuid)))
         (plugins/hook-ui-slot :macro-renderer-slotted (assoc options :uuid block-uuid)))
 
 

+ 3 - 3
src/main/frontend/components/header.cljs

@@ -75,12 +75,12 @@
           :options {:on-click state/open-settings!}
           :options {:on-click state/open-settings!}
           :icon (ui/icon "settings")})
           :icon (ui/icon "settings")})
 
 
-       (when plugin-handler/lsp-enabled?
+       (when config/lsp-enabled?
          {:title (t :plugins)
          {:title (t :plugins)
           :options {:on-click #(plugin-handler/goto-plugins-dashboard!)}
           :options {:on-click #(plugin-handler/goto-plugins-dashboard!)}
           :icon (ui/icon "apps")})
           :icon (ui/icon "apps")})
 
 
-       (when plugin-handler/lsp-enabled?
+       (when config/lsp-enabled?
          {:title (t :themes)
          {:title (t :themes)
           :options {:on-click #(plugins/open-select-theme!)}
           :options {:on-click #(plugins/open-select-theme!)}
           :icon (ui/icon "palette")})
           :icon (ui/icon "palette")})
@@ -209,7 +209,7 @@
       (when sync-enabled?
       (when sync-enabled?
         (login))
         (login))
 
 
-      (when plugin-handler/lsp-enabled?
+      (when config/lsp-enabled?
         (plugins/hook-ui-items :toolbar))
         (plugins/hook-ui-items :toolbar))
 
 
       (when (util/electron?)
       (when (util/electron?)

+ 1 - 2
src/main/frontend/components/page.cljs

@@ -23,7 +23,6 @@
             [frontend.handler.graph :as graph-handler]
             [frontend.handler.graph :as graph-handler]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
             [frontend.handler.page :as page-handler]
             [frontend.handler.page :as page-handler]
-            [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.mixins :as mixins]
             [frontend.mixins :as mixins]
             [frontend.mobile.util :as mobile-util]
             [frontend.mobile.util :as mobile-util]
@@ -425,7 +424,7 @@
                 [:h1.title.ls-page-title (page-title page-name icon title format fmt-journal?)]])
                 [:h1.title.ls-page-title (page-title page-name icon title format fmt-journal?)]])
              (when (not config/publishing?)
              (when (not config/publishing?)
                [:div.flex.flex-row
                [:div.flex.flex-row
-                (when plugin-handler/lsp-enabled?
+                (when config/lsp-enabled?
                   (plugins/hook-ui-slot :page-head-actions-slotted nil)
                   (plugins/hook-ui-slot :page-head-actions-slotted nil)
                   (plugins/hook-ui-items :pagebar))])])
                   (plugins/hook-ui-items :pagebar))])])
           [:div
           [:div

+ 1 - 2
src/main/frontend/components/page_menu.cljs

@@ -12,7 +12,6 @@
             [frontend.util :as util]
             [frontend.util :as util]
             [frontend.util.url :as url-util]
             [frontend.util.url :as url-util]
             [frontend.handler.shell :as shell]
             [frontend.handler.shell :as shell]
-            [frontend.handler.plugin :as plugin-handler]
             [frontend.mobile.util :as mobile-util]
             [frontend.mobile.util :as mobile-util]
             [electron.ipc :as ipc]
             [electron.ipc :as ipc]
             [frontend.config :as config]
             [frontend.config :as config]
@@ -152,7 +151,7 @@
                        (fn []
                        (fn []
                          (ipc/ipc "openFileBackupDir" (config/get-local-dir repo) file-path))}})
                          (ipc/ipc "openFileBackupDir" (config/get-local-dir repo) file-path))}})
 
 
-          (when plugin-handler/lsp-enabled?
+          (when config/lsp-enabled?
             (for [[_ {:keys [label] :as cmd} action pid] (state/get-plugins-commands-with-type :page-menu-item)]
             (for [[_ {:keys [label] :as cmd} action pid] (state/get-plugins-commands-with-type :page-menu-item)]
               {:title label
               {:title label
                :options {:on-click #(commands/exec-plugin-simple-command!
                :options {:on-click #(commands/exec-plugin-simple-command!

+ 7 - 6
src/main/frontend/components/plugins.cljs

@@ -5,7 +5,8 @@
             [frontend.context.i18n :refer [t]]
             [frontend.context.i18n :refer [t]]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.ui :as ui-handler]
-            [frontend.handler.plugin-config :as plugin-config]
+            [frontend.handler.plugin-config :as plugin-config-handler]
+            [frontend.handler.common.plugin :as plugin-common-handler]
             [frontend.search :as search]
             [frontend.search :as search]
             [frontend.util :as util]
             [frontend.util :as util]
             [frontend.mixins :as mixins]
             [frontend.mixins :as mixins]
@@ -199,7 +200,7 @@
     [:a.btn
     [:a.btn
      {:class    (util/classnames [{:disabled   (or installed? installing-or-updating?)
      {:class    (util/classnames [{:disabled   (or installed? installing-or-updating?)
                                    :installing installing-or-updating?}])
                                    :installing installing-or-updating?}])
-      :on-click #(plugin-handler/install-marketplace-plugin item)}
+      :on-click #(plugin-common-handler/install-marketplace-plugin item)}
      (if installed?
      (if installed?
        (t :plugin/installed)
        (t :plugin/installed)
        (if installing-or-updating?
        (if installing-or-updating?
@@ -224,8 +225,8 @@
                     {:title      (t :plugin/delete-alert name)
                     {:title      (t :plugin/delete-alert name)
                      :on-confirm (fn [_ {:keys [close-fn]}]
                      :on-confirm (fn [_ {:keys [close-fn]}]
                                    (close-fn)
                                    (close-fn)
-                                   (plugin-handler/unregister-plugin id)
-                                   (plugin-config/remove-plugin id))})]
+                                   (plugin-common-handler/unregister-plugin id)
+                                   (plugin-config-handler/remove-plugin id))})]
                (state/set-sub-modal! confirm-fn {:center? true}))}
                (state/set-sub-modal! confirm-fn {:center? true}))}
        (t :plugin/uninstall)]]]
        (t :plugin/uninstall)]]]
 
 
@@ -548,7 +549,7 @@
                  :options {:on-click #(state/pub-event! [:go/proxy-settings agent-opts])}}]
                  :options {:on-click #(state/pub-event! [:go/proxy-settings agent-opts])}}]
 
 
                [{:title   [:span.flex.items-center (ui/icon "arrow-down-circle") (t :plugin/install-from-file)]
                [{:title   [:span.flex.items-center (ui/icon "arrow-down-circle") (t :plugin/install-from-file)]
-                 :options {:on-click plugin-config/open-sync-modal}}]
+                 :options {:on-click plugin-config-handler/open-sync-modal}}]
 
 
                (when (state/developer-mode?)
                (when (state/developer-mode?)
                  [{:hr true}
                  [{:hr true}
@@ -822,7 +823,7 @@
       [:div.pt-5
       [:div.pt-5
        (ui/button [:span "Install"]
        (ui/button [:span "Install"]
                   :on-click #(do
                   :on-click #(do
-                               (plugin-config/update-plugins plugins)
+                               (plugin-config-handler/replace-plugins plugins)
                                (state/close-sub-modal! "ls-plugins-from-file-modal")))]]
                                (state/close-sub-modal! "ls-plugins-from-file-modal")))]]
      ;; all done
      ;; all done
      [:div.py-4 [:strong.text-xl "\uD83C\uDF89 All synced!"]])])
      [:div.py-4 [:strong.text-xl "\uD83C\uDF89 All synced!"]])])

+ 1 - 1
src/main/frontend/components/settings.cljs

@@ -726,7 +726,7 @@
   (let [current-repo (state/sub :git/current-repo)
   (let [current-repo (state/sub :git/current-repo)
         ;; enable-block-timestamps? (state/enable-block-timestamps?)
         ;; enable-block-timestamps? (state/enable-block-timestamps?)
         _installed-plugins (state/sub :plugin/installed-plugins)
         _installed-plugins (state/sub :plugin/installed-plugins)
-        plugins-of-settings (and plugin-handler/lsp-enabled? (seq (plugin-handler/get-enabled-plugins-if-setting-schema)))
+        plugins-of-settings (and config/lsp-enabled? (seq (plugin-handler/get-enabled-plugins-if-setting-schema)))
         *active (::active state)]
         *active (::active state)]
 
 
     [:div#settings.cp__settings-main
     [:div#settings.cp__settings-main

+ 7 - 3
src/main/frontend/components/theme.cljs

@@ -1,7 +1,8 @@
 (ns frontend.components.theme
 (ns frontend.components.theme
   (:require [frontend.extensions.pdf.highlights :as pdf]
   (:require [frontend.extensions.pdf.highlights :as pdf]
             [frontend.config :as config]
             [frontend.config :as config]
-            [frontend.handler.plugin :refer [lsp-enabled?] :as plugin-handler]
+            [frontend.handler.plugin :as plugin-handler]
+            [frontend.handler.plugin-config :as plugin-config-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
@@ -41,9 +42,12 @@
      [sidebar-open? restored-sidebar? sidebar-blocks-len])
      [sidebar-open? restored-sidebar? sidebar-blocks-len])
 
 
     (rum/use-effect!
     (rum/use-effect!
-     #(when lsp-enabled?
+     #(when config/lsp-enabled?
         (plugin-handler/setup-install-listener!)
         (plugin-handler/setup-install-listener!)
-        (plugin-handler/load-plugin-preferences))
+        (plugin-config-handler/setup-install-listener!)
+        (plugin-handler/load-plugin-preferences)
+        (fn []
+          (js/window.apis.removeAllListeners "lsp-installed")))
      [])
      [])
 
 
     (rum/use-effect!
     (rum/use-effect!

+ 17 - 5
src/main/frontend/config.cljs

@@ -35,16 +35,32 @@
       (def API-DOMAIN "api-dev.logseq.com")
       (def API-DOMAIN "api-dev.logseq.com")
       (def WS-URL "wss://ws-dev.logseq.com/file-sync?graphuuid=%s")))
       (def WS-URL "wss://ws-dev.logseq.com/file-sync?graphuuid=%s")))
 
 
-;; feature flags
+;; Feature flags
+;; =============
 
 
 (goog-define ENABLE-PLUGINS true)
 (goog-define ENABLE-PLUGINS true)
 (defonce enable-plugins? ENABLE-PLUGINS)
 (defonce enable-plugins? ENABLE-PLUGINS)
 
 
 (swap! state/state assoc :plugin/enabled enable-plugins?)
 (swap! state/state assoc :plugin/enabled enable-plugins?)
 
 
+;; Desktop only as other platforms requires better understanding of their
+;; multi-graph workflows and optimal place for a "global" dir
+(def global-config-enabled? util/electron?)
+
+;; User level configuration for whether plugins are enabled
+(defonce lsp-enabled?
+         (and (util/electron?)
+              (state/lsp-enabled?-or-theme)))
+
+(defn plugin-config-enabled?
+  []
+  (and lsp-enabled? (global-config-enabled?)))
+
 ;; :TODO: How to do this?
 ;; :TODO: How to do this?
 ;; (defonce desktop? ^boolean goog.DESKTOP)
 ;; (defonce desktop? ^boolean goog.DESKTOP)
 
 
+;; ============
+
 (def app-name "logseq")
 (def app-name "logseq")
 (def website
 (def website
   (if dev?
   (if dev?
@@ -289,10 +305,6 @@
 
 
 (def config-default-content (rc/inline "config.edn"))
 (def config-default-content (rc/inline "config.edn"))
 
 
-;; Desktop only as other platforms requires better understanding of their
-;; multi-graph workflows and optimal place for a "global" dir
-(def global-config-enabled? util/electron?)
-
 (defonce idb-db-prefix "logseq-db/")
 (defonce idb-db-prefix "logseq-db/")
 (defonce local-db-prefix "logseq_local_")
 (defonce local-db-prefix "logseq_local_")
 (defonce local-handle "handle")
 (defonce local-handle "handle")

+ 2 - 2
src/main/frontend/extensions/latex.cljs

@@ -4,7 +4,7 @@
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.config :as config]
             [frontend.config :as config]
             [frontend.util :as util]
             [frontend.util :as util]
-            [frontend.handler.plugin :refer [lsp-enabled? hook-extensions-enhancer-by-type] :as plugin-handler]
+            [frontend.handler.plugin :refer [hook-extensions-enhancer-by-type] :as plugin-handler]
             [promesa.core :as p]
             [promesa.core :as p]
             [goog.dom :as gdom]))
             [goog.dom :as gdom]))
 
 
@@ -42,7 +42,7 @@
           (config/asset-uri "/static/js/mhchem.min.js")
           (config/asset-uri "/static/js/mhchem.min.js")
           (fn []
           (fn []
             (p/finally
             (p/finally
-              (p/all (when-let [enhancers (and lsp-enabled? (seq (hook-extensions-enhancer-by-type :katex)))]
+              (p/all (when-let [enhancers (and config/lsp-enabled? (seq (hook-extensions-enhancer-by-type :katex)))]
                        (for [{f :enhancer} enhancers]
                        (for [{f :enhancer} enhancers]
                          (when (fn? f) (f js/window.katex)))))
                          (when (fn? f) (f js/window.katex)))))
               (fn []
               (fn []

+ 2 - 2
src/main/frontend/extensions/pdf/highlights.cljs

@@ -7,7 +7,7 @@
             [frontend.extensions.pdf.utils :as pdf-utils]
             [frontend.extensions.pdf.utils :as pdf-utils]
             [frontend.extensions.pdf.toolbar :refer [pdf-toolbar *area-dashed? *area-mode? *highlight-mode? *highlights-ctx*]]
             [frontend.extensions.pdf.toolbar :refer [pdf-toolbar *area-dashed? *area-mode? *highlight-mode? *highlights-ctx*]]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
-            [frontend.handler.plugin :as plugin-handler]
+            [frontend.config :as config]
             [frontend.modules.shortcut.core :as shortcut]
             [frontend.modules.shortcut.core :as shortcut]
             [frontend.commands :as commands]
             [frontend.commands :as commands]
             [frontend.rum :refer [use-atom]]
             [frontend.rum :refer [use-atom]]
@@ -193,7 +193,7 @@
 
 
      (and id [:li.item {:data-action "del"} (t :delete)])
      (and id [:li.item {:data-action "del"} (t :delete)])
 
 
-     (when (and plugin-handler/lsp-enabled? text?)
+     (when (and config/lsp-enabled? text?)
        (for [[_ {:keys [key label extras] :as _cmd} action pid]
        (for [[_ {:keys [key label extras] :as _cmd} action pid]
              (state/get-plugins-commands-with-type :highlight-context-menu-item)]
              (state/get-plugins-commands-with-type :highlight-context-menu-item)]
          [:li.item {:key         key
          [:li.item {:key         key

+ 2 - 3
src/main/frontend/handler.cljs

@@ -28,7 +28,7 @@
             [frontend.handler.user :as user-handler]
             [frontend.handler.user :as user-handler]
             [frontend.handler.repo-config :as repo-config-handler]
             [frontend.handler.repo-config :as repo-config-handler]
             [frontend.handler.global-config :as global-config-handler]
             [frontend.handler.global-config :as global-config-handler]
-            [frontend.handler.plugin-config :as plugin-config]
+            [frontend.handler.plugin-config :as plugin-config-handler]
             [frontend.handler.metadata :as metadata-handler]
             [frontend.handler.metadata :as metadata-handler]
             [frontend.idb :as idb]
             [frontend.idb :as idb]
             [frontend.mobile.util :as mobile-util]
             [frontend.mobile.util :as mobile-util]
@@ -93,8 +93,7 @@
             (p/do! (repo-config-handler/start {:repo repo})
             (p/do! (repo-config-handler/start {:repo repo})
                    (when (config/global-config-enabled?)
                    (when (config/global-config-enabled?)
                      (global-config-handler/start {:repo repo}))
                      (global-config-handler/start {:repo repo}))
-                   ;; TODO: Is there a better place for this setup?
-                   (plugin-config/start))
+                   (when (config/plugin-config-enabled?) (plugin-config-handler/start)))
             (p/finally
             (p/finally
               (fn []
               (fn []
                 ;; install after config is restored
                 ;; install after config is restored

+ 27 - 0
src/main/frontend/handler/common/plugin.cljs

@@ -0,0 +1,27 @@
+(ns frontend.handler.common.plugin
+  "Common plugin related fns for handlers and api"
+  (:require [frontend.state :as state]
+            [promesa.core :as p]
+            [electron.ipc :as ipc]))
+
+(defn installed?
+  "For the given plugin id, returns boolean indicating if it is installed"
+  [id]
+  (and (contains? (:plugin/installed-plugins @state/state) (keyword id))
+       (get-in @state/state [:plugin/installed-plugins (keyword id) :iir])))
+
+(defn install-marketplace-plugin
+  "Installs plugin given plugin map with id"
+  [{:keys [id] :as mft}]
+  (when-not (and (:plugin/installing @state/state)
+                 (installed? id))
+    (p/create
+     (fn [resolve]
+       (state/set-state! :plugin/installing mft)
+       (ipc/ipc :installMarketPlugin mft)
+       (resolve id)))))
+
+(defn unregister-plugin
+  "Unregister and uninstall plugin given plugin id"
+  [id]
+  (js/LSPluginCore.unregister id))

+ 8 - 38
src/main/frontend/handler/plugin.cljs

@@ -6,7 +6,7 @@
             [clojure.walk :as walk]
             [clojure.walk :as walk]
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
-            [frontend.handler.plugin-config :as plugin-config]
+            [frontend.handler.common.plugin :as plugin-common-handler]
             [camel-snake-kebab.core :as csk]
             [camel-snake-kebab.core :as csk]
             [frontend.state :as state]
             [frontend.state :as state]
             [medley.core :as medley]
             [medley.core :as medley]
@@ -17,12 +17,9 @@
             [lambdaisland.glogi :as log]
             [lambdaisland.glogi :as log]
             [frontend.components.svg :as svg]
             [frontend.components.svg :as svg]
             [frontend.context.i18n :refer [t]]
             [frontend.context.i18n :refer [t]]
+            [frontend.config :as config]
             [frontend.format :as format]))
             [frontend.format :as format]))
 
 
-(defonce lsp-enabled?
-         (and (util/electron?)
-              (state/lsp-enabled?-or-theme)))
-
 (defn- normalize-keyword-for-json
 (defn- normalize-keyword-for-json
   [input]
   [input]
   (when input
   (when input
@@ -112,25 +109,10 @@
             (util/fetch stats-url on-ok reject)))))
             (util/fetch stats-url on-ok reject)))))
     (p/resolved nil)))
     (p/resolved nil)))
 
 
-(defn installed?
-  [id]
-  (and (contains? (:plugin/installed-plugins @state/state) (keyword id))
-       (get-in @state/state [:plugin/installed-plugins (keyword id) :iir])))
-
-(defn install-marketplace-plugin
-  [{:keys [id] :as mft}]
-  (when-not (and (:plugin/installing @state/state)
-                 (installed? id))
-    (p/create
-      (fn [resolve]
-        (state/set-state! :plugin/installing mft)
-        (ipc/ipc :installMarketPlugin mft)
-        (resolve id)))))
-
 (defn check-or-update-marketplace-plugin
 (defn check-or-update-marketplace-plugin
   [{:keys [id] :as pkg} error-handler]
   [{:keys [id] :as pkg} error-handler]
   (when-not (and (:plugin/installing @state/state)
   (when-not (and (:plugin/installing @state/state)
-                 (not (installed? id)))
+                 (not (plugin-common-handler/installed? id)))
     (p/catch
     (p/catch
       (p/then
       (p/then
         (do (state/set-state! :plugin/installing pkg)
         (do (state/set-state! :plugin/installing pkg)
@@ -198,7 +180,7 @@
                              name (or title name "Untitled")]
                              name (or title name "Untitled")]
                          (if only-check
                          (if only-check
                            (state/consume-updates-coming-plugin payload false)
                            (state/consume-updates-coming-plugin payload false)
-                           (if (installed? id)
+                           (if (plugin-common-handler/installed? id)
                              (when-let [^js pl (get-plugin-inst id)] ;; update
                              (when-let [^js pl (get-plugin-inst id)] ;; update
                                (p/then
                                (p/then
                                 (.reload pl)
                                 (.reload pl)
@@ -212,10 +194,6 @@
                                (p/then
                                (p/then
                                 (js/LSPluginCore.register (bean/->js {:key id :url dst}))
                                 (js/LSPluginCore.register (bean/->js {:key id :url dst}))
                                 (fn [] (when theme (js/setTimeout #(select-a-plugin-theme id) 300))))
                                 (fn [] (when theme (js/setTimeout #(select-a-plugin-theme id) 300))))
-                               (plugin-config/add-or-update-plugin
-                                (assoc payload
-                                       :version (:installed-version payload)
-                                       :name name))
                                (notification/show!
                                (notification/show!
                                 (str (t :plugin/installed) (t :plugins) ": " name) :success)))))
                                 (str (t :plugin/installed) (t :plugins) ": " name) :success)))))
 
 
@@ -252,23 +230,15 @@
                    (js/setTimeout #(state/set-state! :plugin/installing nil) 512)
                    (js/setTimeout #(state/set-state! :plugin/installing nil) 512)
                    true)]
                    true)]
 
 
-    (js/window.apis.addListener channel listener)
-
-    ;; clear
-    (fn []
-      (js/window.apis.removeAllListeners channel))))
+    (js/window.apis.addListener channel listener)))
 
 
 (defn register-plugin
 (defn register-plugin
   [pl]
   [pl]
   (swap! state/state update-in [:plugin/installed-plugins] assoc (keyword (:id pl)) pl))
   (swap! state/state update-in [:plugin/installed-plugins] assoc (keyword (:id pl)) pl))
 
 
-(defn unregister-plugin
-  [id]
-  (js/LSPluginCore.unregister id))
-
 (defn host-mounted!
 (defn host-mounted!
   []
   []
-  (and lsp-enabled? (js/LSPluginCore.hostMounted)))
+  (and config/lsp-enabled? (js/LSPluginCore.hostMounted)))
 
 
 (defn register-plugin-slash-command
 (defn register-plugin-slash-command
   [pid [cmd actions]]
   [pid [cmd actions]]
@@ -469,7 +439,7 @@
 
 
 (defn hook-plugin
 (defn hook-plugin
   [tag type payload plugin-id]
   [tag type payload plugin-id]
-  (when lsp-enabled?
+  (when config/lsp-enabled?
     (try
     (try
       (js-invoke js/LSPluginCore
       (js-invoke js/LSPluginCore
                  (str "hook" (string/capitalize (name tag)))
                  (str "hook" (string/capitalize (name tag)))
@@ -706,6 +676,6 @@
 (defn setup!
 (defn setup!
   "setup plugin core handler"
   "setup plugin core handler"
   [callback]
   [callback]
-  (if (not lsp-enabled?)
+  (if (not config/lsp-enabled?)
     (callback)
     (callback)
     (init-plugins! callback)))
     (init-plugins! callback)))

+ 41 - 30
src/main/frontend/handler/plugin_config.cljs

@@ -1,6 +1,7 @@
 (ns frontend.handler.plugin-config
 (ns frontend.handler.plugin-config
-  "This ns is a system component that encapsulate the global plugin.edn.
-This component depends on TODO"
+  "This system component encapsulates the global plugin.edn and depends on the
+  global-config component. This component is only enabled? if both the
+  global-config and plugin components are enabled"
   (:require [frontend.handler.global-config :as global-config-handler]
   (:require [frontend.handler.global-config :as global-config-handler]
             ["path" :as path]
             ["path" :as path]
             [promesa.core :as p]
             [promesa.core :as p]
@@ -8,24 +9,26 @@ This component depends on TODO"
             [frontend.fs :as fs]
             [frontend.fs :as fs]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
-            [electron.ipc :as ipc]
+            [frontend.handler.common.plugin :as plugin-common-handler]
             [clojure.edn :as edn]
             [clojure.edn :as edn]
             [clojure.set :as set]
             [clojure.set :as set]
             [clojure.pprint :as pprint]
             [clojure.pprint :as pprint]
             [malli.core :as m]
             [malli.core :as m]
             [malli.error :as me]
             [malli.error :as me]
             [frontend.schema.handler.plugin-config :as plugin-config-schema]
             [frontend.schema.handler.plugin-config :as plugin-config-schema]
+            [cljs-bean.core :as bean]
             [lambdaisland.glogi :as log]))
             [lambdaisland.glogi :as log]))
 
 
-(defn- plugin-config-path
+(defn plugin-config-path
   []
   []
-  (path/join @global-config-handler/root-dir "plugins.edn"))
+  (path/join (global-config-handler/global-config-dir) "plugins.edn"))
 
 
 (def common-plugin-keys
 (def common-plugin-keys
   "Vec of plugin keys to store in plugins.edn and to compare with installed-plugins state"
   "Vec of plugin keys to store in plugins.edn and to compare with installed-plugins state"
   (->> plugin-config-schema/Plugin rest (mapv first)))
   (->> plugin-config-schema/Plugin rest (mapv first)))
 
 
 (defn add-or-update-plugin
 (defn add-or-update-plugin
+  "Adds or updates a plugin from plugin.edn"
   [{:keys [id] :as plugin}]
   [{:keys [id] :as plugin}]
   (p/let [content (fs/read-file "" (plugin-config-path))
   (p/let [content (fs/read-file "" (plugin-config-path))
           updated-content (-> content
           updated-content (-> content
@@ -37,6 +40,7 @@ This component depends on TODO"
          (fs/write-file! nil "" (plugin-config-path) updated-content {:skip-compare? true})))
          (fs/write-file! nil "" (plugin-config-path) updated-content {:skip-compare? true})))
 
 
 (defn remove-plugin
 (defn remove-plugin
+  "Removes a plugin from plugin.edn"
   [plugin-id]
   [plugin-id]
   (p/let [content (fs/read-file "" (plugin-config-path))
   (p/let [content (fs/read-file "" (plugin-config-path))
           updated-content (-> content rewrite/parse-string (rewrite/dissoc (keyword plugin-id)) str)]
           updated-content (-> content rewrite/parse-string (rewrite/dissoc (keyword plugin-id)) str)]
@@ -54,13 +58,18 @@ This component depends on TODO"
   "Given installed plugins state and plugins from plugins.edn,
   "Given installed plugins state and plugins from plugins.edn,
 returns map of plugins to install and uninstall"
 returns map of plugins to install and uninstall"
   [installed-plugins edn-plugins]
   [installed-plugins edn-plugins]
+  ;; :name is removed from comparison because it isn't used for reproducible builds
+  ;; and is just for display purposes
   (let [installed-plugins-set (->> installed-plugins
   (let [installed-plugins-set (->> installed-plugins
                                    vals
                                    vals
-                                   (map #(assoc (select-keys % common-plugin-keys)
-                                                :id (keyword (:id %))))
+                                   (map #(-> (select-keys % common-plugin-keys)
+                                             (assoc :id (keyword (:id %)))
+                                             (dissoc :name)))
                                    set)
                                    set)
         edn-plugins-set (->> edn-plugins
         edn-plugins-set (->> edn-plugins
-                             (map (fn [[k v]] (assoc v :id k)))
+                             (map (fn [[k v]] (-> v
+                                                  (assoc :id k)
+                                                  (dissoc :name))))
                              set)]
                              set)]
     (if (= installed-plugins-set edn-plugins-set)
     (if (= installed-plugins-set edn-plugins-set)
       {}
       {}
@@ -89,34 +98,36 @@ returns map of plugins to install and uninstall"
                            :error)
                            :error)
        (log/error :unexpected-error e)))))
        (log/error :unexpected-error e)))))
 
 
-;; TODO: Extract from handler.plugin
-(defn installed?
-  [id]
-  (and (contains? (:plugin/installed-plugins @state/state) (keyword id))
-       (get-in @state/state [:plugin/installed-plugins (keyword id) :iir])))
-
-(defn install-marketplace-plugin
-  [{:keys [id] :as mft}]
-  ; (prn :IN {:k1 (:plugin/installing @state/state)
-  ;           :k2 (installed? id)})
-  ;; TODO:
-  (when-not (and (:plugin/installing @state/state)
-                 (installed? id))
-    (p/create
-     (fn [resolve]
-       (state/set-state! :plugin/installing mft)
-       (ipc/ipc :installMarketPlugin mft)
-       (resolve id)))))
-
-(defn update-plugins
+(defn replace-plugins
+  "Replaces current plugins given plugins to install and uninstall"
   [plugins]
   [plugins]
   (log/info :uninstall-plugins (:uninstall plugins))
   (log/info :uninstall-plugins (:uninstall plugins))
   (doseq [plugin (:uninstall plugins)]
   (doseq [plugin (:uninstall plugins)]
-    (js/LSPluginCore.unregister (name (:id plugin))))
+    (plugin-common-handler/unregister-plugin (name (:id plugin))))
   (log/info :install-plugins (:install plugins))
   (log/info :install-plugins (:install plugins))
   (doseq [plugin (:install plugins)]
   (doseq [plugin (:install plugins)]
-    (install-marketplace-plugin plugin)))
+    (plugin-common-handler/install-marketplace-plugin plugin)))
+
+(defn setup-install-listener!
+  "Sets up a listener for the lsp-installed event to update plugins.edn"
+  []
+  (let [listener (fn listener [_ e]
+                   (when-let [{:keys [status payload only-check]} (bean/->clj e)]
+                     (when (and (= status "completed") (not only-check))
+                       (let [{:keys [name title theme]} payload
+                             ;; Same defaults as plugin/setup-install-listener!
+                             name (or title name "Untitled")]
+                         (add-or-update-plugin
+                          (assoc payload
+                                 :version (:installed-version payload)
+                                 ;; Manual install doesn't have theme field but
+                                 ;; plugin.edn requires this field
+                                 :theme (if (some? theme) theme false)
+                                 :name name))))))]
+    (js/window.apis.addListener "lsp-installed" listener)))
 
 
 (defn start
 (defn start
+  "This component has just one reponsibility on start, to create a plugins.edn
+  if none exists"
   []
   []
   (create-plugin-config-file-if-not-exists))
   (create-plugin-config-file-if-not-exists))

+ 5 - 4
src/main/frontend/modules/shortcut/config.cljs

@@ -14,12 +14,13 @@
             [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.export :as export-handler]
             [frontend.handler.export :as export-handler]
             [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.handler.whiteboard :as whiteboard-handler]
-            [frontend.handler.plugin-config :as plugin-config]
+            [frontend.handler.plugin-config :as plugin-config-handler]
             [frontend.modules.shortcut.dicts :as dicts]
             [frontend.modules.shortcut.dicts :as dicts]
             [frontend.modules.shortcut.before :as m]
             [frontend.modules.shortcut.before :as m]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.util :refer [mac?] :as util]
             [frontend.util :refer [mac?] :as util]
             [frontend.commands :as commands]
             [frontend.commands :as commands]
+            [frontend.config :as config]
             [electron.ipc :as ipc]
             [electron.ipc :as ipc]
             [promesa.core :as p]
             [promesa.core :as p]
             [clojure.data :as data]
             [clojure.data :as data]
@@ -406,13 +407,13 @@
                                      :fn      plugin-handler/show-themes-modal!}
                                      :fn      plugin-handler/show-themes-modal!}
 
 
    :ui/goto-plugins                 {:binding "t p"
    :ui/goto-plugins                 {:binding "t p"
-                                     :inactive (not plugin-handler/lsp-enabled?)
+                                     :inactive (not config/lsp-enabled?)
                                      :fn      plugin-handler/goto-plugins-dashboard!}
                                      :fn      plugin-handler/goto-plugins-dashboard!}
 
 
    :ui/install-plugins-from-file    {:binding false
    :ui/install-plugins-from-file    {:binding false
-                                     :inactive (not plugin-handler/lsp-enabled?)
+                                     :inactive (not (config/plugin-config-enabled?))
                                      ;; TODO: Remove dev convenience
                                      ;; TODO: Remove dev convenience
-                                     :fn      (fn [] (plugin-config/open-sync-modal))}
+                                     :fn      (fn [] (plugin-config-handler/open-sync-modal))}
 
 
    :editor/toggle-open-blocks       {:binding "t o"
    :editor/toggle-open-blocks       {:binding "t o"
                                      :fn      editor-handler/toggle-open!}
                                      :fn      editor-handler/toggle-open!}

+ 3 - 3
src/main/frontend/ui.cljs

@@ -12,6 +12,7 @@
             [datascript.core :as d]
             [datascript.core :as d]
             [electron.ipc :as ipc]
             [electron.ipc :as ipc]
             [frontend.components.svg :as svg]
             [frontend.components.svg :as svg]
+            [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.context.i18n :refer [t]]
             [frontend.db-mixins :as db-mixins]
             [frontend.db-mixins :as db-mixins]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
@@ -32,7 +33,6 @@
             [goog.object :as gobj]
             [goog.object :as gobj]
             [lambdaisland.glogi :as log]
             [lambdaisland.glogi :as log]
             [medley.core :as medley]
             [medley.core :as medley]
-            [frontend.config :as config]
             [promesa.core :as p]
             [promesa.core :as p]
             [rum.core :as rum]))
             [rum.core :as rum]))
 
 
@@ -361,7 +361,7 @@
       style)))
       style)))
 
 
 (defn apply-custom-theme-effect! [theme]
 (defn apply-custom-theme-effect! [theme]
-  (when plugin-handler/lsp-enabled?
+  (when config/lsp-enabled?
     (when-let [custom-theme (state/sub [:ui/custom-theme (keyword theme)])]
     (when-let [custom-theme (state/sub [:ui/custom-theme (keyword theme)])]
       (when-let [url (:url custom-theme)]
       (when-let [url (:url custom-theme)]
         (js/LSPluginCore.selectTheme (bean/->js custom-theme)
         (js/LSPluginCore.selectTheme (bean/->js custom-theme)
@@ -939,7 +939,7 @@
                            (when (:class opts)
                            (when (:class opts)
                              (str " " (string/trim (:class opts)))))
                              (str " " (string/trim (:class opts)))))
                       (if extension? "tie tie" "ti ti"))}
                       (if extension? "tie tie" "ti ti"))}
-                    (dissoc opts :class :extension?))]
+                    (dissoc opts :class :extension? :font?))]
 
 
          ;; tabler svg react
          ;; tabler svg react
          (when-let [klass (gobj/get js/tablerIcons (str "Icon" (csk/->PascalCase class)))]
          (when-let [klass (gobj/get js/tablerIcons (str "Icon" (csk/->PascalCase class)))]

+ 2 - 1
src/main/logseq/api.cljs

@@ -21,6 +21,7 @@
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
             [frontend.handler.page :as page-handler]
             [frontend.handler.page :as page-handler]
             [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.plugin :as plugin-handler]
+            [frontend.handler.common.plugin :as plugin-common-handler]
             [frontend.modules.outliner.core :as outliner]
             [frontend.modules.outliner.core :as outliner]
             [frontend.modules.outliner.tree :as outliner-tree]
             [frontend.modules.outliner.tree :as outliner-tree]
             [frontend.handler.command-palette :as palette-handler]
             [frontend.handler.command-palette :as palette-handler]
@@ -776,7 +777,7 @@
     (when-let [{:keys [repo id] :as mft} (bean/->clj manifest)]
     (when-let [{:keys [repo id] :as mft} (bean/->clj manifest)]
       (if-not (and repo id)
       (if-not (and repo id)
         (throw (js/Error. "[required] :repo :id"))
         (throw (js/Error. "[required] :repo :id"))
-        (plugin-handler/install-marketplace-plugin mft)))))
+        (plugin-common-handler/install-marketplace-plugin mft)))))
 
 
 ;; db
 ;; db
 (defn ^:export q
 (defn ^:export q

+ 44 - 51
src/test/frontend/handler/plugin_config_test.cljs

@@ -2,7 +2,7 @@
   (:require [clojure.test :refer [is use-fixtures testing deftest]]
   (:require [clojure.test :refer [is use-fixtures testing deftest]]
             [frontend.test.helper :as test-helper :include-macros true :refer [deftest-async]]
             [frontend.test.helper :as test-helper :include-macros true :refer [deftest-async]]
             [frontend.test.fixtures :as fixtures]
             [frontend.test.fixtures :as fixtures]
-            [frontend.handler.plugin-config :as plugin-config]
+            [frontend.handler.plugin-config :as plugin-config-handler]
             [frontend.handler.global-config :as global-config-handler]
             [frontend.handler.global-config :as global-config-handler]
             [frontend.schema.handler.plugin-config :as plugin-config-schema]
             [frontend.schema.handler.plugin-config :as plugin-config-schema]
             ["fs" :as fs-node]
             ["fs" :as fs-node]
@@ -15,88 +15,81 @@
 
 
 (use-fixtures :once fixtures/redef-get-fs)
 (use-fixtures :once fixtures/redef-get-fs)
 
 
+(defn- create-global-config-dir
+  []
+  (let [dir (test-helper/create-tmp-dir "config")
+        root-dir (path/dirname dir)]
+    (reset! global-config-handler/root-dir root-dir)
+    dir))
+
+(defn- delete-global-config-dir
+  [config-dir]
+  (doseq [relative-file (fs-node/readdirSync config-dir)]
+    (fs-node/unlinkSync (path/join config-dir relative-file)))
+  (reset! global-config-handler/root-dir nil)
+  (fs-node/rmdirSync config-dir)
+  (fs-node/rmdirSync (path/dirname config-dir)))
+
 (deftest-async add-or-update-plugin
 (deftest-async add-or-update-plugin
-  (let [dir (test-helper/create-tmp-dir)
-        plugins-file (path/join dir "plugins.edn")
+  (let [dir (create-global-config-dir)
         plugin-to-add {:id :foo :name "Foo" :repo "some-user/foo" :version "v0.9.0"}
         plugin-to-add {:id :foo :name "Foo" :repo "some-user/foo" :version "v0.9.0"}
         body (pr-str (mg/generate plugin-config-schema/Plugins-edn {:size 10}))]
         body (pr-str (mg/generate plugin-config-schema/Plugins-edn {:size 10}))]
-    (fs-node/writeFileSync plugins-file body)
-    (reset! global-config-handler/root-dir dir)
+    (fs-node/writeFileSync (plugin-config-handler/plugin-config-path) body)
 
 
     (->
     (->
      (p/do!
      (p/do!
-      (plugin-config/add-or-update-plugin plugin-to-add)
+      (plugin-config-handler/add-or-update-plugin plugin-to-add)
       (is (= (dissoc plugin-to-add :id)
       (is (= (dissoc plugin-to-add :id)
-             (:foo (edn/read-string (str (fs-node/readFileSync plugins-file)))))))
+             (:foo (edn/read-string (str (fs-node/readFileSync (plugin-config-handler/plugin-config-path))))))))
 
 
-     (.finally
-      (fn []
-        (reset! global-config-handler/root-dir nil)
-        (fs-node/unlinkSync plugins-file)
-        (fs-node/rmdirSync dir))))))
+     (p/finally #(delete-global-config-dir dir)))))
 
 
 (deftest-async remove-plugin
 (deftest-async remove-plugin
-  (let [dir (test-helper/create-tmp-dir)
-        plugins-file (path/join dir "plugins.edn")
+  (let [dir (create-global-config-dir)
         ;; use seed to consistently generate 5 plugins
         ;; use seed to consistently generate 5 plugins
         ;; if we want more randomness we could look into gen/such-that
         ;; if we want more randomness we could look into gen/such-that
         plugins (mg/generate plugin-config-schema/Plugins-edn {:size 5 :seed 1})
         plugins (mg/generate plugin-config-schema/Plugins-edn {:size 5 :seed 1})
         some-plugin-id (first (keys plugins))]
         some-plugin-id (first (keys plugins))]
-    (fs-node/writeFileSync plugins-file (pr-str plugins))
-    (reset! global-config-handler/root-dir dir)
+    (fs-node/writeFileSync (plugin-config-handler/plugin-config-path) (pr-str plugins))
 
 
     (->
     (->
      (p/do!
      (p/do!
-      (plugin-config/remove-plugin some-plugin-id)
+      (plugin-config-handler/remove-plugin some-plugin-id)
       (is (= nil
       (is (= nil
-             (get (edn/read-string (str (fs-node/readFileSync plugins-file)))
+             (get (edn/read-string (str (fs-node/readFileSync (plugin-config-handler/plugin-config-path))))
                   some-plugin-id))))
                   some-plugin-id))))
 
 
-     (.finally
-      (fn []
-        (reset! global-config-handler/root-dir nil)
-        (fs-node/unlinkSync plugins-file)
-        (fs-node/rmdirSync dir))))))
+     (p/finally #(delete-global-config-dir dir)))))
 
 
 (deftest-async open-sync-modal-malformed-edn
 (deftest-async open-sync-modal-malformed-edn
-  (let [dir (test-helper/create-tmp-dir)
-        plugins-file (path/join dir "plugins.edn")
+  (let [dir (create-global-config-dir)
         error-message (atom nil)]
         error-message (atom nil)]
-    (fs-node/writeFileSync plugins-file "{:id {}")
-    (reset! global-config-handler/root-dir dir)
+    (fs-node/writeFileSync (plugin-config-handler/plugin-config-path) "{:id {}")
 
 
     (test-helper/with-reset reset
     (test-helper/with-reset reset
       [notification/show! (fn [msg _] (reset! error-message msg))]
       [notification/show! (fn [msg _] (reset! error-message msg))]
       (->
       (->
        (p/do!
        (p/do!
-        (plugin-config/open-sync-modal)
+        (plugin-config-handler/open-sync-modal)
         (is (string/starts-with? @error-message "Malformed plugins.edn")
         (is (string/starts-with? @error-message "Malformed plugins.edn")
             "User sees correct notification"))
             "User sees correct notification"))
-       (p/finally (fn []
-                    (reset)
-                    (reset! global-config-handler/root-dir nil)
-                    (fs-node/unlinkSync plugins-file)
-                    (fs-node/rmdirSync dir)))))))
+       (p/finally #(delete-global-config-dir dir))))))
 
 
 (deftest-async open-sync-modal-invalid-edn
 (deftest-async open-sync-modal-invalid-edn
-  (let [dir (test-helper/create-tmp-dir)
-        plugins-file (path/join dir "plugins.edn")
+  (let [dir (create-global-config-dir)
         error-message (atom nil)]
         error-message (atom nil)]
     ;; Missing a couple plugin keys
     ;; Missing a couple plugin keys
-    (fs-node/writeFileSync plugins-file (pr-str {:id {:theme true :repo "user/repo"}}))
-    (reset! global-config-handler/root-dir dir)
+    (fs-node/writeFileSync (plugin-config-handler/plugin-config-path)
+                           (pr-str {:id {:theme true :repo "user/repo"}}))
 
 
     (test-helper/with-reset reset
     (test-helper/with-reset reset
       [notification/show! (fn [msg _] (reset! error-message msg))]
       [notification/show! (fn [msg _] (reset! error-message msg))]
       (->
       (->
        (p/do!
        (p/do!
-        (plugin-config/open-sync-modal)
+        (plugin-config-handler/open-sync-modal)
         (is (string/starts-with? @error-message "Invalid plugins.edn")
         (is (string/starts-with? @error-message "Invalid plugins.edn")
             "User sees correct notification"))
             "User sees correct notification"))
-       (p/finally (fn []
-                    (reset)
-                    (fs-node/unlinkSync plugins-file)
-                    (fs-node/rmdirSync dir)))))))
+       (p/finally #(delete-global-config-dir dir))))))
 
 
 (defn- installed-plugins->edn-plugins
 (defn- installed-plugins->edn-plugins
   "Converts installed plugins state to edn.plugins format"
   "Converts installed plugins state to edn.plugins format"
@@ -107,26 +100,26 @@
 ;; install and uninstall
 ;; install and uninstall
 (deftest determine-plugins-to-change
 (deftest determine-plugins-to-change
   (testing "no changes to make"
   (testing "no changes to make"
-    (let [plugins {:foo {:id :foo :name "Foo" :repo "some-user/foo" :version "v0.9.0"}
-                   :bar {:id :bar :name "Bar" :repo "some-user/bar" :version "v0.1.0"}}]
-      (is (= {} (#'plugin-config/determine-plugins-to-change
+    (let [plugins {:foo {:id :foo :repo "some-user/foo" :version "v0.9.0"}
+                   :bar {:id :bar :repo "some-user/bar" :version "v0.1.0"}}]
+      (is (= {} (#'plugin-config-handler/determine-plugins-to-change
                   plugins
                   plugins
                   (installed-plugins->edn-plugins plugins))))))
                   (installed-plugins->edn-plugins plugins))))))
 
 
   (testing "differing versions are uninstalled and installed"
   (testing "differing versions are uninstalled and installed"
-    (let [plugins {:bar {:id :bar :name "Bar" :repo "some-user/bar" :version "v0.1.0"}}]
+    (let [plugins {:bar {:id :bar :repo "some-user/bar" :version "v0.1.0"}}]
       (is (= {:uninstall [(:bar plugins)]
       (is (= {:uninstall [(:bar plugins)]
               :install [(assoc (:bar plugins) :version "v1.0.0" :plugin-action "install")]}
               :install [(assoc (:bar plugins) :version "v1.0.0" :plugin-action "install")]}
-             (#'plugin-config/determine-plugins-to-change
+             (#'plugin-config-handler/determine-plugins-to-change
                plugins
                plugins
                (installed-plugins->edn-plugins (assoc-in plugins [:bar :version] "v1.0.0")))))))
                (installed-plugins->edn-plugins (assoc-in plugins [:bar :version] "v1.0.0")))))))
 
 
   (testing "replaced plugins are uninstalled and new plugins are installed"
   (testing "replaced plugins are uninstalled and new plugins are installed"
-    (let [plugins {:foo {:id :foo :name "Foo" :repo "some-user/foo" :version "v0.9.0"}
-                   :bar {:id :bar :name "Bar" :repo "some-user/bar" :version "v0.1.0"}}
-          new-plugin {:id :baz :name "Baz" :repo "some-user/baz" :version "v0.5.0"}]
+    (let [plugins {:foo {:id :foo :repo "some-user/foo" :version "v0.9.0"}
+                   :bar {:id :bar :repo "some-user/bar" :version "v0.1.0"}}
+          new-plugin {:id :baz :repo "some-user/baz" :version "v0.5.0"}]
       (is (= {:uninstall [(:foo plugins)]
       (is (= {:uninstall [(:foo plugins)]
               :install [(assoc new-plugin :plugin-action "install")]}
               :install [(assoc new-plugin :plugin-action "install")]}
-             (#'plugin-config/determine-plugins-to-change
+             (#'plugin-config-handler/determine-plugins-to-change
                plugins
                plugins
                (-> plugins (dissoc :foo) (assoc :baz new-plugin) installed-plugins->edn-plugins)))))))
                (-> plugins (dissoc :foo) (assoc :baz new-plugin) installed-plugins->edn-plugins)))))))

+ 3 - 2
src/test/frontend/handler/repo_conversion_test.cljs

@@ -121,8 +121,9 @@
         ;; only test file name parsing, don't consider title prop overriding
         ;; only test file name parsing, don't consider title prop overriding
         rename-target (:target (#'conversion-handler/calc-rename-target-impl :legacy :triple-lowbar original-body nil))]
         rename-target (:target (#'conversion-handler/calc-rename-target-impl :legacy :triple-lowbar original-body nil))]
     (if rename-target
     (if rename-target
-      (do (prn "conversion triple-lowbar: " original-body " -> " rename-target)
-          (#'page-handler/compute-new-file-path path rename-target))
+      #_:clj-kondo/ignore
+      (do #_(prn "conversion triple-lowbar: " original-body " -> " rename-target)
+        (#'page-handler/compute-new-file-path path rename-target))
       path)))
       path)))
 
 
 (defn- convert-graph-files-path
 (defn- convert-graph-files-path

+ 13 - 3
src/test/frontend/test/helper.cljs

@@ -16,6 +16,8 @@
   (conn/destroy-all!))
   (conn/destroy-all!))
 
 
 (defn load-test-files
 (defn load-test-files
+  "Given a collection of file maps, loads them into the current test-db.
+This can be called in synchronous contexts as no async fns should be invoked"
   [files]
   [files]
   (repo-handler/parse-files-and-load-to-db!
   (repo-handler/parse-files-and-load-to-db!
    test-db
    test-db
@@ -24,6 +26,14 @@
    {:re-render? false :verbose false :refresh? true}))
    {:re-render? false :verbose false :refresh? true}))
 
 
 (defn create-tmp-dir
 (defn create-tmp-dir
-  []
-  (when-not (fs-node/existsSync "tmp") (fs-node/mkdirSync "tmp"))
-  (fs-node/mkdtempSync (path/join "tmp" "unit-test-")))
+  "Creates a temporary directory under tmp/. If a subdir is given, creates an
+  additional subdirectory under the newly created temp directory."
+  ([] (create-tmp-dir nil))
+  ([subdir]
+   (when-not (fs-node/existsSync "tmp") (fs-node/mkdirSync "tmp"))
+   (let [dir (fs-node/mkdtempSync (path/join "tmp" "unit-test-"))]
+     (if subdir
+       (do
+         (fs-node/mkdirSync (path/join dir subdir))
+         (path/join dir subdir))
+       dir))))