0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 07:50:43 -05:00

🔧 Add optional validation to check missing swap slots

This commit is contained in:
Andrés Moya 2024-05-28 13:55:38 +02:00
parent b8bff31aca
commit 3e8c665b7f
2 changed files with 60 additions and 1 deletions

View file

@ -460,6 +460,21 @@
(pcb/with-library-data file-data)
(pcb/update-component (:id shape) repair-component))))
(defmethod repair-error :missing-slot
[_ {:keys [shape page-id args] :as error} file-data _]
(let [repair-shape
(fn [shape]
;; Set the desired swap slot
(let [slot (:swap-slot args)]
(when (some? slot)
(log/debug :hint (str " -> set swap-slot to " slot))
(update shape :touched cfh/set-touched-group (ctk/build-swap-slot-group slot)))))]
(log/dbg :hint "repairing shape :missing-slot" :id (:id shape) :name (:name shape) :page-id page-id)
(-> (pcb/empty-changes nil page-id)
(pcb/with-file-data file-data)
(pcb/update-shapes [(:id shape)] repair-shape))))
(defmethod repair-error :default
[_ error file _]
(log/error :hint "Unknown error code, don't know how to repair" :code (:code error))

View file

@ -6,6 +6,7 @@
(ns app.common.files.validate
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.files.helpers :as cfh]
@ -50,7 +51,8 @@
:not-head-copy-not-allowed
:not-component-not-allowed
:component-nil-objects-not-allowed
:instance-head-not-frame})
:instance-head-not-frame
:missing-slot})
(def ^:private
schema:error
@ -454,6 +456,8 @@
;; PUBLIC API: VALIDATION FUNCTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare check-swap-slots)
(defn validate-file
"Validate full referential integrity and semantic coherence on file data.
@ -464,6 +468,8 @@
(doseq [page (filter :id (ctpl/pages-seq data))]
(check-shape uuid/zero file page libraries)
(when (str/includes? (:name file) "check-swap-slot")
(check-swap-slots uuid/zero file page libraries))
(->> (get-orphan-shapes page)
(run! #(check-shape % file page libraries))))
@ -517,3 +523,41 @@
:hint "error on validating file referential integrity"
:file-id (:id file)
:details errors)))
(declare compare-slots)
;; Optional check to look for missing swap slots.
;; Search for copies that do not point the shape-ref to the near component but don't have swap slot
;; (looking for position relative to the parent, in the copy and the main).
;;
;; This check cannot be generally enabled, because files that have been migrated from components v1
;; may have copies with shapes that do not match by position, but have not been swapped. So we enable
;; it for specific files only. To activate the check, you need to add the string "check-swap-slot" to
;; the name of the file.
(defn- check-swap-slots
[shape-id file page libraries]
(let [shape (ctst/get-shape page shape-id)]
(if (and (ctk/instance-root? shape) (ctk/in-component-copy? shape))
(let [ref-shape (ctf/find-ref-shape file page libraries shape :include-deleted? true :with-context? true)
container (:container (meta ref-shape))]
(when (some? ref-shape)
(compare-slots shape ref-shape file page container)))
(doall (for [child-id (:shapes shape)]
(check-swap-slots child-id file page libraries))))))
(defn- compare-slots
[shape-copy shape-main file container-copy container-main]
(if (and (not= (:shape-ref shape-copy) (:id shape-main))
(nil? (ctk/get-swap-slot shape-copy)))
(report-error :missing-slot
"Shape has been swapped, should have swap slot"
shape-copy file container-copy
:swap-slot (or (ctk/get-swap-slot shape-main) (:id shape-main)))
(when (nil? (ctk/get-swap-slot shape-copy))
(let [children-id-pairs (d/zip-all (:shapes shape-copy) (:shapes shape-main))]
(doall (for [[child-copy-id child-main-id] children-id-pairs]
(let [child-copy (ctst/get-shape container-copy child-copy-id)
child-main (ctst/get-shape container-main child-main-id)]
(when (and (some? child-copy) (some? child-main))
(compare-slots child-copy child-main file container-copy container-main)))))))))