mirror of
https://github.com/penpot/penpot.git
synced 2026-05-30 04:08:08 +00:00
🐛 Fix migrations throwing exception on corrupted file (#9868)
This commit is contained in:
parent
eb095169b8
commit
34f30e38aa
@ -44,43 +44,55 @@
|
||||
breaks the subcopy-head? predicate, which expects nil. Remove the explicit false so the
|
||||
downstream fixers can recognize these shapes as nested copy heads."
|
||||
[file-data]
|
||||
(ctf/update-all-shapes
|
||||
file-data
|
||||
(fn [shape]
|
||||
(if (false? (:component-root shape))
|
||||
(do
|
||||
(log/warn :msg "Normalizing :component-root false on shape"
|
||||
:shape-id (:id shape)
|
||||
:shape-name (:name shape)
|
||||
:file-id (:id file-data))
|
||||
{:result :update :updated-shape (dissoc shape :component-root)})
|
||||
{:result :keep}))))
|
||||
(try
|
||||
(ctf/update-all-shapes
|
||||
file-data
|
||||
(fn [shape]
|
||||
(if (false? (:component-root shape))
|
||||
(do
|
||||
(log/warn :msg "Normalizing :component-root false on shape"
|
||||
:shape-id (:id shape)
|
||||
:shape-name (:name shape)
|
||||
:file-id (:id file-data))
|
||||
{:result :update :updated-shape (dissoc shape :component-root)})
|
||||
{:result :keep})))
|
||||
(catch #?(:clj Throwable :cljs :default) e
|
||||
(log/error :msg "Failed to normalize :component-root on shapes"
|
||||
:file-id (:id file-data)
|
||||
:cause e)
|
||||
file-data)))
|
||||
|
||||
(defn fix-missing-swap-slots
|
||||
"Locate shapes that have been swapped (i.e. their shape-ref does not point to the near match) but
|
||||
they don't have a swap slot. In this case, add one pointing to the near match."
|
||||
[file-data libraries]
|
||||
(ctf/update-all-shapes
|
||||
file-data
|
||||
(fn [shape]
|
||||
(if (ctk/subcopy-head? shape)
|
||||
(let [container (:container (meta shape))
|
||||
file {:id (:id file-data) :data file-data}
|
||||
near-match (ctf/find-near-match file container libraries shape :include-deleted? true :with-context? false)]
|
||||
(if (and (some? near-match)
|
||||
(not= (:shape-ref shape) (:id near-match))
|
||||
(nil? (ctk/get-swap-slot shape)))
|
||||
(let [updated-shape (ctk/set-swap-slot shape (:id near-match))]
|
||||
(log/warn :msg "Adding missing swap slot to shape"
|
||||
:shape-id (:id shape)
|
||||
:shape-name (:name shape)
|
||||
:swap-slot (:id near-match)
|
||||
:file-id (:id file)
|
||||
:container-id (:id container)
|
||||
:container-type (:type container))
|
||||
{:result :update :updated-shape updated-shape})
|
||||
{:result :keep}))
|
||||
{:result :keep}))))
|
||||
(try
|
||||
(ctf/update-all-shapes
|
||||
file-data
|
||||
(fn [shape]
|
||||
(if (ctk/subcopy-head? shape)
|
||||
(let [container (:container (meta shape))
|
||||
file {:id (:id file-data) :data file-data}
|
||||
near-match (ctf/find-near-match file container libraries shape :include-deleted? true :with-context? false)]
|
||||
(if (and (some? near-match)
|
||||
(not= (:shape-ref shape) (:id near-match))
|
||||
(nil? (ctk/get-swap-slot shape)))
|
||||
(let [updated-shape (ctk/set-swap-slot shape (:id near-match))]
|
||||
(log/warn :msg "Adding missing swap slot to shape"
|
||||
:shape-id (:id shape)
|
||||
:shape-name (:name shape)
|
||||
:swap-slot (:id near-match)
|
||||
:file-id (:id file)
|
||||
:container-id (:id container)
|
||||
:container-type (:type container))
|
||||
{:result :update :updated-shape updated-shape})
|
||||
{:result :keep}))
|
||||
{:result :keep})))
|
||||
(catch #?(:clj Throwable :cljs :default) e
|
||||
(log/error :msg "Failed to fix missing swap slots on shapes"
|
||||
:file-id (:id file-data)
|
||||
:cause e)
|
||||
file-data)))
|
||||
|
||||
(defn sync-component-id-with-ref-shape
|
||||
"Ensure that all copies heads have the same component id and file as the referenced shape.
|
||||
@ -88,40 +100,46 @@
|
||||
[file-data libraries]
|
||||
(letfn [(sync-one-iteration
|
||||
[file-data libraries]
|
||||
(ctf/update-all-shapes
|
||||
file-data
|
||||
(fn [shape]
|
||||
(if (and (ctk/subcopy-head? shape) (nil? (ctk/get-swap-slot shape)))
|
||||
(let [container (:container (meta shape))
|
||||
file {:id (:id file-data) :data file-data}
|
||||
ref-shape (ctf/find-ref-shape file container libraries shape {:include-deleted? true :with-context? true})]
|
||||
(if (and (some? ref-shape)
|
||||
(or (not= (:component-id shape) (:component-id ref-shape))
|
||||
(not= (:component-file shape) (:component-file ref-shape))))
|
||||
(let [shape' (cond-> shape
|
||||
(some? (:component-id ref-shape))
|
||||
(assoc :component-id (:component-id ref-shape))
|
||||
(try
|
||||
(ctf/update-all-shapes
|
||||
file-data
|
||||
(fn [shape]
|
||||
(if (and (ctk/subcopy-head? shape) (nil? (ctk/get-swap-slot shape)))
|
||||
(let [container (:container (meta shape))
|
||||
file {:id (:id file-data) :data file-data}
|
||||
ref-shape (ctf/find-ref-shape file container libraries shape {:include-deleted? true :with-context? true})]
|
||||
(if (and (some? ref-shape)
|
||||
(or (not= (:component-id shape) (:component-id ref-shape))
|
||||
(not= (:component-file shape) (:component-file ref-shape))))
|
||||
(let [shape' (cond-> shape
|
||||
(some? (:component-id ref-shape))
|
||||
(assoc :component-id (:component-id ref-shape))
|
||||
|
||||
(nil? (:component-id ref-shape))
|
||||
(dissoc :component-id)
|
||||
(nil? (:component-id ref-shape))
|
||||
(dissoc :component-id)
|
||||
|
||||
(some? (:component-file ref-shape))
|
||||
(assoc :component-file (:component-file ref-shape))
|
||||
(some? (:component-file ref-shape))
|
||||
(assoc :component-file (:component-file ref-shape))
|
||||
|
||||
(nil? (:component-file ref-shape))
|
||||
(dissoc :component-file))]
|
||||
(log/warn :msg "Syncing component id and file with ref shape"
|
||||
:shape-id (:id shape)
|
||||
:shape-name (:name shape)
|
||||
:component-id (:component-id shape')
|
||||
:component-file (:component-file shape')
|
||||
:ref-shape-id (:id ref-shape)
|
||||
:file-id (:id file)
|
||||
:container-id (:id container)
|
||||
:container-type (:type container))
|
||||
{:result :update :updated-shape shape'})
|
||||
{:result :keep}))
|
||||
{:result :keep}))))]
|
||||
(nil? (:component-file ref-shape))
|
||||
(dissoc :component-file))]
|
||||
(log/warn :msg "Syncing component id and file with ref shape"
|
||||
:shape-id (:id shape)
|
||||
:shape-name (:name shape)
|
||||
:component-id (:component-id shape')
|
||||
:component-file (:component-file shape')
|
||||
:ref-shape-id (:id ref-shape)
|
||||
:file-id (:id file)
|
||||
:container-id (:id container)
|
||||
:container-type (:type container))
|
||||
{:result :update :updated-shape shape'})
|
||||
{:result :keep}))
|
||||
{:result :keep})))
|
||||
(catch #?(:clj Throwable :cljs :default) e
|
||||
(log/error :msg "Failed to sync component id and file with ref shape"
|
||||
:file-id (:id file-data)
|
||||
:cause e)
|
||||
file-data)))]
|
||||
;; If a copy inside a main is updated, we need to repeat the process for the change to be
|
||||
;; propagated to all copies.
|
||||
(loop [current-data file-data
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user