由Podfile组建的工程里,每一个模块都有一个对应的PodSpec文件,在Pods/Headers中,每一个Pods的Header都有Public和Private之分。清楚的知道哪些文件是公开还是私有,对未来模块化框架下开发有很多作用。
这次脚本使用Python开发,顺便学习下。
思路:
1、遍历所有Pods中的文件以及文件的import,获得一个大的字典。如:
{pod1:{file1:file1node,file2:file2node}}
pod1是pod名字,file1是文件名,file1node是一个包含多个信息的文件实例。
2、递归遍历每个文件和文件里的import,如果检测到import的文件不是当前pods,标记为公开。(在一个Pods中,递归过的文件标记为已递归不再递归,加快速度)
3、扫描字典,把标记为公开的文件放在数组里,提供结果。
4、把结果分别写进各个pod的podspec中:s.public_header_files = xxx。podspec是ruby格式的。可以把结果写在另一个文件里。
#!/usr/bin/python
#coding:utf-8
import os
import os.path
import re
import sys
import glob
#要遍历的pod目录
rootdirs = [
'pod1'
]
#{pods名:{文件名:WeiboFile}}
WeiboFiles = {}
class WeiboFile(object):
def __init__(self,filename, podsName, path, imports, isPublic, isRecursion):
self.filename = filename
self.podsName = podsName
self.path = path
self.imports = imports
self.isPublic = isPublic
self.isRecursion = isRecursion
"""
遍历Pod,创建 { pods:{文件名:文件类} }
"""
def InitFileInPod(_pod):
for root,dirs,files in os.walk(_pod):
for filename in files:
# print filename
if re.search('.*\.(h|m|pch)',filename,flags=0): #如果是.hm文件
node = WeiboFile(filename,_pod,root+'/'+filename,[],False,False)
if not WeiboFiles.has_key(_pod):WeiboFiles.update({_pod:{}})
WeiboFiles[_pod].update({filename:node})
def InitFileInPods(_pods):
for _pod in _pods:
InitFileInPod(_pod)
"""
遍历WeiboFiles里的文件,把文件里所有import文件塞到实例中
"""
def ImportsInFile(_filePath):
imports = []
readFile = open(_filePath)
while 1:
line = readFile.readline()
if not line:
break
if re.search('.*#import.*',line,flags=0):
importfile = re.split('\"|<|>',line)[1]
imports.append(re.split('/',importfile)[-1]) #有些import中带有/ 如#import <WBWebBrowser/xxx.h>
return imports
def InitImportsForFileNodes(_FileNodes):
for filename,fileNodes in _FileNodes.items():
for _file,node in fileNodes.items():
_path = node.path
node.imports = ImportsInFile(_path)
"""
Tools
"""
#把所有isRecursion置为0
def ResetIsRecursion(_FileNodes):
for podsName, _files in _FileNodes.items():
for fileName, node in _files.items():
node.isRecursion = False
#根据文件名获取一个node
def NodeByFileName(_filename,_FileNodes):
nodes = []
for podsName, _files in _FileNodes.items():
for fileName, node in _files.items():
if _filename == fileName:
nodes.append(node)
if len(nodes) > 0:return nodes
return False
#打印所有Public
def AllPublic(_FileNodes):
result = {}
for podsName, _files in _FileNodes.items():
for fileName, node in _files.items():
if not node.isPublic:continue
if not result.has_key(node.podsName):result.update({node.podsName:[]})
result[node.podsName].append(node.path[len(node.podsName)+1:])
return result
"""
开始递归遍历node
"""
def RecursionNodes(_FileNodes):
for podsName,dicts in _FileNodes.items():
ResetIsRecursion(_FileNodes)
RecursionPods(podsName,dicts)
def RecursionPods(_podsName,_dicts):
for filename,node in _dicts.items():
# print filename + "File In Recursion ...."
RecursionNode(_podsName,node)
# print filename + "File Recursion Successed!"
def RecursionNode(_podsName,_node):
imports = _node.imports
if _node.podsName != _podsName : _node.isPublic = True
for filename in imports:
_imNodes = NodeByFileName(filename,WeiboFiles)
if _imNodes == False: continue
for _imNode in _imNodes:
# if _node.filename == "TweetterAppDelegate.m" and filename == "WBWebBrowserLocalResourceProtocol.h":
# print _imNode.podsName
# print _podsName
if _imNode.podsName != _podsName :
_imNode.isPublic = True #当前节点不属于当前pods,标记为public
if not _imNode.isRecursion : #在当前pods如果没递归过,进行递归
_imNode.isRecursion = True
RecursionNode(_podsName,_imNode)
"""
写文件
"""
def WritePublicHeadersToRbFile(_result):
for podsname,files in _result.items():
f = open(podsname+'/PublicHeaders.rb','w')
f.write('$'+re.split('/',podsname)[-1]+'=')
f.write('[\n"')
f.write('",\n"'.join(files))
f.write('"\n]')
f.close()
def WriteToPodfile(_result):
for podsname,files in _result.items():
filepath = glob.glob(r"%s/*.podspec"%podsname)
for podspecfile in filepath:
WritePodSpec(podspecfile,podsname)
def WritePodSpec(podspecfile,podsname):
f = open(podspecfile,'r+')
lines = f.readlines()
f.seek(0,0)
for line in lines:
if re.search('.*public_header_files.*',line):
lines.remove(line)
for line in lines:
if re.search('.*require_relative.*',line):
lines.remove(line)
for line in lines:
if re.search('.*publicHeaders.*',line):
lines.remove(line)
f.write('require_relative "PublicHeaders.rb"\n')
f.write('publicHeaders=$'+re.split('/',podsname)[-1]+'\n')
totoalcount = len(lines)
targetindex = 0;
for line in lines[::-1]:
if len(line.strip())>0 and re.search('\s*end\s*(?!\w)',line):
targetindex = lines.index(line)
break
for index,line in enumerate(lines):
if index == targetindex:
f.write(" s.public_header_files = publicHeaders\n")
f.write(line)
f.close()
#初始化大字典 { pods:{文件名:文件类} }
InitFileInPods(rootdirs)
#遍历大字典,把所有import塞入文件类中
InitImportsForFileNodes(WeiboFiles)
#开始递归标记
RecursionNodes(WeiboFiles)
#{podname:[]}
result = AllPublic(WeiboFiles)
WritePublicHeadersToRbFile(result)
WriteToPodfile(result)