Adds remove_library as the symmetric counterpart to add_library.
Script (src/scripts/remove_library.py):
- IronPython 2.7 / ASCII-only; no f-strings, no KeyboardInterrupt in
except-Exception clauses.
- Placeholder substitution: LIBRARY_NAME (bare) and LIBRARY_FQN_OR_NAME
(bare or "Name, Version (Company)").
- Locates the project Library Manager via the same three-step discovery
used in add_library.py: has_library_manager/get_library_manager on the
project, first-level child walk, then find("Library Manager") fallback.
- Pre-check: walks lm.references using _ref_name_matches logic (handles
placeholder "#Name" and managed "Name, Version (Company)" forms).
If the library is not referenced the script exits SCRIPT_SUCCESS with
the "Library Not Present:" marker -- idempotent, same convention as
add_library's dedup no-op branch.
- If found: calls lm.remove_library(existing_name) per the SP22 stub
(ScriptLibManObject.pyi: remove_library(name: str)), confirms removal
from lm.references, then project.save().
- Emits SCRIPT_SUCCESS or SCRIPT_ERROR with traceback on exception.
Server (src/server.ts):
- Tool registered immediately after add_library (~line 2067).
- Reads "Library Not Present:" marker to pick idempotent vs removed
wording -- same marker-driven pattern as add_library's dedup wording.
- Thin surface: projectFilePath + libraryName (required) +
libraryFqnOrName (optional, for multi-version disambiguation).
Tests (tests/integration/e2e.test.ts):
- Template-prep test asserts: no leftover {PLACEHOLDER}s, substituted
values present, remove_library call present, references walk present,
"Library Not Present" marker present, SCRIPT_SUCCESS/SCRIPT_ERROR
markers present.
- All 22 tests pass.
References:
- helpme-codesys.com scripting engine > ScriptLibManObject
- SP22 stub: Stubs/scriptengine/ScriptLibManObject.pyi (remove_library
at line 455, references property at line 464)
Co-authored-by: Karstein Phobic Nyvold Kvistad <karstein.kvistad@maritimerobotics.com>