Including/excluding entire groups from targets

萝らか妹 提交于 2019-12-02 10:19:18

Here's the hack I ended up using—I'd obviously still appreciate a better solution.

#!/usr/bin/env python3

import os
import plistlib
import sys

pbxproj = os.path.join(sys.argv[1], 'project.pbxproj')
groupname = sys.argv[2]
extensions = 'm mm c cc cpp'.split()

with open(pbxproj, 'rb') as f:
    p = plistlib.load(f)

objs = p['objects']

groupid, group = next((k, v) for k, v in objs.items()
                      if v.get('path') == groupname)

def descendants(id):
    obj = objs[id]
    if obj['isa'] == 'PBXFileReference':
        yield (id, obj)
    for child in obj.get('children', []):
        yield from descendants(child)

mdict = {id: obj for id, obj in descendants(group_id)
         if os.path.splitext(obj['path'])[-1] in extensions}

proj_id, proj = next((k, v) for k, v in objs.items()
                     if v['isa'] == 'PBXProject')

for target_id in proj['targets']:
    target = objs[target_id]
    phase_ids = target['buildPhases']
    phases = [(phase_id, objs[phase_id]) for phase_id in phase_ids]
    phase_id, phase = next((phase_id, phase)
                           for phase_id, phase in phases
                           if phase['isa'] == 'PBXSourcesBuildPhase')
    fileref_ids = [i
                   for i, buildfile_id in enumerate(phase['files'])
                   if objs[buildfile_id]['fileRef'] in mdict]
    fileref_ids.sort(reverse=True)
    for i in fileref_ids:
        del phase['files'][i]

with open(pbxproj + '.new', 'wb') as f:
    plistlib.dump(p, f)
os.rename(pbxproj, pbxproj + '.bak')
os.rename(pbxproj + '.new', pbxproj)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!