Пример #1
0
    def __setattr__(self, name, value):
        if name == u'pbx_buildConfigurationList':
            pbxhelper.pbxobj_set_pbxobj_attr(self, PBXProject, name, value, \
                lambda o:isinstance(o, baseobject.PBXBaseObject) and o.isa == 'XCConfigurationList')

        elif name in [u'pbx_mainGroup', u'pbx_productRefGroup']:
            pbxhelper.pbxobj_set_pbxobj_attr(self, PBXProject, name, value, \
                lambda o:isinstance(o, baseobject.PBXBaseObject) and o.isa == 'PBXGroup')

        elif name == u'pbx_targets':
            pbxhelper.pbxobj_set_pbxlist_attr(self, PBXProject, name, value, self.is_valid_target)

        elif name == u'pbx_projectReferences':
            self.__set_project_references(value)

        elif name == u'pbx_attributes':
            if not func.isdict(value):
                value = dict()
            super(PBXProject, self).__setattr__(name, value)

        elif name == u'pbx_knownRegions':
            if not func.isseq(value):
                value = [value]
            super(PBXProject, self).__setattr__(name, value)

        else:
            super(PBXProject, self).__setattr__(name, value)
Пример #2
0
 def get_object(self, guid):
     """ 
     get pbx-object with specified guid
     :param guid:    the object's guid
     """
     obj = self.__objects.get(guid)
     if obj is None and not self.__plist_objects is None:
         # self.__plist_objects is None indicates that the parsing process is finished
         objdict = self.__plist_objects.pop(guid, None)
         if func.isdict(objdict):
             objcls = objdict.pop(u'isa', None)
             if not objcls is None:
                 try:
                     obj = self.__new_object(objcls, guid)
                     obj.parse(objdict)
                 except Exception as e:
                     logger.warn(e)
                     raise
             else:
                 logger.warn(u'[XcodeProj] Bad format. "isa" not found for object:{guid}'\
                     .format(guid=guid))
         elif not objdict is None:
             logger.warn(\
                 u'[XcodeProj] {guid} invalid object dict:{dic}'.format(guid=guid, dic=objdict))
     return obj
Пример #3
0
 def __dispatch(obj):
     if func.isseq(obj):
         return __canonical_list(list(obj))
     elif func.isdict(obj):
         return __canonical_dict(obj)
     else:
         return __canonical_obj(obj)
Пример #4
0
        def __recursively_check_and_replace(obj, keys, oldval, newval):
            if isinstance(obj, PBXBaseObject):
                __recursively_check_and_replace(obj.__dict__, keys, oldval,
                                                newval)
            elif func.isseq(obj):
                __replace_array_item(obj, keys, oldval, newval)

            elif func.isdict(obj):
                k = keys.pop(0)
                v = obj.get(k)

                if isinstance(v, PBXBaseObject) and v.guid == oldval.guid:
                    if newval is None:
                        obj.pop(k, None)
                    else:
                        obj[k] = newval
                        newval.add_referrer(self, keypath)
                    v.remove_referrer(self)
                elif func.isdict(v):
                    assert len(keys) > 0
                    __recursively_check_and_replace(v, keys, oldval, newval)
                elif func.isseq(v):
                    __replace_array_item(v, keys, oldval, newval)
Пример #5
0
 def __parse_dict_attr_val(self, dic, pbxkey):
     for k, v in dic.items():
         depkey = u'{0}.{1}'.format(pbxkey, k)
         if func.isstr(v) and pbxhelper.is_valid_guid(v):
             obj = self.project().get_object(v)
             if not obj is None:
                 obj.add_referrer(self, depkey)
                 dic[k] = obj
             else:
                 dic[k] = v
         elif func.isseq(v):
             dic[k] = self.__parse_arr_attr_val(v, depkey)
         elif func.isdict(v):
             self.__parse_dict_attr_val(v, depkey)
Пример #6
0
    def is_valid_project_reference(self, value):
        """ check if value is valid project reference """
        if not func.isdict(value):
            return False

        obj = value.get(u'ProductGroup')
        if not isinstance(obj, baseobject.PBXBaseObject) or not obj.isa == u'PBXGroup':
            return False

        obj = value.get(u'ProjectRef')
        if not isinstance(obj, baseobject.PBXBaseObject) or not obj.isa == u'PBXFileReference':
            return False

        return True
Пример #7
0
    def __parse(self, plist_dict):
        objects = plist_dict.pop(u'objects', None)
        self.__plist_objects = objects if func.isdict(objects) else None

        for k, v in plist_dict.items():
            plist_dict.pop(k)
            pbxkey = u'pbx_{name}'.format(name=k)
            if k == u'rootObject':
                v = self.get_object(v)
            setattr(self, pbxkey, v)

        if len(self.__plist_objects) > 0:
            logger.warn(u'[XcodeProj] isolate objects are not be parsed:\n\t{0}'\
                .format(u'\n\t'.join([u'{0}:{1}'.format(k, v.get(u'isa')) \
                    for k, v in self.__plist_objects.items()])))
        self.__plist_objects = None  # process complete
