poky/bitbake/bin/bitbake-diffsigs
Richard Purdie 79834a7144 bitbake: bitbake: Add initial pass of SPDX license headers to source code
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>
2019-05-04 10:44:04 +01:00

8.2 KiB
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))