def test_zip_dir(): src_path = r'E:\temp\crash\to_process' # src_root = 'E:\temp' src_root = None dst_path = r'E:\temp\test_zip_02.zip' myzip.zip_dir(src_path, dst_path, src_root, to_print=True) src_path = r'E:\temp\crash\crash_info_201512011634.txt' dst_path = r'E:\temp\test_zip_01.zip' myzip.zip_dir(src_path, dst_path, to_print=True)
def build(self, chan_id, mode=apk_builder.RELEASE_MODE): self._update_chan_info(chan_id) # update_str = 'updated version info with chan_id "{0}".'.format(chan_id) # print(update_str) print('building apk begin ...') # 获取apk名称 apk_name = os.path.basename(self.prj_path) apk_out_path = self.prj_path + '/build/outputs/apk/' apk_path = '{}{}-{}.apk'.format(apk_out_path, apk_name, apk_builder.MODE_MAP[mode]) apk_path = os.sep.join(re.split('[\\\/]+', apk_path)) # 先把现有的apk文件直接删除 if os.path.exists(apk_path) and os.path.isfile(apk_path): os.remove(apk_path) cmd_str = self.get_build_cmd() make_apk_with_gradle(self.prj_path, cmd_str) src_file = apk_path if os.path.exists(src_file): apk_items = apk_util.get_apk_info(src_file) if apk_items['versionName'] != self.info[ ProjectBuilder.VER_NAME_FLAG]: info = 'set version name is {}, but actual is {}!'.format( self.info[ProjectBuilder.VER_NAME_FLAG], apk_items['versionName']) raise Exception(info) if apk_items['versionCode'] != self.info[ ProjectBuilder.VER_CODE_FLAG]: info = 'set version code is {}, but actual is {}!'.format( self.info[ProjectBuilder.VER_CODE_FLAG], apk_items['versionCode']) raise Exception(info) dst_file = self.info[ ProjectBuilder.OUTPUT_DIRECTORY_FLAG] + os.sep + self.info[ ProjectBuilder.OUTPUT_NAME_FLAG] file_util.replace_file(src_file, dst_file) # 拷贝编译生成的class文件,便于服务器生成代码覆盖率文件 if ProjectBuilder.BUILD_CLASS_FLAG in self.info and len( self.info[ProjectBuilder.BUILD_CLASS_FLAG]) >= 2: src_class_path = self.prj_path + os.sep + self.info[ ProjectBuilder.BUILD_CLASS_FLAG][ ProjectBuilder.SRC_PATH_FLAG] src_class_path = file_util.normalpath(src_class_path) dst_class_relative_path = self.info[ ProjectBuilder.BUILD_CLASS_FLAG][ ProjectBuilder.DST_PATH_FLAG] dst_class_zip_path = self.info[ ProjectBuilder. OUTPUT_DIRECTORY_FLAG] + os.sep + 'classes.zip' # dst_class_path = self.info[ProjectBuilder.OUTPUT_DIRECTORY_FLAG] + os.sep + dst_class_relative_path # dst_class_path = file_util.normalize_path(dst_class_path) # # if os.path.isdir(dst_class_path): # shutil.rmtree(dst_class_path) if os.path.isdir(src_class_path): # shutil.copytree(src_class_path, dst_class_path) rev_index = -len(dst_class_relative_path) zip_src_root = src_class_path[:rev_index] zip_util.zip_dir(src_class_path, dst_class_zip_path, zip_src_root) print('success zip {} to {}.'.format( dst_class_relative_path, dst_class_zip_path)) print('built the apk {}.'.format(dst_file)) else: print('build {} failed!'.format(apk_name))
def process_item(src_dir, dst_dir, temp_dir, _type, ver_code, filter_folders, filter_out=_PACK_FILTER_OUT, ver_file=_PACK_VER_FILE, target_root_name=_PACK_TARGET_ROOT_NAME, target_file=_PACK_TARGET_FILE, filter_file=None): temp_target_dir = temp_dir + os.sep + target_root_name file_map = FileMap(_PACK_FLAGS[_type], src_dir, temp_target_dir) func = FileCopy(file_map) child_dir_arr = get_firstfolderitem(src_dir) if filter_folders: for listfile in child_dir_arr: listfile_path = src_dir + os.sep + listfile # 是否在文件排除列表里面 if listfile in filter_folders: # 判断是文件还是文件夹 if os.path.isfile(listfile_path): shutil.copy(listfile_path, temp_target_dir + os.sep + listfile) elif os.path.isdir(listfile_path): shutil.copytree(listfile_path, temp_target_dir + os.sep + listfile) else: if os.path.isfile(listfile_path): func(listfile_path) elif os.path.isdir(listfile_path): file_util.process_dir(listfile_path, func) else: file_util.process_dir(src_dir, func) # 更新配置文件版本号 if ver_file: # 将路径归一化,避免路径分隔符不一致引起问题 ref_path = os.sep.join(re.split('[\\\/]+', ver_file)) ver_path = temp_target_dir + os.sep + ref_path file_util.write_to_file(ver_path, str(ver_code), 'utf-8') # 将要排除的文件去除 if filter_out: for item in filter_out: # 将路径归一化,避免路径分隔符不一致引起问题 ref_path = os.sep.join(re.split('[\\\/]+', item)) filepath = temp_target_dir + os.sep + ref_path if os.path.exists(filepath): if os.path.isfile(filepath): os.remove(filepath) elif os.path.isdir(filepath): shutil.rmtree(filepath) else: print('not exists ' + filepath) print('filter out files ok') if filter_file: child_temp_dir_arr = get_firstfolderitem(temp_target_dir) for folder_detail_file in filter_file: for list_file in child_temp_dir_arr: list_file_path = temp_target_dir + os.sep + list_file for root, dirs, files in os.walk(list_file_path): if folder_detail_file in list_file_path: shutil.rmtree(list_file_path) if folder_detail_file in dirs: shutil.rmtree(os.path.join(root, folder_detail_file)) for name in files: if folder_detail_file == name: os.remove(os.path.join(root, folder_detail_file)) print('filter files ok') # 将整个配置文件打包 if target_file: target_path = dst_dir + os.sep + target_file base_target_dir = os.path.dirname(target_path) if not os.path.exists(base_target_dir): os.makedirs(base_target_dir) if os.path.isfile(target_path): os.remove(target_path) zip_util.zip_dir(temp_dir, target_path)
def process(self): git_flag = 'use_git' if not hasattr(self, git_flag): self.use_git = False # 进行代码更新操作 if self.to_update: code_url = self.app_build_cofig[BuildConfigParser.CODE_URL_FLAG] if self.use_git: self.sftp_config_path = ['config', 'base', 'sftp_config.xml'] self.sftp_config_path = os.sep.join(self.sftp_config_path) self.sftp_config_path = self.work_path + os.sep + self.sftp_config_path doc = xmltodict.parse( myfile.read_file_content(self.sftp_config_path)) sftp_config_data = doc['config'] self.temp_username = sftp_config_data['username'] self.temp_password = sftp_config_data['password'] git.checkout_or_update(self.project_path, code_url, self.code_ver, self.branch) git.revert_temporary(self.project_path) else: # 根据参数配置svn用户名和密码 username_flag = 'svn_user' password_flag = 'svn_pwd' if hasattr(self, username_flag) and hasattr( self, password_flag): # print('{}: {}'.format(username_flag, self.svn_user)) # print('{}: {}'.format(password_flag, self.svn_pwd)) svn.set_user_info(getattr(self, username_flag), getattr(self, password_flag)) svn.checkout_or_update(self.project_path, code_url, self.code_ver) # 获取当前代码版本号 if self.use_git: git_root = git.get_git_root(self.project_path) self.code_ver = git.get_revision(git_root) else: self.code_ver = svn.get_revision(self.project_path) print('current code version is ' + str(self.code_ver)) # 进行版本编译操作 if self.to_build: to_check_vals = ['ver_name', 'ver_code', 'ver_env', 'ver_type'] for name in to_check_vals: value = getattr(self, name) if not value: info = 'Please specify the {}.'.format(name) print(info) exit(1) # 参数非空判断验证通过开始进行正式业务逻辑 self.pro_build_config = self._get_pro_build_config() self.pre_build() self.build(self.pro_build_config) if os.path.isfile(self.ipa_output_path): # 将编译信息写文件 build_info_format = self.ori_build_config[ BuildConfigParser.BUILD_INFO_TEMPLET_FLAG] build_info = build_info_format.format(ver_name=self.ver_name, code_ver=self.code_ver, ver_code=self.ver_code) build_info_path = self.output_directory + os.sep + 'readme-{}-{}.txt'.format( self.ver_name, self.ver_code) myfile.write_to_file(build_info_path, build_info, encoding='utf-8') str_info = 'Build success, current code version is {}.'.format( self.code_ver) print(str_info) else: str_info = 'Build failed, current code version is {}.'.format( self.code_ver) raise Exception(str_info) # 将*.ipa包上传到sftp服务器 if self.to_upload_sftp: doc = ET.parse(self.sftp_config_path) root = doc.getroot() username = root.find('username') username.text = self.temp_username password = root.find('password') password.text = self.temp_password doc.write(self.sftp_config_path) print('----------change it--------') # 复制podfile.lock 到目标文件夹 pods_lock_file = self.pods_path + os.sep + 'Podfile.lock' shutil.copy(pods_lock_file, self.output_directory) # 为防止上传的东西太多,将部分文件打成zip包 print('Archiving data file') tmp_folder = tempfile.mkdtemp() dst_zip_file = self.output_directory + os.sep + '%s_data.zip' % ( self.ipa_name) myfile.process_dir_src_to_dst(self.output_directory, tmp_folder, self.process_func) myzip.zip_dir(tmp_folder, dst_zip_file) shutil.rmtree(tmp_folder) for file in os.listdir(self.output_directory): if os.path.splitext(file)[1] == '.xcarchive': xcarchive_file_path = os.path.join( self.output_directory, file) shutil.rmtree(xcarchive_file_path) sftp.upload_to_sftp(self.work_path, self.ver_name, self.ver_env, self.code_ver, self.app_code, self.output_directory, 'IOS', '', self.ipa_name, self.ipa_name) # 复制文件到document ipa_file_path = self.output_directory + os.sep + self.ipa_name ipa_dir_path = myfile.normalpath('/Users/caifh/Documents/ipa') if os.path.exists(ipa_dir_path): shutil.copy(ipa_file_path, ipa_dir_path) # 更新工程文件 print('更新工程文件') print(self.project_path) new_project_path = self.project_path allfilelist = os.listdir(self.project_path) for file in allfilelist: filepath = os.path.join(self.project_path, file) if os.path.isdir(filepath): new_project_path = myfile.normalpath(filepath) break dst_dir = os.path.abspath(new_project_path) os.chdir(dst_dir) rtn_str = subprocess.check_output( 'git diff --name-only --diff-filter=ACM', shell=True, universal_newlines=True) if rtn_str: info_arr = rtn_str.split('\n') new_info_arr = [] for item in info_arr: if len(item) > 0: new_info_arr.append(item) try: source_path = git.get_git_root(self.project_path) git.push_to_remote(new_info_arr, '[other]: 提交打包版本信息', repository=None, refspecs=None, _dir=source_path) git.revert_temporary(source_path) except Exception as e: raise Exception(e)
def build(self): print('building apk begin ...') # 获取apk名称 apk_name = os.path.basename(self.main_prj_path) apk_out_path = self.main_prj_path + '/build/outputs/apk/' # 自定义名称形式 apk_path = os.path.join(apk_out_path, self._get_output_relative_path(), self.info[BuilderLabel.OUTPUT_NAME_FLAG]) apk_path = os.path.normpath(apk_path) # 先把现有的apk文件直接删除 if os.path.exists(apk_path) and os.path.isfile(apk_path): os.remove(apk_path) cmd_str = self.get_build_cmd() make_apk_with_gradle(self.main_prj_path, cmd_str) src_file = apk_path print('source apk path: {}'.format(src_file)) if os.path.exists(src_file): apk_items = apk.get_apk_info(src_file) actual_ver_name = self.get_main_ver_name(apk_items['versionName']) if actual_ver_name != self.info[BuilderLabel.VER_NAME_FLAG]: info = 'set version name is {}, but actual is {}!'.format( self.info[BuilderLabel.VER_NAME_FLAG], actual_ver_name) raise Exception(info) if apk_items['versionCode'] != str( self.info[BuilderLabel.VER_CODE_FLAG]): info = 'set version code is {}, but actual is {}!'.format( self.info[BuilderLabel.VER_CODE_FLAG], apk_items['versionCode']) raise Exception(info) dst_file = self.info[ BuilderLabel.OUTPUT_DIRECTORY_FLAG] + os.sep + self.info[ BuilderLabel.OUTPUT_NAME_FLAG] file_util.replace_file(src_file, dst_file) # 拷贝编译生成的class文件,便于服务器生成代码覆盖率文件 if BuilderLabel.BUILD_CLASS_FLAG in self.info and len( self.info[BuilderLabel.BUILD_CLASS_FLAG]) >= 2: src_class_path = self.main_prj_path + os.sep + self.info[ BuilderLabel.BUILD_CLASS_FLAG][BuilderLabel.SRC_PATH_FLAG] src_class_path = file_util.normalpath(src_class_path) dst_class_relative_path = self.info[ BuilderLabel.BUILD_CLASS_FLAG][BuilderLabel.DST_PATH_FLAG] dst_class_zip_path = self.info[ BuilderLabel. OUTPUT_DIRECTORY_FLAG] + os.sep + 'classes.zip' if os.path.isdir(src_class_path): # shutil.copytree(src_class_path, dst_class_path) rev_index = -len(dst_class_relative_path) zip_src_root = src_class_path[:rev_index] zip_util.zip_dir(src_class_path, dst_class_zip_path, zip_src_root) print('success zip {} to {}.'.format( dst_class_relative_path, dst_class_zip_path)) print('built the apk {}.'.format(dst_file)) else: print('build {} failed!'.format(apk_name))