Преглед на файлове

fix: don't store broken config in DB (#8578)

* fix: don't store broken config in DB

Also, all configs should be clojure maps.

* fix: editor should show the corresponding file's content from disk
Tienson Qin преди 3 години
родител
ревизия
dcf9559094
променени са 3 файла, в които са добавени 99 реда и са изтрити 81 реда
  1. 40 18
      src/main/frontend/components/file.cljs
  2. 55 60
      src/main/frontend/handler/file.cljs
  3. 4 3
      src/main/frontend/state.cljs

+ 40 - 18
src/main/frontend/components/file.cljs

@@ -11,11 +11,15 @@
             [frontend.handler.export :as export-handler]
             [frontend.handler.export :as export-handler]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.util :as util]
             [frontend.util :as util]
+            [frontend.fs :as fs]
+            [frontend.config :as config]
+            [frontend.ui :as ui]
             [logseq.graph-parser.config :as gp-config]
             [logseq.graph-parser.config :as gp-config]
             [logseq.graph-parser.util :as gp-util]
             [logseq.graph-parser.util :as gp-util]
             [goog.object :as gobj]
             [goog.object :as gobj]
             [reitit.frontend.easy :as rfe]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]))
+            [rum.core :as rum]
+            [promesa.core :as p]))
 
 
 (defn- get-path
 (defn- get-path
   [state]
   [state]
@@ -66,18 +70,25 @@
    (files-all)
    (files-all)
    ])
    ])
 
 
-(rum/defcs file < rum/reactive
-  {:did-mount (fn [state]
+(rum/defcs file-inner < rum/reactive
+  {:will-mount (fn [state]
+                 (let [*content (atom nil)
+                       [path format] (:rum/args state)]
+                   (when (and format (contains? (gp-config/text-formats) format))
+                     (p/let [content (fs/read-file
+                                      (config/get-repo-dir (state/get-current-repo)) path)]
+                       (reset! *content content)))
+                   (assoc state ::file-content *content)))
+   :did-mount (fn [state]
                 (state/set-file-component! (:rum/react-component state))
                 (state/set-file-component! (:rum/react-component state))
                 state)
                 state)
    :will-unmount (fn [state]
    :will-unmount (fn [state]
                    (state/clear-file-component!)
                    (state/clear-file-component!)
                    state)}
                    state)}
-  [state]
-  (let [path (get-path state)
-        format (gp-util/get-format path)
-        original-name (db/get-file-page path)
-        random-id (str (d/squuid))]
+  [state path format]
+  (let [original-name (db/get-file-page path)
+        random-id (str (d/squuid))
+        content (rum/react (::file-content state))]
     [:div.file {:id (str "file-edit-wrapper-" random-id)
     [:div.file {:id (str "file-edit-wrapper-" random-id)
                 :key path}
                 :key path}
      [:h1.title
      [:h1.title
@@ -107,16 +118,27 @@
        (and format (contains? (gp-config/img-formats) format))
        (and format (contains? (gp-config/img-formats) format))
        [:img {:src (util/node-path.join "file://" path)}]
        [:img {:src (util/node-path.join "file://" path)}]
 
 
-       (and format (contains? (gp-config/text-formats) format))
-       (when-let [file-content (or (db/get-file path) "")]
-         (let [content (string/trim file-content)
-               mode (util/get-file-ext path)]
-            (lazy-editor/editor {:file?     true
-                                 :file-path path}
-                                (str "file-edit-" random-id)
-                                {:data-lang mode}
-                                content
-                               {})))
+       (and format
+            (contains? (gp-config/text-formats) format)
+            content)
+       (let [content' (string/trim content)
+             mode (util/get-file-ext path)]
+         (lazy-editor/editor {:file?     true
+                              :file-path path}
+                             (str "file-edit-" random-id)
+                             {:data-lang mode}
+                             content'
+                             {}))
+
+       (and format
+            (contains? (gp-config/text-formats) format))
+       (ui/loading "Loading ...")
 
 
        :else
        :else
        [:div (t :file/format-not-supported (name format))])]))
        [:div (t :file/format-not-supported (name format))])]))
