iOS-使用python脚本替换方法引用同时修改导入的头文件

背景

iOS项目废弃旧的类及方法引用,替换成新的类及新的方法, 如果调用较多, 手动替换将是一件费时费力且容易出错的事情,交给脚本就轻松多了

归根结底, 懒惰是第一生产力

实现效果

  • 替换旧的方法引用为新的方法引用
  • 删除旧的方法需要导入的头文件
  • 新增新的方法需要导入的头文件, 放在当前类所有import的最后一行
  • 同一个类不会重复导入相同的头文件
  • 若和pod目录平级,不会修改pod目录下的文件
  • 终端打印修改的内容和行数

使用方式

  1. 脚本需要放在与要替换的工程代码最外层文件夹平级

    eg:
    20190827165629.png
  1. cd该目录,执行语句
python replaceMethod.py '要废弃的方法调用' '新的方法调用' '要废弃的方法调用的头文件导入' '新的方法调用的头文件导入'

eg : 要替换 [JYUserInfoManager userToken]
引用为 JYLoginMaintUser.token

因为 [JYUserInfoManager userToken] 需要导入头文件 #import <JYModuleDeprecated/JYUserInfoManager.h>

JYLoginMaintUser.token 需要导入头文件
#import <JYModuleAccount/JYLoginMaintUser.h>

执行

python replaceMethod.py '[JYUserInfoManager userToken]' 'JYLoginMaintUser.token' '#import <JYModuleDeprecated/JYUserInfoManager.h>' '#import <JYModuleAccount/JYLoginMaintUser.h>'

脚本源码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#0.1.0
import os
import sys
import os.path
import shutil

def main():
    methodName = sys.argv[1]
    newMethodName =  sys.argv[2]
    removeName = sys.argv[3]
    importName = sys.argv[4]
    print ('methodName:',  methodName )
    print ('newMethodName:',  methodName )
    print ('importName:',  importName)
    print ('removeName:',  removeName)

    # os.getcwd() 方法用于返回当前工作目录
    current_path = os.getcwd()
    print('ℹ️  脚本所在路径:' + current_path)

    code_files = []
    #1. 找到除了Pods文件夹下的代码文件
    for root, dirs, files in os.walk(current_path):
        for file in files:
            # 找到所有类
            if os.path.splitext(file)[1] == '.m' or  os.path.splitext(file)[1] == '.mm' :
                
                code_file_path = os.path.join(root,file)
                #如果文件是在pods中,就忽略掉
                if code_file_path.find('/Pods/')<0:
                    code_files.append(code_file_path)
                    


    print('类的总数: %d'  %len(code_files))


    print('ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️  获取含有' + methodName + '方法的类 ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️  ')
    print('\n')


   #2. 找到所有包含原方法的类 
    methodClassList = []

    for code_file in code_files:
        read_file = open(code_file)
        file_contents = read_file.read()
        read_file.close()

        method_file_list = file_contents.split('\n')

        for method_file in method_file_list:
            if methodName in method_file:
                if code_file not in methodClassList:
                   methodClassList.append(code_file)
                   print('ℹ️  包含该方法的类:' + code_file)


    print('包含该方法类的总数: %d'  %len(methodClassList)) 

    #3. 找到该方法, 替换成新的方法
    for code_file in methodClassList:
        read_file = open(code_file)
        file_contents = read_file.readlines()
        read_file.close()

        write_file = open(code_file, "w")
        for line in file_contents:
            if methodName in line:
                line =  line.replace(methodName,newMethodName)
                print('ℹ️  替换:' + methodName + '为' + newMethodName)
                print('-----line:' + line)
            write_file.write(line)
        write_file.close()


#4. 删除原本导入的头文件
    for code_file in methodClassList:
        read_file = open(code_file)
        file_contents = read_file.readlines()
        read_file.close()

        write_file = open(code_file, "w")
        for line in file_contents:
            if removeName in line:
                continue
            write_file.write(line)
        write_file.close()



#5.添加需要导入的头文件 
    for code_file in methodClassList:
        read_file = open(code_file)
        file_contents = read_file.read()
        read_file.close()

         #循环获取 #import数组
        import_file_list = file_contents.split('\n')

        line = 0
        maxline = 0;  #在最后一行import 后导入头文件
        for import_file in import_file_list:
            line = line + 1
            if '#import' in import_file:
                 if maxline < line:
                     maxline = line;
                 # print('ℹ️  包含该方法的类:' + code_file)
                 # print('import_file:    ', import_file)
                 # print('行数:    ', line)
        print('ℹ️  包含该方法的类:' + code_file)         

        checkSelfResult =   checkSelf(code_file, importName)
        if checkSelfResult == False:
            if importName not in  import_file_list:
                 writeinfile(code_file, importName, maxline + 1)

#判断是否是要import的类本身
def checkSelf (code_file, importName):
    #导入pod中库 忽略
    if  '#import<' in  importName.replace(" ", "") : 
        return False
    import_class_name =  importName.replace(" ", "").split('#import"')[1].split('.h')[0]  

    if(import_class_name in code_file):
        return True
    else :
        return False


 #写入文件
def writeinfile(path, content, line=0):
    lines = []
    with open(path, 'r') as r:
        for l in r:
            lines.append(l)
    if line == 0:
        lines.insert(0, '{}\n'.format(content))
    else:
        lines.insert(line-1, '{}\n'.format(content))
    s = ''.join(lines)

    with open(path, 'w') as m:
        m.write(s)
        print('写入 :' + content)
        print('💕写入行数: %d' %line)
        m.close()       

if __name__ == '__main__':
    main()

写在最后

完全业余写法, 仅用于限于使用, 不建议学习

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容