def substitute_old_keys(self): self.vprint('replace UUIDs and remove unused UUIDs') key_ptn = re_compile('(?<=\s)([0-9A-Z]{24}|[0-9A-F]{32})(?=[\s;])') for line in fi_input(self.xcode_pbxproj_path, backup='.ubak', inplace=1): # project.pbxproj is an utf-8 encoded file line = line.decode('utf-8') key_list = key_ptn.findall(line) if not key_list: output_u8line(line) else: new_line = line # remove line with non-existing element if self.__result.get('to_be_removed') and any( i for i in key_list if i in self.__result['to_be_removed']): continue # remove incorrect entry that somehow does not exist in project node tree elif not all(self.__result.get(uuid) for uuid in key_list): continue else: for key in key_list: new_key = self.__result[key]['new_key'] new_line = new_line.replace(key, new_key) output_u8line(new_line) fi_close() tmp_path = self.xcode_pbxproj_path + '.ubak' if filecmp_cmp(self.xcode_pbxproj_path, tmp_path, shallow=False): unlink(self.xcode_pbxproj_path) rename(tmp_path, self.xcode_pbxproj_path) warning_print('Ignore uniquify, no changes made to "', self.xcode_pbxproj_path, sep='') else: unlink(tmp_path) self._is_modified = True success_print('Uniquify done')
def sort_pbxproj_pl(self): """ deprecated, use pure python method sort_pbxproj() below https://github.com/truebit/webkit/commits/master/Tools/Scripts/sort-Xcode-project-file my modified version which supports: 1. sort PBXFileReference and PBXBuildFile sections 2. avoid creating new file if no changes made """ sort_script_path = path.join(path.dirname(path.abspath(__file__)), 'sort-Xcode-project-file-mod2.pl') if not path.exists(sort_script_path): print 'downloading sort-Xcode-project-file' f_path, http_msgs = urlretrieve( 'https://raw.githubusercontent.com/truebit/webkit/master/Tools/Scripts/sort-Xcode-project-file', filename=sort_script_path) if int(http_msgs['content-length']) < 1000: # current is 6430 raise SystemExit( 'Cannot download script file from "https://raw.githubusercontent.com/truebit/webkit/master/Tools/Scripts/sort-Xcode-project-file"') for line in fi_input(sort_script_path, inplace=1, backup='.bak'): print line.replace('{24}', '{32}'), fi_close() unlink(sort_script_path + '.bak') print 'sort project.xpbproj file' sp_cc(['perl', sort_script_path, self.xcode_pbxproj_path])
def sort_pbxproj_pl(self): """ deprecated, use pure python method sort_pbxproj() below https://github.com/truebit/webkit/commits/master/Tools/Scripts/sort-Xcode-project-file my modified version which supports: 1. sort PBXFileReference and PBXBuildFile sections 2. avoid creating new file if no changes made """ sort_script_path = path.join(path.dirname(path.abspath(__file__)), 'sort-Xcode-project-file-mod2.pl') if not path.exists(sort_script_path): self.vprint('downloading sort-Xcode-project-file') f_path, http_msgs = urlretrieve( 'https://raw.githubusercontent.com/truebit/webkit/master/Tools/Scripts/sort-Xcode-project-file', filename=sort_script_path) if int(http_msgs['content-length']) < 1000: # current is 6430 raise SystemExit( 'Cannot download script file from "https://raw.githubusercontent.com/truebit/webkit/master/Tools/Scripts/sort-Xcode-project-file"') for line in fi_input(sort_script_path, inplace=1, backup='.bak'): print(line.replace('{24}', '{32}'), end='') fi_close() unlink(sort_script_path + '.bak') self.vprint('sort project.xpbproj file') sp_cc(['perl', sort_script_path, self.xcode_pbxproj_path])
def replace_uuids_with_file(self): self.vprint('replace UUIDs and remove unused UUIDs') uuid_ptn = re_compile('(?<=\s)[0-9A-F]{24}(?=[\s;])') for line in fi_input(self.xcode_pbxproj_path, backup='.bak', inplace=1): # project.pbxproj is an utf-8 encoded file line = line.decode('utf-8') uuid_list = uuid_ptn.findall(line) if not uuid_list: print(line.encode('utf-8'), end='') else: new_line = line # remove line with non-existing element if self.__result.get('to_be_removed') and any( i for i in uuid_list if i in self.__result['to_be_removed']): continue else: for uuid in uuid_list: new_line = new_line.replace(uuid, self.__result[uuid]['new_key']) print(new_line.encode('utf-8'), end='') fi_close() tmp_path = self.xcode_pbxproj_path + '.bak' if filecmp_cmp(self.xcode_pbxproj_path, tmp_path, shallow=False): unlink(self.xcode_pbxproj_path) rename(tmp_path, self.xcode_pbxproj_path) print('Ignore uniquify, no changes made to', self.xcode_pbxproj_path) else: unlink(tmp_path) print('Uniquify done')
def desymbolicate_file(self): self.symbolicatecrash() desym_result = self.desymbolicate() for line in fi_input(self.crashlog_path, backup='.dbak', inplace=1): if line in desym_result.keys(): print_ng(desym_result[line]) else: print_ng(line.rstrip()) fi_close() print_ng("desymbolicated log saved to '",self.crashlog_path,"', original log saved to '",self.crashlog_path + '.dbak',"'",sep='')
def substitute_old_keys(self): self.vprint('replace UUIDs and remove unused UUIDs') key_ptn = re_compile('(?<=\s)([0-9A-Z]{24}|[0-9A-F]{32})(?=[\s;])') removed_lines = [] for line in fi_input(self.xcode_pbxproj_path, backup='.ubak', inplace=1): # project.pbxproj is an utf-8 encoded file line = line.decode('utf-8') key_list = key_ptn.findall(line) if not key_list: output_u8line(line) else: new_line = line # remove line with non-existing element if self.__result.get('to_be_removed') and any( i for i in key_list if i in self.__result['to_be_removed']): removed_lines.append(new_line) continue # remove incorrect entry that somehow does not exist in project node tree elif not all(self.__result.get(uuid) for uuid in key_list): self.vprint( "Some node(s) are not in generated result, remove this line :", key_list) removed_lines.append(new_line) continue else: for key in key_list: new_key = self.__result[key]['new_key'] new_line = new_line.replace(key, new_key) output_u8line(new_line) fi_close() tmp_path = self.xcode_pbxproj_path + '.ubak' if filecmp_cmp(self.xcode_pbxproj_path, tmp_path, shallow=False): unlink(self.xcode_pbxproj_path) rename(tmp_path, self.xcode_pbxproj_path) warning_print('Ignore uniquify, no changes made to "', self.xcode_pbxproj_path, sep='') else: unlink(tmp_path) self._is_modified = True success_print('Uniquify done') if removed_lines: warning_print( 'Following lines were deleted because of invalid format or no longer being used:' ) print_ng(*removed_lines, end='')
def replace_uuids_with_file(self): print 'replace UUIDs and remove unused UUIDs' uuid_ptn = re_compile('(?<=\s)[0-9A-F]{24}(?=[\s;])') for line in fi_input(self.xcode_pbxproj_path, backup='.bak', inplace=1): uuid_list = uuid_ptn.findall(line) if not uuid_list: print line, else: new_line = line # remove line with non-existing element if self.__result.get('to_be_removed') and any( i for i in uuid_list if i in self.__result['to_be_removed']): continue else: for uuid in uuid_list: new_line = new_line.replace(uuid, self.__result[uuid]['new_key']) print new_line, fi_close() unlink(self.xcode_pbxproj_path + '.bak')
def sort_pbxproj(self, sort_pbx_by_file_name=False): self.vprint('sort project.xpbproj file') lines = [] removed_lines = [] files_start_ptn = re_compile('^(\s*)files = \(\s*$') files_key_ptn = re_compile( '((?<=[A-Z0-9]{24} \/\* )|(?<=[A-F0-9]{32} \/\* )).+?(?= in )') fc_end_ptn = '\);' files_flag = False children_start_ptn = re_compile('^(\s*)children = \(\s*$') children_pbx_key_ptn = re_compile( '((?<=[A-Z0-9]{24} \/\* )|(?<=[A-F0-9]{32} \/\* )).+?(?= \*\/)') child_flag = False pbx_start_ptn = re_compile( '^.*Begin (PBXBuildFile|PBXFileReference) section.*$') pbx_key_ptn = re_compile( '^\s+(([A-Z0-9]{24})|([A-F0-9]{32}))(?= \/\*)') pbx_end_ptn = ('^.*End ', ' section.*$') pbx_flag = False last_two = deque([]) def file_dir_cmp(x, y): if '.' in x: if '.' in y: return cmp(x, y) else: return 1 else: if '.' in y: return -1 else: return cmp(x, y) for line in fi_input(self.xcode_pbxproj_path, backup='.sbak', inplace=1): # project.pbxproj is an utf-8 encoded file line = line.decode('utf-8') last_two.append(line) if len(last_two) > 2: last_two.popleft() # files search and sort files_match = files_start_ptn.search(line) if files_match: output_u8line(line) files_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile(files_match.group(1) + fc_end_ptn) if files_flag: if fc_end_ptn.search(line): if lines: lines.sort(key=lambda file_str: files_key_ptn.search( file_str).group()) output_u8line(''.join(lines)) lines = [] files_flag = False fc_end_ptn = '\);' elif files_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # children search and sort children_match = children_start_ptn.search(line) if children_match: output_u8line(line) child_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile( children_match.group(1) + fc_end_ptn) if child_flag: if fc_end_ptn.search(line): if lines: if self.main_group_hex not in last_two[0]: lines.sort( key=lambda file_str: children_pbx_key_ptn. search(file_str).group(), cmp=file_dir_cmp) output_u8line(''.join(lines)) lines = [] child_flag = False fc_end_ptn = '\);' elif children_pbx_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # PBX search and sort pbx_match = pbx_start_ptn.search(line) if pbx_match: output_u8line(line) pbx_flag = True if isinstance(pbx_end_ptn, tuple): pbx_end_ptn = re_compile( pbx_match.group(1).join(pbx_end_ptn)) if pbx_flag: if pbx_end_ptn.search(line): if lines: if sort_pbx_by_file_name: lines.sort( key=lambda file_str: children_pbx_key_ptn. search(file_str).group()) else: lines.sort(key=lambda file_str: pbx_key_ptn.search( file_str).group(1)) output_u8line(''.join(lines)) lines = [] pbx_flag = False pbx_end_ptn = ('^.*End ', ' section.*') elif children_pbx_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # normal output if not (files_flag or child_flag or pbx_flag): output_u8line(line) fi_close() tmp_path = self.xcode_pbxproj_path + '.sbak' if filecmp_cmp(self.xcode_pbxproj_path, tmp_path, shallow=False): unlink(self.xcode_pbxproj_path) rename(tmp_path, self.xcode_pbxproj_path) warning_print('Ignore sort, no changes made to "', self.xcode_pbxproj_path, sep='') else: unlink(tmp_path) self._is_modified = True success_print('Sort done') if removed_lines: warning_print( 'Following lines were deleted because of duplication:') print_ng(*removed_lines, end='')
def sort_pbxproj(self): print 'sort project.xpbproj file' lines = [] files_start_ptn = re_compile('^(\s*)files = \(\s*$') files_key_ptn = re_compile('(?<=[A-F0-9]{32} \/\* ).+?(?= in )') fc_end_ptn = '\);' files_flag = False children_start_ptn = re_compile('^(\s*)children = \(\s*$') children_pbx_key_ptn = re_compile('(?<=[A-F0-9]{32} \/\* ).+?(?= \*\/)') child_flag = False pbx_start_ptn = re_compile('^.*Begin (PBXBuildFile|PBXFileReference) section.*$') pbx_end_ptn = ('^.*End ', ' section.*$') pbx_flag = False last_two = deque([]) def file_dir_cmp(x, y): if '.' in x: if '.' in y: return cmp(x, y) else: return 1 else: if '.' in y: return -1 else: return cmp(x, y) for line in fi_input(self.xcode_pbxproj_path, backup='.bak', inplace=1): last_two.append(line) if len(last_two) > 2: last_two.popleft() # files search and sort files_match = files_start_ptn.search(line) if files_match: print line, files_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile(files_match.group(1) + fc_end_ptn) if files_flag: if fc_end_ptn.search(line): if lines: lines.sort(key=lambda file_str: files_key_ptn.search(file_str).group()) print ''.join(lines), lines = [] files_flag = False fc_end_ptn = '\);' elif files_key_ptn.search(line): lines.append(line) # children search and sort children_match = children_start_ptn.search(line) if children_match: print line, child_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile(children_match.group(1) + fc_end_ptn) if child_flag: if fc_end_ptn.search(line): if lines: if last_two[0] != self.__main_group_hex: lines.sort(key=lambda file_str: children_pbx_key_ptn.search(file_str).group(),cmp=file_dir_cmp) print ''.join(lines), lines = [] child_flag = False fc_end_ptn = '\);' elif children_pbx_key_ptn.search(line): lines.append(line) # PBX search and sort pbx_match = pbx_start_ptn.search(line) if pbx_match: print line, pbx_flag = True if isinstance(pbx_end_ptn, tuple): pbx_end_ptn = re_compile(pbx_match.group(1).join(pbx_end_ptn)) if pbx_flag: if pbx_end_ptn.search(line): if lines: lines.sort(key=lambda file_str: children_pbx_key_ptn.search(file_str).group()) print ''.join(lines), lines = [] pbx_flag = False pbx_end_ptn = ('^.*End ', ' section.*') elif children_pbx_key_ptn.search(line): lines.append(line) # normal output if not (files_flag or child_flag or pbx_flag): print line, fi_close() tmp_path = self.xcode_pbxproj_path + '.bak' if filecmp_cmp(self.xcode_pbxproj_path, tmp_path, shallow=False): unlink(self.xcode_pbxproj_path) rename(tmp_path,self.xcode_pbxproj_path) print 'Ignore, no changes made to {}'.format(self.xcode_pbxproj_path) else: unlink(self.xcode_pbxproj_path + '.bak')
def sort_pbxproj(self, sort_pbx_by_file_name = False): self.vprint('sort project.xpbproj file') lines = [] removed_lines=[] files_start_ptn = re_compile('^(\s*)files = \(\s*$') files_key_ptn = re_compile('((?<=[A-Z0-9]{24} \/\* )|(?<=[A-F0-9]{32} \/\* )).+?(?= in )') fc_end_ptn = '\);' files_flag = False children_start_ptn = re_compile('^(\s*)children = \(\s*$') children_pbx_key_ptn = re_compile('((?<=[A-Z0-9]{24} \/\* )|(?<=[A-F0-9]{32} \/\* )).+?(?= \*\/)') child_flag = False pbx_start_ptn = re_compile('^.*Begin (PBXBuildFile|PBXFileReference) section.*$') pbx_key_ptn = re_compile('^\s+(([A-Z0-9]{24})|([A-F0-9]{32}))(?= \/\*)') pbx_end_ptn = ('^.*End ', ' section.*$') pbx_flag = False last_two = deque([]) def file_dir_cmp(x, y): if '.' in x: if '.' in y: return cmp(x, y) else: return 1 else: if '.' in y: return -1 else: return cmp(x, y) for line in fi_input(self.xcode_pbxproj_path, backup='.sbak', inplace=1): # project.pbxproj is an utf-8 encoded file line = line.decode('utf-8') last_two.append(line) if len(last_two) > 2: last_two.popleft() # files search and sort files_match = files_start_ptn.search(line) if files_match: output_u8line(line) files_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile(files_match.group(1) + fc_end_ptn) if files_flag: if fc_end_ptn.search(line): if lines: lines.sort(key=lambda file_str: files_key_ptn.search(file_str).group()) output_u8line(''.join(lines)) lines = [] files_flag = False fc_end_ptn = '\);' elif files_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # children search and sort children_match = children_start_ptn.search(line) if children_match: output_u8line(line) child_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile(children_match.group(1) + fc_end_ptn) if child_flag: if fc_end_ptn.search(line): if lines: if self.main_group_hex not in last_two[0]: lines.sort(key=lambda file_str: children_pbx_key_ptn.search(file_str).group(), cmp=file_dir_cmp) output_u8line(''.join(lines)) lines = [] child_flag = False fc_end_ptn = '\);' elif children_pbx_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # PBX search and sort pbx_match = pbx_start_ptn.search(line) if pbx_match: output_u8line(line) pbx_flag = True if isinstance(pbx_end_ptn, tuple): pbx_end_ptn = re_compile(pbx_match.group(1).join(pbx_end_ptn)) if pbx_flag: if pbx_end_ptn.search(line): if lines: if sort_pbx_by_file_name: lines.sort(key=lambda file_str: children_pbx_key_ptn.search(file_str).group()) else: lines.sort(key=lambda file_str: pbx_key_ptn.search(file_str).group(1)) output_u8line(''.join(lines)) lines = [] pbx_flag = False pbx_end_ptn = ('^.*End ', ' section.*') elif children_pbx_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # normal output if not (files_flag or child_flag or pbx_flag): output_u8line(line) fi_close() tmp_path = self.xcode_pbxproj_path + '.sbak' if filecmp_cmp(self.xcode_pbxproj_path, tmp_path, shallow=False): unlink(self.xcode_pbxproj_path) rename(tmp_path, self.xcode_pbxproj_path) warning_print('Ignore sort, no changes made to "', self.xcode_pbxproj_path, sep='') else: unlink(tmp_path) self._is_modified = True success_print('Sort done') if removed_lines: warning_print('Following lines were deleted because of duplication:') print_ng(*removed_lines, end='')
def sort_pbxproj(self): self.vprint('sort project.xpbproj file') uuid_chars = len(self.main_group_hex) lines = [] files_start_ptn = re_compile('^(\s*)files = \(\s*$') files_key_ptn = re_compile('(?<=[A-F0-9]{{{}}} \/\* ).+?(?= in )'.format(uuid_chars)) fc_end_ptn = '\);' files_flag = False children_start_ptn = re_compile('^(\s*)children = \(\s*$') children_pbx_key_ptn = re_compile('(?<=[A-F0-9]{{{}}} \/\* ).+?(?= \*\/)'.format(uuid_chars)) child_flag = False pbx_start_ptn = re_compile('^.*Begin (PBXBuildFile|PBXFileReference) section.*$') pbx_end_ptn = ('^.*End ', ' section.*$') pbx_flag = False last_two = deque([]) def file_dir_cmp(x, y): if '.' in x: if '.' in y: return cmp(x, y) else: return 1 else: if '.' in y: return -1 else: return cmp(x, y) for line in fi_input(self.xcode_pbxproj_path, backup='.bak', inplace=1): # project.pbxproj is an utf-8 encoded file line = line.decode('utf-8') last_two.append(line) if len(last_two) > 2: last_two.popleft() # files search and sort files_match = files_start_ptn.search(line) if files_match: print(line, end='') files_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile(files_match.group(1) + fc_end_ptn) if files_flag: if fc_end_ptn.search(line): if lines: lines.sort(key=lambda file_str: files_key_ptn.search(file_str).group()) print(''.join(lines).encode('utf-8'), end='') lines = [] files_flag = False fc_end_ptn = '\);' elif files_key_ptn.search(line): lines.append(line) # children search and sort children_match = children_start_ptn.search(line) if children_match: print(line, end='') child_flag = True if isinstance(fc_end_ptn, unicode): fc_end_ptn = re_compile(children_match.group(1) + fc_end_ptn) if child_flag: if fc_end_ptn.search(line): if lines: if self.main_group_hex not in last_two[0]: lines.sort(key=lambda file_str: children_pbx_key_ptn.search(file_str).group(), cmp=file_dir_cmp) print(''.join(lines).encode('utf-8'), end='') lines = [] child_flag = False fc_end_ptn = '\);' elif children_pbx_key_ptn.search(line): lines.append(line) # PBX search and sort pbx_match = pbx_start_ptn.search(line) if pbx_match: print(line, end='') pbx_flag = True if isinstance(pbx_end_ptn, tuple): pbx_end_ptn = re_compile(pbx_match.group(1).join(pbx_end_ptn)) if pbx_flag: if pbx_end_ptn.search(line): if lines: lines.sort(key=lambda file_str: children_pbx_key_ptn.search(file_str).group()) print(''.join(lines).encode('utf-8'), end='') lines = [] pbx_flag = False pbx_end_ptn = ('^.*End ', ' section.*') elif children_pbx_key_ptn.search(line): lines.append(line) # normal output if not (files_flag or child_flag or pbx_flag): print(line, end='') fi_close() tmp_path = self.xcode_pbxproj_path + '.bak' if filecmp_cmp(self.xcode_pbxproj_path, tmp_path, shallow=False): unlink(self.xcode_pbxproj_path) rename(tmp_path, self.xcode_pbxproj_path) print('Ignore sort, no changes made to', self.xcode_pbxproj_path) else: unlink(tmp_path) print('Sort done')
def sort_pbxproj(self, sort_pbx_by_file_name=False): self.vprint('sort project.xpbproj file') lines = [] removed_lines = [] files_start_ptn = re_compile('^(\s*)files = \(\s*$') files_key_ptn = re_compile('((?<=[A-Z0-9]{24} \/\* )|(?<=[A-F0-9]{32} \/\* )).+?(?= in )') fc_end_ptn = '\);' files_flag = False children_start_ptn = re_compile('^(\s*)children = \(\s*$') children_pbx_key_ptn = re_compile('((?<=[A-Z0-9]{24} \/\* )|(?<=[A-F0-9]{32} \/\* )).+?(?= \*\/)') child_flag = False pbx_start_ptn = re_compile('^.*Begin (PBXBuildFile|PBXFileReference) section.*$') pbx_key_ptn = re_compile('^\s+(([A-Z0-9]{24})|([A-F0-9]{32}))(?= \/\*)') pbx_end_ptn = ('^.*End ', ' section.*$') pbx_flag = False last_two = deque([]) tempOutputFilename = self.xcode_pbxproj_path + '.tempoutput' def file_dir_order(x): x = children_pbx_key_ptn.search(x).group() return '.' in x, x orig_stdout = sys.stdout tempOutput = open(tempOutputFilename, 'w+') sys.stdout = tempOutput for line in fi_input(self.xcode_pbxproj_path): try: # project.pbxproj is an utf-8 encoded file line = decoded_string(line, 'utf-8') last_two.append(line) if len(last_two) > 2: last_two.popleft() # files search and sort files_match = files_start_ptn.search(line) if files_match: output_u8line(line) files_flag = True if isinstance(fc_end_ptn, six.text_type): fc_end_ptn = re_compile(files_match.group(1) + fc_end_ptn) if files_flag: if fc_end_ptn.search(line): if lines: lines.sort(key=lambda file_str: files_key_ptn.search(file_str).group()) output_u8line(''.join(lines)) lines = [] files_flag = False fc_end_ptn = '\);' elif files_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # children search and sort children_match = children_start_ptn.search(line) if children_match: output_u8line(line) child_flag = True if isinstance(fc_end_ptn, six.text_type): fc_end_ptn = re_compile(children_match.group(1) + fc_end_ptn) if child_flag: if fc_end_ptn.search(line): if lines: if self.main_group_hex not in last_two[0]: lines.sort(key=file_dir_order) output_u8line(''.join(lines)) lines = [] child_flag = False fc_end_ptn = '\);' elif children_pbx_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # PBX search and sort pbx_match = pbx_start_ptn.search(line) if pbx_match: output_u8line(line) pbx_flag = True if isinstance(pbx_end_ptn, tuple): pbx_end_ptn = re_compile(pbx_match.group(1).join(pbx_end_ptn)) if pbx_flag: if pbx_end_ptn.search(line): if lines: if sort_pbx_by_file_name: lines.sort(key=lambda file_str: children_pbx_key_ptn.search(file_str).group()) else: lines.sort(key=lambda file_str: pbx_key_ptn.search(file_str).group(1)) output_u8line(''.join(lines)) lines = [] pbx_flag = False pbx_end_ptn = ('^.*End ', ' section.*') elif children_pbx_key_ptn.search(line): if line in lines: removed_lines.append(line) else: lines.append(line) # normal output if not (files_flag or child_flag or pbx_flag): output_u8line(line) except: # abort current file write and resume to backup pbxproj file unlink(tempOutputFilename) raise XUniqueExit("Sort Failed") fi_close() tempOutput.close() sys.stdout = orig_stdout if filecmp_cmp(self.xcode_pbxproj_path, tempOutputFilename, shallow=False): unlink(tempOutputFilename) warning_print('Ignore sort, no changes made to "', self.xcode_pbxproj_path, sep='') else: unlink(self.xcode_pbxproj_path) rename(tempOutputFilename, self.xcode_pbxproj_path) self._is_modified = True success_print('Sort done') if removed_lines: warning_print('Following lines were deleted because of duplication:') print_ng(*removed_lines, end='')