1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# Copyright (c) 2023 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16 17import subprocess 18import argparse 19import os 20import sys 21 22from util import build_utils 23from util import file_utils 24 25 26def parse_args(args): 27 parser = argparse.ArgumentParser() 28 build_utils.add_depfile_option(parser) 29 30 parser.add_argument('--keyPwd', help='') 31 parser.add_argument('--sign-algo', help='') 32 parser.add_argument('--keyalias', help='') 33 parser.add_argument('--keystoreFile', help='') 34 parser.add_argument('--keystorePwd', help='') 35 parser.add_argument('--profileFile', help='') 36 parser.add_argument('--hapsigner', help='') 37 parser.add_argument('--unsigned-hap-path-list', help='') 38 parser.add_argument('--compatible_version', help='compatible_version') 39 parser.add_argument('--hap-out-dir', help='') 40 parser.add_argument('--inFile', help='') 41 parser.add_argument('--outFile', help='') 42 parser.add_argument('--profileSigned', help='') 43 parser.add_argument('--inForm', help='') 44 parser.add_argument('--certificate-file', help='') 45 parser.add_argument('--hap-name', help='') 46 parser.add_argument('--hap-list', help='') 47 options = parser.parse_args(args) 48 return options 49 50 51def sign_app(options, unsigned_hap_path: str, signed_hap_path: str): 52 cmd = ['java', '-jar', options.hapsigner, 'sign-app'] 53 cmd.extend(['-mode', 'localsign']) 54 cmd.extend(['-signAlg', options.sign_algo]) 55 cmd.extend(['-keyAlias', options.keyalias]) 56 cmd.extend(['-inFile', unsigned_hap_path]) 57 cmd.extend(['-outFile', signed_hap_path]) 58 cmd.extend(['-profileFile', options.profileFile]) 59 cmd.extend(['-keystoreFile', options.keystoreFile]) 60 cmd.extend(['-keystorePwd', options.keystorePwd]) 61 cmd.extend(['-keyPwd', options.keyPwd]) 62 cmd.extend(['-appCertFile', options.certificate_file]) 63 cmd.extend(['-profileSigned', (options.profileSigned or '1')]) 64 cmd.extend(['-inForm', (options.inForm or 'zip')]) 65 child = subprocess.Popen(cmd, 66 stdout=subprocess.PIPE, 67 stderr=subprocess.PIPE) 68 stdout, stderr = child.communicate() 69 if child.returncode: 70 print(stdout.decode(), stderr.decode()) 71 raise Exception("Failed to sign hap") 72 73 74def main(args): 75 options = parse_args(args) 76 if not options.hap_out_dir: 77 sign_app(options, options.inFile, options.outFile) 78 else: 79 if not os.path.exists(options.hap_out_dir): 80 os.makedirs(options.hap_out_dir, exist_ok=True) 81 unsigned_hap_path_list = file_utils.read_json_file(options.unsigned_hap_path_list) 82 signed_hap_names = {} 83 if os.path.isfile(options.hap_list): 84 hap_list = file_utils.read_json_file(options.hap_list) 85 signed_hap_names['do_filter'] = hap_list.get('do_filter') 86 for unsigned_to_signed in hap_list.get('hap_list'): 87 names = unsigned_to_signed.split(':') 88 if len(names) == 2: 89 signed_hap_names[f'{names[0]}.hsp'] = f'{names[1]}.hsp' 90 signed_hap_names[f'{names[0]}.hap'] = f'{names[1]}.hap' 91 else: 92 raise ValueError(f'Value hap_list {hap_list} not compliant with format') 93 for unsigned_hap_path in unsigned_hap_path_list.get('unsigned_hap_path_list'): 94 signed_hap_path = unsigned_hap_path.replace('unsigned', 'signed') 95 output_hap_name = f'{options.hap_name}-{os.path.basename(signed_hap_path)}' 96 unsigned_hap_name = f'{options.hap_name}-{os.path.basename(unsigned_hap_path)}' 97 if len(unsigned_hap_path_list.get('unsigned_hap_path_list')) == 1 and options.hap_name: 98 if unsigned_hap_path_list.get('unsigned_hap_path_list')[0].endswith('.hsp'): 99 output_hap_name = f'{options.hap_name}.hsp' 100 unsigned_hap_name = output_hap_name 101 else: 102 output_hap_name = f'{options.hap_name}.hap' 103 unsigned_hap_name = output_hap_name 104 if signed_hap_names.get('do_filter'): 105 if signed_hap_names.get(unsigned_hap_name): 106 output_hap_name = signed_hap_names.get(unsigned_hap_name) 107 output_hap = os.path.join(options.hap_out_dir, output_hap_name) 108 sign_app(options, unsigned_hap_path, output_hap) 109 110 111if __name__ == '__main__': 112 sys.exit(main(sys.argv[1:])) 113