From 4e242ca824790111565671abd32557d9ac6d9fb9 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 5 May 2026 21:19:00 -0400 Subject: [PATCH] Revert "graccesscli: fail fast on package-only attribute writes (writeback gap fix)" This reverts commit bd95ace1c5d8e29ab15c15b77e2dd98eb6f5b019. --- .../GRAccess/GRAccessCommandDispatcher.cs | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/graccesscli/src/ZB.MOM.WW.GRAccess.Cli/GRAccess/GRAccessCommandDispatcher.cs b/graccesscli/src/ZB.MOM.WW.GRAccess.Cli/GRAccess/GRAccessCommandDispatcher.cs index bd8977f..9f4e2ea 100644 --- a/graccesscli/src/ZB.MOM.WW.GRAccess.Cli/GRAccess/GRAccessCommandDispatcher.cs +++ b/graccesscli/src/ZB.MOM.WW.GRAccess.Cli/GRAccess/GRAccessCommandDispatcher.cs @@ -503,7 +503,6 @@ namespace ZB.MOM.WW.GRAccess.Cli.GRAccess return AtomicObjectEdit(obj, editObj => { var editAttr = FindAttributeForMutation(editObj, Arg(args, "attribute")); - EnsureMutableViaSetValue(editAttr, Arg(args, "attribute")); editAttr.SetValue(CreateMxValue(Arg(args, "value"), Arg(args, "data-type", "string"))); return CommandSummary(editAttr, "Set attribute value"); }); @@ -1624,40 +1623,11 @@ namespace ZB.MOM.WW.GRAccess.Cli.GRAccess } var attr = FindAttributeForMutation(obj, attributeName); - EnsureMutableViaSetValue(attr, attributeName); var body = File.ReadAllText(file); attr.SetValue(CreateMxValue(body, "string")); return CommandSummary(attr, $"Set script {attributeName}"); } - // Checks whether `attr.SetValue` will actually persist on this attribute, - // or whether the attribute is package-only (in which case SetValue silently - // no-ops despite returning Successful=true). Discovered via investigation - // documented in the writeback-gap notes: ScriptExtension text fields - // (ExecuteText, DeclarationsText, StartupText, ShutdownText, OnScanText, - // OffScanText, Expression) are all `MxCategoryPackageOnly_Lockable` — - // editable only via the package import/export round-trip, never via the - // generic `IAttribute.SetValue` path. Same for any other attribute whose - // category starts with `MxCategoryPackageOnly`. - private static void EnsureMutableViaSetValue(IAttribute attr, string attributeName) - { - string category; - try { category = attr.AttributeCategory.ToString(); } - catch { return; } // best-effort; if we can't read the category, let the write proceed - - if (category != null && category.StartsWith("MxCategoryPackageOnly", StringComparison.OrdinalIgnoreCase)) - { - throw new InvalidOperationException( - $"Attribute '{attributeName}' has category '{category}'. " + - "Package-only attributes silently no-op via IAttribute.SetValue and can only be " + - "edited through the package import/export round-trip. " + - "For ScriptExtension bodies (ExecuteText / DeclarationsText / StartupText / etc.), " + - "edit the source object in the System Platform IDE and re-import, " + - "or use a future package-rewrite path. " + - "See docs/script-parsing.md:8."); - } - } - private static string ObjectScriptCreate(IGalaxy galaxy, IgObject obj, IDictionary args) { var scriptName = Arg(args, "script"); @@ -1724,7 +1694,6 @@ namespace ZB.MOM.WW.GRAccess.Cli.GRAccess if (!string.IsNullOrWhiteSpace(expression)) { var attr = FindAttributeForMutation(obj, scriptName + ".Expression"); - EnsureMutableViaSetValue(attr, scriptName + ".Expression"); attr.SetValue(CreateMxValue(expression, "string")); yield return CommandSummary(attr, $"Set script {scriptName}.Expression"); }