1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2025 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import json 19import os 20import logging 21from pathlib import Path 22from typing import Union, Any, Dict 23from vmb.helpers import create_file, copy_file, load_json 24from vmb.tool import ToolBase 25from vmb.unit import BenchUnit 26 27here = os.path.realpath(os.path.dirname(__file__)) 28certs = Path(here).parent.parent.joinpath('resources', 'hap-sign') 29log = logging.getLogger('vmb') 30 31hvigor_config = { 32 "modelVersion": "5.0.0", 33 "dependencies": {}, 34 "execution": {}, 35 "logging": { 36 "level": "info" 37 }, 38 "debugging": {}, 39 "nodeOptions": {} 40} 41 42build_config: Dict = { 43 "app": { 44 "signingConfigs": [], 45 "products": [ 46 { 47 "name": "default", 48 "compileSdkVersion": 12, 49 "compatibleSdkVersion": 12, 50 "targetSdkVersion": 12, 51 "runtimeOS": "OpenHarmony", 52 } 53 ], 54 "buildModeSet": [ 55 { 56 "name": "debug", 57 } 58 ] 59 }, 60 "modules": [ 61 { 62 "name": "entry", 63 "srcPath": "./entry", 64 "targets": [ 65 { 66 "name": "default", 67 "applyToProducts": [ 68 "default" 69 ] 70 } 71 ] 72 } 73 ] 74} 75 76build_config_module = { 77 "apiType": "stageMode", 78 "buildOption": {}, 79 "targets": [{"name": "default"}] 80} 81 82oh_package = { 83 "modelVersion": "5.0.0", 84 "description": "blah", 85 "dependencies": {}, 86 "devDeppendencies": {} 87} 88 89HVIGORFILE_TS = """ 90import { appTasks } from '@ohos/hvigor-ohos-plugin'; 91export default { 92 system: appTasks, plugins: [] 93} 94""" 95 96MODULE_HVIGORFILE_TS = """ 97import { hapTasks } from '@ohos/hvigor-ohos-plugin'; 98export default { 99 system: hapTasks, plugins: [] 100} 101""" 102 103app = { 104 "app": { 105 "bundleName": "com.example.hellopanda", 106 "vendor": "example", 107 "versionCode": 1000, 108 "versionName": "1.0.0", 109 "icon": "$media:app_icon", 110 "label": "$string:app_name" 111 } 112} 113 114app_string = { 115 "string": [{"name": "app_name", "value": "HelloPanda"}] 116} 117 118color = { 119 "color": [{ 120 "name": "start_window_background", 121 "value": "#FFFFFF" 122 }] 123} 124 125string = { 126 "string": [ 127 {"name": "module_desc", "value": "module description"}, 128 {"name": "EntryAbility_desc", "value": "description"}, 129 {"name": "EntryAbility_label", "value": "arkUiDemo"} 130 ] 131} 132 133main_pages = { 134 "src": ["pages/Index"] 135} 136 137 138class Tool(ToolBase): 139 140 app_name = 'com.example.hellopanda' 141 mod_name = 'entry' 142 143 def __init__(self, *args) -> None: 144 super().__init__(*args) 145 self.ohos_sdk = self.ensure_dir_env('OHOS_BASE_SDK_HOME') 146 self.hvigorw = ToolBase.get_cmd_path('hvigorw', 'HVIGORW') 147 self.signing_config = os.environ.get('HAP_SIGNING_CONFIG', '') 148 self.resource_dir = Path(here).parent.parent.joinpath('resources', 'hap') 149 150 @property 151 def name(self) -> str: 152 return 'Build HAP package (hvigorw)' 153 154 @staticmethod 155 def emit_config(content: Any, path: Union[str, Path]) -> None: 156 p = Path(path) 157 p.parent.mkdir(parents=True, exist_ok=True) 158 with create_file(p) as f: 159 f.write(json.dumps(content, indent=4)) 160 161 def exec(self, bu: BenchUnit) -> None: 162 if self.signing_config: 163 try: 164 build_config['app']['signingConfigs'] = [{ 165 "name": "default", 166 "material": load_json(self.signing_config)}] 167 build_config['app']['products'][0]['signingConfig'] = 'default' 168 except KeyError as e: 169 raise RuntimeError('Corrupted build config') from e 170 Tool.emit_config(build_config, bu.path.joinpath('build-profile.json5')) 171 Tool.emit_config(oh_package, bu.path.joinpath('oh-package.json5')) 172 Tool.emit_config(oh_package, bu.path.joinpath(self.mod_name, 'oh-package.json5')) 173 Tool.emit_config(hvigor_config, bu.path.joinpath('hvigor', 'hvigor-config.json5')) 174 Tool.emit_config(build_config_module, bu.path.joinpath(self.mod_name, 'build-profile.json5')) 175 Tool.emit_config(app, bu.path.joinpath('AppScope', 'app.json5')) 176 Tool.emit_config(app_string, bu.path.joinpath( 177 'AppScope', 'resources', 'base', 'element', 'string.json')) 178 Tool.emit_config(color, bu.path.joinpath( 179 self.mod_name, 'src', 'main', 'resources', 'base', 'element', 'color.json')) 180 Tool.emit_config(string, bu.path.joinpath( 181 self.mod_name, 'src', 'main', 'resources', 'en_US', 'element', 'string.json')) 182 Tool.emit_config(string, bu.path.joinpath( 183 self.mod_name, 'src', 'main', 'resources', 'base', 'element', 'string.json')) 184 Tool.emit_config(main_pages, bu.path.joinpath( 185 self.mod_name, 'src', 'main', 'resources', 'base', 'profile', 'main_pages.json')) 186 # to do: links instead of files? 187 with create_file(bu.path.joinpath('hvigorfile.ts')) as f: 188 f.write(HVIGORFILE_TS) 189 with create_file(bu.path.joinpath(self.mod_name, 'hvigorfile.ts')) as f: 190 f.write(MODULE_HVIGORFILE_TS) 191 # icon.png 192 icon_src = self.resource_dir.joinpath('icon.png') 193 icon = bu.path.joinpath('entry', 'src', 'main', 'resources', 'base', 'media', 'icon.png') 194 icon_app = bu.path.joinpath('AppScope', 'resources', 'base', 'media', 'app_icon.png') 195 copy_file(icon_src, icon) 196 copy_file(icon_src, icon_app) 197 # Index.ets 198 index_ets_src = self.resource_dir.joinpath('Index.ets') 199 index_ets = bu.path.joinpath('entry', 'src', 'main', 'ets', 'pages', 'Index.ets') 200 copy_file(index_ets_src, index_ets) 201 self.sh.run(f'{self.hvigorw} -d --mode module -p module={self.mod_name}@default ' 202 '-p product=default -p debuggable=true --no-daemon assembleHap', 203 cwd=str(bu.path)) 204 hap = bu.path.joinpath(self.mod_name, 205 f'build/default/outputs/default/{self.mod_name}-default-signed.hap') 206 self.ensure_file(hap) 207 self.hdc.install(hap, self.app_name) 208