
getVarFlag() now defaults to expanding by default, thus remove the True option from getVarFlag() calls with a regex search and replace. Search made with the following regex: getVarFlag ?\(( ?[^,()]*, ?[^,()]*), True\) (From OE-Core rev: 3e4806063fe11092b2307f113a6c0b0f04104091) Signed-off-by: Joshua Lock <joshua.g.lock@intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
3.7 KiB
Executable File
#!/usr/bin/env python3
import sys, os, subprocess, re, shutil
whitelist = ( # type is supported by dash 'if type systemctl >/dev/null 2>/dev/null; then', 'if type systemd-tmpfiles >/dev/null 2>/dev/null; then', 'if type update-rc.d >/dev/null 2>/dev/null; then', 'command -v', # HOSTNAME is set locally 'buildhistory_single_commit "$CMDLINE" "$HOSTNAME"', # False-positive, match is a grep not shell expression 'grep "^$groupname:[^:]:[^:]:\([^,],\)$username\(,[^,]\)"', # TODO verify dash's '. script args' behaviour '. $target_sdk_dir/${oe_init_build_env_path} $target_sdk_dir >> $LOGFILE' )
def is_whitelisted(s): for w in whitelist: if w in s: return True return False
def process(recipe, function, script): import tempfile
if not script.startswith("#!"):
script = "#! /bin/sh\n" + script
fn = tempfile.NamedTemporaryFile(mode="w+t")
fn.write(script)
fn.flush()
try:
subprocess.check_output(("checkbashisms.pl", fn.name), universal_newlines=True, stderr=subprocess.STDOUT)
# No bashisms, so just return
return
except subprocess.CalledProcessError as e:
# TODO check exit code is 1
# Replace the temporary filename with the function and split it
output = e.output.replace(fn.name, function).splitlines()
if len(results) % 2 != 0:
print("Unexpected output from checkbashism: %s" % str(output))
return
# Turn the output into a list of (message, source) values
result = []
# Check the results against the whitelist
for message, source in zip(output[0::2], output[1::2]):
if not is_whitelisted(source):
result.append((message, source))
return result
def get_tinfoil(): scripts_path = os.path.dirname(os.path.realpath(file)) lib_path = scripts_path + '/lib' sys.path = sys.path + [lib_path] import scriptpath scriptpath.add_bitbake_lib_path() import bb.tinfoil tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare() # tinfoil.logger.setLevel(logging.WARNING) return tinfoil
if name=='main': import shutil if shutil.which("checkbashisms.pl") is None: print("Cannot find checkbashisms.pl on $PATH") sys.exit(1)
tinfoil = get_tinfoil()
# This is only the default configuration and should iterate over
# recipecaches to handle multiconfig environments
pkg_pn = tinfoil.cooker.recipecaches[""].pkg_pn
# TODO: use argparse and have --help
if len(sys.argv) > 1:
initial_pns = sys.argv[1:]
else:
initial_pns = sorted(pkg_pn)
pns = []
print("Generating file list...")
for pn in initial_pns:
for fn in pkg_pn[pn]:
# There's no point checking multiple BBCLASSEXTENDed variants of the same recipe
realfn, _, _ = bb.cache.virtualfn2realfn(fn)
if realfn not in pns:
pns.append(realfn)
def func(fn):
result = []
data = tinfoil.parse_recipe_file(fn)
for key in data.keys():
if data.getVarFlag(key, "func") and not data.getVarFlag(key, "python"):
script = data.getVar(key, False)
if not script: continue
#print ("%s:%s" % (fn, key))
r = process(fn, key, script)
if r: result.extend(r)
return fn, result
print("Scanning scripts...\n")
import multiprocessing
pool = multiprocessing.Pool()
for pn,results in pool.imap(func, pns):
if results:
print(pn)
for message,source in results:
print(" %s\n %s" % (message, source))
print()