sb: Add an orphan check to sb-check.

The orphans check lets you see which configuration and build set
files in the RSB are not referernced. You can audit the list and
remove any configuration files not being used. Top level
build set files are included so you need to becareful not to
remove something that is valid and useful. To run:

 $ ./source-builder/sb-check --check-orphans
This commit is contained in:
Chris Johns
2018-01-18 13:16:47 +11:00
parent f3b1700dfd
commit 3ddbd791b8
2 changed files with 115 additions and 3 deletions

View File

@@ -27,9 +27,11 @@ import os
import error
import execute
import fnmatch
import log
import options
import path
import re
import version
def _check_none(_opts, macro, value, constraint):
@@ -162,15 +164,117 @@ def check_exe(label, exe):
return _check_exe(None, label, exe, None, True)
def check_orphans(opts):
def _find_files(path, globs, excludes = []):
ff = []
for root, dirs, files in os.walk(path, followlinks = True):
for f in files:
for g in globs:
if fnmatch.fnmatch(f, g) and f not in excludes:
ff += [os.path.join(root, f)]
return sorted(ff)
def _clean(line):
line = line[0:-1]
b = line.find('#')
if b >= 0:
line = line[1:b]
return line.strip()
def _find(name, opts):
ename = opts.defaults.expand(name)
if ':' in ename:
paths = path.dirname(ename).split(':')
name = path.basename(name)
else:
paths = opts.defaults.get_value('_configdir').split(':')
for p in paths:
n = path.join(opts.defaults.expand(p), name)
if path.exists(n):
return n
return None
paths = opts.defaults.get_value('_configdir').split(':')
cfgs = {}
for p in paths:
ep = opts.defaults.expand(p)
print('Scanning: %s (%s)' % (p, ep))
for f in _find_files(ep, ['*.cfg', '*.bset']):
root, ext = path.splitext(f)
cfgs[f] = { 'src': None, 'ext': ext, 'refs': 0, 'errors':[] }
wss = re.compile(r'\s+')
for c in cfgs:
with open(c, 'r') as f:
cfgs[c]['src'] = f.readlines()
lc = 0
for l in cfgs[c]['src']:
lc += 1
l = _clean(l)
if len(l) == 0:
continue
if l[0] == '%':
ls = wss.split(l, 2)
if ls[0] == '%include':
name = _find(ls[1], opts)
if name is None:
cfgs[c]['errors'] += [lc]
elif name not in cfgs:
raise error.general('include: %s: not present' % (ls[1]))
else:
cfgs[name]['refs'] += 1
elif cfgs[c]['ext'] == '.bset' and ':' not in l:
for ext in ['', '.cfg', '.bset']:
name = _find(l + ext, opts)
if name is not None:
if name not in cfgs:
raise error.general('include: %s: not present' % (ls[1]))
else:
cfgs[name]['refs'] += 1
break
topdir = opts.defaults.expand('%{_topdir}')
orphans = []
show = True
for c in cfgs:
if cfgs[c]['refs'] == 0:
orphans += [c]
if len(cfgs[c]['errors']) != 0:
if show:
print('Warnings:')
show = False
print(' %s:' % (path.relpath(c)))
for l in cfgs[c]['errors']:
print(' %3d: %s' % (l, cfgs[c]['src'][l - 1][:-1]))
show = True
for o in sorted(orphans):
if show:
print('Orphans:')
show = False
print(' %s' % (path.relpath(o)))
def run():
import sys
try:
_opts = options.load(args = sys.argv)
log.notice('RTEMS Source Builder - Check, %s' % (version.str()))
if host_setup(_opts):
print('Environment is ok')
orphans = _opts.parse_args('--check-orphans', error = False, extra = False)
if orphans:
print('Checking for orphans...')
check_orphans(_opts)
else:
print('Environment is not correctly set up')
if host_setup(_opts):
print('Environment is ok')
else:
print('Environment is not correctly set up')
except error.general as gerr:
print(gerr)
sys.exit(1)