Sfoglia il codice sorgente

fix: editing global config.edn and export.css in desktop app

Only enable export.css for desktop since it doesn't work
for browser and db graphs. Also remove a related and
unused db-graph? flag
Gabriel Horner 4 giorni fa
parent
commit
94d3b9eecc

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

@@ -619,7 +619,7 @@
      (when (config/global-config-enabled?) (edit-global-config-edn))
      (when current-repo (edit-config-edn))
      (when current-repo (edit-custom-css))
-     (when current-repo (edit-export-css))]))
+     (when (and current-repo (util/electron?)) (edit-export-css))]))
 
 (rum/defcs settings-editor < rum/reactive
   [_state]

+ 15 - 0
src/main/frontend/fs.cljs

@@ -3,6 +3,7 @@
   platforms by delegating to implementations of the fs protocol"
   (:require [cljs-bean.core :as bean]
             [clojure.string :as string]
+            [electron.ipc :as ipc]
             [frontend.fs.memory-fs :as memory-fs]
             [frontend.fs.node :as node]
             [frontend.fs.protocol :as protocol]
@@ -98,6 +99,20 @@
                   ;; (js/alert "Current file can't be saved! Please copy its content to your local file system and click the refresh button.")
                   ))))))
 
+(defn write-file!
+  "A node only version of write-plain-text-file! to avoid using the fs-protocol
+   which has file graph assumptions"
+  [path content]
+  (when (util/electron?)
+    (let [file-fpath (common-util/path-normalize path)]
+      ;; repo is nil because we don't want a backup file written
+      (-> (ipc/ipc "writeFile" nil file-fpath content)
+          (p/catch (fn [error]
+                     (state/pub-event! [:capture-error {:error error
+                                                        :payload {:type :write-file/failed
+                                                                  :user-agent (when js/navigator js/navigator.userAgent)
+                                                                  :content-length (count content)}}])))))))
+
 ;; read-file should return string on all platforms
 (defn read-file
   ([dir path]

+ 1 - 0
src/main/frontend/fs/node.cljs

@@ -29,6 +29,7 @@
            (error-handler error)
            (log/error :write-file-failed error))))
 
+      ;; TODO: Remove backupDbFile which is a file graph concept
       (p/let [disk-content (when (not= stat :not-found)
                              (-> (ipc/ipc "readFile" file-fpath)
                                  (p/then bean/->clj)

+ 19 - 1
src/main/frontend/handler/code.cljs

@@ -2,12 +2,30 @@
   "Codemirror editor related."
   (:require [clojure.string :as string]
             [frontend.db :as db]
+            [frontend.fs :as fs]
             [frontend.handler.db-based.editor :as db-editor-handler]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.global-config :as global-config-handler]
             [frontend.state :as state]
+            [frontend.util :as util]
             [goog.object :as gobj]
+            [logseq.common.path :as path]
             [logseq.graph-parser.utf8 :as utf8]))
 
+(defn- save-file! [path content]
+  (if (db/entity [:file/path path])
+    ;; This fn assumes path is is already in db
+    (db-editor-handler/save-file! path content)
+    (when (util/electron?)
+      (if (path/absolute? path)
+        (do
+          ;; Set global state first in case it's invalid edn
+          (when (= path (global-config-handler/global-config-path))
+            (global-config-handler/set-global-config-state! content)
+            (state/pub-event! [:shortcut/refresh]))
+          (fs/write-file! path content))
+        (js/console.error "Saving relative file ignored" path content)))))
+
 (defn save-code-editor!
   []
   (let [{:keys [config state editor]} (get @state/state :editor/code-block-context)]
@@ -42,7 +60,7 @@
               (editor-handler/save-block-if-changed! block new-content))
 
             (not-empty (:file-path config))
-            (db-editor-handler/save-file! (:file-path config) value)
+            (save-file! (:file-path config) value)
 
             :else
             nil))))))

+ 3 - 5
src/main/frontend/handler/common/config_edn.cljs