Пример #8
0
    def parse(self, objdict):
        """
        parse object attribute values from 'objdict'
        """
        objdict.pop(u'isa', None)
        for key in objdict.keys():
            value = objdict.pop(key)
            pbxkey = u'pbx_{name}'.format(name=key)

            if func.isseq(value):
                newarr = self.__parse_arr_attr_val(value, pbxkey)
                setattr(self, pbxkey, newarr)
            elif func.isdict(value):
                self.__parse_dict_attr_val(value, pbxkey)
                setattr(self, pbxkey, value)
            else:
                self.__parse_str_attr(pbxkey, value)
Пример #9
0
    def _print_value(self, buff, val, identstr, singleline=False):
        from xcodeproj.pbxproj import baseobject
        # self.safely_write(buff, u'')

        if func.isdict(val):
            pairs = sorted(val.items(), key=lambda e: e)
            self._print_pairs(buff, pairs, identstr, singleline)
        elif func.isseq(val):
            self._print_list(buff, val, identstr, singleline)
        elif isinstance(val, baseobject.PBXBaseObject):
            self.safely_write(buff, pbxhelper.pbxstr_escape(val.guid))
            comment = val.comment()
            if not comment is None:
                self.safely_write(buff,
                                  u' /* {comment} */'.format(comment=comment))
        else:
            self.safely_write(buff, pbxhelper.pbxstr_escape(val))
Пример #10
0
    def load(xcprojpath, pbxprojfile=u'project.pbxproj'):
        """
        load and parse pbxproj file.
        :param xcprojpath:      path to ".xcodeproj".
        :param pbxprojfile:     default is 'project.pbxproj', 
                                you can specified another name if needed
        """
        xcprojpath = os.path.normpath(os.path.abspath(xcprojpath))

        projname, projext = os.path.splitext(os.path.basename(xcprojpath))
        if not projext == u'.xcodeproj' or not os.path.isdir(xcprojpath):
            logger.error(u'[XcodeProj] Illegal Xcode Project path: "%s"' %
                         xcprojpath)
            sys.exit(1)

        pbxproj_path = os.path.join(xcprojpath, pbxprojfile)
        if not os.path.isfile(pbxproj_path):
            logger.error(u'[XcodeProj] Illegal Project file: "%s"' %
                         pbxproj_path)
            sys.exit(1)

        import subprocess
        cmd_args = (u'/usr/bin/plutil', u'-convert', u'json', u'-o', u'-',
                    pbxproj_path)
        p = subprocess.Popen(cmd_args, stdout=subprocess.PIPE)
        stdout, stderr = p.communicate()
        if not p.returncode == 0:
            logger.error(u'[XcodeProj] Incomprehensible file: %s; %s' %
                         (pbxproj_path, stderr))
            sys.exit(1)

        import json
        plist_dict = json.loads(stdout)
        if not func.isdict(plist_dict):
            logger.error(u'[XcodeProj] Bad format: %s; %s' %
                         (pbxproj_path, stderr))
            sys.exit(1)

        # parse objects
        xcproj = XcodeProj()
        xcproj.__project_file_path = xcprojpath
        xcproj.__pbxfile = pbxprojfile

        xcproj.__parse(plist_dict)
        return xcproj
Пример #11
0
 def __parse_arr_attr_val(self, arr, pbxkey):
     newarr = []
     for val in arr:
         if func.isstr(val) and pbxhelper.is_valid_guid(val):
             obj = self.project().get_object(val)
             if not obj is None:
                 obj.add_referrer(self, pbxkey)
                 newarr.append(obj)
             else:
                 newarr.append(val)  # error?
         elif func.isseq(val):
             newarr.append(self.__parse_arr_attr_val(val, pbxkey))
         elif func.isdict(val):
             self.__parse_dict_attr_val(val, pbxkey)
             newarr.append(val)
         else:
             newarr.append(val)
     return newarr
Пример #12
0
    def _validate(self):
        resolved, issues = super(PBXProject, self)._validate()

        pbxhelper.pbxobj_validate_pbxobj_attr(self, u'pbx_buildConfigurationList', issues=issues)
        pbxhelper.pbxobj_validate_pbxobj_attr(self, u'pbx_mainGroup', issues=issues)
        pbxhelper.pbxobj_validate_pbxobj_attr(self, u'pbx_productRefGroup', issues=issues)

        pbxhelper.pbxobj_validate_pbxlist_attr(self, u'pbx_targets', self.is_valid_target, \
            resolved=resolved, issues=issues)

        dic = self.pbx_attributes.get(u'TargetAttributes')
        if not dic is None:
            if not func.isdict(dic):
                issues.append(u'invalid attributes.TargetAttributes: {0}'.format(dic))
            else:
                for k, v in dic.items():
                    if not self.hastarget(k):
                        dic.pop(k, None)
                        resolved.append(\
                            u'remove attribute for dangling target:{guid}'.format(guid=k))

        self.__validate_project_references(resolved, issues)
        self.__deduplicate_project_reference(resolved, issues)
        return resolved, issues
Пример #13
0
 def __set_build_settings(self, value):
     if func.isdict(value):
         super(XCBuildConfiguration,
               self).__setattr__(u'pbx_buildSettings', value)
     else:
         logger.error(u'{0} illegal buildSettings:{1}'.format(self, value))
Пример #14
0
 def __set_settings(self, value):
     if value is None or func.isdict(value):
         super(PBXBuildFile, self).__setattr__(u'pbx_settings', value)
     else:
         logger.error(u'[PBXBuildFile] illegal settings:{0}'.format(obj))