fix(compile_messages): discover real category GUIDs via system.get_message_categories()
The 0.6.3 fix replaced 'first-non-empty-pattern-wins' with category iteration but used a HARDCODED list of 'well-known V3.5 GUIDs' that was wrong. None of those GUIDs matched the actual Build category, so compile errors stayed invisible (compile_project still reported '0 errors' even when the IDE-side download path saw them). Diagnosed via a one-shot probe injected into compile_project on 2026-04-29: dumped attrs of script_engine.system, then called script_engine.system.get_message_categories() (the METHOD) directly. That returned the actual 7 category GUIDs in this CODESYS V3.5 SP22 Patch 1 install: 05581bd1-66d3-4251-aff2-047cc8e9adf7 Offline Help 936e1a33-3af8-47fa-b40b-903f0ae0b6cc Application Composer a9b26e07-6ae1-4c06-9cd1-9ddddd397a2d SVN 0a6fcb64-7f24-43c6-a6d3-f70cb5d31114 (no parameterless ctor; Git) 194b48a9-ab51-43ae-b9a9-51d3edaaddf3 Script Messages 97f48d64-a2a3-4856-b640-75c046e37ea9 Build <-- the one we needed 220493a1-f49b-4416-9a3f-a545db707cbe Additional code checks Real fix: replace the hardcoded list in _enumerate_categories() in both compile_project.py and get_compile_messages.py with a call to system.get_message_categories(); label each one via get_message_category_description(guid). Iterate per category as before. GUIDs are now discovered at runtime so the same code works on any SP and any locale. Verification: injected `THIS_IS_NOT_VALID_IEC_KEYWORD;` into PLC_PRG.implementation, ran compile_project; output now reads "1 error(s), 2 warning(s). ERROR: Identifier 'THIS_IS_NOT_VALID_IEC_KEYWORD' not defined". Restored PLC_PRG; 0 error(s) again. End-to-end fix confirmed. Bumped 0.6.3 -> 0.6.4.
This commit is contained in:
parent
2c19eca4b3
commit
d4e71f61ca
3 changed files with 63 additions and 60 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "codesys-mcp-sp21-plus",
|
||||
"version": "0.6.3",
|
||||
"version": "0.6.4",
|
||||
"description": "Codesys-MCP-SP21+ -- fork of luke-harriman/Codesys-MCP carrying CODESYS V3.5 SP22 Patch 1 fixes (and forward-compat with later SPs): script-engine API drift, online/runtime tool auto-login, dual-SHA release classifier, set_pou_code omitted-decl wipe fix, add_library managed-overload, etc. MCP server for CODESYS with persistent UI instance and file-based IPC.",
|
||||
"main": "dist/server.js",
|
||||
"bin": {
|
||||
|
|
|
|||
|
|
@ -106,36 +106,43 @@ def _build_message_entry(msg, category_name=None):
|
|||
|
||||
|
||||
def _enumerate_categories(script_engine_arg):
|
||||
"""Returns a list of (label, category_guid_or_None) tuples for every
|
||||
message category the IDE exposes plus a (None, None) sentinel for the
|
||||
no-filter call.
|
||||
|
||||
Discovery path: script_engine.system.get_message_categories() (the
|
||||
METHOD) returns the live List[Guid] of category IDs registered in
|
||||
this IDE session. script_engine.system.get_message_category_description(guid)
|
||||
gives the human-readable label per category ('Build', 'Application
|
||||
Composer', 'SVN', 'Script Messages', 'Additional code checks', etc.).
|
||||
|
||||
History: pre-0.6.4 the function looked at `system.message_categories`
|
||||
(a property) which doesn't exist, then fell back to a hardcoded list
|
||||
of GUIDs that happened to NOT include the actual Build category
|
||||
(97f48d64-a2a3-4856-b640-75c046e37ea9). Result: compile errors were
|
||||
invisible. Verified by diagnostic probe with intentional syntax-error
|
||||
injection on 2026-04-29."""
|
||||
cats = [('<default-no-filter>', None)]
|
||||
se_sys = getattr(script_engine_arg, 'system', None)
|
||||
if se_sys is None or not hasattr(se_sys, 'get_message_categories'):
|
||||
return cats
|
||||
try:
|
||||
se_sys = getattr(script_engine_arg, 'system', None)
|
||||
if se_sys is not None:
|
||||
mc = getattr(se_sys, 'message_categories', None)
|
||||
if mc is not None:
|
||||
try:
|
||||
for c in mc:
|
||||
try:
|
||||
label = (
|
||||
_coerce_str(getattr(c, 'name', None))
|
||||
or _coerce_str(getattr(c, 'guid', None))
|
||||
or _coerce_str(c)
|
||||
or '<unnamed>'
|
||||
)
|
||||
cats.append((label, c))
|
||||
except Exception:
|
||||
continue
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
well_known = [
|
||||
('Compile (well-known GUID)', '90F1B997-7AB7-4B11-B637-D55D71BC4F2A'),
|
||||
('Build (well-known GUID)', '7390398F-1B2F-4B30-B6E2-37F2BB7B57E0'),
|
||||
('Online (well-known GUID)', '15F65557-DC73-4193-B7F2-EFF5A2A6C10C'),
|
||||
('LibMan (well-known GUID)', '0B8D54FB-C68A-43F9-9B4D-79DBE1F8DF44'),
|
||||
]
|
||||
for lbl, g in well_known:
|
||||
cats.append((lbl, g))
|
||||
guids = se_sys.get_message_categories()
|
||||
except Exception as e:
|
||||
print("DEBUG: get_message_categories() raised: %s" % e)
|
||||
return cats
|
||||
if guids is None:
|
||||
return cats
|
||||
for g in guids:
|
||||
label = None
|
||||
try:
|
||||
if hasattr(se_sys, 'get_message_category_description'):
|
||||
label = _coerce_str(se_sys.get_message_category_description(g))
|
||||
except Exception:
|
||||
label = None
|
||||
if not label:
|
||||
label = _coerce_str(g) or '<unnamed>'
|
||||
cats.append((label, g))
|
||||
return cats
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -106,39 +106,35 @@ def _build_message_entry(msg, category_name=None):
|
|||
|
||||
|
||||
def _enumerate_categories(script_engine_arg):
|
||||
"""Returns a list of (label, category_obj_or_guid_or_None). Always
|
||||
includes a (None, None) sentinel for the no-filter call."""
|
||||
"""Returns a list of (label, category_guid_or_None) tuples for every
|
||||
message category the IDE exposes plus a (None, None) sentinel for the
|
||||
no-filter call.
|
||||
|
||||
Discovery path: script_engine.system.get_message_categories() (the
|
||||
METHOD) returns the live List[Guid]. script_engine.system.get_message_category_description(guid)
|
||||
gives the human-readable label per category. See compile_project.py
|
||||
for the verified-on-SP22 history note."""
|
||||
cats = [('<default-no-filter>', None)]
|
||||
se_sys = getattr(script_engine_arg, 'system', None)
|
||||
if se_sys is None or not hasattr(se_sys, 'get_message_categories'):
|
||||
return cats
|
||||
try:
|
||||
se_sys = getattr(script_engine_arg, 'system', None)
|
||||
if se_sys is not None:
|
||||
mc = getattr(se_sys, 'message_categories', None)
|
||||
if mc is not None:
|
||||
try:
|
||||
for c in mc:
|
||||
try:
|
||||
label = (
|
||||
_coerce_str(getattr(c, 'name', None))
|
||||
or _coerce_str(getattr(c, 'guid', None))
|
||||
or _coerce_str(c)
|
||||
or '<unnamed>'
|
||||
)
|
||||
cats.append((label, c))
|
||||
except Exception:
|
||||
continue
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
# Well-known V3.5 category GUIDs (probed as fallback strings).
|
||||
well_known = [
|
||||
('Compile (well-known GUID)', '90F1B997-7AB7-4B11-B637-D55D71BC4F2A'),
|
||||
('Build (well-known GUID)', '7390398F-1B2F-4B30-B6E2-37F2BB7B57E0'),
|
||||
('Online (well-known GUID)', '15F65557-DC73-4193-B7F2-EFF5A2A6C10C'),
|
||||
('LibMan (well-known GUID)', '0B8D54FB-C68A-43F9-9B4D-79DBE1F8DF44'),
|
||||
]
|
||||
for lbl, g in well_known:
|
||||
cats.append((lbl, g))
|
||||
guids = se_sys.get_message_categories()
|
||||
except Exception as e:
|
||||
print("DEBUG: get_message_categories() raised: %s" % e)
|
||||
return cats
|
||||
if guids is None:
|
||||
return cats
|
||||
for g in guids:
|
||||
label = None
|
||||
try:
|
||||
if hasattr(se_sys, 'get_message_category_description'):
|
||||
label = _coerce_str(se_sys.get_message_category_description(g))
|
||||
except Exception:
|
||||
label = None
|
||||
if not label:
|
||||
label = _coerce_str(g) or '<unnamed>'
|
||||
cats.append((label, g))
|
||||
return cats
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue