import os
import json
class BaseRule(object):
RULE_NAME = ""
def __init__(self, mgr, args):
self._mgr = mgr
self._args = args
self.__white_lists = self.load_files("whitelist.json")
self.__out_path = mgr.get_product_out_path()
self.__base_sofiles = ["libc.so", "libutils.z.so", "ld-musl-aarch64.so.1", "libconfiguration.z.so", "libusbmanager.z.so",
"libsms.z.so"]
def load_lists(self):
self.__passthroughs_lists = self.load_list_json("Passthrough", "passthrough_info.json")
self.__llndk_lists = self.load_list_json("LLndk", "llndk_info.json")
self.__chipsetsdksp_lists = self.load_list_json("ChipsetsdkSP", "chipsetsdk_sp_info.json")
self.__chipsetsdk_lists = self.load_list_json("ChipsetSDK", "chipsetsdk_info.json")
def load_files(self, name):
rules_dir = []
rules_dir.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../rules"))
if self._args and self._args.rules:
rules_dir = rules_dir + self._args.rules
res = []
for d in rules_dir:
rules_file = os.path.join(d, self.__class__.RULE_NAME, name)
try:
with open(rules_file, "r") as f:
jsonstr = "".join([line.strip() for line in f if not line.strip().startswith("//")])
res = res + json.loads(jsonstr)
except:
pass
return res
def get_mgr(self):
return self._mgr
def get_white_lists(self):
return self.__white_lists
def log(self, info):
print(info)
def warn(self, info):
print("\033[35m[WARNING]\x1b[0m: %s" % info)
def error(self, info):
print("\033[91m[NOT ALLOWED]\x1b[0m: %s" % info)
def get_help_url(self):
return "https://gitee.com/openharmony/developtools_integration_verification/tree/master/tools/deps_guard/rules/%s/README.md" % self.__class__.RULE_NAME
def get_out_path(self):
return self.__out_path
def is_only(self, mod):
vendor_paths = ["vendor/", "updater_vendor/", "chip_prod/", "eng_chipset/", "log/", "userdata/"]
system_paths = ["system/", "updater/", "ramdisk/", "eng_system/", "patch/", "updater_ramdisk/"]
innerapi_tags = ["llndk", "chipsetsdk", "chipsetsdk_indirect", "chipsetsdk_sp", "chipsetsdk_sp_indirect",
"passthrough", "passthrough_indirect"]
is_system = False
is_vendor = False
if not (mod["name"].endswith(".so") or mod["name"].endswith(".so.1")):
return "other"
mod_path = mod["path"]
for system_path in system_paths:
if system_path in mod_path:
is_system = True
break
for vendor_path in vendor_paths:
if vendor_path in mod_path:
is_vendor = True
break
mod_innerapi_tags = mod["innerapi_tags"]
if all(item not in mod_innerapi_tags for item in innerapi_tags):
if is_system:
return "system"
elif is_vendor:
return "vendor"
else:
return "other"
else:
return "other"
def get_dep_whitelist(self):
whitelist_file = os.path.join(self.get_out_path().replace("out", "out/products_ext"), "chipsetsdk_dep_whitelist.json")
if not os.path.exists(whitelist_file):
whitelist_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), f"../rules/chipsetsdk_dep_whitelist.json")
res = []
if os.path.exists(whitelist_file):
self.log("****chipsetsdk dep whitelist file is {}****".format(whitelist_file))
with open(whitelist_file, "r") as f:
contents = f.read()
if not contents:
self.log("****system/vendor only whitelist.json {} is null****".format(whitelist_file))
json_data = json.loads(contents)
for so in json_data:
so_file_name = so.get("so_file_name")
dep_file_name = so.get("dep_file_name")
so_dict = {so_file_name: dep_file_name}
if so_dict not in res:
res.append(so_dict)
return res
def check(self):
return True
def check_if_deps_correctly(self, check_modules, valid_mod_tags, valid_dep_tags, white_lists):
self.load_lists()
passed = True
for mod in check_modules:
innerapi_tags = mod["innerapi_tags"]
if innerapi_tags and all(item in valid_mod_tags for item in innerapi_tags):
for dep in mod["deps"]:
callee = dep["callee"]
if callee["name"] in self.__base_sofiles:
continue
if "duplicate" in callee.keys() and callee["duplicate"]:
passed = False
self.error("NEED MODIFY: %s has the same name in other package path, sofile name should be modified" % (callee["name"]))
dep_innerapi_tags = callee["innerapi_tags"]
wrong_tags = [item for item in dep_innerapi_tags if item not in valid_dep_tags]
in_whitelist = False
for so_dict in white_lists:
for k, v in so_dict.items():
if k == mod["name"] and v == callee["name"]:
in_whitelist = True
break
if in_whitelist:
continue
if "system" in valid_dep_tags and self.is_only(callee) == "system":
continue
if self.is_only(callee) == "system":
passed = False
self.error("NEED MODIFY: %s with innerapi_tags [%s] cannot depend system only file %s with %s"
% (mod["name"], ",".join(innerapi_tags), callee["name"], callee["labelPath"]))
elif self.is_only(callee) == "vendor":
passed = False
self.error("NEED MODIFY: %s with innerapi_tags [%s] cannot depend vendor only file %s with %s"
% (mod["name"], ",".join(innerapi_tags), callee["name"], callee["labelPath"]))
if dep_innerapi_tags and all(item in valid_dep_tags for item in dep_innerapi_tags):
continue
elif not dep_innerapi_tags:
continue
passed = False
self.error("NEED MODIFY: %s with innerapi_tags [%s] has dep file %s with %s contains wrong dep innerapi_tags [%s] in innerapi_tags [%s]"
% (mod["name"], ",".join(innerapi_tags), callee["name"], callee["labelPath"], ",".join(wrong_tags), ",".join(dep_innerapi_tags)))
for dep_name in mod["missing"]:
if dep_name in self.__base_sofiles:
continue
in_whitelist = False
for so_dict in white_lists:
for k, v in so_dict.items():
if k == mod["name"] and v == dep_name:
in_whitelist = True
break
if in_whitelist:
continue
else:
self.error("NEED MODIFY: system only module %s depends on %s which is unknown so type"
%(mod["name"], dep_name))
passed = False
else:
wrong_tags = [item for item in innerapi_tags if item not in valid_mod_tags]
self.error("NEED MODIFY: module %s with %s contains wrong mod innerapi_tags [%s] in innerapi_tags [%s]"
% (mod["name"], mod["path"], ",".join(wrong_tags), ",".join(innerapi_tags)))
return False
return passed
def get_allow_list(self):
return self.__passthroughs_lists + self.__llndk_lists + self.__chipsetsdksp_lists
def get_vendor_allow_list(self):
return self.__passthroughs_lists + self.__llndk_lists + self.__chipsetsdksp_lists + self.__chipsetsdk_lists
def parser_rules_file(self, rules_file, res):
try:
self.log("****Parsing rules file in {}****".format(rules_file))
with open(rules_file, "r") as f:
contents = f.read()
if not contents:
self.log("****rules file {} is null****".format(rules_file))
return res
json_data = json.loads(contents)
for so in json_data:
so_file_name = so.get("so_file_name")
if so_file_name and so_file_name not in res:
res.append(so_file_name)
except (FileNotFoundError, IOError, UnicodeDecodeError) as file_open_or_decode_err:
self.error(file_open_or_decode_err)
return res
def load_list_json(self, rule_name, name):
rules_dir = []
if self._args and self._args.rules:
self.log("****add more info in:{}****".format(self._args.rules))
rules_dir = rules_dir + self._args.rules
chipsetsdk_rules_path = self.get_out_path().replace("out", "out/products_ext")
new_rule_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../rules")
if os.path.exists(chipsetsdk_rules_path):
rules_dir.append(chipsetsdk_rules_path)
self.log("****add more info in dir:{}****".format(chipsetsdk_rules_path))
elif os.path.exists(new_rule_path):
rules_dir.append(new_rule_path)
self.log("****add path:{}****".format(new_rule_path))
res = []
for d in rules_dir:
rules_file = os.path.join(d, rule_name, name)
if os.path.isfile(rules_file):
res = self.parser_rules_file(rules_file, res)
else:
self.warn("****rules path not exist: {}****".format(rules_file))
return res