Files
2026-09-22 09:38:26 +08:00

625 lines
24 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# _*_ 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 ==============================")