def aabInstall(bundleToolPath_: str, aabPath_: str, apksPath_: str): _cmd = "java -jar {0} build-apks --bundle={1} --output={2} --local-testing --connected-device".format( bundleToolPath_, aabPath_, apksPath_) cmdUtils.doStrAsCmd(_cmd, os.getcwd()) _cmd = "java -jar {0} install-apks --apks={1}".format( bundleToolPath_, apksPath_) cmdUtils.doStrAsCmd(_cmd, os.getcwd())
def Build(self, dParameters_): dParameters_["projectFolderPath"] = sysUtils.folderPathFixEnd(dParameters_["projectFolderPath"]) _cmd = "{cocosCreatorAppPath} " \ "--path {projectFolderPath} " \ "--build \"configPath={projectFolderPath}WeChatGameConfig.json\"" _cmd = _cmd.format(**dParameters_) print('Execute : \n ' + str(_cmd)) cmdUtils.doStrAsCmd(_cmd, dParameters_["projectFolderPath"], True)
def runPackage(packageName_): _mainActivity = getMainActivity(packageName_) if _mainActivity is None: print(packageName_ + " 没有对应的 mainActivity") sys.exit(1) # 启动 app 至给定 Activity cmdUtils.doStrAsCmd( "adb shell am start -n {0}/{1}".format(packageName_, _mainActivity), _pwd, False)
def PbCreator(self, dParameters_: dict): _protoFolderPath = sysUtils.folderPathFixEnd(dParameters_["protoFolderPath"]) _pbFolderPath = sysUtils.folderPathFixEnd(dParameters_["pbFolderPath"]) _filePathDict = folderUtils.getFilePathKeyValue(_protoFolderPath, [".proto"]) for _, _protoPath in _filePathDict.items(): # 每一个proto文件 _protoShortPath = _protoPath.split(_protoFolderPath)[1] _pbShortPath = _protoShortPath.split(".proto")[0] + ".pb" _cmd = "protoc --descriptor_set_out ./{0} ./{1}".format(_pbShortPath, _protoShortPath) cmdUtils.doStrAsCmd( _cmd, _protoFolderPath, True ) # 将生成出来的.pb文件拷贝到目标文件一份 fileCopyUtils.copyFilesInFolderTo([".pb"], _protoFolderPath, _pbFolderPath, "include", True) folderUtils.removeFileByFilter(_protoFolderPath, [".pb"]) # 再删除刚拷贝过的.pb文件
def createPuml(csFoderPath_: str, pumlFolderPath_: str): csFoderPath_ = sysUtils.folderPathFixEnd(csFoderPath_) folderUtils.makeSureDirIsExists(pumlFolderPath_) pumlFolderPath_ = sysUtils.folderPathFixEnd(pumlFolderPath_) # 生成 puml 文本文件,cs文件和puml文件一一对应 _umlDocCMD = "puml-gen " + csFoderPath_ + " " + pumlFolderPath_ + " -dir" cmdUtils.doStrAsCmd(_umlDocCMD, pumlFolderPath_, True) # puml-gen 会生成一个 include.puml 文件,用来整合所有的文件 _pumlList = folderUtils.getFileListInFolder(pumlFolderPath_, [".puml"]) # include.puml 的内容格式和最新的plantuml不匹配,我们手动生成一个 _includeContent = "@startuml\n" # 先打印最外层文件 for _i in range(len(_pumlList)): _includeContent += "!include " + _pumlList[_i] + "\n" _includeContent += "@enduml" # 覆盖掉原有的 include.puml fileUtils.writeFileWithStr(os.path.join(pumlFolderPath_, "include.puml"), _includeContent)
def ToolsInSystem(self, dParameters_: dict): _toolPathOrTooName = str( dParameters_["toolPathOrTooName"]) # 工具路径,或者是全局已经配置好的名称 _execFolderPath = sysUtils.folderPathFixEnd( dParameters_["execFolderPath"]) # 路径需要确保后面有/ _cmdStr = _toolPathOrTooName + " " # 列表形式的参数需求 if "parameterList" in dParameters_: _parameterList = dParameters_["parameterList"] for _i in range(len(_parameterList)): _parameterElement = _parameterList[_i] if isinstance(_parameterElement, dict): # 键值对形式的参数 _cmdStr += "--" + _parameterElement[ "key"] + " '" + _parameterElement["value"] + "' " else: # 列表形式的参数 _cmdStr += "'" + str(_parameterElement) + "' " else: self.raiseError(pyUtils.getCurrentRunningFunctionName(), "必须有 parameterList 参数") cmdUtils.doStrAsCmd(_cmdStr, _execFolderPath, True)
def CMDInProject(self, dParameters_: dict): _toolName = str(dParameters_["toolName"]) _toolPath = os.path.join(self.subResPath, _toolName, _toolName + ".py") _cmdStr = "python " + _toolPath + " " if "parameterList" in dParameters_: # 列表形式的参数需求 _parameterList = dParameters_["parameterList"] for _i in range(len(_parameterList)): _parameterElement = _parameterList[_i] if isinstance(_parameterElement, dict): # 键值对形式的参数 _cmdStr += "--" + _parameterElement[ "key"] + " '" + _parameterElement["value"] + "' " else: # 纯值形 参数 _cmdStr += "'" + str(_parameterElement) + "' " else: self.raiseError(pyUtils.getCurrentRunningFunctionName(), "必须有 parameterList 参数") cmdUtils.doStrAsCmd( _cmdStr, os.path.dirname(_toolPath), # 工具所在目录执行工具 True)
def BuildIOS(self, dParameters_): _unityPathPath = dParameters_["unityPath"] _projectPath = sysUtils.folderPathFixEnd(dParameters_["projectPath"]) _version = dParameters_["version"] _bundle = dParameters_["bundle"] _platform = dParameters_["platform"] _logFile = dParameters_["logFile"] _executeMethod = None if _platform == "iOS": _executeMethod = "platformBuild.BuildIOS" else: self.raiseError(pyUtils.getCurrentRunningFunctionName(), " platform 不支持") _cmdStr = _unityPathPath + " -quit -batchmode -projectPath " + _projectPath + " -executeMethod " + _executeMethod + " " + _version + " " + _bundle + " -buildTarget " + _platform + " -logFile " + _logFile # 执行命令 cmdUtils.doStrAsCmd(_cmdStr, _projectPath, False) # Unity 工具 "/Volumes/18604037792/Applications/Unity2018.4.11f1/Unity.app/Contents/MacOS/Unity"
def createUML(plantUmlJarPath_: str, pumlPath_: str, umlFolderPath_: str): # 判断其存在性 if not os.path.exists(pumlPath_): print("ERROR : puml文件错误") # 确保文件夹正确性 folderUtils.makeSureDirIsExists(umlFolderPath_) umlFolderPath_ = sysUtils.folderPathFixEnd(umlFolderPath_) # 获取 puml 所在文件夹 _pumlFolderPath = os.path.dirname(pumlPath_) _justName = os.path.splitext(os.path.split(pumlPath_)[1])[0] # 通过 puml 生成 uml 图 _umlPicCMD = "java -jar " + plantUmlJarPath_ + " -tsvg " + pumlPath_ cmdUtils.doStrAsCmd(_umlPicCMD, _pumlFolderPath, True) # 将生成的 puml 转移到指定文件夹内 _umpPath = os.path.join(_pumlFolderPath, _justName + ".svg") if os.path.exists(_umpPath): shutil.copy(_umpPath, os.path.join(umlFolderPath_, _justName + ".svg")) os.remove(pumlPath_) os.remove(_umpPath) else: print("ERROR : UML图创建错误")
def toDotPng(self, outputFolderPath_: str): _stateInfoDict = self.toJsonDict() # 构成 dot 文件 _dot_state_str = "digraph " + self.sheetName + " { " + _stateInfoDict[ "init"] + " [shape = Msquare]\n" for _i in range(len(_stateInfoDict["stateList"])): _dot_state_str = _dot_state_str + _stateInfoDict["stateList"][ _i] + " \n" for _i in range(len(_stateInfoDict["transitions"])): _dot_trans_dict = _stateInfoDict["transitions"][_i] _dot_state_str = _dot_state_str + _dot_trans_dict["from"] + \ " -> " + _dot_trans_dict["to"] + \ " [ label= " + _dot_trans_dict["name"] + " ]" + " \n" _dot_state_str = _dot_state_str + "}" # 生成dot 给 可视化 用 _targetDotPath = os.path.join(outputFolderPath_, self.sheetName + ".dot") _targetPngPath = os.path.join(outputFolderPath_, self.sheetName + ".png") fileUtils.writeFileWithStr(_targetDotPath, _dot_state_str) _graphCmd = "dot '" + _targetDotPath + "' -T png -o '" + _targetPngPath + "'" cmdUtils.doStrAsCmd(_graphCmd, outputFolderPath_, True)
def recompileApk(decompileTo_, keyStorePath_, keyPassword_, key_, targetApkFolder_, targetApkName_): cmdLogUtils.log("重编译 apk") if not os.path.exists(decompileTo_): cmdLogUtils.err("ERROR : Apk已解压目录不存在 " + decompileTo_) sys.exit(1) folderUtils.makeSureDirIsExists(targetApkFolder_) _tempApkName = "unsigned.apk" # 临时 apk 名称 _tempApkPath = os.path.join(targetApkFolder_, _tempApkName) # 临时文件路径 _targetApkPath = os.path.join(targetApkFolder_, targetApkName_) # 目标APK路径 if os.path.exists(_targetApkPath): os.remove(_targetApkPath) _cmd = "apktool b %s -o %s" % (decompileTo_, _tempApkName) cmdUtils.doStrAsCmd(_cmd, targetApkFolder_, True) if os.path.exists(_tempApkPath): cmdLogUtils.log("重签名") _cmd = "jarsigner -verbose -keystore %s -storepass %s -signedjar %s -digestalg SHA1 -sigalg MD5withRSA %s %s" % ( keyStorePath_, keyPassword_, _targetApkPath, _tempApkPath, key_) os.system(_cmd) os.remove(_tempApkPath) # 移除临时文件 else: cmdLogUtils.err("ERROR : 重编译失败") sys.exit(1)
def exportSpineInFolder(self, spineFolderPath_: str, jsonOutputFolderPath_: str, exportJsonPath_: str, pngFolderPath_: str, altasOutputFolderPath_: str, packJsonPath_: str, altasName_: str): folderUtils.makeSureDirIsExists(jsonOutputFolderPath_) _spineList = folderUtils.getFilterFilesInPath(spineFolderPath_, [".spine"]) # spine 名称队列,用于校验导出骨骼信息是否匹配 _spineJustNameList = [] # 根据配置,导出动画文件 _cmd = self.spineAppPath for _i in range(len(_spineList)): _spinePath = _spineList[_i] _spineJustNameList.append(fileUtils.justName(_spinePath)) _cmd = _cmd + " -i '" + _spinePath + "' -m -o '" + jsonOutputFolderPath_ + "' -e '" + exportJsonPath_ + "' " _pipeLines = cmdUtils.doStrAsCmd(_cmd, spineFolderPath_, False) if not _pipeLines: sys.exit(1) # 发布动画是否和文件名一致,导出的文件是按照动画编辑时的骨骼命名进行的,有可能骨骼和文件的名称不一致,需要提示。 _outputJsonPathList = folderUtils.getFilterFilesInPath( jsonOutputFolderPath_, [".json"]) for _i in range(len(_outputJsonPathList)): _outputJsonPath = _outputJsonPathList[_i] listUtils.findAndRemove(_spineJustNameList, fileUtils.justName(_outputJsonPath)) if len(_spineJustNameList) > 0: print("spine骨骼与Spine文件名不一致") for _i in range(len(_spineJustNameList)): print(" " + _spineJustNameList[_i]) sys.exit(1) # 根据配置,打包图片 _cmd = self.spineAppPath _cmd = _cmd + " -i '" + pngFolderPath_ + "' -o '" + altasOutputFolderPath_ + "' -n '" + altasName_ + "' -p '" + packJsonPath_ + "'" _pipeLines = cmdUtils.doStrAsCmd(_cmd, spineFolderPath_, False) if not _pipeLines: sys.exit(1)
def CheckOut(self, dParameters_): _gitFolderPath = sysUtils.folderPathFixEnd( dParameters_["gitFolderPath"]) _branch = dParameters_["branch"] _path = dParameters_["path"] # 本地没有的时候,将远程的迁出到本地。本地和远端同名 _localBranchName = _branch.split("/")[-1] # 本地该叫什么名 _branchStrList = cmdUtils.doStrAsCmd('git branch', _gitFolderPath, True) # 输出本地有什么 _localBranchNameList = [] _currentLocalBranchName = "" for _i in range(len(_branchStrList)): _currentBranchName = _branchStrList[_i][2:] _localBranchNameList.append(_currentBranchName) # 记录本地名列表 if _branchStrList[_i].startswith("* "): # 当前所在那个本地分支 _currentLocalBranchName = _currentBranchName # 不在指定名称分支内 if not _currentLocalBranchName == _localBranchName: # 本地没有这个名称的分支 if not _localBranchName in _localBranchNameList: # 在当前git所在目录,检出分支,指定其名称 cmdUtils.doStrAsCmd( "git checkout " + _branch + " -b " + _localBranchName, _gitFolderPath, True) else: # 本地,有分支,只需要检出 cmdUtils.doStrAsCmd("git checkout " + _localBranchName, _gitFolderPath, True) # 路径整理 if _path.startswith("\\") or _path.startswith("/"): self.raiseError(pyUtils.getCurrentRunningFunctionName(), "path 不能以 \\ 或 / 开头") _path = str(Path(_path)) # "" 会被转换成 "." if _path == ".": cmdUtils.doStrAsCmd('git checkout .', _gitFolderPath, True) else: cmdUtils.doStrAsCmd('git checkout -- ' + _path, _gitFolderPath, True)
def JustCMD(self, dParameters_: dict): _cmdStr = str(dParameters_["CMD"]) _execFolderPath = sysUtils.folderPathFixEnd( dParameters_["execFolderPath"]) # 路径需要确保后面有/ cmdUtils.doStrAsCmd(_cmdStr, _execFolderPath, True)
return _baseInService else: sys.exit(1) if __name__ == "__main__": # res下的Excel文件 _excelFileName = "ExecSample" # excel驱动脚本。(os.pardir 相当于 ..) _excelCommandPath = os.path.realpath( os.path.join( os.path.realpath(__file__), # ExcelApp.py 路径 os.pardir, # Excel Folder os.pardir, # PY_Service Folder "ExcelCommand.py" # 执行脚本名 )) # 当前执行目录 _resFolderPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "res") # 拼接驱动样例的命令 _sampleExcelCommand = "python " + _excelCommandPath + \ " --sProjectFolderPath '" + _resFolderPath + "'" + \ " --excelPath '" + _excelFileName + ".xlsx" + "'" + \ " --executeType ExcelApp->测试" # 执行命令 cmdUtils.doStrAsCmd( _sampleExcelCommand, # 执行命令行驱动 Excel 工作流配置 os.path.join(os.path.dirname(os.path.realpath(__file__)), "res"), # Excel 对应的 res 文件夹内执行 True)