iOS 自动化打包工具-利用Python修改源文件,自动切换服务器地址

在不断填坑中前进。。

Posted by 三十一 on June 14, 2018

iOS 自动化打包工具-利用Python修改源文件,自动切换服务器地址

之前写过一个打包工具 自动化的一些实践

使用了一段时间后,觉得有两个问题:

  1. 无法切换服务器地址
  2. 每次 Swift 版本更新,需要重新编译

所以觉得抛弃 Swift ,重写写一个版本的工具。

1. 用户输入打包的服务器地址以及本次 APP 更新的内容

没什么好讲的,直接看代码

import sys
from termcolor import colored

address = ""
updateDescription = ""
updateInfoFile = "updateInfoFile/XXXXX.txt"

def inputServer():
    print(colored("输入服务器地址,服务器地址如下:","blue"))
    print(colored("""
    "测试内网138": "http://XXX:8082",
    "测试外网119": "http://XXX:8082",
    "测试Https138": "https://XXX",
    "验收环境": "http://XXX:8000",
    "Https验收环境": "https://XXX:8083",
    "生产环境": "http://XXX:8000",
    "生产https环境": "https://XXX",
        ""","yellow"))
    address = input()
    servers = ["测试内网138","测试外网119","测试Https138","验收环境","Https验收环境","生产环境","生产https环境"]
    if address not in servers:
        print(colored("请输入正确的服务器地址","red"))
        inputServer()
    else:
        print(colored("输入的地址为 %s"%(address),"green"))
        return address



def inputUpdateInfo(server):
    print("请输入本次更新内容")

    updateInfo = file_write()
    print(updateInfo)
    if updateInfo:
        updateDescription = "优你家 (%s)\n下载地址:https://www.pgyer.com/v0H1\n更新:\n%s"%(server,updateInfo)
        print(colored("本次更新内容为 %s"%(updateDescription),"green"))
        return updateDescription
    else:
        print(colored("请输入更新内容","red"))
        inputUpdateInfo(server)



def file_write():
    f = open(updateInfoFile, 'w')
    print('请输入内容【单独输入\':q\'保存退出】:')
    while True:
        file_content = input()
        if file_content != ':q':
            f.write('%s\n' % file_content)
        else:
            break
    f.close()

    f = open(updateInfoFile, 'r')
    updateInfo=f.read()
    f.close()
    return updateInfo

值得说的一点是: 输入 App 更新内容的时候,为了看起来清晰明了需要换行,但是 Pythoninput 函数,一旦输入回车,输入过程就结束了,输入 \n 换行符,不知道什么原因,也没有正确的显示出来。 最后只能以写文件的方式来解决这个问题。参看链接:python将回车作为输入内容

2. 切换服务器地址

在第一步中确定了打包地址,以及更新内容以后,接下来就是根据用户的输入,修改项目工程的源文件,切换服务器地址。

我们公司的服务器地址存在一个配置文件中,形式类似于:

//测试内网138
//NSString * const BaseAddress  = @"http://XXX:8082";
//测试外网119
//NSString * const BaseAddress  = @"http://XXXX:8082";
//测试Https138
//NSString * const BaseAddress  = @"https://XXXX.cn";
//验收环境
NSString * const BaseAddress  = @"http://XXX:8000";
//Https验收环境
//NSString * const BaseAddress  = @"https://XXX:8083";
//生产环境
//NSString * const BaseAddress  = @"http://XXX:8000";
//生产https环境
//NSString * const BaseAddress  = @"https://XXX";

我们要做的就是找到要打包的服务器地址哪一行,然后让它处于生效的状态。

  1. 查找到包含 BaseAddress 的行
  2. 判断这行是否注释,如果没有注释,将其注释
  3. 判断打包服务器环境是那个,找出服务器环境对应的那行,去除前面注释

用的了一点点正则:

  • re.match(".*BaseAddress.*", line) 是匹配 包含 BaseAddress 的行
  • re.match("^//", line) 是匹配开头为 // 的行
  • re.match(".*%s.*"%(serverAdd), line) 是匹配 包含 生效服务器地址 serverAdd 的行

其他的就没什么好说的,直接看代码吧。

def formatServerContent(file):
    fr = open(file,'r',encoding="utf-8")
    lines = fr.readlines()
    for line in lines:
        # 匹配 行中 带有 BaseAddress 的行
        if re.match(".*BaseAddress.*", line) != None:
            # 匹配开头 是否为 //
            if re.match("^//", line) is None:
                # 如果开头 不为 // ,为头添加 //
                index =lines.index(line)
                lines[index] = "//" + line

    #写文件
    fw = open(file,'w+')
    fw.writelines(lines)