@@ -89,17 +89,15 @@ nested keys or positional errors e.g. tuples"
 
 (defn detect-deprecations
   "Detects config keys that will or have been deprecated"
-  [path content {:keys [db-graph?]}]
+  [path content]
   (let [body (try (edn/read-string content)
                   (catch :default _ ::failed-to-detect))
-        warnings (cond->
+        warnings (merge
                   {:editor/command-trigger
                    "is no longer supported. Please use '/' and report bugs on it."
                    :arweave/gateway
                    "is no longer supported."}
-                   db-graph?
-                   (merge
-                    common-config/file-only-config))]
+                  common-config/file-only-config)]
     (cond
       (= body ::failed-to-detect)
       (log/info :msg "Skip deprecation check since config is not valid edn")

+ 1 - 1
src/main/frontend/handler/db_based/editor.cljs

@@ -73,7 +73,7 @@
   "This fn is the db version of file-handler/alter-file"
   [path content]
   (let [file-valid? (if (= path "logseq/config.edn")
-                      (do (config-edn-common-handler/detect-deprecations path content {:db-graph? true})
+                      (do (config-edn-common-handler/detect-deprecations path content)
                           (config-edn-common-handler/validate-config-edn path content repo-config-schema/Config-edn))
                       true)]
 

+ 3 - 5
src/main/frontend/handler/global_config.cljs

@@ -63,16 +63,14 @@
                      (rewrite/dissoc result (first ks))
                      (rewrite/assoc-in result ks v))
         new-str-content (str new-result)]
-    (fs/write-plain-text-file! nil nil (global-config-path) new-str-content {:skip-compare? true})
+    (fs/write-file! (global-config-path) new-str-content)
     (state/set-global-config! (rewrite/sexpr new-result) new-str-content)))
 
 (defn start
-  "This component has four responsibilities on start:
+  "This component has three responsibilities on start:
 - Fetch root-dir for later use with config paths
 - Manage ui state of global config
-- Create a global config dir and file if it doesn't exist
-- Start a file watcher for global config dir if it's not already started.
-  Watcher ensures client db is seeded with correct file data."
+- Create a global config dir and file if it doesn't exist"
   [{:keys [repo]}]
   (-> (p/do!
        (p/let [root-dir' (ipc/ipc "getLogseqDotDirRoot")]

+ 6 - 8
src/main/frontend/handler/plugin_config.cljs

@@ -1,7 +1,7 @@
 (ns frontend.handler.plugin-config
   "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. plugin.edn is automatically updated
+  global-config and plugin components are enabled. plugins.edn is automatically updated
 when a plugin is installed, updated or removed"
   (:require [borkdude.rewrite-edn :as rewrite]
             [cljs-bean.core :as bean]
@@ -31,23 +31,21 @@ when a plugin is installed, updated or removed"
   (->> plugin-config-schema/Plugin rest (mapv first)))
 
 (defn add-or-update-plugin
-  "Adds or updates a plugin from plugin.edn"
+  "Adds or updates a plugin from plugins.edn"
   [{:keys [id] :as plugin}]
   (p/let [content (fs/read-file nil (plugin-config-path))
           updated-content (-> content
                               rewrite/parse-string
                               (rewrite/assoc (keyword id) (select-keys plugin common-plugin-keys))
                               str)]
-         ;; fs protocols require repo and dir when they aren't necessary. For this component,
-         ;; neither is needed so these are blank and nil respectively
-    (fs/write-plain-text-file! "" nil (plugin-config-path) updated-content {:skip-compare? true})))
+    (fs/write-file! (plugin-config-path) updated-content)))
 
 (defn remove-plugin
-  "Removes a plugin from plugin.edn"
+  "Removes a plugin from plugins.edn"
   [plugin-id]
-  (p/let [content (fs/read-file "" (plugin-config-path))
+  (p/let [content (fs/read-file nil (plugin-config-path))
           updated-content (-> content rewrite/parse-string (rewrite/dissoc (keyword plugin-id)) str)]
-    (fs/write-plain-text-file! "" nil (plugin-config-path) updated-content {:skip-compare? true})))
+    (fs/write-file! (plugin-config-path) updated-content)))
 
 (defn- create-plugin-config-file-if-not-exists
   []

+ 3 - 3
src/test/frontend/handler/common/config_edn_test.cljs

@@ -21,7 +21,7 @@
   (let [error-message (atom nil)]
     (with-redefs [notification/show! (fn [msg _] (reset! error-message msg))
                   rfe/href (constantly "")]
-      (config-edn-common-handler/detect-deprecations "config.edn" config-body {})
+      (config-edn-common-handler/detect-deprecations "config.edn" config-body)
       (str @error-message))))
 
 (deftest validate-config-edn
@@ -61,8 +61,8 @@
 (deftest detect-deprecations
   (is (re-find
        #":editor/command-trigger.*is"
-       (deprecation-warnings-for "{:preferred-workflow :todo :editor/command-trigger \",\"}"))
+       (deprecation-warnings-for "{:editor/command-trigger \",\"}"))
       "Warning when there is a deprecation")
 
-  (is (= "" (deprecation-warnings-for "{:preferred-workflow :todo}"))
+  (is (= "" (deprecation-warnings-for "{}"))
       "No warning when there is no deprecation"))

+ 29 - 24
src/test/frontend/handler/plugin_config_test.cljs

@@ -1,19 +1,22 @@
 (ns frontend.handler.plugin-config-test
-  (:require [clojure.test :refer [is use-fixtures testing deftest]]
-            [frontend.test.helper :as test-helper :include-macros true :refer [deftest-async]]
-            [frontend.test.node-helper :as test-node-helper]
-            [frontend.test.node-fixtures :as node-fixtures]
-            [frontend.handler.plugin-config :as plugin-config-handler]
-            [frontend.handler.global-config :as global-config-handler]
-            [frontend.schema.handler.plugin-config :as plugin-config-schema]
-            ["fs" :as fs-node]
+  (:require ["fs" :as fs-node]
+            ["fs/promises" :as fsp]
             ["path" :as node-path]
             [clojure.edn :as edn]
-            [malli.generator :as mg]
-            [promesa.core :as p]
             [clojure.string :as string]
-            [frontend.handler.notification :as notification]))
+            [clojure.test :refer [is use-fixtures testing deftest]]
+            [frontend.fs :as fs]
+            [frontend.handler.global-config :as global-config-handler]
+            [frontend.handler.notification :as notification]
+            [frontend.handler.plugin-config :as plugin-config-handler]
+            [frontend.schema.handler.plugin-config :as plugin-config-schema]
+            [frontend.test.helper :as test-helper :include-macros true :refer [deftest-async]]
+            [frontend.test.node-fixtures :as node-fixtures]
+            [frontend.test.node-helper :as test-node-helper]
+            [malli.generator :as mg]
+            [promesa.core :as p]))
 
+;; For tests that call fs/readFile
 (use-fixtures :once node-fixtures/redef-get-fs)
 
 (defn- create-global-config-dir
@@ -37,13 +40,14 @@
         body (pr-str (mg/generate plugin-config-schema/Plugins-edn {:size 10}))]
     (fs-node/writeFileSync (plugin-config-handler/plugin-config-path) body)
 
-    (->
-     (p/do!
-      (plugin-config-handler/add-or-update-plugin plugin-to-add)
-      (is (= (dissoc plugin-to-add :id)
-             (:foo (edn/read-string (str (fs-node/readFileSync (plugin-config-handler/plugin-config-path))))))))
+    (p/with-redefs [fs/write-file! fsp/writeFile]
+     (->
+      (p/do!
+       (plugin-config-handler/add-or-update-plugin plugin-to-add)
+       (is (= (dissoc plugin-to-add :id)
+              (:foo (edn/read-string (str (fs-node/readFileSync (plugin-config-handler/plugin-config-path))))))))
 
-     (p/finally #(delete-global-config-dir dir)))))
+      (p/finally #(delete-global-config-dir dir))))))
 
 (deftest-async remove-plugin
   (let [dir (create-global-config-dir)
@@ -53,14 +57,15 @@
         some-plugin-id (first (keys plugins))]
     (fs-node/writeFileSync (plugin-config-handler/plugin-config-path) (pr-str plugins))
 
-    (->
-     (p/do!
-      (plugin-config-handler/remove-plugin some-plugin-id)
-      (is (= nil
-             (get (edn/read-string (str (fs-node/readFileSync (plugin-config-handler/plugin-config-path))))
-                  some-plugin-id))))
+    (p/with-redefs [fs/write-file! fsp/writeFile]
+     (->
+      (p/do!
+       (plugin-config-handler/remove-plugin some-plugin-id)
+       (is (= nil
+              (get (edn/read-string (str (fs-node/readFileSync (plugin-config-handler/plugin-config-path))))
+                   some-plugin-id))))
 
-     (p/finally #(delete-global-config-dir dir)))))
+      (p/finally #(delete-global-config-dir dir))))))
 
 (deftest-async open-replace-plugins-modal-malformed-edn
   (let [dir (create-global-config-dir)