kumquat-buildroot/utils/checksymbolslib/file.py
Ricardo Martincoski 0c5472ace2 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>
2023-02-06 16:30:20 +01:00

84 lines
2.4 KiB
Python

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)