mirror of
https://git.yoctoproject.org/poky-contrib
synced 2025-05-08 15:42:17 +08:00

This adds the SPDX-License-Identifier license headers to the majority of our source files to make it clearer exactly which license files are under. The bulk of the files are under GPL v2.0 with one found to be under V2.0 or later, some under MIT and some have dual license. There are some files which are potentially harder to classify where we've imported upstream code and those can be handled specifically in later commits. The COPYING file is replaced with LICENSE.X files which contain the full license texts. (Bitbake rev: ff237c33337f4da2ca06c3a2c49699bc26608a6b) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
211 lines
8.2 KiB
Python
Executable File
211 lines
8.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# bitbake-diffsigs / bitbake-dumpsig
|
|
# BitBake task signature data dump and comparison utility
|
|
#
|
|
# Copyright (C) 2012-2013, 2017 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License version 2 as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
import os
|
|
import sys
|
|
import warnings
|
|
import argparse
|
|
import logging
|
|
import pickle
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
|
|
|
|
import bb.tinfoil
|
|
import bb.siggen
|
|
import bb.msg
|
|
|
|
myname = os.path.basename(sys.argv[0])
|
|
logger = bb.msg.logger_create(myname)
|
|
|
|
is_dump = myname == 'bitbake-dumpsig'
|
|
|
|
def find_siginfo(tinfoil, pn, taskname, sigs=None):
|
|
result = None
|
|
tinfoil.set_event_mask(['bb.event.FindSigInfoResult',
|
|
'logging.LogRecord',
|
|
'bb.command.CommandCompleted',
|
|
'bb.command.CommandFailed'])
|
|
ret = tinfoil.run_command('findSigInfo', pn, taskname, sigs)
|
|
if ret:
|
|
while True:
|
|
event = tinfoil.wait_event(1)
|
|
if event:
|
|
if isinstance(event, bb.command.CommandCompleted):
|
|
break
|
|
elif isinstance(event, bb.command.CommandFailed):
|
|
logger.error(str(event))
|
|
sys.exit(2)
|
|
elif isinstance(event, bb.event.FindSigInfoResult):
|
|
result = event.result
|
|
elif isinstance(event, logging.LogRecord):
|
|
logger.handle(event)
|
|
else:
|
|
logger.error('No result returned from findSigInfo command')
|
|
sys.exit(2)
|
|
return result
|
|
|
|
def find_siginfo_task(bbhandler, pn, taskname, sig1=None, sig2=None):
|
|
""" Find the most recent signature files for the specified PN/task """
|
|
|
|
if not taskname.startswith('do_'):
|
|
taskname = 'do_%s' % taskname
|
|
|
|
if sig1 and sig2:
|
|
sigfiles = find_siginfo(bbhandler, pn, taskname, [sig1, sig2])
|
|
if len(sigfiles) == 0:
|
|
logger.error('No sigdata files found matching %s %s matching either %s or %s' % (pn, taskname, sig1, sig2))
|
|
sys.exit(1)
|
|
elif not sig1 in sigfiles:
|
|
logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig1))
|
|
sys.exit(1)
|
|
elif not sig2 in sigfiles:
|
|
logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig2))
|
|
sys.exit(1)
|
|
latestfiles = [sigfiles[sig1], sigfiles[sig2]]
|
|
else:
|
|
filedates = find_siginfo(bbhandler, pn, taskname)
|
|
latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-2:]
|
|
if not latestfiles:
|
|
logger.error('No sigdata files found matching %s %s' % (pn, taskname))
|
|
sys.exit(1)
|
|
|
|
return latestfiles
|
|
|
|
|
|
# Define recursion callback
|
|
def recursecb(key, hash1, hash2):
|
|
hashes = [hash1, hash2]
|
|
hashfiles = find_siginfo(tinfoil, key, None, hashes)
|
|
|
|
recout = []
|
|
if len(hashfiles) == 0:
|
|
recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2))
|
|
elif not hash1 in hashfiles:
|
|
recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash1))
|
|
elif not hash2 in hashfiles:
|
|
recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash2))
|
|
else:
|
|
out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, color=color)
|
|
for change in out2:
|
|
for line in change.splitlines():
|
|
recout.append(' ' + line)
|
|
|
|
return recout
|
|
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description=("Dumps" if is_dump else "Compares") + " siginfo/sigdata files written out by BitBake")
|
|
|
|
parser.add_argument('-D', '--debug',
|
|
help='Enable debug output',
|
|
action='store_true')
|
|
|
|
if is_dump:
|
|
parser.add_argument("-t", "--task",
|
|
help="find the signature data file for the last run of the specified task",
|
|
action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))
|
|
|
|
parser.add_argument("sigdatafile1",
|
|
help="Signature file to dump. Not used when using -t/--task.",
|
|
action="store", nargs='?', metavar="sigdatafile")
|
|
else:
|
|
parser.add_argument('-c', '--color',
|
|
help='Colorize the output (where %(metavar)s is %(choices)s)',
|
|
choices=['auto', 'always', 'never'], default='auto', metavar='color')
|
|
|
|
parser.add_argument('-d', '--dump',
|
|
help='Dump the last signature data instead of comparing (equivalent to using bitbake-dumpsig)',
|
|
action='store_true')
|
|
|
|
parser.add_argument("-t", "--task",
|
|
help="find the signature data files for the last two runs of the specified task and compare them",
|
|
action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))
|
|
|
|
parser.add_argument("-s", "--signature",
|
|
help="With -t/--task, specify the signatures to look for instead of taking the last two",
|
|
action="store", dest="sigargs", nargs=2, metavar=('fromsig', 'tosig'))
|
|
|
|
parser.add_argument("sigdatafile1",
|
|
help="First signature file to compare (or signature file to dump, if second not specified). Not used when using -t/--task.",
|
|
action="store", nargs='?')
|
|
|
|
parser.add_argument("sigdatafile2",
|
|
help="Second signature file to compare",
|
|
action="store", nargs='?')
|
|
|
|
options = parser.parse_args()
|
|
if is_dump:
|
|
options.color = 'never'
|
|
options.dump = True
|
|
options.sigdatafile2 = None
|
|
options.sigargs = None
|
|
|
|
if options.debug:
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
color = (options.color == 'always' or (options.color == 'auto' and sys.stdout.isatty()))
|
|
|
|
if options.taskargs:
|
|
with bb.tinfoil.Tinfoil() as tinfoil:
|
|
tinfoil.prepare(config_only=True)
|
|
if not options.dump and options.sigargs:
|
|
files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1], options.sigargs[0], options.sigargs[1])
|
|
else:
|
|
files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1])
|
|
|
|
if options.dump:
|
|
logger.debug("Signature file: %s" % files[-1])
|
|
output = bb.siggen.dump_sigfile(files[-1])
|
|
else:
|
|
if len(files) < 2:
|
|
logger.error('Only one matching sigdata file found for the specified task (%s %s)' % (options.taskargs[0], options.taskargs[1]))
|
|
sys.exit(1)
|
|
|
|
# Recurse into signature comparison
|
|
logger.debug("Signature file (previous): %s" % files[-2])
|
|
logger.debug("Signature file (latest): %s" % files[-1])
|
|
output = bb.siggen.compare_sigfiles(files[-2], files[-1], recursecb, color=color)
|
|
else:
|
|
if options.sigargs:
|
|
logger.error('-s/--signature can only be used together with -t/--task')
|
|
sys.exit(1)
|
|
try:
|
|
if not options.dump and options.sigdatafile1 and options.sigdatafile2:
|
|
with bb.tinfoil.Tinfoil() as tinfoil:
|
|
tinfoil.prepare(config_only=True)
|
|
output = bb.siggen.compare_sigfiles(options.sigdatafile1, options.sigdatafile2, recursecb, color=color)
|
|
elif options.sigdatafile1:
|
|
output = bb.siggen.dump_sigfile(options.sigdatafile1)
|
|
else:
|
|
logger.error('Must specify signature file(s) or -t/--task')
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
except IOError as e:
|
|
logger.error(str(e))
|
|
sys.exit(1)
|
|
except (pickle.UnpicklingError, EOFError):
|
|
logger.error('Invalid signature data - ensure you are specifying sigdata/siginfo files')
|
|
sys.exit(1)
|
|
|
|
if output:
|
|
print('\n'.join(output))
|