kumquat-buildroot/utils/checksymbolslib/file.py

84 lines
2.4 KiB
Python
Raw Normal View History

utils/check-symbols: new script This script checks for inconsistencies on symbols declared in Config.in and used in .mk files. Currently it checks only symbols following the pattern BR2_\w+ . The script first gets the list of all files in the repository (using git ls-files like 'make check-flake8' already do). Then it parses all relevant files, searching for symbol definitions and usages, and add entries into a database. At the end, the database is searched for inconsistencies: - symbol that is part of "choice" and is referenced with "select"; - legacy symbol being referenced in packages; - legacy symbol being redefined in packages; - symbol referenced but not defined; - symbol defined but not referenced; - legacy symbol that has a Note stating it is referenced by a package (for legacy handling) but is referenced in the package without a comment "# legacy"; - legacy symbol that has a Note stating it is referenced by a package but it is not actually referenced. There is also a debug parameter --search that dumps any filename or symbol entries from the database that matches a regexp. Sample usages: $ utils/check-symbols $ utils/docker-run utils/check-symbols $ utils/check-symbols --search 'GETTEXT\b|\/openssl' At same time the script is created: - add unit tests for it, they can be run using: utils/docker-run python3 -m pytest -v utils/checksymbolslib/ - add two more GitLab CI jobs: check-symbols (to check current tree using the script) and check-check-symbols (to check the script against its unit tests) Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> [Peter: print warnings to stderr, rename change_current_dir() to change_to_top_dir()] Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2022-11-27 14:07:39 +01:00
import re
import subprocess
import checksymbolslib.br as br
import checksymbolslib.kconfig as kconfig
import checksymbolslib.makefile as makefile
file_types = [
kconfig,
makefile,
]
def get_list_of_files_in_the_repo():
cmd = ['git', 'ls-files']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = p.communicate()[0]
processed_output = [str(line.decode().rstrip()) for line in stdout.splitlines() if line]
return processed_output
def get_list_of_files_to_process(all_files):
files_to_process = []
for f in all_files:
if br.file_belongs_to_an_ignored_diretory(f):
continue
for t in file_types:
if t.check_filename(f):
files_to_process.append(f)
break
return files_to_process
def get_list_of_filenames_with_pattern(all_files, exclude_list, pattern):
re_pattern = re.compile(r'{}'.format(pattern))
matching_filenames = []
for filename in all_files:
if re_pattern.search(filename):
if filename not in exclude_list:
matching_filenames.append(filename)
return matching_filenames
def read_file(filename):
file_content_raw = []
with open(filename, 'r', errors='surrogateescape') as f:
for lineno, text in enumerate(f.readlines()):
file_content_raw.append([lineno + 1, text])
return file_content_raw
def cleanup_file_content(file_content_raw):
cleaned_up_content = []
continuation = False
last_line = None
first_lineno = None
for cur_lineno, cur_line in file_content_raw:
if continuation:
line = last_line + cur_line
lineno = first_lineno
else:
line = cur_line
lineno = cur_lineno
continuation = False
last_line = None
first_lineno = None
clean_line = line.rstrip('\n')
if clean_line.endswith('\\'):
continuation = True
last_line = clean_line.rstrip('\\')
first_lineno = lineno
continue
cleaned_up_content.append([lineno, clean_line])
return cleaned_up_content
def populate_db_from_file(db, filename):
file_content_raw = read_file(filename)
file_content_to_process = cleanup_file_content(file_content_raw)
for t in file_types:
if t.check_filename(filename):
t.populate_db(db, filename, file_content_to_process)