Пример #1
0
def pbxobj_set_pbxlist_attr(obj, objclass, attr, value, validator):
    """
    obj.attr is type of [PBXBaseObject] 
    """
    assert value is None or func.isseq(value)
    value = value if not value is None else []

    oldvalue = getattr(obj, attr, None)
    if not oldvalue is None:
        for oldv in oldvalue:
            oldv.remove_referrer(obj)

    if not value is None:
        rejects = []
        if func.isseq(value):
            value, rejects = func.filter_items(validator, value)
        else:
            value, rejects = ([], value)
        if len(rejects) > 0:
            logger.warn(u'{obj} ignore invalid {attr}:\n\t{v}'\
                .format(obj=obj, attr=attr[len(pbxconsts.PBX_ATTR_PREFIX):], \
                    v='\n\t'.join([str(v) for v in rejects])))

        super(objclass, obj).__setattr__(attr, value)
        for v in value:
            v.add_referrer(obj, attr)
Пример #2
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)
Пример #3
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)
Пример #4
0
    def __set_project_references(self, value):
        if not func.isseq(value):
            return

        value, rejects = func.filter_items(self.is_valid_project_reference, value)
        if len(rejects) > 0:
            logger.warn(u'{0} ignore invalid project reference:\n\t{1}'\
                .format(self, u'\n\t'.join(map(lambda o: str(o), rejects))))

        super(PBXProject, self).__setattr__(u'pbx_projectReferences', value)
Пример #5
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)
Пример #6
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)
Пример #7
0
    def add_array_build_settings(self, name, value):
        """
        add values to an existed settings. If the value is already exists, ignore.
        The value of setting is type of list, eg: 
            HEADER_SEARCH_PATHS = (
                /usr/include,
                /usr/local/include,
            };

        examples:
            add_array_build_settings('HEADER_SEARCH_PATHS', '../thirdparty')
            =>
            HEADER_SEARCH_PATHS = (
                /usr/include,
                /usr/local/include,
                ../thirdparty,
            };

            add_array_build_settings('HEADER_SEARCH_PATHS', \
                ['../thirdparty', '/usr/include'])
            =>
            HEADER_SEARCH_PATHS = (
                /usr/include,
                /usr/local/include,
                ../thirdparty,
            };
    
        @param name     the setting name
        @param value    str or [str]
        """
        settingval = self.get_build_setting(name, default=[])

        arr = []
        if func.isseq(value):
            arr.extend(value)
        else:
            arr.append(str(value))

        for v in arr:
            if not v in settingval:
                settingval.append(v)

        count = len(settingval)
        if count == 0:
            settingval = ''
        elif count == 1:
            settingval = str(settingval[0])

        self.pbx_buildSettings[name] = settingval
Пример #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 __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
Пример #11
0
    def __validate_project_references(self, resolved, issues):
        prodrefs = self.pbx_projectReferences
        if not prodrefs is None:
            if not func.isseq(prodrefs):
                issues.append(u'illegal projectReferences: {ref}'.format(ref=prodrefs))
            else:
                for refdict in list(prodrefs):
                    if not self.is_valid_project_reference(refdict):
                        prodrefs.remove(refdict)
                        for obj in [refdict.get(u'ProductGroup'), refdict.get(u'ProjectRef')]:
                            if not obj is None:
                                obj.remove_referrer(self)
                        issues.append(u'remove invalid projectReference:{ref}'.format(ref=refdict))
                        continue

                    for obj in [refdict.get(u'ProductGroup'), refdict.get(u'ProjectRef')]:
                        try:
                            obj.validate()
                        except baseobject.PBXValidationError as e:
                            self.remove_project_reference(refdict)
                            resolved.append(u'remove invalid projectReference:{ref}; {ex}'\
                                .format(ref=obj, ex=e))
Пример #12
0
    def add_str_build_settings(self, name, value, seperator=' '):
        """
        add values to an existed settings. If the value is already exists, ignore.
        The value of setting is a str, eg: 
            VALID_ARCHS = "armv7 arm64";

        examples:
            add_str_build_settings('VALID_ARCHS', 'armv7s') => VALID_ARCHS = "armv7 arm64 armv7s";
    
            add_str_build_settings('VALID_ARCHS', ['i386', 'x86_64']) => 
                VALID_ARCHS = "armv7 arm64 i386 x86_64";

            add_str_build_settings('VALID_ARCHS', ['armv7s', 'arm64']) => 
                VALID_ARCHS = "armv7 arm64 armv7s";
        
        @param name     the setting name
        @param value    str or [str]
        @param seperator the seperator of items in setting value
        """
        arr = []
        if func.isseq(value):
            arr = list(value)
        elif not value is None:
            arr = [str(value)]

        settingval = self.get_build_setting(name, default='')
        for v in arr:
            if v is None:
                continue
            if settingval == v or func.hasprefix(settingval, v + seperator):
                continue
            if func.hassubfix(settingval, seperator + v):
                continue
            if seperator + v + seperator in settingval:
                continue

            settingval += seperator + v
        self.pbx_buildSettings[name] = settingval
Пример #13
0
    def deduplicate_paths(self, paths):
        """
        return deduplicate paths
        complete and normalize the paths, deduplicate the result
        """
        if func.isstr(paths):
            return paths

        if not func.isseq(paths):
            return u''

        path_dict = dict()
        for path in paths:
            normpath = path
            while func.hasprefix(normpath, '"') and func.hassubfix(
                    normpath, '"'):
                normpath = normpath[1:len(normpath) - 1]
            normpath = pbxpath.normalize_path(normpath)
            realpath = pbxpath.realpath(self.project(), normpath)

            if realpath in path_dict:
                continue
            if not func.hassubfix(realpath, os.sep + '**'):
                p = os.path.join(realpath, '**')
                if p in path_dict:
                    continue
            else:
                p = realpath[0:len(realpath) - len(os.sep + '**')]
                path_dict.pop(p, None)

            path_dict[realpath] = (path, normpath)

        return [
            p[1] for p in sorted(path_dict.values(),
                                 key=lambda p: paths.index(p[0]))
        ]