15f9996aaSopenharmony_ci#!/usr/bin/env python3
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ci
175f9996aaSopenharmony_ciimport subprocess
185f9996aaSopenharmony_ciimport argparse
195f9996aaSopenharmony_ciimport os
205f9996aaSopenharmony_ciimport sys
215f9996aaSopenharmony_ci
225f9996aaSopenharmony_cifrom util import build_utils
235f9996aaSopenharmony_cifrom util import file_utils
245f9996aaSopenharmony_ci
255f9996aaSopenharmony_ci
265f9996aaSopenharmony_cidef parse_args(args):
275f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
285f9996aaSopenharmony_ci    build_utils.add_depfile_option(parser)
295f9996aaSopenharmony_ci
305f9996aaSopenharmony_ci    parser.add_argument('--keyPwd', help='')
315f9996aaSopenharmony_ci    parser.add_argument('--sign-algo', help='')
325f9996aaSopenharmony_ci    parser.add_argument('--keyalias', help='')
335f9996aaSopenharmony_ci    parser.add_argument('--keystoreFile', help='')
345f9996aaSopenharmony_ci    parser.add_argument('--keystorePwd', help='')
355f9996aaSopenharmony_ci    parser.add_argument('--profileFile', help='')
365f9996aaSopenharmony_ci    parser.add_argument('--hapsigner', help='')
375f9996aaSopenharmony_ci    parser.add_argument('--unsigned-hap-path-list', help='')
385f9996aaSopenharmony_ci    parser.add_argument('--compatible_version', help='compatible_version')
395f9996aaSopenharmony_ci    parser.add_argument('--hap-out-dir', help='')
405f9996aaSopenharmony_ci    parser.add_argument('--inFile', help='')
415f9996aaSopenharmony_ci    parser.add_argument('--outFile', help='')
425f9996aaSopenharmony_ci    parser.add_argument('--profileSigned', help='')
435f9996aaSopenharmony_ci    parser.add_argument('--inForm', help='')
445f9996aaSopenharmony_ci    parser.add_argument('--certificate-file', help='')
455f9996aaSopenharmony_ci    parser.add_argument('--hap-name', help='')
465f9996aaSopenharmony_ci    parser.add_argument('--hap-list', help='')
475f9996aaSopenharmony_ci    options = parser.parse_args(args)
485f9996aaSopenharmony_ci    return options
495f9996aaSopenharmony_ci
505f9996aaSopenharmony_ci
515f9996aaSopenharmony_cidef sign_app(options, unsigned_hap_path: str, signed_hap_path: str):
525f9996aaSopenharmony_ci    cmd = ['java', '-jar', options.hapsigner, 'sign-app']
535f9996aaSopenharmony_ci    cmd.extend(['-mode', 'localsign'])
545f9996aaSopenharmony_ci    cmd.extend(['-signAlg', options.sign_algo])
555f9996aaSopenharmony_ci    cmd.extend(['-keyAlias', options.keyalias])
565f9996aaSopenharmony_ci    cmd.extend(['-inFile', unsigned_hap_path])
575f9996aaSopenharmony_ci    cmd.extend(['-outFile', signed_hap_path])
585f9996aaSopenharmony_ci    cmd.extend(['-profileFile', options.profileFile])
595f9996aaSopenharmony_ci    cmd.extend(['-keystoreFile', options.keystoreFile])
605f9996aaSopenharmony_ci    cmd.extend(['-keystorePwd', options.keystorePwd])
615f9996aaSopenharmony_ci    cmd.extend(['-keyPwd', options.keyPwd])
625f9996aaSopenharmony_ci    cmd.extend(['-appCertFile', options.certificate_file])
635f9996aaSopenharmony_ci    cmd.extend(['-profileSigned', (options.profileSigned or '1')])
645f9996aaSopenharmony_ci    cmd.extend(['-inForm', (options.inForm or 'zip')])
655f9996aaSopenharmony_ci    child = subprocess.Popen(cmd,
665f9996aaSopenharmony_ci                             stdout=subprocess.PIPE,
675f9996aaSopenharmony_ci                             stderr=subprocess.PIPE)
685f9996aaSopenharmony_ci    stdout, stderr = child.communicate()
695f9996aaSopenharmony_ci    if child.returncode:
705f9996aaSopenharmony_ci        print(stdout.decode(), stderr.decode())
715f9996aaSopenharmony_ci        raise Exception("Failed to sign hap")
725f9996aaSopenharmony_ci
735f9996aaSopenharmony_ci
745f9996aaSopenharmony_cidef main(args):
755f9996aaSopenharmony_ci    options = parse_args(args)
765f9996aaSopenharmony_ci    if not options.hap_out_dir:
775f9996aaSopenharmony_ci        sign_app(options, options.inFile, options.outFile)
785f9996aaSopenharmony_ci    else:
795f9996aaSopenharmony_ci        if not os.path.exists(options.hap_out_dir):
805f9996aaSopenharmony_ci            os.makedirs(options.hap_out_dir, exist_ok=True)
815f9996aaSopenharmony_ci        unsigned_hap_path_list = file_utils.read_json_file(options.unsigned_hap_path_list)
825f9996aaSopenharmony_ci        signed_hap_names = {}
835f9996aaSopenharmony_ci        if os.path.isfile(options.hap_list):
845f9996aaSopenharmony_ci            hap_list = file_utils.read_json_file(options.hap_list)
855f9996aaSopenharmony_ci            signed_hap_names['do_filter'] = hap_list.get('do_filter')
865f9996aaSopenharmony_ci            for unsigned_to_signed in hap_list.get('hap_list'):
875f9996aaSopenharmony_ci                names = unsigned_to_signed.split(':')
885f9996aaSopenharmony_ci                if len(names) == 2:
895f9996aaSopenharmony_ci                    signed_hap_names[f'{names[0]}.hsp'] = f'{names[1]}.hsp'
905f9996aaSopenharmony_ci                    signed_hap_names[f'{names[0]}.hap'] = f'{names[1]}.hap'
915f9996aaSopenharmony_ci                else:
925f9996aaSopenharmony_ci                    raise ValueError(f'Value hap_list {hap_list} not compliant with format')
935f9996aaSopenharmony_ci        for unsigned_hap_path in unsigned_hap_path_list.get('unsigned_hap_path_list'):
945f9996aaSopenharmony_ci            signed_hap_path = unsigned_hap_path.replace('unsigned', 'signed')
955f9996aaSopenharmony_ci            output_hap_name = f'{options.hap_name}-{os.path.basename(signed_hap_path)}'
965f9996aaSopenharmony_ci            unsigned_hap_name = f'{options.hap_name}-{os.path.basename(unsigned_hap_path)}'
975f9996aaSopenharmony_ci            if len(unsigned_hap_path_list.get('unsigned_hap_path_list')) == 1 and options.hap_name:
985f9996aaSopenharmony_ci                if unsigned_hap_path_list.get('unsigned_hap_path_list')[0].endswith('.hsp'):
995f9996aaSopenharmony_ci                    output_hap_name = f'{options.hap_name}.hsp'
1005f9996aaSopenharmony_ci                    unsigned_hap_name = output_hap_name
1015f9996aaSopenharmony_ci                else:
1025f9996aaSopenharmony_ci                    output_hap_name = f'{options.hap_name}.hap'
1035f9996aaSopenharmony_ci                    unsigned_hap_name = output_hap_name
1045f9996aaSopenharmony_ci            if signed_hap_names.get('do_filter'):
1055f9996aaSopenharmony_ci                if signed_hap_names.get(unsigned_hap_name):
1065f9996aaSopenharmony_ci                    output_hap_name = signed_hap_names.get(unsigned_hap_name)
1075f9996aaSopenharmony_ci            output_hap = os.path.join(options.hap_out_dir, output_hap_name)
1085f9996aaSopenharmony_ci            sign_app(options, unsigned_hap_path, output_hap)
1095f9996aaSopenharmony_ci
1105f9996aaSopenharmony_ci
1115f9996aaSopenharmony_ciif __name__ == '__main__':
1125f9996aaSopenharmony_ci    sys.exit(main(sys.argv[1:]))
113