def modify_to_target_server(file,server):
    # 先复原文件
    formatServerContent(file)

    serverAdd = switch_to_server(server)

    fr = open(file,'r',encoding="utf-8")
    lines = fr.readlines()
    for line in lines:
        # 匹配 行中 带有 要打包服务器地址 的行
        if re.match(".*%s.*"%(serverAdd), line) != None:
            # 匹配开头 是否为 //
            if re.match("^//", line) != None:
                # 如果开头 为 // ,为头除去 //
                index =lines.index(line)
                lines[index] = line[2:]

    #写文件
    fw = open(file,'w+')
    fw.writelines(lines)

def switch_to_server(argument):
    switcher = {
        "测试内网138": "http://XXX:8082",
        "测试外网119": "http://XXX:8082",
        "测试Https138": "https://XXX",
        "验收环境": "http://XXX:8000",
        "Https验收环境": "https://XXX:8083",
        "生产环境": "http://XXX:8000",
        "生产https环境": "https://XXX",
    }
    return switcher.get(argument, "nothing")

3. 打包并上传到蒲公英

# -*- coding: utf-8 -*-
import os
import sys
import time
import user_Input_Info as input_info
import change_file_content as change_server
# 项目根目录
project_path = "project_path"
# 服务器地址配置文件
serverFilePath = project_path + "XXX.m"
#工程名称
projectName = "XXXX"+".xcodeproj"
#scheme
scheme = "XXXX"
# 打包后ipa存储目录
targerIPA_parth = "XXXXX"

#时间戳
timeStr = time.strftime('%Y-%m-%d_%H-%M-%S',time.localtime(time.time()))
#activePath
activePath = targerIPA_parth  + timeStr +"/" +timeStr+".xcarchive"
#蒲公英Key
PGY_key="XXXXX"
#蒲公英APIKey
PGY_APIkey="XXXXXX"
DOWNLOAD_BASE_URL = "http://www.pgyer.com"
PGYER_UPLOAD_URL  = "http://www.pgyer.com/apiv1/app/upload"



# 清理项目 创建build目录
def clean_project_mkdir_build():
    print("******clean******")

    os.system('cd %s;xcodebuild clean -project "%s" -scheme %s -configuration release  | xcpretty' % (project_path,projectName,scheme)) # clean 项目

def build_project():
    print("build xcarchive start")
    print("activePath %s"%(activePath))

    os.system('xcodebuild -list | xcpretty')
    os.system('cd %s;xcodebuild archive -project "%s" -scheme %s -configuration release -sdk iphoneos11.1  IPHONEOS_DEPLOYMENT_TARGET=9.0 -archivePath %s -quiet | xcpretty;  ' % (project_path,projectName,scheme,activePath))
    print("build xcarchive end")

# 打包ipa 并且保存在桌面
def build_ipa():
    print("build IPA start")
    os.chdir(targerIPA_parth)
    os.system('xcodebuild -exportArchive -archivePath %s -exportPath %s/%s -exportOptionsPlist %sIPA.plist -quiet | xcpretty'%(activePath,targerIPA_parth,timeStr,targerIPA_parth))
    print("build IPA end")


def updateSVN():
    print("更新SVN数据")
    os.chdir(project_path)

    print("更新SVN数据 %s"%(os.getcwd()))
    os.system('svn update ')
    time.sleep(1)

    print("更新SVN完成")

def updateIPAToPGY(updateDescription):
    print("开始上传蒲公英")

    os.system ('curl -F \"updateDescription=%s\" -F \"file=@%s%s/copm_cust.ipa\" -F \"uKey=%s\" -F \"_api_key=%s\" https://qiniu-storage.pgyer.com/apiv1/app/upload'%(updateDescription,targerIPA_parth,timeStr,PGY_key,PGY_APIkey))
    print("上传蒲公英完成")

def creatQQMessage(updateDescription):
    file_object = open('xxxx/QQ.txt', 'w')
    file_object.write(updateDescription)
    file_object.close()
    os.system("open /XXXX/QQ.txt")
    os.system("open /XXXX/QRCode.rtfd")


def main():
    #更新SVN
    updateSVN()

    # 用户输入要打包的服务器地址
    address = input_info.inputServer()
    # 用户输入本次更新的信息
    updateDescription = input_info.inputUpdateInfo(address1)
    print(str(updateDescription))
    # 修改源文件
    change_server.modify_to_target_server(serverFilePath,address)

    # 清理并创建build目录
    clean_project_mkdir_build()
    # 编译项目文件并 执行编译目录
    build_project()
    # 打包ipa 并制定到桌面
    build_ipa()
    #上传到蒲公英
    updateIPAToPGY(updateDescription)
    # 生成更新下载信息
    creatQQMessage(updateDescription)

# 执行
main()

我把这个简陋的工具上传到了YunisTool