Enhance instance metadata and reconciliation logic for glob-ignored children

- Added `globIgnoredChildren` to `ApiInstanceMetadata` to manage child deletion behavior based on glob patterns.
- Updated `shouldDeleteChild` function to suppress deletions when `globIgnoredChildren` is true, differentiating from scripts-only mode.
- Enhanced tests to verify correct behavior of instance deletion based on the new metadata, ensuring robust handling of unknown scripts.
- Refactored snapshot handling to incorporate `globIgnoredChildren` in metadata, improving clarity and maintainability.
This commit is contained in:
Joe 2026-03-07 11:44:07 -06:00
parent 4b38c070fb
commit 12bccf91c5
50 changed files with 247 additions and 14 deletions

View file

@ -35,11 +35,17 @@ local SCRIPT_CLASS_NAMES = {
}
local function shouldDeleteChild(virtualInstance, childInstance)
-- If the parent allows deleting unknown instances, always allow
if shouldDeleteUnknownInstances(virtualInstance) then
return true
end
-- When the parent has glob-ignored children, suppress ALL deletions
-- (including scripts). This differs from scripts-only mode where
-- scripts are still eligible for deletion.
if virtualInstance.Metadata and virtualInstance.Metadata.globIgnoredChildren then
return false
end
-- In scripts-only mode (where parent has ignoreUnknownInstances: true),
-- we still want to allow deletion of scripts. This ensures deleted
-- script files show up in the sync diff.

View file

@ -244,6 +244,64 @@ return function()
assert(isEmpty(patch.removed))
end)
it(
"should still remove unknown scripts when ignoreUnknownInstances is true but globIgnoredChildren is false",
function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Folder",
Properties = {},
Children = {},
Metadata = {
ignoreUnknownInstances = true,
globIgnoredChildren = false,
},
},
}
local rootInstance = Instance.new("Folder")
local unknownScript = Instance.new("ModuleScript")
unknownScript.Parent = rootInstance
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
expect(#patch.removed).to.equal(1)
expect(patch.removed[1]).to.equal(unknownScript)
end
)
it("should NOT remove unknown scripts when globIgnoredChildren is true", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {
ROOT = {
ClassName = "Folder",
Name = "Folder",
Properties = {},
Children = {},
Metadata = {
ignoreUnknownInstances = true,
globIgnoredChildren = true,
},
},
}
local rootInstance = Instance.new("Folder")
local unknownScript = Instance.new("ModuleScript")
unknownScript.Parent = rootInstance
knownInstances:insert("ROOT", rootInstance)
local ok, patch = diff(knownInstances, virtualInstances, "ROOT")
assert(ok, tostring(patch))
assert(isEmpty(patch.removed))
end)
it("should generate a patch with an added child", function()
local knownInstances = InstanceMap.new()
local virtualInstances = {

View file

@ -9,6 +9,7 @@ local ApiValue = t.keys(t.string)
local ApiInstanceMetadata = t.interface({
ignoreUnknownInstances = t.optional(t.boolean),
globIgnoredChildren = t.optional(t.boolean),
})
local ApiInstance = t.interface({