def process(self): # 先解析配置文件获取基本配置信息 self._parse_base_config() target_path = self.common_config[ConfigLabel.TARGET_PATH_FLAG] self.apk_root_parent_path = os.path.join(self.work_path, target_path, self.app_code) self.apk_root_path = os.path.join(self.work_path, target_path, self.app_code, self.ver_name) self.apk_root_path = file_util.normalpath(self.apk_root_path) channel_relative = self.common_config[ConfigLabel.RELATIVE_FLAG][ConfigLabel.CHANNEL_FLAG] self.apk_channel_path = os.path.join(self.apk_root_path, channel_relative) self.apk_channel_path = file_util.normalpath(self.apk_channel_path) zip_relative = self.common_config[ConfigLabel.RELATIVE_FLAG][ConfigLabel.ZIP_FLAG] self.zip_channel_path = os.path.join(self.apk_root_path, zip_relative) self.zip_channel_path = file_util.normalpath(self.zip_channel_path) # 先进行清理本地apk文件夹操作 self._clear_output_directory(self.apk_root_parent_path) # 如果已经存在目标文件夹,则先删除 if os.path.isdir(self.apk_root_path): shutil.rmtree(self.apk_root_path) # 从sftp服务器下载通用apk文件 download_manager.download_sftp_file(self.sftp_config_path, self.apk_root_path, self.ver_name, sftp_root_tag=self.app_code, as_file=False) # 使用下载的apk文件生成渠道包 self.generate_channel_apk() # 将单独打包的渠道包也下载下来并以渠道名称命名 self.download_exceptional_apk() # 将需要外发的渠道包压缩成zip包 self.zip_channel_apk()
def pre_build(self): # 在需要更新代码条件下先进行pod update更新操作 if self.to_update and self.use_git: # 执行"pod install"下载新增的库配置,在执行pod update更新相关的库 pod_path = self.project_path + os.sep + 'PYH5Bridge/PYH5Bridge' pod_path = myfile.normalpath(pod_path) cmd_str = 'pod install --no-repo-update' cmd_update_str = 'pod update --no-repo-update' exec_cmd.run_cmd_with_system_in_specified_dir(pod_path, cmd_str, print_flag=True) exec_cmd.run_cmd_with_system_in_specified_dir(pod_path, cmd_update_str, print_flag=True) # 先恢复正常的编译配置 reinit_config_script_path = self.project_path + os.sep + 'PYH5Bridge/PYH5Bridge/PYH5Bridge/init.rb' reinit_config_script_path = myfile.normalpath( reinit_config_script_path) # 执行初始化恢复操作 str_format = 'ruby {}' cmd_str = str_format.format(reinit_config_script_path) print(cmd_str) os.system(cmd_str) # 更新版本名称及编译编号 info_plist_path = self.project_path + os.sep + \ self.ori_build_config[build_base.BuildConfigParser.WORKSPACE_FLAG][ build_base.BuildConfigParser.INFO_PLIST_FLAG] info_plist_path = myfile.normalpath(info_plist_path) build_base.update_build_no(info_plist_path, self.ver_code) build_base.update_version_name(info_plist_path, self.ver_name)
def sync_project(self, project): path = project.path path_with_namespace = project.path_with_namespace if not path_with_namespace.endswith(path): raise Exception(f'{path_with_namespace} not endswith {path}!') if path == path_with_namespace: namespace = None prj_path = self.git_root else: namespace = path_with_namespace[0:-len(path)] prj_path = file_util.normalpath(os.path.join(self.git_root, namespace)) prj_git_path = file_util.normalpath(os.path.join(self.git_root, path_with_namespace)) code_url = project.ssh_url_to_repo if self.to_reprocess: if os.path.isdir(prj_git_path): shutil.rmtree(prj_git_path) # 将从服务器端checkout的目录添加到有效列表 self.valid_local_paths.append(prj_git_path) print(f'to process {path_with_namespace}.') self.checkout(prj_path, path, code_url) sync_git.Manager.sync_repo(prj_git_path) print(f'processed {path_with_namespace}.')
def _get_src_path(self, tag): src_relative_path = self.common_config[ConfigLabel.TARGET_PATH_FLAG] apk_root_path = os.path.join(self.work_path, src_relative_path, self.app_code, self.ver_name) apk_root_path = file_util.normalpath(apk_root_path) tag_relative = self.common_config[ConfigLabel.RELATIVE_FLAG][tag] apk_tag_path = os.path.join(apk_root_path, tag_relative) apk_tag_path = file_util.normalpath(apk_tag_path) return apk_tag_path
def _get_pro_build_config(self): #指定项目地址 params = {} bin_name = self.ori_build_config[BuildConfigParser.ENCRYPT_FLAG][BuildConfigParser.BIN_NAME_FLAG] enc_bin_path = self.work_path + os.sep + bin_name enc_bin_path = myfile.normalpath(enc_bin_path) params[ProjectBuilder.ENC_BIN_PATH_FLAG] = enc_bin_path net_config_path = self.project_path + os.sep + self.ori_build_config[BuildConfigParser.NETWORK_FLAG][BuildConfigParser.RELATIVE_PATH_FLAG] net_config_path = myfile.normalpath(net_config_path) params[ProjectBuilder.NET_CONFIG_PATH_FLAG] = net_config_path params[ProjectBuilder.NET_INFO_FLAG] = self.ori_build_config[BuildConfigParser.NETWORK_FLAG] params[ProjectBuilder.ENV_MODE_FLAG] = self.ori_build_config[BuildConfigParser.ENV_FLAG][BuildConfigParser.MAP_FLAG][self.ver_env] params[ProjectBuilder.NET_INFO_FLAG] = self.ori_build_config[BuildConfigParser.NETWORK_FLAG] params[ProjectBuilder.JPUSH_APPKEY_FLAG] = self.ori_build_config[BuildConfigParser.JPUSH_APPKEY_FLAG] params[ProjectBuilder.EASEMOB_APPKEY_FLAG] = self.ori_build_config[BuildConfigParser.EASEMOB_APPKEY_FLAG] # 将时间格式化 curr_time = time.localtime() time_str = time.strftime('%Y%m%d_%H%M%S', curr_time) output_directory = self.work_path + os.sep + self.ori_build_config[BuildConfigParser.WORKSPACE_FLAG][BuildConfigParser.TARGET_PATH_FLAG] output_directory = myfile.normalpath(output_directory) output_directory = output_directory + os.sep + self.ver_env + os.sep + time_str params[ProjectBuilder.OUTPUT_DIRECTORY_FLAG] = output_directory self.output_directory = params[ProjectBuilder.OUTPUT_DIRECTORY_FLAG] params[ProjectBuilder.VER_NAME_FLAG] = self.ver_name params[ProjectBuilder.VER_CODE_FLAG] = self.ver_code params[ProjectBuilder.ENV_FLAG] = self.ori_build_config[BuildConfigParser.ENV_FLAG] #指定输出归档文件地址 date_str = time.strftime('%Y%m%d', curr_time) if self.is_debug: mode_flag = apk_builder.DEBUG_FLAG #指定输出apk名称 params[ProjectBuilder.OUTPUT_NAME_FLAG]="{}-{}-{}-{}.apk".format(self.ver_name, self.ver_code, mode_flag, date_str) else: mode_flag = apk_builder.RELEASE_FLAG #指定输出apk名称 params[ProjectBuilder.OUTPUT_NAME_FLAG]="{}-{}-{}.apk".format(self.ver_name, self.ver_code, date_str) params[ProjectBuilder.TYPE_FLAG] = mode_flag self.apk_output_path = params[ProjectBuilder.OUTPUT_DIRECTORY_FLAG] + os.sep + params[ProjectBuilder.OUTPUT_NAME_FLAG] pprint.pprint(params) return params
def __init__(self, info): self.prj_root = info[Label.prj_root] self.info = info self.prj_root = self.info[Label.prj_root] config_file_path = os.path.join(self.prj_root, self.info[Label.info][Label.file_item]) self.config_file_path = file_util.normalpath(config_file_path) env_config_path = os.path.join(self.prj_root, self.info[Label.env][Label.file_item]) self.env_config_path = file_util.normalpath(env_config_path)
def update_git_file(git_root, relative_file_path, new_file, msg, zip_password=None): # 先判断git目录状态是否正常 if not git.is_repository(git_root): raise Exception( '{} is not a valid git source directory!'.format(git_root)) target_file = file_util.normalpath( os.path.join(git_root, relative_file_path)) if not is_same_config(new_file, target_file, zip_password=zip_password): if platform.system() == 'Darwin' and zip_password: UNZIP_CMD = 'unzip -o {}'.format(new_file) exec_cmd.run_cmd_with_system_in_specified_dir( os.path.dirname(new_file), UNZIP_CMD, print_flag=True) os.remove(new_file) ZIP_CMD = 'zip -m -r -P {} {} {}'.format(zip_password, 'config_file.zip', 'config_file') exec_cmd.run_cmd_with_system_in_specified_dir( os.path.dirname(new_file), ZIP_CMD, print_flag=True) file_util.replace_file(new_file, target_file) paths = [] paths.append(relative_file_path) git.push_to_remote(paths, msg, repository=None, refspecs=None, _dir=git_root) else: print('{} and {} is the same!'.format(new_file, target_file))
def __init__(self, args, work_path): # 先将输入的控制参数全部存储为成员变量 # 透传过来的数据类型为“netref class 'rpyc.core.netref.type'”,不支持dict的方法items,需要换成键访问方式 # for name, value in args.items(): # setattr(self, name, value) for k in args: setattr(self, k, args[k]) # pprint.pprint(vars(self)) self.work_path = os.path.abspath(work_path) # 解析基础配置文件路径 base_config_dirs = ['config', 'base', 'update_config.xml'] base_config = os.sep.join(base_config_dirs) self.base_config = os.path.join(self.work_path, base_config) # 先解析配置 configParser = BuildConfigParser(self.base_config) configParser.parse() self.ori_build_config = configParser.get_config() # project目录 ori_project_path = os.path.join(self.work_path, self.ori_build_config[BuildConfigLabel.WORKSPACE_FLAG][BuildConfigLabel.PRJ_PATH_FLAG]) self.project_path = file_util.normalpath(ori_project_path) self.api_ver_config = None self.curr_env_output_root = None
def _protect_file(self, main_prj_path): ip = self.pro_build_config[BuilderLabel.PROTECT_FLAG][BuilderLabel.IP_FLAG] user_name = self.pro_build_config[BuilderLabel.PROTECT_FLAG][BuilderLabel.USER_FLAG] api_key = self.pro_build_config[BuilderLabel.PROTECT_FLAG][BuilderLabel.API_KEY_FLAG] api_secret = self.pro_build_config[BuilderLabel.PROTECT_FLAG][BuilderLabel.API_SECRET_FLAG] protected_path = protect_app.protect(ip, user_name, api_key, api_secret, self.apk_output_path) if self.to_align: aligned_path = file_util.get_middle_path(protected_path) apk_util.zipalign(protected_path, aligned_path) to_sign_path = aligned_path else: to_sign_path = protected_path keystore = os.path.join(main_prj_path, self.pro_build_config[BuilderLabel.SIGNER_FLAG][ BuilderLabel.KEYSTORE_FLAG]) keystore = os.path.abspath(file_util.normalpath(keystore)) storepass = self.pro_build_config[BuilderLabel.SIGNER_FLAG][BuilderLabel.STOREPASS_FLAG] storealias = self.pro_build_config[BuilderLabel.SIGNER_FLAG][BuilderLabel.STOREALIAS_FLAG] signed_path = apk_util.get_default_signed_path(protected_path) rtn = apk_util.sign_apk(keystore, storepass, storealias, to_sign_path, signed_path) if rtn: str_info = 'Protect {} and sign success.'.format(self.apk_output_path) source_name = os.path.basename(signed_path) else: str_info = 'Protect {} and sign failed!'.format(self.apk_output_path) raise Exception(str_info) print(str_info) return source_name
def __init__(self, args): # 先将输入的控制参数全部存储为成员变量 for name, value in vars(args).items(): setattr(self, name, value) # pprint.pprint(vars(self)) self.work_path = os.path.abspath(self.work_path) # 解析基础配置文件路径 if not self.base_config: base_config_dirs = ['config', 'base', 'update_config.xml'] base_config = os.sep.join(base_config_dirs) else: base_config = self.base_config self.base_config = os.path.join(self.work_path, base_config) # 先解析配置 configParser = BuildConfigParser(self.base_config) configParser.parse() self.ori_build_config = configParser.get_config() # project目录 ori_project_path = os.path.join(self.work_path, self.ori_build_config[BuildConfigLabel.WORKSPACE_FLAG][ BuildConfigLabel.PRJ_PATH_FLAG]) self.project_path = file_util.normalpath(ori_project_path) self.api_ver_config = None self.curr_env_output_root = None
def zip_files(file_items, dst_path, src_root=None, to_print=False): pre_len = 0 if src_root: src_root = file_util.normalpath(src_root) if src_root.endswith(os.sep): pre_len = len(src_root) else: pre_len = len(src_root) + len(os.sep) base_dir = os.path.dirname(dst_path) if not os.path.isdir(base_dir): os.makedirs(base_dir) with zipfile.ZipFile(dst_path, "w", zipfile.zlib.DEFLATED) as zf: if to_print: print('to pack file to {}:'.format(dst_path)) for item in file_items: if pre_len > 0: zip_name = item[pre_len:] else: zip_name = item if to_print: print(zip_name) zf.write(item, zip_name)
def _update_local_build_file(self): # 更新android sdk本地配置 local_file_name = 'local.properties' static_config_path = os.path.join(self.work_path, self.ori_build_config[BuildConfigLabel.ROOT_FLAG][BuildConfigLabel.STATIC_FLAG]) static_config_path = file_util.normalpath(static_config_path) local_build_file = os.path.join(static_config_path, local_file_name) target_build_file = os.path.join(self.prj_root, local_file_name) file_util.replace_file(local_build_file, target_build_file)
def init_path_config(self, ver_name_code, ver_env, code_version, sftp_root_tag='txxy', local_dir_path='', mobile_os='', channel=''): self.ver_name_code = ver_name_code self.ver_env = ver_env self.code_version = code_version self.sftp_root_tag = sftp_root_tag self.local_dir_path = file_util.normalpath(local_dir_path) self.mobile_os = mobile_os self.channel = channel
def __init__(self, prj_path, chan_map, res_path, info): self.prj_path = prj_path self.chan_map = chan_map self.res_path = res_path self.info = info self.manifest_path = self.prj_path + os.sep + 'src/main/AndroidManifest.xml' self.manifest_path = file_util.normalpath(self.manifest_path)
def pre_build(self): # 更新版本名称及编译编号 info_plist_path = self.project_path + os.sep + self.app_build_cofig[ BuildConfigParser.WORKSPACE_FLAG][ BuildConfigParser.INFO_PLIST_FLAG] info_plist_path = myfile.normalpath(info_plist_path) update_build_no(info_plist_path, self.ver_code) update_version_name(info_plist_path, self.ver_name)
def commit_with_svn(self, source_url, source_path, targer_config_path): print('\n=====svn url {}====='.format(source_url)) source_path = file_util.normalpath(source_path) svn.checkout_or_update(source_path, source_url) to_upload_file_path = source_path + os.sep + _PACK_TARGET_FILE update_svn_file(to_upload_file_path, targer_config_path, _SVN_UPDATE_MSG) self.success_upload_path_arr.append(source_path)
def clean_history(self, project): path = project.path path_with_namespace = project.path_with_namespace if not path_with_namespace.endswith(path): raise Exception(f'{path_with_namespace} not endswith {path}!') if path == path_with_namespace: namespace = None prj_path = self.git_root else: namespace = path_with_namespace[0:-len(path)] prj_path = file_util.normalpath( os.path.join(self.git_root, namespace)) prj_git_path = file_util.normalpath( os.path.join(self.git_root, path_with_namespace)) code_url = project.ssh_url_to_repo if self.to_reprocess: if os.path.isdir(prj_git_path): shutil.rmtree(prj_git_path) # 只有本地不存在相关目录才从服务器端同步 if not os.path.isdir(prj_git_path): print(f'to process {path_with_namespace}.') if project.archived: print( f'{path_with_namespace} is archived and can not been process.' ) return if self.to_clean_tag: # 如果要清理tag,先删除远程服务器上的tag信息,本地clone的时候就不会存在该信息 self.clean_tag(project) self.checkout(prj_path, path, code_url) sync_git.Manager.sync_repo(prj_git_path) Manager.clean_branch_history(prj_git_path, project) print(f'processed {path_with_namespace}.') else: print(f'{path_with_namespace} already exists.')
def sync_project_support_v3(self): src_items = self.get_projects_sync_item_support_v3( self.src, self.src_token, self.src_api) dst_items = self.get_projects_sync_item_support_v3( self.dst, self.dst_token, self.dst_api) other_info = dict() for k, v in src_items.items(): if k in dst_items: path = v[DataLabel.path] path_with_namespace = v[DataLabel.path_with_namespace] if not path_with_namespace.endswith(path): print(f'{path_with_namespace} not endswith {path}!') other_info[k] = v continue relative_path = path_with_namespace[:-len(path)] prj_path = file_util.normalpath( os.path.join(self.git_root, relative_path)) root_path = file_util.normalpath(os.path.join(prj_path, path)) code_url = v[DataLabel.ssh_url_to_repo] self.checkout(prj_path, path, code_url) dst_item = dst_items[k] rtn = self.pull_all(root_path) if not rtn: other_info[k] = v continue dst_url = dst_item[DataLabel.ssh_url_to_repo] rtn = self.update_remote_url(root_path, dst_url) if not rtn: other_info[k] = v continue self.push_all_to_remote(root_path) else: other_info[k] = v for k, v in dst_items.items(): if k not in src_items: other_info[k] = v print('need manual operation items:') pprint.pprint(other_info)
def _get_pro_build_config(self): # 指定项目地址 params = {} params[ProjectBuilder.JPUSH_APPKEY_FLAG] = self.ori_build_config[build_base.BuildConfigParser.JPUSH_APPKEY_FLAG] params[ProjectBuilder.ENV_MODE_FLAG] = \ self.ori_build_config[build_base.BuildConfigParser.ENV_FLAG][build_base.BuildConfigParser.MAP_FLAG][ self.ver_env] # 将时间格式化 curr_time = time.localtime() time_str = time.strftime('%Y%m%d_%H%M%S', curr_time) output_directory = self.work_path + os.sep + self.ori_build_config[build_base.BuildConfigParser.WORKSPACE_FLAG][ build_base.BuildConfigParser.TARGET_PATH_FLAG] output_directory = file_util.normalpath(output_directory) output_directory = output_directory + os.sep + self.ver_env + os.sep + time_str params[build_base.ProjectBuilder.OUTPUT_DIRECTORY_FLAG] = output_directory self.output_directory = params[build_base.ProjectBuilder.OUTPUT_DIRECTORY_FLAG] params[build_base.ProjectBuilder.VER_NAME_FLAG] = self.ver_name params[build_base.ProjectBuilder.VER_CODE_FLAG] = self.ver_code params[build_base.ProjectBuilder.ENV_FLAG] = self.ori_build_config[build_base.BuildConfigParser.ENV_FLAG] # 获取加固配置信息 params[ProjectBuilder.PROTECT_FLAG] = self.ori_build_config[build_base.BuildConfigParser.PROTECT_FLAG] is_need_infos = params[ProjectBuilder.PROTECT_FLAG][ProjectBuilder.IS_NEED_FLAG] for k in is_need_infos: is_need_infos[k] = str_util.get_bool(is_need_infos[k]) params[ProjectBuilder.SIGNER_FLAG] = self.ori_build_config[build_base.BuildConfigParser.SIGNER_FLAG] # 指定输出归档文件地址 date_str = time.strftime('%Y%m%d', curr_time) if self.is_debug: mode_flag = apk_builder.DEBUG_FLAG # 指定输出apk名称 params[build_base.ProjectBuilder.OUTPUT_NAME_FLAG] = "{}-{}-{}-{}.apk".format(self.ver_name, self.ver_code, mode_flag, date_str) else: mode_flag = apk_builder.RELEASE_FLAG # 指定输出apk名称 params[build_base.ProjectBuilder.OUTPUT_NAME_FLAG] = "{}-{}-{}.apk".format(self.ver_name, self.ver_code, date_str) params[build_base.ProjectBuilder.TYPE_FLAG] = mode_flag self.apk_output_path = params[build_base.ProjectBuilder.OUTPUT_DIRECTORY_FLAG] + os.sep + params[ build_base.ProjectBuilder.OUTPUT_NAME_FLAG] pprint.pprint(params) return params
def __init__(self, args): # 先将输入的控制参数全部存储为成员变量 for name, value in vars(args).items(): setattr(self, name, value) self.work_path = os.path.abspath(self.work_path) # 解析基础配置文件路径 if not self.base_config: base_config_dirs = ['base', 'update_config.xml'] base_config = os.sep.join(base_config_dirs) else: base_config = self.base_config self.base_config = self.work_path + os.sep + base_config # 先解析配置 configParser = BuildConfigParser(self.base_config) configParser.parse() self.ori_build_config = configParser.get_config() # svn配置文件目录 ori_source_path = self.work_path + os.sep + self.ori_build_config[ BuildConfigParser.WORKSPACE_FLAG][ BuildConfigParser.SOURCE_PATH_FLAG] self.source_path = file_util.normalpath(ori_source_path) if self.svn_user and self.svn_pwd: svn.set_user_info(self.svn_user, self.svn_pwd) # 目标输出文件夹 target_path = self.work_path + os.sep + self.ori_build_config[ BuildConfigParser.WORKSPACE_FLAG][ BuildConfigParser.TARGET_PATH_FLAG] self.target_path = file_util.normalpath(target_path) # 不加入打包的文件 self.filter_file = [] if BuildConfigParser.FILTER_FILE_FLAG in self.ori_build_config[ BuildConfigParser.WORKSPACE_FLAG]: self.filter_file = self.ori_build_config[ BuildConfigParser.WORKSPACE_FLAG][ BuildConfigParser.FILTER_FILE_FLAG]
def sftp_download(sftp_cli, sftp_file_path, local_dir_path): handle_result = [1, ""] try: sftp_file_path = file_util.normal_unix_path(sftp_file_path) local_dir_path = file_util.normalpath(local_dir_path) # download file if stat.S_ISREG(sftp_cli.stat(sftp_file_path).st_mode): sftp_file_name = os.path.basename(sftp_file_path) local_dir_path = os.path.join(local_dir_path, sftp_file_name) local_dir = os.path.split(local_dir_path)[0] local_dir = file_util.normalpath(local_dir) if not os.path.exists(local_dir): os.makedirs(local_dir) sftp_cli.get(sftp_file_path, local_dir_path) handle_result = [1, "DOWNLOAD " + sftp_file_name + " SUCCESS"] # download dir else: for filename in sftp_cli.listdir(sftp_file_path): sftp_file_name = file_util.join_unix_path(sftp_file_path, filename) if is_dir(sftp_cli, sftp_file_name): lad = os.path.join(local_dir_path, filename) else: lad = local_dir_path rs = sftp_download(sftp_cli, sftp_file_name, lad) handle_result[1] = handle_result[1] + rs[1] if rs[0] == -1: handle_result[0] = -1 else: if handle_result[0] != -1: handle_result[0] = 1 except Exception as e: handle_result = [-1, "download fail, reason:{0}".format(e)] return handle_result
def _upload_desc_file(self, sftp_cli, remote_dir, data, file_name='description.txt'): sftp_cli.chdir(remote_dir) local_file_path = file_util.normalpath(os.path.join(self.local_dir_path, file_name)) with open(local_file_path, 'w') as json_file: json.dump(data, json_file, sort_keys=True) result = sftp_util.sftp_upload_file(sftp_cli, remote_dir, local_file_path) print(result[1]) if result[0] == 1: os.remove(local_file_path)
def backup_project(self): src_items = self.get_projects_sync_item(self.src, self.src_token) other_info = dict() # cnt_butt = 4 # cnt_index = 0 for k, v in src_items.items(): path = v.path path_with_namespace = v.path_with_namespace if not path_with_namespace.endswith(path): print(f'{path_with_namespace} not endswith {path}!') other_info[k] = v continue # branches = v.branches.list() # for branch in branches: # branch_id = branch.get_id() # relative_path = os.path.join(path_with_namespace, branch_id) # prj_path = file_util.normalpath(os.path.join(self.git_root, relative_path)) # code_url = v.ssh_url_to_repo # self.checkout(prj_path, path, code_url, branch=branch_id) if path == path_with_namespace: namespace = None prj_path = self.git_root else: namespace = path_with_namespace[0:-len(path)] prj_path = file_util.normalpath( os.path.join(self.git_root, namespace)) prj_git_path = file_util.normalpath( os.path.join(self.git_root, path_with_namespace)) code_url = v.ssh_url_to_repo self.checkout(prj_path, path, code_url) sync_git.Manager.sync_repo(prj_git_path) # cnt_index += 1 # if cnt_index >= cnt_butt: # break print('need manual operation items:') pprint.pprint(other_info)
def __init__(self, prj_path, chan_map, res_path, info): self.prj_path = prj_path self.chan_map = chan_map self.res_path = res_path self.info = info self.gradle_path = os.path.join(self.prj_path, 'build.gradle') self.gradle_path = os.path.normpath(self.gradle_path) self.manifest_path = os.path.join(self.prj_path, 'src/main/AndroidManifest.xml') self.manifest_path = myfile.normalpath(self.manifest_path)
def _get_pro_build_config(self): # 指定项目地址 params = {} # 将时间格式化 curr_time = time.localtime() time_str = time.strftime('%Y%m%d_%H%M%S', curr_time) output_directory = self.work_path + os.sep + self.ori_build_config[ build_base.BuildConfigParser.WORKSPACE_FLAG][ build_base.BuildConfigParser.TARGET_PATH_FLAG] output_directory = myfile.normalpath(output_directory) output_directory = os.path.join(output_directory, self.ver_env, time_str) params[ build_base.ProjectBuilder.OUTPUT_DIRECTORY_FLAG] = output_directory self.output_directory = params[ build_base.ProjectBuilder.OUTPUT_DIRECTORY_FLAG] params[build_base.ProjectBuilder.VER_NAME_FLAG] = self.ver_name params[build_base.ProjectBuilder.VER_CODE_FLAG] = self.ver_code params[ProjectBuilder.ENV_NET_FLAG] = self.ver_env params[ProjectBuilder.NET_INFO_FLAG] = self.ori_build_config[ BuildConfigParser.NETWORK_FLAG] # 指定输出归档文件地址 date_str = time.strftime('%Y%m%d', curr_time) if self.is_debug: mode_flag = apk_builder.DEBUG_FLAG # 指定输出apk名称 params[build_base.ProjectBuilder. OUTPUT_NAME_FLAG] = "{}-{}-{}-{}.apk".format( self.ver_name, self.ver_code, mode_flag, date_str) else: mode_flag = apk_builder.RELEASE_FLAG # 指定输出apk名称 params[build_base.ProjectBuilder. OUTPUT_NAME_FLAG] = "{}-{}-{}.apk".format( self.ver_name, self.ver_code, date_str) params[build_base.ProjectBuilder.TYPE_FLAG] = mode_flag self.apk_output_path = os.path.join( params[build_base.ProjectBuilder.OUTPUT_DIRECTORY_FLAG], params[build_base.ProjectBuilder.OUTPUT_NAME_FLAG]) pprint.pprint(params) return params
def pre_build(self): pod_path = self.project_path + os.sep + 'GZJD' pod_path = myfile.normalpath(pod_path) cmd_update_local_pod = 'pod repo update PYPodSpec' cmd_str = 'pod install' cmd_update_str = 'pod update --no-repo-update' pods_path = pod_path + os.sep + 'Pods' pods_path = myfile.normalpath(pods_path) exec_cmd.run_cmd_with_system_in_specified_dir(pod_path, cmd_update_local_pod, print_flag=True) if os.path.exists(pods_path): exec_cmd.run_cmd_with_system_in_specified_dir(pod_path, cmd_update_str, print_flag=True) else: exec_cmd.run_cmd_with_system_in_specified_dir(pod_path, cmd_str, print_flag=True) # 先恢复正常的编译配置 reinit_config_script_path = self.project_path + os.sep + 'GZJD/init.rb' reinit_config_script_path = myfile.normalpath( reinit_config_script_path) # 执行初始化恢复操作 str_format = 'ruby {}' cmd_str = str_format.format(reinit_config_script_path) print(cmd_str) os.system(cmd_str) # 更新版本名称及编译编号 info_plist_path = self.project_path + os.sep + self.app_build_cofig[ build_base.BuildConfigParser.WORKSPACE_FLAG][ build_base.BuildConfigParser.INFO_PLIST_FLAG] info_plist_path = myfile.normalpath(info_plist_path) build_base.update_build_no(info_plist_path, self.ver_code) build_base.update_version_name(info_plist_path, self.ver_name)
def commit_with_git(self, source_url, source_path, relative_path, targer_config_path, git_branch_name, zip_password=None): print('\n=====git url {}====='.format(source_url)) source_path = source_path + os.sep + git_branch_name source_path = file_util.normalpath(source_path) git.checkout_or_update(source_path, source_url, branch=git_branch_name) git_root = git.get_git_root(source_path) relative_file_path = relative_path + os.sep + _PACK_TARGET_FILE update_git_file(git_root, relative_file_path, targer_config_path, _SVN_UPDATE_MSG, zip_password) self.success_upload_path_arr.append(source_path)
def sftp_download_file(sftp_cli, sftp_file_path, local_file_path, force=True, as_file=True, callback=None): handle_result = [SUCCESS, ''] try: sftp_file_path = file_util.normal_unix_path(sftp_file_path) local_file_path = file_util.normalpath(local_file_path) # download file if stat.S_ISREG(sftp_cli.stat(sftp_file_path).st_mode): sftp_file_name = os.path.basename(sftp_file_path) local_dir_path = os.path.dirname(local_file_path) if not os.path.isdir(local_dir_path): os.makedirs(local_dir_path) # 如果本地已有相应文件,强制覆盖时,则直接删除本地现有文件,否则报本地已有相应文件。 if os.path.isfile(local_file_path): if force: os.remove(local_file_path) else: handle_result = [ FAILED, f'file {local_file_path} already exists!' ] return handle_result if as_file: with sftp_cli.open(sftp_file_path, 'rb') as fp: shutil.copyfileobj(fp, open(local_file_path, 'wb')) else: sftp_cli.get(sftp_file_path, local_file_path, callback=callback) handle_result = [SUCCESS, f'download {sftp_file_name} success.'] else: handle_result = [ FAILED, f'sftp_file_path {sftp_file_path} is not a file!' ] except Exception as e: handle_result = [FAILED, 'download failed, reason:{}!'.format(e)] return handle_result
def _upload_record_file(self, sftp_cli, remote_dir, data, file_name='record.txt'): sftp_cli.chdir(remote_dir) sftp_dir_list = sftp_cli.listdir(remote_dir) remote_file_path = file_util.join_unix_path(remote_dir, file_name) local_file_path = file_util.normalpath(os.path.join(self.local_dir_path, file_name)) for filename in sftp_dir_list: if file_name in filename: sftp_util.sftp_download(sftp_cli, remote_file_path, self.local_dir_path) with open(local_file_path, 'a') as json_file: json.dump(data, json_file, sort_keys=True) json_file.write(os.linesep) result = sftp_util.sftp_upload_file(sftp_cli, remote_dir, local_file_path) print(result[1]) if result[0] == 1: os.remove(local_file_path)
def _download_file(self, sftp_cli, local_dir_path, ver_no, channel, target_file_name, force, as_file): env_info = self.config_data[ConfigLabel.ENV_FLAG] remote_root_dir = self.config_data[ConfigLabel.SFTP_PATH_FLAG] remote_dir = os.path.join(remote_root_dir[self.sftp_root_tag], self.ver_name, env_info[self.ver_env]) remote_dir = file_util.normal_unix_path(remote_dir) # 生产版本不一定有ver_no if ver_no: remote_dir = file_util.join_unix_path(remote_dir, ver_no, self.mobile_os) else: remote_dir = file_util.join_unix_path(remote_dir, self.mobile_os) if len(channel): remote_dir = file_util.join_unix_path(remote_dir, channel) sftp_cli.chdir(remote_dir) sftp_dir_list = sftp_cli.listdir(remote_dir) for filename in sftp_dir_list: if filename.endswith(Manager.APK_SUFFIX): remote_file_path = file_util.join_unix_path( remote_dir, filename) local_file_name = filename if len(channel): local_file_name = channel + Manager.APK_SUFFIX if target_file_name: local_file_name = target_file_name local_file_path = file_util.normalpath( os.path.join(local_dir_path, local_file_name)) # self._download_single_file(sftp_cli, remote_file_path, local_file_path, force) if self.debug: monitor = DownloadMonitor(remote_file_path, local_file_path) callback = monitor.feedback else: callback = None self._download_single_file(sftp_cli, remote_file_path, local_file_path, force, as_file, callback=callback)