Files

625 lines
24 KiB
Python
Raw Permalink Normal View History

2026-09-22 09:38:26 +08:00
# _*_ coding: utf-8 _*_
#
# SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0
# SPDX-FileCopyrightText: 2023 Unisoc (Shanghai) Technologies Co., Ltd
#
# Copyright 2020-2025 Unisoc (Shanghai) Technologies Co., Ltd.
#
# Licensed under the Unisoc General Software License, version 1.0 (the License);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.unisoc.com/en_us/license/UNISOC_GENERAL_LICENSE_V1.0-EN_US
#
# Software distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OF ANY KIND, either express or implied.
# See the Unisoc General Software License, version 1.0 for more details.
"""
解析当前目录下的 ini 文件
A)生成单个pac 的打包配置文件。
B)打包是否带运营商,并列出。
C)编译工程是否需要做ota,且提供出 modem 获取路径。
调用方法:
A)没有运营商信息:
python parser_ini.py --project "project" --board "board" --out "out_dir"
B)有运营商信息:
python parser_ini.py --project "project" --board "board" --out "out_dir" --carrier "carriers"
C)有modem_type信息:
python parser_ini.py --project "project" --board "board" --out "out_dir" --carrier "carriers" --modem_type "modem_type"
D)有客户信息
python parser_ini.py --project "project" --customers "cus01" "cus02"
project Eg:s9863a1h10_Natv-userdebug-gms
board Eg:s9863a1h10
out :out目录绝对路径。
carrier :运营商名,多个运营商之间用空格分隔。
customers:客户代号,多个客户代号之间使用空格分隔。
modem_type:modem type 名称,如SHARKL3_1C,SHARKL3_1C_CTS_GSI;多个modem type之间用英文逗号隔开
"""
import os
import sys
try:
# python2
reload(sys)
sys.setdefaultencoding('utf-8')
except:
# python3
import importlib
importlib.reload(sys)
import codecs
import optparse
#import ConfigParser
try:
# Python3
from configparser import ConfigParser
except ImportError:
# Python2
from ConfigParser import ConfigParser
OTA_CARRIER_FLAG_FILE = 'ota_carrier_flag'
PAC_CFG_FILE = 'pac.ini'
PAC_SECTION = 'pac_list'
def help(args):
init_optparse = optparse.OptionParser(
usage="usage: %prog [options] arg",
description="show help")
init_optparse.add_option(
'--project',
help='project name',
metavar='version',
dest='project')
init_optparse.add_option(
'--board',
help='board name',
metavar='version',
dest='board')
init_optparse.add_option(
'--out',
help='out directory',
metavar='version',
dest='out')
init_optparse.add_option(
'--carriers',
help='carriers info',
metavar='version',
dest='carriers')
init_optparse.add_option(
'--customers',
help='customers info',
metavar='version',
dest='customers'
)
init_optparse.add_option(
'--modem_type',
help='modem type name',
metavar='version',
dest='modem_type')
(options, args) = init_optparse.parse_args(args)
if options.project:
return (options, args)
else:
print("please check your params")
return (None, args)
def _create_pac_ini(project, modem_first_part, modem_type_list, cfg_parser, settings_info, work_dir, out_dir, input_identifiers_list=None, identifiers_list=None, partitions=None, _type="base"):
"""制作pac ini,支持三种类型:carrier,customer,base,默认base类型"""
modem_type, ota_flag = modem_first_part, "false"
first_part_list = modem_first_part.split(":")
if len(first_part_list) > 1:
modem_type = first_part_list[0]
if first_part_list[1] == "ota":
ota_flag = "true"
if _type in ["carrier", "customer"]:
if not input_identifiers_list:
return
for identify in input_identifiers_list:
# 判断传入的运营商是否在ini配置中
pac_info, _ota_flag = '', "false"
for _item in identifiers_list:
_item_list = _item.split(":")
_identify = _item_list[0]
if identify != _identify:
continue
if len(_item_list) > 1 and _item_list[1] == "ota":
_ota_flag = "true"
if modem_type_list and modem_type not in modem_type_list:
continue
# 从配置文件中获取 modem_type字段的值
for (k, v) in cfg_parser.items(modem_type):
# 换分区
if k in partitions:
img_dir, img_name = os.path.dirname(v), os.path.basename(v)
v = os.path.join(img_dir, identify, img_name)
line = "%s=%s\n" % (k, v)
pac_info += line
dirs = os.path.join(out_dir, "%s_%s" % (modem_type, identify)) # cp_sign/ ota_sign
if not os.path.exists(dirs):
os.makedirs(dirs)
pac_name = "%s_%s_%s.pac" % (project, modem_type, identify)
create_file(dirs, '', _ota_flag, settings_info, pac_info)
parser = BMConfigParser()
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'r') as pf:
parser.read(pf)
carrier, customer = "", ""
if _type == "carrier":
carrier = identify
if _type == "customer":
customer = identify
parser.add_section("Attr")
parser.set("Attr", "PAC_NAME", pac_name)
parser.set("Attr", "WORK_DIR", work_dir)
parser.set("Attr", "ota_flag", _ota_flag)
parser.set("Attr", "carrier", carrier)
parser.set("Attr", "customer", customer)
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'a', encoding='utf-8') as f:
parser.write(f)
elif _type == "base":
dirs = os.path.join(out_dir, "%s" % modem_type) # cp_sign/ ota_sign
if os.path.exists(os.path.join(dirs, PAC_CFG_FILE)):
return
if not os.path.exists(dirs):
os.makedirs(dirs)
# 生成base版本
pac_info = ''
# 从配置文件中获取 modem_type字段的值
for (k, v) in cfg_parser.items(modem_type):
line = "%s=%s\n" % (k, v)
pac_info += line
pac_name = "%s_%s.pac" % (project, modem_type)
create_file(dirs, '', ota_flag, settings_info, pac_info)
parser = BMConfigParser()
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'r') as pf:
parser.read(pf)
parser.add_section("Attr")
parser.set("Attr", "PAC_NAME", pac_name)
parser.set("Attr", "WORK_DIR", work_dir)
parser.set("Attr", "ota_flag", ota_flag)
parser.set("Attr", "carrier", "")
parser.set("Attr", "customer", "")
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'a', encoding='utf-8') as f:
parser.write(f)
def create_pac_cfg_v2(cwd, cfg_file, project, out_dir, carrier_list=None, modem_type_list=None, customer_list=None):
"""创建pac ini,支持运营商和客户配置,合并相同逻辑"""
os.chdir(cwd)
# 校验cfg_file
if not os.path.exists(cfg_file):
print("cfg file not exist!")
print("cp_sign_fail")
sys.exit(1)
cfg_parser = BMConfigParser()
cfg_parser.read(cfg_file)
# 校验工程
prj_ops = cfg_parser.options('project')
print("projects in cfg :", prj_ops)
print("current project : ", project)
if project not in prj_ops:
print("No project : %s. Please check! " % project)
print("cp_sign_fail")
sys.exit(1)
settings_info = ''
# [Setting]字段内容
with open(cfg_file, 'r') as fp:
for line in fp:
if '[project]' not in line:
settings_info += line
else:
break
dir_path = os.path.abspath(os.path.dirname(__file__))
config_ini_path = os.path.abspath(os.path.join(dir_path, '..', 'pac_config', 'config.ini'))
common_parser = BMConfigParser()
common_parser.read(config_ini_path)
cfg_work_dir = common_parser.get('work_dir', 'dir').strip()
if cfg_work_dir:
work_dir = dir_path.split(cfg_work_dir)[0]
else:
work_dir = dir_path
print("work dir : ", work_dir)
project_info = cfg_parser.get('project', project).strip()
project_info_list = [x.strip() for x in cfg_parser.get('project', project).split('\n') if x.strip()]
print("project_info: ", project_info)
carrier_partitions = cfg_parser.get("partition", "carrier_partition").strip().split(',')
customer_partitions = []
if cfg_parser.has_option("partition", "customer_partition"):
customer_partitions = cfg_parser.get("partition", "customer_partition").strip().split(',')
for item in project_info_list:
# 遍历modem 类型;示例: QoGIRN5_SUPER_NOSEC:ota@cmcc,cucc@cus01,cus02
item_list = item.split("@")
len_item_list = len(item_list)
_carriers = [x.strip() for x in item_list[1].split("|")] if len_item_list > 1 else []
_customers = [x.strip() for x in item_list[2].split("|")] if len_item_list > 2 else []
modem_first_part = item_list[0]
# 运营商版本
_create_pac_ini(project, modem_first_part, modem_type_list, cfg_parser, settings_info, work_dir, out_dir, carrier_list, _carriers, carrier_partitions, _type="carrier")
# 客户版本
_create_pac_ini(project, modem_first_part, modem_type_list, cfg_parser, settings_info, work_dir, out_dir, customer_list, _customers, customer_partitions, _type="customer")
# base版本
_create_pac_ini(project, modem_first_part, modem_type_list, cfg_parser, settings_info, work_dir, out_dir, _type="base")
# 备份
if os.path.exists(out_dir):
os.chdir(out_dir)
os.system('find -name pac.ini |xargs -i cp {} {}.bak')
sys.stdout.flush()
os.system('find .')
def create_pac_cfg(cfg_file, project, out_dir, carriers=None, modem_type_list=None):
"""
生成mini cfg file
:param cfg_file:out_dir
:param project:
:param carriers:
:return:
"""
settings_info = ''
if not os.path.exists(cfg_file):
print("cfg file not exist!")
print("cp_sign_fail")
sys.exit(1)
cfg_parser = BMConfigParser()
cfg_parser.read(cfg_file)
# [Setting]字段内容
with open(cfg_file, 'r') as fp:
for line in fp:
if '[project]' not in line:
settings_info += line
else:
break
######## Settings ##########
#settings_info = "[Setting]\n"
#for (k, v) in cfg_parser.items('Setting'):
# settings_info +="%s=%s\n" % (k,v)
######### WORK_DIR/PAC_NAME #######
py_path = os.path.abspath(os.path.dirname(__file__))
config_ini_path = os.path.abspath(os.path.join(py_path,'..','pac_config','config.ini'))
common_parser = BMConfigParser()
common_parser.read(config_ini_path)
cfg_work_dir = common_parser.get('work_dir','dir').strip()
if cfg_work_dir:
work_dir = py_path.split(cfg_work_dir)[0]
else:
work_dir = py_path
#if 'vendor' in py_path:
# work_dir = py_path[0:py_path.rindex('vendor')]
#else:
# work_dir = py_path
print("work dir : ",work_dir)
work_dir_line = "%s" % work_dir
carrier_partitions = cfg_parser.get(
"partition", "carrier_partition").strip().split(',')
prj_ops = cfg_parser.options('project')
print("projects in cfg :",prj_ops)
print("current project : ", project)
if project not in prj_ops:
print("No project : %s. Please check! " % project)
print("cp_sign_fail")
sys.exit(1)
project_info = cfg_parser.get('project', project).strip().split('\n')
print(project_info)
if not project_info:
print("Project : %s not in config file!" % project)
print("cp_sign_fail")
sys.exit(1)
modem_type_info = ''
if modem_type_list:
modem_type_info = modem_type_list.strip().split(',')
print("modem_type_info:")
print(modem_type_info)
if carriers: # 有运营商
exist_ca = False
for ca in carriers.split(' '):
if ca in cfg_parser.get('project', project):
print("Carrier: %s in project %s !" % (ca, project))
exist_ca = True
if not exist_ca: # 该project中不存在 carrier值
print("No carrier in project!! Please check!")
print("cp_sign_fail")
sys.exit(1)
########## 存在 carrier, 遍历 ###########
for ca in carriers.split(' '):
no_ca = True
for content in project_info:
pac_info = ''
if ca in content:
no_ca = False
print("Carrier: %s in : %s !" % (ca, content))
modem_type = content.split('@')[0]
if ":" in modem_type: # 类似这样的字符串: HARKL3_9863A_9_GSI:ota@xx
# ota_flag = modem_type.split(':')[1] # ota flag
modem_type = modem_type.split(':')[0]
if modem_type_list and (modem_type not in modem_type_info):
print("%s not in modem_type_list"%modem_type)
continue
# 从配置文件中获取 modem_type字段的值
for (k, v) in cfg_parser.items(modem_type):
# carrier 分区
if k in carrier_partitions:
last_data = str(v).strip().split('/')[-1]
v = str(v).split(last_data)[0]
v = os.path.join(v, ca, last_data)
line = "%s=%s\n" % (k, v)
pac_info += line
carrier_info_list = content.split(
'@')[1].split('|') # ca1:ota1|ca2:ota2
for info in carrier_info_list:
if ':' in info: # carrier:ota
ota_flag = info.split(':')[1]
carrier = info.split(':')[0]
if ota_flag == 'ota':
ota_flag = 'true'
else:
ota_flag = 'false'
else:
carrier = info.strip()
ota_flag = 'false'
if ca == carrier:
# 创建以modem type和运营商名称为名字的文件夹
dirs = os.path.join(
out_dir, "%s_%s" %
(modem_type, ca))
if not os.path.exists(dirs):
os.makedirs(dirs)
pac_name_line = "%s_%s_%s.pac" % (project,modem_type,ca)
create_file(dirs,ca,ota_flag, settings_info, pac_info)
parser = BMConfigParser()
with codecs.open(os.path.join(dirs, PAC_CFG_FILE),'r') as pf:
parser.read(pf)
parser.add_section("Attr")
parser.set("Attr","PAC_NAME",pac_name_line)
parser.set("Attr", "WORK_DIR", work_dir_line)
parser.set("Attr", "ota_flag", ota_flag)
parser.set("Attr", "carrier", ca)
with codecs.open(os.path.join(dirs, PAC_CFG_FILE),'a', encoding='utf-8') as f:
parser.write(f)
#####################default ######################
pac_info = ''
dirs = os.path.join(out_dir, "%s" %(modem_type))
if not os.path.exists(dirs):
os.makedirs(dirs)
ota_flag = 'false'
if ":" in content.split('@')[0]: # 类似这样的字符串: HARKL3_9863A_9_GSI:ota@xx
ota_flag = content.split('@')[0].split(':')[1] # ota flag
if ota_flag == 'ota':
ota_flag = 'true'
else:
ota_flag = 'false'
pac_name_line = "%s_%s.pac" % (project,modem_type)
for (k, v) in cfg_parser.items(modem_type):
line = "%s=%s\n" % (k, v)
pac_info += line
create_file(dirs, '', ota_flag, settings_info, pac_info)
parser = BMConfigParser()
parser.add_section("Attr")
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'r') as pf:
parser.read(pf)
parser.set("Attr", "PAC_NAME", pac_name_line)
parser.set("Attr", "WORK_DIR", work_dir_line)
parser.set("Attr","ota_flag",ota_flag)
parser.set("Attr","carrier",'')
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'a', encoding='utf-8') as f:
parser.write(f)
else:
ota_flag = 'false'
pac_info = ''
modem_type = content.split('@')[0]
print("modem type :", modem_type)
if ":" in modem_type: # 类似这样的字符串: HARKL3_9863A_9_GSI:ota@xx
ota_flag = modem_type.split(':')[1] # ota flag
modem_type = modem_type.split(':')[0]
if ota_flag == 'ota':
ota_flag = 'true'
else:
ota_flag = 'false'
if modem_type_list and (modem_type not in modem_type_info):
print("%s not in modem_type_list"%modem_type)
continue
# 从配置文件中获取 modem_type字段的值
for (k, v) in cfg_parser.items(modem_type):
line = "%s=%s\n" % (k, v)
pac_info += line
dirs = os.path.join(
out_dir, "%s" %
modem_type) # cp_sign/ ota_sign
if not os.path.exists(dirs):
os.makedirs(dirs)
#settings_info += '\n'
pac_name_line = "%s_%s.pac" % (project, modem_type)
#settings_info += '\n'
create_file(dirs,'', ota_flag, settings_info, pac_info)
parser = BMConfigParser()
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'r') as pf:
parser.read(pf)
parser.add_section("Attr")
parser.set("Attr", "PAC_NAME", pac_name_line)
parser.set("Attr", "WORK_DIR", work_dir_line)
parser.set("Attr","ota_flag",ota_flag)
parser.set("Attr","carrier",'')
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'a', encoding='utf-8') as f:
parser.write(f)
if no_ca:
print("Carrier : %s not in config file! Please check!" % ca)
else: # 没有运营商
for content in project_info:
print(content)
ota_flag = 'false'
pac_info = ''
modem_type = content.split('@')[0]
print("modem type :", modem_type)
if ":" in modem_type: # 类似这样的字符串: HARKL3_9863A_9_GSI:ota@xx
ota_flag = modem_type.split(':')[1] # ota flag
modem_type = modem_type.split(':')[0]
if ota_flag == 'ota':
ota_flag = 'true'
else:
ota_flag = 'false'
if modem_type_list and (modem_type not in modem_type_info):
print("%s not in modem_type_list"%modem_type)
continue
# 从配置文件中获取 modem_type字段的值
for (k, v) in cfg_parser.items(modem_type):
line = "%s=%s\n" % (k, v)
pac_info += line
dirs = os.path.join(
out_dir, "%s" %
modem_type) # cp_sign/ ota_sign
if not os.path.exists(dirs):
os.makedirs(dirs)
pac_name_line = "%s_%s.pac" % (project, modem_type)
create_file(dirs,'',ota_flag,settings_info,pac_info)
parser = BMConfigParser()
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'r') as pf:
parser.read(pf)
parser.add_section("Attr")
parser.set("Attr", "PAC_NAME", pac_name_line)
parser.set("Attr","WORK_DIR",work_dir_line)
parser.set("Attr", "ota_flag", ota_flag)
parser.set("Attr", "carrier", '')
with codecs.open(os.path.join(dirs, PAC_CFG_FILE), 'a', encoding='utf-8') as f:
parser.write(f)
if os.path.exists(out_dir):
os.chdir(out_dir)
os.system('find -name pac.ini |xargs -i cp {} {}.bak')
sys.stdout.flush()
os.system('find .')
def create_file(dirs,carrier,ota_flag,settings_info,pac_info):
#################### 生成 pac.ini 和 flag文件 ########################
#with open(os.path.join(dirs, OTA_CARRIER_FLAG_FILE), 'w') as flg:
# flg.writelines("ota_flag=%s\n" % ota_flag)
# flg.writelines("carrier=%s" % carrier)
with open(os.path.join(dirs, PAC_CFG_FILE), 'w') as cf:
cf.writelines(settings_info)
cf.writelines('\n')
cf.writelines('[%s]' % PAC_SECTION)
cf.writelines('\n')
cf.writelines(pac_info)
cf.writelines('\n')
class BMConfigParser(ConfigParser):
def __init__(self, defaults=None):
ConfigParser.__init__(self, defaults=defaults)
def optionxform(self, option_str):
return option_str
if __name__ == '__main__':
args = sys.argv[1:]
(options, args) = help(args)
if args is None:
print("Parameter error! Parameter is None! Please check!")
print("cp_sign_fail")
sys.exit(1)
print("====================== parser_ini start ==============================")
project = options.project
out_dir = options.out
board = options.board
carriers = options.carriers if options.carriers else ''
carriers = carriers.strip()
# 增加客户参数
customers = options.customers if options.customers else ''
customers = customers.strip()
modem_type = options.modem_type if options.modem_type else ''
modem_type = modem_type.strip()
cwd = os.getcwd()
file_path = os.path.abspath(os.path.dirname(__file__))
print("parser_ini.py path : %s" % file_path)
cfg_file = os.path.join(file_path,"..","pac_config","%s.ini" % str(board).strip())
print("pac config file :", cfg_file)
if not os.path.exists(cfg_file):
print("Config file : %s not exit. Please check!!" % cfg_file)
print("cp_sign_fail")
sys.exit(1)
create_pac_cfg(cfg_file, str(project).strip(), out_dir, carriers=carriers, modem_type_list=modem_type)
# v2版本支持运营商和cus,暂时只使用cus,待carrier验证稳定后,再全部切v2版本
# carrier_list = [x.strip() for x in carriers.split(" ")] if carriers else []
customer_list = [x.strip() for x in customers.split(" ")] if customers else []
modem_type_list = [x.strip() for x in modem_type.split(",")] if modem_type else []
create_pac_cfg_v2(cwd, cfg_file, project.strip(), out_dir, modem_type_list=modem_type_list, customer_list=customer_list)
print("====================== parser_ini end ==============================")