+
+(rum/defcs file
+  [state]
+  (let [path (get-path state)
+        format (gp-util/get-format path)]
+    (rum/with-key (file-inner path format) path)))

+ 55 - 60
src/main/frontend/handler/file.cljs

@@ -21,6 +21,7 @@
             [promesa.core :as p]
             [promesa.core :as p]
             [frontend.mobile.util :as mobile-util]
             [frontend.mobile.util :as mobile-util]
             [logseq.graph-parser.config :as gp-config]
             [logseq.graph-parser.config :as gp-config]
+            [clojure.string :as string]
             ["path" :as path]))
             ["path" :as path]))
 
 
 ;; TODO: extract all git ops using a channel
 ;; TODO: extract all git ops using a channel
@@ -104,8 +105,7 @@
     :else
     :else
     true))
     true))
 
 
-(defn- validate-and-write-file
-  "Validates and if valid writes file. Returns boolean indicating if file content was valid"
+(defn- write-file-aux!
   [repo path content write-file-options]
   [repo path content write-file-options]
   (let [original-content (db/get-file repo path)
   (let [original-content (db/get-file repo path)
         path-dir (if (and
         path-dir (if (and
@@ -117,12 +117,7 @@
                    (config/get-repo-dir repo))
                    (config/get-repo-dir repo))
         write-file-options' (merge write-file-options
         write-file-options' (merge write-file-options
                                    (when original-content {:old-content original-content}))]
                                    (when original-content {:old-content original-content}))]
-    (p/do!
-     (if (validate-file repo path content)
-       (do
-         (fs/write-file! repo path-dir path content write-file-options')
-         true)
-       false))))
+    (fs/write-file! repo path-dir path content write-file-options')))
 
 
 ;; TODO: Remove this function in favor of `alter-files`
 ;; TODO: Remove this function in favor of `alter-files`
 (defn alter-file
 (defn alter-file
@@ -133,58 +128,58 @@
                            from-disk? false
                            from-disk? false
                            skip-compare? false}}]
                            skip-compare? false}}]
   (let [path (gp-util/path-normalize path)
   (let [path (gp-util/path-normalize path)
-        write-file! (if from-disk?
-                      #(p/promise (validate-file repo path content))
-                      #(validate-and-write-file repo path content {:skip-compare? skip-compare?}))
-        opts {:new-graph? new-graph?
-              :from-disk? from-disk?
-              :skip-db-transact? skip-db-transact?}
-        result (if reset?
-                 (do
-                   (when-not skip-db-transact?
-                     (when-let [page-id (db/get-file-page-id path)]
-                       (db/transact! repo
-                                     [[:db/retract page-id :block/alias]
-                                      [:db/retract page-id :block/tags]]
-                                     opts)))
-                   (file-common-handler/reset-file! repo path content (merge opts
-                                                                             (when (some? verbose) {:verbose verbose}))))
-                 (db/set-file-content! repo path content opts))]
-    (util/p-handle (write-file!)
-                   (fn [valid-result?]
-                     (when re-render-root? (ui-handler/re-render-root!))
-
-                     (cond
-                       (= path (config/get-custom-css-path repo))
-                       (ui-handler/add-style-if-exists!)
-
-                       (and (= path (config/get-repo-config-path repo))
-                            valid-result?)
-                       (p/let [_ (repo-config-handler/restore-repo-config! repo content)]
-                              (state/pub-event! [:shortcut/refresh]))
-
-                       (and (config/global-config-enabled?)
-                            (= path (global-config-handler/global-config-path))
-                            valid-result?)
-                       (p/let [_ (global-config-handler/restore-global-config!)]
-                              (state/pub-event! [:shortcut/refresh]))))
-                   (fn [error]
-                     (when (and (config/global-config-enabled?)
-                                ;; Global-config not started correctly but don't
-                                ;; know root cause yet
-                                ;; https://sentry.io/organizations/logseq/issues/3587411237/events/4b5da8b8e58b4f929bd9e43562213d32/events/?cursor=0%3A0%3A1&project=5311485&statsPeriod=14d
-                                (global-config-handler/global-config-dir-exists?)
-                                (= path (global-config-handler/global-config-path)))
-                       (state/pub-event! [:notification/show
-                                          {:content (str "Failed to write to file " path)
-                                           :status :error}]))
-
-                     (println "Write file failed, path: " path ", content: " content)
-                     (log/error :write/failed error)
-                     (state/pub-event! [:capture-error
-                                        {:error error
-                                         :payload {:type :write-file/failed-for-alter-file}}])))
-    result))
+        config-file? (string/ends-with? path config/config-file)
+        config-valid? (and config-file? (validate-file repo path content))]
+    (when-not (and config-file? (not config-valid?)) ; non-config file or valid config
+      (let [opts {:new-graph? new-graph?
+                  :from-disk? from-disk?
+                  :skip-db-transact? skip-db-transact?}
+            result (if reset?
+                     (do
+                       (when-not skip-db-transact?
+                         (when-let [page-id (db/get-file-page-id path)]
+                           (db/transact! repo
+                             [[:db/retract page-id :block/alias]
+                              [:db/retract page-id :block/tags]]
+                             opts)))
+                       (file-common-handler/reset-file!
+                        repo path content (merge opts
+                                                 (when (some? verbose) {:verbose verbose}))))
+                     (db/set-file-content! repo path content opts))]
+        (-> (p/let [_ (when-not from-disk?
+                        (write-file-aux! repo path content {:skip-compare? skip-compare?}))]
+              (when re-render-root? (ui-handler/re-render-root!))
+
+              (cond
+                (= path (config/get-custom-css-path repo))
+                (ui-handler/add-style-if-exists!)
+
+                (= path (config/get-repo-config-path repo))
+                (p/let [_ (repo-config-handler/restore-repo-config! repo content)]
+                  (state/pub-event! [:shortcut/refresh]))
+
+                (and (config/global-config-enabled?)
+                     (= path (global-config-handler/global-config-path)))
+                (p/let [_ (global-config-handler/restore-global-config!)]
+                  (state/pub-event! [:shortcut/refresh]))))
+            (p/catch
+                (fn [error]
+                  (when (and (config/global-config-enabled?)
+                             ;; Global-config not started correctly but don't
+                             ;; know root cause yet
+                             ;; https://sentry.io/organizations/logseq/issues/3587411237/events/4b5da8b8e58b4f929bd9e43562213d32/events/?cursor=0%3A0%3A1&project=5311485&statsPeriod=14d
+                             (global-config-handler/global-config-dir-exists?)
+                             (= path (global-config-handler/global-config-path)))
+                    (state/pub-event! [:notification/show
+                                       {:content (str "Failed to write to file " path)
+                                        :status :error}]))
+
+                  (println "Write file failed, path: " path ", content: " content)
+                  (log/error :write/failed error)
+                  (state/pub-event! [:capture-error
+                                     {:error error
+                                      :payload {:type :write-file/failed-for-alter-file}}]))))
+        result))))
 
 
 (defn set-file-content!
 (defn set-file-content!
   [repo path new-content]
   [repo path new-content]

+ 4 - 3
src/main/frontend/state.cljs

@@ -324,12 +324,13 @@
   "Merges user configs in given orders. All values are overridden except for maps
   "Merges user configs in given orders. All values are overridden except for maps
   which are merged."
   which are merged."
   [& configs]
   [& configs]
-  (apply merge-with
+  (->> configs
+       (filter map?)
+       (apply merge-with
          (fn merge-config [current new]
          (fn merge-config [current new]
            (if (and (map? current) (map? new))
            (if (and (map? current) (map? new))
              (merge current new)
              (merge current new)
-             new))
-         configs))
+             new)))))
 
 
 (defn get-config
 (defn get-config
   "User config for the given repo or current repo if none given. All config fetching
   "User config for the given repo or current repo if none given. All config fetching