diff --git a/llvm-build/file_integrity_check/file_permission_check.py b/llvm-build/file_integrity_check/file_permission_check.py
index 0a6727a889883bdc2037c590d5a38ec6c91fa762..fc31492bf6a409486d93e984527607bfef9cf2f4 100644
--- a/llvm-build/file_integrity_check/file_permission_check.py
+++ b/llvm-build/file_integrity_check/file_permission_check.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python3
# Copyright (C) 2024 Huawei Device Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,12 +18,13 @@ import stat
import sys
from datetime import datetime
import logging
+import argparse
class FilePermissionCheck:
SO_PERMISSION_CHECK_MIN_ARGS_NUMBER = 3
DEFAULT_CLANG_FILE_PERMISSION_CHECKLIST_PATH = "default_clang_file_permission.checklist"
- DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH = "default_ndk_flie_permission.checklist"
+ DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH = "default_ndk_file_permission.checklist"
TEMP_CLANG_FILE_PERMISSION_CHECKLIST_PATH = "temp_clang_file_permission.checklist"
logger = None
@@ -36,8 +37,8 @@ class FilePermissionCheck:
ch.setFormatter(formatter)
self.logger.addHandler(ch)
- def get_file_size(file_path):
- """返回文件的大小,以字节为单位"""
+ def get_file_size(self, file_path):
+ """ļĴСֽΪλ"""
if os.path.exists(file_path):
return os.path.getsize(file_path)
return 0
@@ -72,54 +73,87 @@ class FilePermissionCheck:
True(all permission check succeeded) or False(one or more check failed).
'''
lack = 0
+ extra = 0
total = 0
fail = 0
success = 0
timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
- log_file_path = "file_permissions_check_log" + timestamp + ".txt"
+ log_file_path = "file_permissions_check_log" + timestamp + ".html"
success_log = ""
error_log = ""
lack_log = ""
+ extra_log = ""
+
+ # Read the checklist file into a dictionary
+ checklist = {}
with open(checklist_file, 'r') as ff:
for line in ff:
- lib_file_path = os.path.join(directory, line.split(',')[0].split('lib/', 1)[1]).replace('\\', '/')
- file_stat_expected = line.split(',')[1].replace('\n', '')
- file_size_expected = line.split(',')[2].replace('\n', '')
- file_stat_real = self.get_file_permissions(lib_file_path)
- if file_stat_real is None:
- lack += 1
- total += 1
- lack_log += f"{lib_file_path} check failed, the file is missed, missing file size is {file_size_expected} MB.\n"
- elif file_stat_expected == stat.filemode(os.stat(lib_file_path).st_mode):
- success += 1
- total += 1
- success_log += f"{lib_file_path} check succeeded.\n"
+ parts = line.strip().split(',')
+ checklist[parts[0]] = (parts[1], parts[2])
+
+ # Walk through the directory and compare with the checklist
+ for root, dirs, files in os.walk(directory):
+ for file in files:
+ total += 1
+ file_path = os.path.join(root, file)
+ relative_path = 'lib' + file_path.replace(directory, '').replace('\\', '/')
+ file_stat_real = self.get_file_permissions(file_path)
+
+ if relative_path not in checklist:
+ extra += 1
+ extra_log += f"
{relative_path} | Extra file | - | - |
\n"
else:
- fail += 1
- total += 1
- error_log += f"{lib_file_path} check failed, expected: {file_stat_expected}, real: {stat.filemode(os.stat(lib_file_path).st_mode)}\n"
+ file_stat_expected, file_size_expected = checklist[relative_path]
+ if file_stat_real is None:
+ lack += 1
+ lack_log += f"{relative_path} | Missing file | {file_size_expected} MB | - |
\n"
+ elif file_stat_expected == file_stat_real:
+ success += 1
+ success_log += f"{relative_path} | Check succeeded | {file_size_expected} MB | {file_stat_real} |
\n"
+ else:
+ fail += 1
+ error_log += f"{relative_path} | Check failed | Expected: {file_stat_expected}, Real: {file_stat_real} | {file_size_expected} MB |
\n"
+
+ # Check for missing files in the directory
+ for relative_path, (file_stat_expected, file_size_expected) in checklist.items():
+ if relative_path not in [os.path.join(root, file).replace(directory, '').replace('\\', '/') for root, dirs, files in os.walk(directory) for file in files]:
+ lack += 1
+ lack_log += f"{relative_path} | Missing file | {file_size_expected} MB | - |
\n"
+ # Write the HTML log file
with open(log_file_path, 'w') as f:
- f.write(f'llvm file permissions check complete, Success: {success}/{total}, Failed: {fail}/{total}, Lack: {lack}/{total}\n')
- f.write(f'\n{fail}/{total} checks failed.\n')
+ f.write("\n")
+ f.write("\n")
+ f.write("\n")
+ f.write("File Permissions Check Log\n")
+ f.write("\n")
+ f.write("\n")
+ f.write("\n")
+ f.write(f"File Permissions Check Log - Total Files: {total}, Differences: {lack + extra}
\n")
+ f.write("\n")
+ f.write("File Path | Status | Expected Size | Real Permissions |
\n")
+ f.write(success_log)
f.write(error_log)
- f.write(f'\n{lack}/{total} file missed.\n')
f.write(lack_log)
- f.write(f'\n{success}/{total} checks succeed.\n')
- f.write(success_log)
-
- if success == total:
+ f.write(extra_log)
+ f.write("
\n")
+ f.write("\n")
+ f.write("\n")
+
+ if success == total - (lack + extra):
self.logger.info(f"{directory} files permissions check passed.")
return True
else:
self.logger.error(f"{directory} files permissions check failed.")
- self.logger.error(f"{fail}/{total} checks failed.\n")
- self.logger.error(error_log)
- self.logger.error(f"{lack}/{total} file missed.\n")
- self.logger.error(lack_log)
- self.logger.error(f"{fail + lack}/{total} checks failed, check logs are in {os.path.join(os.getcwd(), log_file_path)}")
+ self.logger.error(f"{fail}/{total} checks failed.")
+ self.logger.error(f"{lack}/{total} file(s) missed.")
+ self.logger.error(f"{extra}/{total} extra file(s) found.")
+ self.logger.error(f"Check logs are in {os.path.join(os.getcwd(), log_file_path)}")
return False
def get_file_permissions(self, file_path: str) -> str:
@@ -129,11 +163,11 @@ class FilePermissionCheck:
permissions = stat.filemode(file_stat.st_mode)
return permissions
except FileNotFoundError:
- self.logger.error(f"file '{file_path}' not found.")
+ self.logger.error(f"File '{file_path}' not found.")
except PermissionError:
- self.logger.error(f"no read permission for '{file_path}'.")
+ self.logger.error(f"No read permission for '{file_path}'.")
except Exception as e:
- self.logger.error(f"unknown error - {e}")
+ self.logger.error(f"Unknown error - {e}")
return None
def check(self, clang_lib_path: str, ndk_lib_path: str) -> bool:
@@ -142,35 +176,80 @@ class FilePermissionCheck:
Check the so file permissions in clang and ndk lib directories based on the default check list.
'''
return self.file_list_check(clang_lib_path, self.DEFAULT_CLANG_FILE_PERMISSION_CHECKLIST_PATH) \
- & self.file_list_check(ndk_lib_path, self.DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH)
+ and self.file_list_check(ndk_lib_path, self.DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH)
def cmd_handler(self) -> None:
'''Perform parameter recognition and execute corresponding tasks.'''
- args = sys.argv
- if len(args) < self.SO_PERMISSION_CHECK_MIN_ARGS_NUMBER:
- self.logger.info("Missing arguments. Correct eg: python file_permission_check.py --generate-default-list clang/lib")
+ if len(sys.argv) < self.SO_PERMISSION_CHECK_MIN_ARGS_NUMBER:
+ self.logger.info("Missing arguments. Correct example: python filepermissioncheck.py --generate-default-list clang/lib")
return
- if len(args) > 1:
- if args[1] == '--generate-list':
- self.file_list_generate(args[2], args[3])
- elif args[1] == '--generate-default-list':
- self.file_list_generate(args[2], self.DEFAULT_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
- elif args[1] == '--generate-ndk-list':
- self.file_list_generate(args[2], self.DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH)
- elif args[1] == '--file-check':
- self.file_list_check(args[2], args[3])
- elif args[1] == '--check-default-clang':
- self.file_list_check(args[2], self.DEFAULT_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
- elif args[1] == '--check-default-ndk':
- self.file_list_check(args[2], self.DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH)
- elif args[1] == '--compare-between-path':
- self.file_list_generate(args[2], self.TEMP_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
- self.file_list_check(args[3], self.TEMP_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
+ parser = argparse.ArgumentParser(description='File permission check tool.')
+ parser.add_argument(
+ '--generate-list',
+ nargs=2,
+ metavar=('DIRECTORY', 'OUTPUT_FILE'),
+ help='Generate a file permission checklist for the given directory and save to the output file.')
+
+ parser.add_argument(
+ '--generate-default-list',
+ nargs=1,
+ metavar='DIRECTORY',
+ help='Generate a default file permission checklist for the given directory.')
+
+ parser.add_argument(
+ '--generate-ndk-list',
+ nargs=1,
+ metavar='DIRECTORY',
+ help='Generate a default NDK library file permission checklist for the given directory.')
+
+ parser.add_argument(
+ '--file-check',
+ nargs=2,
+ metavar=('DIRECTORY', 'CHECKLIST_FILE'),
+ help='Check file permissions in the given directory based on the provided checklist file.')
+
+ parser.add_argument(
+ '--check-default-clang',
+ nargs=1,
+ metavar='DIRECTORY',
+ help='Check file permissions in the given Clang directory based on the default checklist.')
+ parser.add_argument(
+ '--check-default-ndk',
+ nargs=1,
+ metavar='DIRECTORY',
+ help='Check file permissions in the given NDK directory based on the default checklist.')
+
+ parser.add_argument(
+ '--compare-between-path',
+ nargs=2,
+ metavar=('SOURCE_DIRECTORY', 'TARGET_DIRECTORY'),
+ help='Generate a checklist for the source directory and check the target directory against it.')
+
+ args = parser.parse_args()
+
+ if len(vars(args)) > 1:
+ if args.generate_list:
+ self.file_list_generate(args.generate_list[0], args.generate_list[1])
+ elif args.generate_default_list:
+ self.file_list_generate(args.generate_default_list[0], self.DEFAULT_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
+ elif args.generate_ndk_list:
+ self.file_list_generate(args.generate_ndk_list[0], self.DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH)
+ elif args.file_check:
+ self.file_list_check(args.file_check[0], args.file_check[1])
+ elif args.check_default_clang:
+ self.file_list_check(args.check_default_clang[0], self.DEFAULT_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
+ elif args.check_default_ndk:
+ self.file_list_check(args.check_default_ndk[0], self.DEFAULT_NDK_LIB_FILE_PERMISSION_CHECKLIST_PATH)
+ elif args.compare_between_path:
+ self.file_list_generate(args.compare_between_path[0], self.TEMP_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
+ self.file_list_check(args.compare_between_path[1], self.TEMP_CLANG_FILE_PERMISSION_CHECKLIST_PATH)
else:
self.logger.info("The input arguments are incorrect. Check the input arguments by reading the README document.")
+
def main():
file_permission_check = FilePermissionCheck()
file_permission_check.cmd_handler()
+
if __name__ == '__main__':
main()