|
|
@@ -1,11 +1,13 @@
|
|
|
(ns frontend.handler.common.config-edn
|
|
|
"Common fns related to config.edn - global and repo"
|
|
|
- (:require [clojure.edn :as edn]
|
|
|
- [clojure.string :as string :refer [includes?]]
|
|
|
+ (:require [malli.error :as me]
|
|
|
+ [malli.core :as m]
|
|
|
+ [clojure.string :as string]
|
|
|
+ [clojure.edn :as edn]
|
|
|
+ [lambdaisland.glogi :as log]
|
|
|
[frontend.handler.notification :as notification]
|
|
|
[goog.string :as gstring]
|
|
|
- [malli.core :as m]
|
|
|
- [malli.error :as me]))
|
|
|
+ [reitit.frontend.easy :as rfe]))
|
|
|
|
|
|
(defn- humanize-more
|
|
|
"Make error maps from me/humanize more readable for users. Doesn't try to handle
|
|
|
@@ -19,18 +21,34 @@ nested keys or positional errors e.g. tuples"
|
|
|
[k (->> v flatten (remove nil?) first)]))
|
|
|
errors))
|
|
|
|
|
|
+(defn- file-link
|
|
|
+ [path]
|
|
|
+ [:a {:href (rfe/href :file {:path path})} path])
|
|
|
+
|
|
|
+(defn- error-list
|
|
|
+ [errors class]
|
|
|
+ (map (fn [[k v]]
|
|
|
+ [:dl.my-2.mb-0
|
|
|
+ [:dt.m-0 [:strong (str k)]]
|
|
|
+ [:dd {:class class} v]]) errors))
|
|
|
+
|
|
|
+(defn config-notification-show!
|
|
|
+ ([title body]
|
|
|
+ (config-notification-show! title body :error))
|
|
|
+ ([title body status]
|
|
|
+ (config-notification-show! title body status true))
|
|
|
+ ([title body status clear?]
|
|
|
+ (notification/show!
|
|
|
+ [:.mb-2
|
|
|
+ [:.text-lg.mb-2 title]
|
|
|
+ body] status clear?)))
|
|
|
+
|
|
|
(defn- validate-config-map
|
|
|
[m schema path]
|
|
|
(if-let [errors (->> m (m/explain schema) me/humanize)]
|
|
|
(do
|
|
|
- (notification/show! (gstring/format "The file '%s' has the following errors:\n%s"
|
|
|
- path
|
|
|
- (->> errors
|
|
|
- humanize-more
|
|
|
- (map (fn [[k v]]
|
|
|
- (str k " - " v)))
|
|
|
- (string/join "\n")))
|
|
|
- :error)
|
|
|
+ (config-notification-show! [:<> "The file " (file-link path) " has the following errors:"]
|
|
|
+ (error-list (humanize-more errors) "text-error"))
|
|
|
false)
|
|
|
true))
|
|
|
|
|
|
@@ -47,7 +65,7 @@ nested keys or positional errors e.g. tuples"
|
|
|
(cond
|
|
|
(nil? parsed-body)
|
|
|
true
|
|
|
- (and failed? (includes? (second parsed-body) "duplicate key"))
|
|
|
+ (and failed? (string/includes? (second parsed-body) "duplicate key"))
|
|
|
(do
|
|
|
(notification/show! (gstring/format "The file '%s' has duplicate keys. The key '%s' is assigned multiple times."
|
|
|
path, (subs (second parsed-body) 36))
|
|
|
@@ -56,18 +74,35 @@ nested keys or positional errors e.g. tuples"
|
|
|
|
|
|
failed?
|
|
|
(do
|
|
|
-
|
|
|
- (notification/show! (gstring/format "Failed to read file '%s'. Make sure your config is wrapped
|
|
|
-in {}. Also make sure that the characters '( { [' have their corresponding closing character ') } ]'."
|
|
|
- path)
|
|
|
- :error)
|
|
|
- false)
|
|
|
+ (config-notification-show! [:<> "Failed to read file " (file-link path)]
|
|
|
+ "Make sure your config is wrapped in {}. Also make sure that the characters '( { [' have their corresponding closing character ') } ]'.")
|
|
|
+ false)
|
|
|
;; Custom error message is better than malli's "invalid type" error
|
|
|
(not (map? parsed-body))
|
|
|
(do
|
|
|
- (notification/show! (gstring/format "The file '%s' is not valid. Make sure the config is wrapped in {}."
|
|
|
- path)
|
|
|
- :error)
|
|
|
+ (config-notification-show! [:<> "The file " (file-link path) " s not valid."]
|
|
|
+ "Make sure the config is wrapped in {}.")
|
|
|
false)
|
|
|
:else
|
|
|
(validate-config-map parsed-body schema path))))
|
|
|
+
|
|
|
+(defn detect-deprecations
|
|
|
+ "Detects config keys that will or have been deprecated"
|
|
|
+ [path content]
|
|
|
+ (let [body (try (edn/read-string content)
|
|
|
+ (catch :default _ ::failed-to-detect))
|
|
|
+ warnings {:editor/command-trigger
|
|
|
+ "Will no longer be supported soon. Please use '/' and report bugs on it."}]
|
|
|
+ (cond
|
|
|
+ (= body ::failed-to-detect)
|
|
|
+ (log/info :msg "Skip deprecation check since config is not valid edn")
|
|
|
+
|
|
|
+ (not (map? body))
|
|
|
+ (log/info :msg "Skip deprecation check since config is not a map")
|
|
|
+
|
|
|
+ :else
|
|
|
+ (when-let [deprecations (seq (keep #(when (body (key %)) %) warnings))]
|
|
|
+ (config-notification-show! [:<> "The file " (file-link path) " has the following deprecations:"]
|
|
|
+ (error-list deprecations "text-warning")
|
|
|
+ :warning
|
|
|
+ false)))))
|