From b529f57b77df5ee4dfdd48dbf8c1c8e6b10d407b Mon Sep 17 00:00:00 2001 From: RobertoRoos Date: Thu, 12 Mar 2026 10:48:07 +0100 Subject: [PATCH] Fixed issue when patching projects without sources at all --- src/tctools/patch_plc/patch_plc_class.py | 12 ++++ .../MyPlc/MyPlc_empty.plcproj | 56 +++++++++++++++++++ tests/test_patch_plc.py | 11 ++++ 3 files changed, 79 insertions(+) create mode 100644 tests/plc_code/TwinCAT Project1/MyPlc/MyPlc_empty.plcproj diff --git a/src/tctools/patch_plc/patch_plc_class.py b/src/tctools/patch_plc/patch_plc_class.py index 57029de..7883483 100644 --- a/src/tctools/patch_plc/patch_plc_class.py +++ b/src/tctools/patch_plc/patch_plc_class.py @@ -373,6 +373,18 @@ def get_project_sources(self, tree) -> FileItems: # In the XML there are always backslashes, force to native type ref_set.add(path) + if self._element_files is None: # Group doesn't yet exist, create it: + # It must be the first of the set + element_neighbour: Element = tree.find( + "PropertyGroup", namespaces={"": "*"} + ) + self._element_files = etree.XML("") + element_neighbour.addnext(self._element_files) + + if self._element_folders is None: + self._element_folders = etree.XML("") + self._element_files.addnext(self._element_folders) + return sources def sources_to_remove( diff --git a/tests/plc_code/TwinCAT Project1/MyPlc/MyPlc_empty.plcproj b/tests/plc_code/TwinCAT Project1/MyPlc/MyPlc_empty.plcproj new file mode 100644 index 0000000..f56440e --- /dev/null +++ b/tests/plc_code/TwinCAT Project1/MyPlc/MyPlc_empty.plcproj @@ -0,0 +1,56 @@ + + + 1.0.0.0 + 2.0 + {3863e7e1-422f-4d5c-92f7-9f7ce21f2ff0} + True + true + true + false + MyPlc + 3.1.4023.0 + {9b80525c-51bc-47f5-868f-9f61efadf857} + {8c1ac7e2-784c-4117-8c69-6df5131a9b7a} + {4cbef591-f0aa-4f71-8e8c-8748ed72f381} + {bc222fda-9a00-499c-8fe1-56590e05c741} + {85a038e2-e5b4-4af4-916e-a04812cc85b0} + {387c9843-650a-4728-bc5d-67105fea5b12} + + + + Tc2_Standard, * (Beckhoff Automation GmbH) + Tc2_Standard + + + Tc2_System, * (Beckhoff Automation GmbH) + Tc2_System + + + Tc3_Module, * (Beckhoff Automation GmbH) + Tc3_Module + + + + + Content + + + + + + + + "<ProjectRoot>" + + + + + + System.Collections.Hashtable + {54dd0eac-a6d8-46f2-8c27-2f43c7e49861} + System.String + + + + + \ No newline at end of file diff --git a/tests/test_patch_plc.py b/tests/test_patch_plc.py index 1dbec9b..851002e 100644 --- a/tests/test_patch_plc.py +++ b/tests/test_patch_plc.py @@ -251,3 +251,14 @@ def test_reset_duplicate(plc_dir, project, caplog): assert "Refusing to add" in msg and "MAIN.TcPOU" in msg assert project.read_text() == content_before # The project should not be changed + + +def test_reset_empty_project(plc_dir, caplog): + project = plc_dir / "MyPlc_empty.plcproj" # Project with 0 sources + + code = PatchPlc(str(project), "reset", str(plc_dir), "-r").run() + assert code == 0 + + content_after = project.read_text() + assert 'Include="POUs\\untracked_source\\F_UntrackedFunc.TcPOU"' in content_after + assert 'Include="POUs\\untracked_source"' in content_after