1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 5# 6# HDF is dual licensed: you can use it either under the terms of 7# the GPL, or the BSD license, at your option. 8# See the LICENSE file in the root of this repository for complete details. 9 10 11import configparser 12import json 13import os 14import shutil 15from string import Template 16 17import hdf_utils 18from hdf_tool_exception import HdfToolException 19from .hdf_command_error_code import CommandErrorCode 20from .hdf_command_handler_base import HdfCommandHandlerBase 21from .hdf_defconfig_patch import HdfDefconfigAndPatch 22from .hdf_device_info_hcs import HdfDeviceInfoHcsFile 23from .hdf_get_handler import HdfGetHandler 24from .hdf_vendor_build_file import HdfVendorBuildFile 25from .hdf_vendor_kconfig_file import HdfVendorKconfigFile 26from .hdf_vendor_makefile import HdfVendorMakeFile 27from .hdf_vendor_mk_file import HdfVendorMkFile 28from .hdf_module_kconfig_file import HdfModuleKconfigFile 29from .hdf_module_mk_file import HdfModuleMkFile 30from .hdf_driver_config_file import HdfDriverConfigFile 31 32 33class HdfDeleteHandler(HdfCommandHandlerBase): 34 def __init__(self, args): 35 super(HdfDeleteHandler, self).__init__() 36 self.cmd = 'delete' 37 self.handlers = { 38 'vendor': self._delete_vendor_handler, 39 'module': self._delete_module_handler, 40 'driver': self._delete_driver_handler, 41 'module_driver': self._delete_module_driver_handler, 42 } 43 self.parser.add_argument("--action_type", 44 help=' '.join(self.handlers.keys()), 45 required=True) 46 self.parser.add_argument("--root_dir", required=True) 47 self.parser.add_argument("--vendor_name") 48 self.parser.add_argument("--module_name") 49 self.parser.add_argument("--driver_name") 50 self.parser.add_argument("--board_name") 51 self.parser.add_argument("--kernel_name") 52 self.parser.add_argument("--device_name") 53 self.args_original = args 54 self.args = self.parser.parse_args(args) 55 56 def config_delete_operation_liteos( 57 self, driver_name, driver_config_index, temp_file, file_path): 58 key_list = list(filter( 59 lambda x: x.endswith(driver_name.upper()), 60 driver_config_index.keys())) 61 if key_list: 62 key_name = key_list[0] 63 res = temp_file.get_driver_config_str( 64 driver_index=driver_config_index[key_name]) 65 temp_info = hdf_utils.read_file(file_path) 66 hdf_utils.write_file(file_path, "".join(temp_info.split(res))) 67 68 def config_delete_operation_linux( 69 self, driver_name, driver_config_index, file_path): 70 key_list = list(filter( 71 lambda x: x.endswith(driver_name.upper()), 72 driver_config_index.keys())) 73 if key_list: 74 key_name = key_list[0] 75 res = driver_config_index[key_name].rstrip("endif") 76 temp_info = hdf_utils.read_file(file_path) 77 hdf_utils.write_file(file_path, "".join(temp_info.split(res))) 78 79 def linux_liteos_common(self, file_name, file_path, 80 module_name, driver_name): 81 root, _, module, _, _, kernel, device = self.get_args() 82 if file_name == "Kconfig": 83 config_re_str = r"DRIVERS_HDF_(?P<name>.+[A-Z0-9])" 84 flag_re = r"config" 85 temp_file = hdf_utils.MakefileAndKconfigFileParse( 86 file_path=file_path, flag_str=flag_re, re_name=config_re_str) 87 driver_config_index = temp_file.split_driver_start_to_end() 88 self.config_delete_operation_linux( 89 driver_name, driver_config_index, file_path) 90 elif file_name.endswith("hcs"): 91 HdfDeviceInfoHcsFile( 92 root=root, vendor="", module="", 93 board="", driver=" ", path=file_path). \ 94 delete_driver(module=driver_name, temp_flag="device") 95 elif file_name.endswith("dot_configs"): 96 if module_name == "sensor": 97 temp_res = self.sensor_device_rely(module, kernel, device) 98 else: 99 temp_res = [] 100 for dot_path in file_path: 101 if dot_path.split(".")[-1] == "config": 102 template_string = \ 103 "LOSCFG_DRIVERS_HDF_${module_upper}_${driver_upper}=y\n" 104 else: 105 template_string = \ 106 "CONFIG_DRIVERS_HDF_${module_upper}_${driver_upper}=y\n" 107 new_demo_config = Template(template_string). \ 108 substitute({ 109 "module_upper": module_name.upper(), 110 "driver_upper": driver_name.upper(), 111 }) 112 temp_res.append(new_demo_config) 113 defconfig_patch = HdfDefconfigAndPatch( 114 root=root, vendor="", kernel="", board="", 115 data_model="", new_demo_config=temp_res) 116 defconfig_patch.delete_module( 117 path=os.path.join(root, dot_path)) 118 119 def sensor_device_rely(self, module, kernel, device): 120 templates_dir_path = hdf_utils.get_templates_lite_dir() 121 templates_model_dir = [] 122 for path, dir_name, _ in os.walk(templates_dir_path): 123 if dir_name: 124 templates_model_dir.extend(dir_name) 125 temp_templates_model_dir = list( 126 filter( 127 lambda model_dir: module in model_dir, 128 templates_model_dir)) 129 config_file = [ 130 name for name in os.listdir( 131 os.path.join( 132 templates_dir_path, 133 temp_templates_model_dir[0])) if name.endswith(".ini")] 134 if config_file: 135 config_path = os.path.join( 136 templates_dir_path, 137 temp_templates_model_dir[0], 138 config_file[0]) 139 config = configparser.ConfigParser() 140 config.read(config_path) 141 section_list = config.options(section=kernel) 142 if device in section_list: 143 device_enable_config, _ = hdf_utils.ini_file_read_operation( 144 section_name=kernel, 145 node_name=device, path=config_path) 146 else: 147 if kernel == "linux": 148 device_enable_config = [ 149 "CONFIG_DRIVERS_HDF_SENSOR_ACCEL=y\n"] 150 else: 151 device_enable_config = [ 152 "LOSCFG_DRIVERS_HDF_SENSOR_ACCEL=y\n"] 153 else: 154 device_enable_config = [""] 155 return device_enable_config 156 157 def _delete_vendor_handler(self): 158 self.check_arg_raise_if_not_exist("vendor_name") 159 self.check_arg_raise_if_not_exist("board_name") 160 root, vendor, _, _, _ = self.get_args() 161 vendor_hdf_dir = hdf_utils.get_vendor_hdf_dir(root, vendor) 162 if not os.path.exists(vendor_hdf_dir): 163 return 164 for module in os.listdir(vendor_hdf_dir): 165 mod_dir = os.path.join(vendor_hdf_dir, module) 166 if os.path.isdir(mod_dir): 167 pass 168 shutil.rmtree(vendor_hdf_dir) 169 170 def _delete_module(self, root, model, model_info): 171 for key, path_value in model_info.items(): 172 if key.split("_")[-1] == "name": 173 pass 174 elif key == "driver_file_path": 175 split_str = '/%s/driver' % model 176 driver_file = os.path.join( 177 root, path_value.rsplit(split_str, 1)[0], model) 178 if os.path.exists(driver_file): 179 shutil.rmtree(driver_file) 180 else: 181 self._delete_file_func(root, key, model_info, model) 182 create_model_data = self._delete_model_info() 183 delete_model_info = hdf_utils.get_create_model_info( 184 root=root, create_data=json.dumps(create_model_data)) 185 return delete_model_info 186 187 def _delete_model_info(self): 188 self.check_arg_raise_if_not_exist("root_dir") 189 self.check_arg_raise_if_not_exist("module_name") 190 root, _, module, _, _, _, _ = self.get_args() 191 create_file_save_path = hdf_utils.module_save_file_info(root) 192 data = hdf_utils.read_file(create_file_save_path) 193 write_data = json.loads(data) 194 write_data.pop(module) 195 hdf_utils.write_file(create_file_save_path, 196 json.dumps(write_data, indent=4)) 197 return write_data 198 199 def _delete_module_handler(self): 200 self.check_arg_raise_if_not_exist("root_dir") 201 self.check_arg_raise_if_not_exist("module_name") 202 root, _, module, _, _, _, _ = self.get_args() 203 create_file_save_path = hdf_utils.module_save_file_info(root) 204 data = hdf_utils.read_file(create_file_save_path) 205 file_info = json.loads(data) 206 model_info = file_info.get(module, None) 207 if model_info is None: 208 raise HdfToolException( 209 ' delete model "%s" not exist' % 210 module, CommandErrorCode.TARGET_NOT_EXIST) 211 else: 212 return self._delete_module(root, module, model_info) 213 214 def _delete_driver(self, module, driver): 215 root, vendor, _, _, board, kernel = self.get_args() 216 drv_dir = hdf_utils.get_drv_dir(root, vendor, module, driver) 217 if os.path.exists(drv_dir): 218 shutil.rmtree(drv_dir) 219 k_path = hdf_utils.get_module_kconfig_path(root, vendor, module) 220 HdfModuleKconfigFile(root, module, k_path).delete_driver(driver) 221 HdfModuleMkFile(root, vendor, module).delete_driver(driver) 222 HdfDriverConfigFile(root, board, module, driver, kernel).delete_driver() 223 224 def _delete_driver_handler(self): 225 self.check_arg_raise_if_not_exist("vendor_name") 226 self.check_arg_raise_if_not_exist("module_name") 227 self.check_arg_raise_if_not_exist("driver_name") 228 self.check_arg_raise_if_not_exist("board_name") 229 _, _, module, driver, _ = self.get_args() 230 self._delete_driver(module, driver) 231 232 def _delete_file_func(self, root, key, model_info, model): 233 if key.startswith("module_level_config"): 234 for key_name, value in model_info[key].items(): 235 self._delete_config_operation( 236 key_name, value, temp_root=root, temp_model=model) 237 238 elif key == "module_path": 239 for file_name, module_value in model_info[key].items(): 240 self._delete_module_file(root, model, file_name, module_value) 241 242 def _delete_module_file(self, root, model, file_name, module_value): 243 if file_name.startswith("adapter"): 244 file_path = os.path.join(root, module_value) 245 file_info = hdf_utils.read_file_lines(file_path) 246 delete_info = "libhdf_%s_hotplug" % model 247 248 for index, line_info in enumerate(file_info): 249 if line_info.find(delete_info) > 0: 250 file_info.pop(index) 251 hdf_utils.write_file_lines(file_path, file_info) 252 break 253 elif file_name == "group" or file_name == "passwd": 254 file_path = os.path.join(root, module_value) 255 file_info = hdf_utils.read_file_lines(file_path) 256 for index, line in enumerate(file_info): 257 if line.find(model) != -1: 258 file_info.pop(index) 259 hdf_utils.write_file_lines(file_path, file_info) 260 else: 261 if module_value.endswith("hcs"): 262 hcs_path = os.path.join(root, module_value) 263 HdfDeviceInfoHcsFile( 264 root=root, vendor="", module="", 265 board="", driver=" ", path=hcs_path). \ 266 delete_driver(module=model) 267 else: 268 if not module_value: 269 return 270 file_path = os.path.join(root, module_value) 271 if os.path.exists(file_path): 272 os.remove(file_path) 273 model_dir_path = "/".join(file_path.split("/")[:-1]) 274 if not os.path.exists(model_dir_path): 275 return 276 file_list = os.listdir(model_dir_path) 277 if not file_list: 278 shutil.rmtree(model_dir_path) 279 280 def _delete_config_operation(self, key_name, value, temp_root, temp_model): 281 if key_name == "%s_Makefile" % temp_model: 282 HdfVendorMakeFile( 283 temp_root, vendor="", kernel="", 284 path=os.path.join(temp_root, value)).delete_module(temp_model) 285 elif key_name == "%s_Kconfig" % temp_model: 286 HdfVendorKconfigFile( 287 temp_root, vendor="", kernel="", 288 path=os.path.join(temp_root, value)).delete_module(temp_model) 289 elif key_name == "%sBuild" % temp_model: 290 HdfVendorBuildFile( 291 temp_root, vendor="").delete_module( 292 file_path=os.path.join(temp_root, value), model=temp_model) 293 elif key_name == "%s_hdf_lite" % temp_model: 294 HdfVendorMkFile( 295 temp_root, vendor="").delete_module( 296 file_path=os.path.join(temp_root, value), module=temp_model) 297 elif key_name == "%s_dot_configs" % temp_model: 298 for dot_path in value: 299 if dot_path.split(".")[-1] == "config": 300 template_string = \ 301 "LOSCFG_DRIVERS_HDF_${module_upper_case}=y\n" 302 else: 303 template_string = \ 304 "CONFIG_DRIVERS_HDF_${module_upper_case}=y\n" 305 new_demo_config = Template(template_string). \ 306 substitute({"module_upper_case": temp_model.upper()}) 307 defconfig_patch = HdfDefconfigAndPatch( 308 root=temp_root, vendor="", kernel="", board="", 309 data_model="", new_demo_config=new_demo_config) 310 defconfig_patch.delete_module( 311 path=os.path.join(temp_root, dot_path)) 312 313 def _delete_module_driver_handler(self): 314 self.check_arg_raise_if_not_exist("root_dir") 315 self.check_arg_raise_if_not_exist("kernel_name") 316 self.check_arg_raise_if_not_exist("module_name") 317 self.check_arg_raise_if_not_exist("driver_name") 318 self.check_arg_raise_if_not_exist("board_name") 319 self.check_arg_raise_if_not_exist("device_name") 320 root, _, module, driver, board, kernel, device = self.get_args() 321 get_board = HdfGetHandler(self.args_original) 322 section_res = get_board.judgement_device_in_model(device) 323 board_module_driver = get_board.delete_module_driver_list() 324 res_json_format = json.loads(board_module_driver) 325 board_name_list = list(res_json_format.keys()) 326 temp_board_info = "" 327 for board_name in board_name_list: 328 board_driver = res_json_format[board_name] 329 temp_board_name = board_name.rstrip("_kernel") 330 if temp_board_name == board and kernel == "liteos": 331 self._delete_liteos_driver_config( 332 root, model_info=board_driver, module_name=module, 333 driver_name=driver) 334 temp_board_info = board_name 335 elif temp_board_name == board: 336 self._delete_linux_driver_config( 337 model_info=board_driver, module_name=module, 338 driver_name=driver) 339 temp_board_info = board_name 340 if len(board_driver) <= 1: 341 del res_json_format[board_name] 342 temp_driver_name = "-".join([device, driver]) 343 if temp_board_info: 344 get_board.format_delete_driver_file( 345 model_name=module, board_name=temp_board_info, 346 driver_name=temp_driver_name) 347 get_board.delete_device_operation(device, *section_res) 348 res_driver = get_board.judge_create_driver_exist() 349 return res_driver 350 351 def _delete_liteos_driver_config(self, root, model_info, module_name, driver_name): 352 model_info_key_list = list(model_info.keys()) 353 for key_name in model_info_key_list: 354 file_list = list(model_info[key_name].keys()) 355 for file_name in file_list: 356 file_path = model_info[key_name][file_name] 357 if file_name == "Makefile": 358 mk_re_str = r"ifeq.+LOSCFG_DRIVERS_HDF_(?P<name>.+[A-Z0-9])" 359 temp_file = hdf_utils.GnMkFileParse( 360 file_path=file_path, temp_re=mk_re_str) 361 driver_config_index = temp_file.split_driver_start_to_end( 362 flag_str="endif") 363 self.config_delete_operation_liteos( 364 driver_name, driver_config_index, temp_file, file_path) 365 elif file_name == "BUILD.gn": 366 mk_re_str = r"if.+LOSCFG_DRIVERS_HDF_(?P<name>.+\w)" 367 temp_file = hdf_utils.GnMkFileParse( 368 file_path=file_path, temp_re=mk_re_str) 369 driver_config_index = temp_file.split_driver_start_to_end( 370 flag_str="}") 371 self.config_delete_operation_liteos( 372 driver_name, driver_config_index, temp_file, file_path) 373 if file_name == driver_name: 374 self._delete_driver_file(file_path=file_path) 375 del model_info[key_name][file_name] 376 if not model_info[key_name]: 377 del model_info[key_name] 378 else: 379 self.linux_liteos_common( 380 file_name, file_path, module_name, driver_name) 381 382 def _delete_linux_driver_config( 383 self, model_info, module_name, driver_name): 384 model_info_key_list = list(model_info.keys()) 385 for key_name in model_info_key_list: 386 file_list = list(model_info[key_name].keys()) 387 for file_name in file_list: 388 file_path = model_info[key_name][file_name] 389 if file_name == "Makefile": 390 mk_re_str = r"CONFIG_DRIVERS_HDF_(?P<name>.+[A-Z0-9])" 391 flag_re = r"obj" 392 temp_file = hdf_utils.MakefileAndKconfigFileParse( 393 file_path=file_path, flag_str=flag_re, re_name=mk_re_str) 394 driver_config_index = temp_file.split_driver_start_to_end() 395 self.config_delete_operation_linux( 396 driver_name, driver_config_index, file_path) 397 elif file_name == driver_name: 398 self._delete_driver_file(file_path=file_path) 399 del model_info[key_name][file_name] 400 if not model_info[key_name]: 401 del model_info[key_name] 402 else: 403 self.linux_liteos_common( 404 file_name, file_path, module_name, driver_name) 405 406 def _delete_driver_file(self, file_path): 407 for file_path_info in file_path: 408 path_temp = file_path_info 409 while os.path.exists(path_temp): 410 if os.path.isfile(path_temp): 411 os.remove(path_temp) 412 elif os.path.isdir(path_temp) and (not os.listdir(path_temp)): 413 os.rmdir(path_temp) 414 else: 415 break 416 path_temp = os.path.dirname(path_temp) 417