def modifyEnginCompilerFlags(file_recorder): if m_isNoDingXiang == "1": return # 修改 xcode 工程 projPath = getEngineConfigPath() Common.assertExit(os.path.isfile(projPath), '文件 %s 不存在' % projPath) file_recorder.record_file(projPath) sys.path.append(os.path.join(os.path.dirname(__file__), 'obscure')) from modify_pbxproj import XcodeProject pbx_obj = XcodeProject.Load(projPath) build_phase = pbx_obj.get_build_phases('PBXSourcesBuildPhase', 'libcocos2d iOS') build_files = pbx_obj.get_build_files_for_phases(build_phase) need_skip_files = [] if ENGINE_SKIP_PERCENT >= 100: need_skip_files = build_files else: skip_count = int(len(build_files) * ENGINE_SKIP_PERCENT / 100) import random random.seed() random.shuffle(build_files) for i in range(skip_count): need_skip_files.append(build_files[i]) for f in need_skip_files: setting = {'COMPILER_FLAGS': '-skip-steec'} pbx_obj.set_build_file_settings(f, setting) if pbx_obj.modified: pbx_obj.save()
def createNewProj(file_recorder, tmp_files): srcDir = os.path.join(m_projectDir, "%s.xcodeproj" % m_projectName) dstDir = os.path.join(m_projectDir, "%s.xcodeproj" % m_newProjName) FileUtils.copyDirctory(srcDir, dstDir) tmp_files.append(dstDir) # delete the origin project dir # file_recorder.record_folder(srcDir) # FileUtils.removeDirectory(srcDir) # 拷贝配置文件 srcFile = os.path.join(m_projectDir, "WeiLeProjV3-mobile.entitlements") Common.assertExit(os.path.isfile(srcFile), "文件 %s 不存在" % srcFile) dstFile = os.path.join(m_projectDir, "%s-mobile.entitlements" % m_newProjName) FileUtils.copyFile(srcFile, dstFile) tmp_files.append(dstFile) # 修改工程名字 projFilePath = getProjectConfigPath() Sed.replaceContent(m_projectName, m_newProjName, projFilePath) # 移除临时文件 for item in os.listdir(dstDir): full_path = os.path.join(dstDir, item) if full_path == projFilePath: continue if os.path.isdir(full_path): FileUtils.removeDirectory(full_path) elif os.path.isfile(full_path): FileUtils.removeFile(full_path)
def getAbspath(key): Common.assertExit(m_jsonObj[key], "config配置文件缺少参数key=" + key) if os.path.isabs(m_jsonObj[key]): return m_jsonObj[key] configDir = FileUtils.getFileDirectory(m_configPath) return FileUtils.getAbsoluteFromPath(configDir, m_jsonObj[key])
def findPlistInfoForKey(key): tmpPlistPath = getTmpPlistPath() cmd = "/usr/libexec/PlistBuddy -c 'Print %s' %s" % (key, tmpPlistPath) result = Common.getCmdResult(cmd) Common.assertExit( result.find(key) == -1, "查找字段不存在:key=" + key + "(苹果对证书信息做了修改,请查看桌面/Package/tmp.plist数据格式)") return result
def installP12(): p12Path = getAbspath("p12_path") Common.assertExit(os.path.isfile(p12Path), "p12证书文件不存在,请检查配置") p12Password = m_jsonObj["p12_password"] Common.assertExit(p12Password, "未配置参数p12_password") p12Cmd = "security import %s -k /Users/%s/Library/Keychains/login.keychain -P %s -T /usr/bin/codesign" % ( p12Path, Common.getUserName(), p12Password) Common.runCmd(p12Cmd)
def resEncryptByDirName(dirName): encryptScript = os.path.normpath( os.path.abspath( os.path.join(os.path.dirname(__file__), '../../ResEncrypt/ResEncrypt.py'))) if None == encryptScript: return targetDir = os.path.join(m_appPath, dirName) Common.assertExit(os.path.isdir(targetDir), "配置games文件不存在:" + dirName) ASSETS_ENCRYPT_EXCLUDE_CFG = ["mj_common/images/card_packer/*.png"] sys.path.append(os.path.dirname(encryptScript)) from ResEncrypt import ResEncrypt encryptor = ResEncrypt(targetDir, targetDir, True, ASSETS_ENCRYPT_EXCLUDE_CFG, False) encryptor.do_encrypt()
def copyConfigFile(file_recorder): targetConfigFile = FileUtils.getAbsolutePath("./shell_script/config.json") file_recorder.record_file(targetConfigFile) FileUtils.copyFile(m_configPath, targetConfigFile) configDir = FileUtils.getFileDirectory(m_configPath) sourceCfgDir = os.path.join(configDir, "cfg") Common.assertExit(os.path.isdir(sourceCfgDir), "cfg配置文件夹不存在" + sourceCfgDir) # 检查 cfg_package 中是否定义了 APPLE_ID cfg_pkg_file = os.path.join(sourceCfgDir, "cfg_package.lua") Common.assertExit(os.path.isfile(cfg_pkg_file), "cfg配置文件夹中不存在 cfg_package 文件") f = open(cfg_pkg_file) content = f.read() f.close() if content.find("APPLE_ID") == -1: Common.assertExit(False, "cfg_package 中未配置 APPLE_ID ") targetCfgDir = FileUtils.getAbsolutePath("./shell_script/cfg") file_recorder.record_folder(targetCfgDir) FileUtils.replaceCopyDirctory(sourceCfgDir, targetCfgDir)
def loadConfig(): global m_projectDir global m_infoPlistPath global m_projectName global m_schemeName global m_versionName global m_buildName global m_newDisplayName global m_newBundleId global m_archiveType global m_profilePath global m_configPath global m_jsonObj global m_outputPath global m_games global m_newProjName global m_newSchemeName Common.assertExit(len(sys.argv[1:]) != 0, "请传入配置文件绝对路径") Common.assertExit(os.path.isfile(sys.argv[1]), "传入参数文件不存在") m_configPath = sys.argv[1] # print "使用测试配置" # m_configPath = "/Users/weile/Desktop/SVN/tools/PackIOS/proj_template/config.json" # "game_name": "家乡棋牌·微乐", # "pkg_name": "com.wljiaxiang.mj", # "version_name": "1.1.1", # "build_name": "1.1.1.7", m_jsonObj.loadFromFilePath(m_configPath) m_projectDir = os.path.join(os.path.dirname(__file__), "proj.ios.demo/com.weile.test") m_infoPlistPath = os.path.join(m_projectDir, "Info.plist") m_archiveType = m_jsonObj["archive_type"] Common.assertExit(m_archiveType == 'AdHoc' or m_archiveType == 'AppStore', "archive_type参数只能是AdHoc和AppStore") paths = { Archive_Type_Key_AdHoc: getAbspath("profile_path_AdHoc"), Archive_Type_Key_AppStore: getAbspath("profile_path_AppStore"), } m_profilePath = paths[m_archiveType] Common.assertExit(os.path.isfile(m_profilePath), "配置证书文件不存在,请检查配置") m_projectName = "demo" m_schemeName = "com.weile.test" m_versionName = m_jsonObj["version_name"] m_buildName = m_jsonObj["build_name"] m_newDisplayName = m_jsonObj["game_name"] m_newBundleId = m_jsonObj["pkg_name"] m_newProjName = m_jsonObj["proj_name_new"] Common.assertExit(m_newProjName, "必须配置 proj_name_new 参数") Common.assertExit(m_projectName != m_newProjName, "proj_name_new 与 project_name 的值不能相同") m_newSchemeName = m_newProjName Common.assertExit(m_jsonObj["build_name"], "必须配置build_name参数") if m_jsonObj["output"]: m_outputPath = getAbspath("output") else: m_outputPath = None
def loadConfig(): global m_appPath global m_jsonObj Common.assertExit(len(sys.argv[1:]) != 0, "请传入配置文件绝对路径") Common.assertExit(os.path.isdir(sys.argv[1]), "传入参数文件夹不存在") m_appPath = sys.argv[1] configPath = FileUtils.getAbsolutePath("config.json") m_jsonObj = JsonObj() m_jsonObj.loadFromFilePath(configPath) Common.assertExit(Common.isArrayType(m_jsonObj[kGames]), "必须设置参数games") Common.assertExit(m_jsonObj[kCfgFiles], "必须设置参数cfg_files") Common.assertExit(m_jsonObj[kPkgName], "必须设置参数pkg_name") Common.assertExit(m_jsonObj[kRegion], "必须设置参数region")
for parent, dirs, files in os.walk(srcPath): for f in files: full_path = os.path.join(parent, f) rel_path = os.path.relpath(full_path, m_appPath) target_path = os.path.join(m_appPath, getHashPath(rel_path)) target_dir = os.path.dirname(target_path) if not os.path.isdir(target_dir): os.makedirs(target_dir) shutil.copy2(full_path, target_path) # 移除原始文件 shutil.rmtree(srcPath) if __name__ == "__main__": Common.assertExit(len(sys.argv[2:]) != 0, "第二个参数不能为空,必须是${CONFIGURATION}") # Debug版本不处理 appPath = sys.argv[1] srcPath = os.path.join(appPath, "src") # 读取配置表 loadConfig() # 生成 native 环境信息文件 utils.write_native_info(os.path.join(srcPath, 'NativeInfo.lua'), { "no_agora": "true", "ios_no_h5": "true" }) if sys.argv[2] == "Debug":
def loadConfig(): global m_projectDir global m_infoPlistPath global m_notify_info_plist_path global m_projectName global m_schemeName global m_versionName global m_buildName global m_newDisplayName global m_newBundleId global m_newNotifyBundleId global m_archiveType global m_profilePath global m_notifProfilePath global m_configPath global m_jsonObj global m_outputPath global m_games global m_newProjName global m_newSchemeName global m_isNoDingXiang # 是否不使用顶象加固 Common.assertExit(len(sys.argv[1:]) != 0, "请传入配置文件绝对路径") Common.assertExit(os.path.isfile(sys.argv[1]), "传入参数文件不存在") m_configPath = sys.argv[1] # print "使用测试配置" # m_configPath = "/Users/weile/Desktop/SVN/tools/PackIOS/proj_template/config.json" m_jsonObj.loadFromFilePath(m_configPath) m_isNoDingXiang = m_jsonObj["isNoDingXiang"] m_projectDir = getAbspath("project_dir") m_infoPlistPath = getAbspath("info_plist_path") m_notify_info_plist_path = FileUtils.getAbsoluteFromPath( m_projectDir, "notificationService/Info.plist") m_archiveType = m_jsonObj["archive_type"] Common.assertExit(m_archiveType == 'AdHoc' or m_archiveType == 'AppStore', "archive_type参数只能是AdHoc和AppStore") paths = { Archive_Type_Key_AdHoc: getAbspath("profile_path_AdHoc"), Archive_Type_Key_AppStore: getAbspath("profile_path_AppStore"), } m_profilePath = paths[m_archiveType] Common.assertExit(os.path.isfile(m_profilePath), "配置证书文件不存在,请检查配置") notifyPaths = { Archive_Type_Key_AdHoc: getAbspath("notifProfile_path_AdHoc"), Archive_Type_Key_AppStore: getAbspath("notifProfile_path_AppStore"), } m_notifProfilePath = notifyPaths[m_archiveType] Common.assertExit(os.path.isfile(m_notifProfilePath), "NotificationService证书文件不存在,请检查配置") m_projectName = m_jsonObj["project_name"] m_schemeName = m_jsonObj["scheme_name"] m_versionName = m_jsonObj["version_name"] m_buildName = m_jsonObj["build_name"] m_newDisplayName = m_jsonObj["game_name"] m_newBundleId = m_jsonObj["pkg_name"] m_newNotifyBundleId = m_newBundleId + ".notifyService" m_games = m_jsonObj["games"] m_newProjName = m_jsonObj["proj_name_new"] Common.assertExit(m_jsonObj["app_scheme"], "必须配置app_scheme参数") Common.assertExit(m_jsonObj["weixin_id"], "必须配置weixin_id参数") Common.assertExit(m_newProjName, "必须配置 proj_name_new 参数") Common.assertExit(m_projectName != m_newProjName, "proj_name_new 与 project_name 的值不能相同") m_newSchemeName = "%s-mobile" % m_newProjName if m_jsonObj["track_id"] is None: # track_id 必须配置。如果配置为空字符串,效果与不集成热云 SDK 一致 Common.assertExit(False, "必须配置track_id参数,请联系商务获取热云的 app key") if (not m_jsonObj["getui_appId"] or not m_jsonObj["getui_appKey"] or not m_jsonObj["getui_appSecret"] ) and m_jsonObj["turnOffPush"] != "1": # getui 必须配置。如不需要getui需要在config.json文件里添加"turnOffPush": "1" Common.assertExit(False, "必须配置getui参数,个推后台获取") Common.assertExit(m_jsonObj["region"], '必须配置region参数,值为地区码字符串。如:"region":"23"') Common.assertExit(m_jsonObj["build_name"], "必须配置build_name参数") if m_jsonObj["output"]: m_outputPath = getAbspath("output") else: m_outputPath = None
def genResFilesInfo(file_recorder): headerPath = os.path.join(m_projectDir, RES_INFO_HEADER_PATH) Common.assertExit(os.path.isfile(headerPath), '%s 文件不存在' % headerPath) # 扫描需要记录的文件信息 curDir = os.path.dirname(__file__) hallRoot = os.path.dirname(os.path.dirname(curDir)) srcPath = os.path.join(hallRoot, 'src') resPath = os.path.join(hallRoot, 'res') gamesDir = os.path.join(os.path.dirname(hallRoot), 'games') cfgDir = os.path.join(curDir, 'shell_script/cfg') relative_paths = {} scanDirs = {srcPath: 'src', resPath: 'res', cfgDir: 'src'} for g in m_games: key = os.path.join(gamesDir, g) scanDirs[key] = ('games/%s' % g) # 先把 NativeInfo.lua 加进去 native_info_path = "src/NativeInfo.lua" rel_path = convertFilePath(native_info_path) relative_paths[rel_path] = getHashCode(rel_path) for dir in scanDirs: prefix = scanDirs[dir] Common.assertExit(os.path.isdir(dir), "%s 文件夹不存在" % dir) for parent, dirs, files in os.walk(dir): for f in files: if f == '.git' or f == '.DS_Store': continue full_path = os.path.join(parent, f) rel_path = os.path.relpath(full_path, dir) rel_path.lstrip('./') if len(prefix) > 0: rel_path = '%s/%s' % (prefix, rel_path) rel_path = convertFilePath(rel_path) if not relative_paths.has_key(rel_path): relative_paths[rel_path] = getHashCode(rel_path) file_recorder.record_file(headerPath) # 写文件 f = open(headerPath) lines = f.readlines() f.close() dumpLines = [] newLines = [] for line in lines: newLines.append(line) if line.find(INSERT_BEGIN_KEYWORDS) > 0: # 插入数据 for key in relative_paths.keys(): dumpLines.append('"%s" : "%s"' % (key, relative_paths[key])) newLines.append(INSERT_LINE_TEMPLATE % (key, relative_paths[key])) f = open(headerPath, 'w') f.writelines(newLines) f.close() cur_time_str = datetime.datetime.fromtimestamp( time.time()).strftime('%Y%m%d_%H%M%S') dumpFileName = 'DumpPathMap_%s.json' % cur_time_str dumpContent = '{\n%s\n}\n' % ',\n'.join(dumpLines) f = open(os.path.join(getIpaDir(), dumpFileName), 'w') f.write(dumpContent) f.close()