Repository: kronenthaler/mod-pbxproj

Issue:
[BUG] This one project loads but doesn't save
**Describe the bug**
I have a project file (attached) that can be loaded, but when saved errors out with a backtrace.

**System information** 
1. pbxproj version used: 3.4.0
2. python version used: 3.9.13
3. Xcode version used: 13.4.1 (13F100)

**To Reproduce**
Steps to reproduce the behavior:
1. Download the project file and test.py and unzip into a directory: [test.zip](https://github.com/kronenthaler/mod-pbxproj/files/9226878/test.zip)

2. `python3 test.py`
3. See error:
```
% python3 test.py
Traceback (most recent call last):
  File "/Users/tobynelson/Code/InformAppTESTING/Inform/zoom/ZoomCocoa.xcodeproj/test.py", line 4, in <module>
    project.save()
  File "/usr/local/lib/python3.9/site-packages/pbxproj/XcodeProject.py", line 56, in save
    file.write(self.__repr__() + "\n")
  File "/usr/local/lib/python3.9/site-packages/pbxproj/XcodeProject.py", line 65, in __repr__
    return '// !$*UTF8*$!\n' + super(XcodeProject, self).__repr__()
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 75, in __repr__
    return self._print_object()
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 80, in _print_object
    value = self._format(self[key], indent_depth, entry_separator, object_start,
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 101, in _format
    value = value._print_object(indentation_depth + indentation_increment,
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXObjects.py", line 45, in _print_object
    obj = value._print_object(indent_depth + '\t', entry_separator, object_start,
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 80, in _print_object
    value = self._format(self[key], indent_depth, entry_separator, object_start,
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 111, in _format
    value = value.__repr__()
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXKey.py", line 8, in __repr__
    comment = self._get_comment()
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXKey.py", line 20, in _get_comment
    return self.get_parent()._resolve_comment(self)
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 162, in _resolve_comment
    return parent._resolve_comment(key)
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 162, in _resolve_comment
    return parent._resolve_comment(key)
  File "/usr/local/lib/python3.9/site-packages/pbxproj/PBXGenericObject.py", line 157, in _resolve_comment
    return self[key]._get_comment()
  File "/usr/local/lib/python3.9/site-packages/pbxproj/pbxsections/XCConfigurationList.py", line 6, in _get_comment
    info = self._get_section()
  File "/usr/local/lib/python3.9/site-packages/pbxproj/pbxsections/XCConfigurationList.py", line 18, in _get_section
    project = projects.__next__()
StopIteration
```

**Expected behavior**
The project file should be written without any change.



Discussion:

Patch:
diff --git a/pbxproj/pbxsections/PBXBuildRule.py b/pbxproj/pbxsections/PBXBuildRule.py
new file mode 100644
index 0000000..e7d2493
--- /dev/null
+++ b/pbxproj/pbxsections/PBXBuildRule.py
@@ -0,0 +1,6 @@
+from pbxproj import PBXGenericObject
+
+
+class PBXBuildRule(PBXGenericObject):
+    def _get_comment(self):
+        return 'PBXBuildRule'
diff --git a/pbxproj/pbxsections/XCConfigurationList.py b/pbxproj/pbxsections/XCConfigurationList.py
index 4612415..70aa38f 100644
--- a/pbxproj/pbxsections/XCConfigurationList.py
+++ b/pbxproj/pbxsections/XCConfigurationList.py
@@ -10,7 +10,7 @@ class XCConfigurationList(PBXGenericObject):
         objects = self.get_parent()
         target_id = self.get_id()
 
-        for obj in objects.get_objects_in_section('PBXNativeTarget', 'PBXAggregateTarget'):
+        for obj in objects.get_objects_in_section('PBXNativeTarget', 'PBXLegacyTarget', 'PBXAggregateTarget'):
             if target_id in obj.buildConfigurationList:
                 return obj.isa, obj.name
 
diff --git a/pbxproj/pbxsections/__init__.py b/pbxproj/pbxsections/__init__.py
index 7139ba9..8a33a40 100644
--- a/pbxproj/pbxsections/__init__.py
+++ b/pbxproj/pbxsections/__init__.py
@@ -1,4 +1,5 @@
 from pbxproj.pbxsections.PBXBuildFile import *
+from pbxproj.pbxsections.PBXBuildRule import *
 from pbxproj.pbxsections.PBXFileReference import *
 from pbxproj.pbxsections.PBXFrameworksBuildPhase import *
 from pbxproj.pbxsections.PBXProject import *


Test patch:
diff --git a/tests/pbxsections/TestXCConfigurationList.py b/tests/pbxsections/TestXCConfigurationList.py
index 384d0c0..6641588 100644
--- a/tests/pbxsections/TestXCConfigurationList.py
+++ b/tests/pbxsections/TestXCConfigurationList.py
@@ -11,7 +11,7 @@ class XCConfigurationListTest(unittest.TestCase):
 
         self.assertEqual(config._get_comment(), 'Build configuration list for TargetType "name"')
 
-    def testGetSectionOnTarget(self):
+    def testGetSectionOnNativeTarget(self):
         objs = objects(None).parse(
             {
                 '1': {
@@ -26,6 +26,21 @@ class XCConfigurationListTest(unittest.TestCase):
         config = objs['2']
         self.assertEqual(config._get_comment(), 'Build configuration list for PBXNativeTarget "the-target-name"')
 
+    def testGetSectionOnLegacyTarget(self):
+        objs = objects(None).parse(
+            {
+                '1': {
+                    'isa': 'PBXLegacyTarget',
+                    'buildConfigurationList': ['2'],
+                    'name': 'the-target-name'
+                },
+                '2': {
+                    'isa': 'XCConfigurationList'
+                }
+            })
+        config = objs['2']
+        self.assertEqual(config._get_comment(), 'Build configuration list for PBXLegacyTarget "the-target-name"')
+
     def testGetSectionOnProject(self):
         objs = objects(None).parse(
             {