mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00

This adds SPDX license headers in place of the wide assortment of things currently in our script headers. We default to GPL-2.0-only except for the oeqa code where it was clearly submitted and marked as MIT on the most part or some scripts which had the "or later" GPL versioning. The patch also drops other obsolete bits of file headers where they were encoountered such as editor modelines, obsolete maintainer information or the phrase "All rights reserved" which is now obsolete and not required in copyright headers (in this case its actually confusing for licensing as all rights were not reserved). More work is needed for OE-Core but this takes care of the bulk of the scripts and meta/lib directories. The top level LICENSE files are tweaked to match the new structure and the SPDX naming. (From OE-Core rev: f8c9c511b5f1b7dbd45b77f345cb6c048ae6763e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
158 lines
5.6 KiB
Python
Executable File
158 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2018 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import logging
|
|
import re
|
|
|
|
class Dot(object):
|
|
def __init__(self):
|
|
parser = argparse.ArgumentParser(
|
|
description="Analyse recipe-depends.dot generated by bitbake -g",
|
|
epilog="Use %(prog)s --help to get help")
|
|
parser.add_argument("dotfile",
|
|
help = "Specify the dotfile", nargs = 1, action='store', default='')
|
|
parser.add_argument("-k", "--key",
|
|
help = "Specify the key, e.g., recipe name",
|
|
action="store", default='')
|
|
parser.add_argument("-d", "--depends",
|
|
help = "Print the key's dependencies",
|
|
action="store_true", default=False)
|
|
parser.add_argument("-w", "--why",
|
|
help = "Print why the key is built",
|
|
action="store_true", default=False)
|
|
parser.add_argument("-r", "--remove",
|
|
help = "Remove duplicated dependencies to reduce the size of the dot files."
|
|
" For example, A->B, B->C, A->C, then A->C can be removed.",
|
|
action="store_true", default=False)
|
|
|
|
self.args = parser.parse_args()
|
|
|
|
if len(sys.argv) != 3 and len(sys.argv) < 5:
|
|
print('ERROR: Not enough args, see --help for usage')
|
|
|
|
@staticmethod
|
|
def insert_dep_chain(chain, rdeps, alldeps):
|
|
"""
|
|
insert elements to chain from rdeps, according to alldeps
|
|
"""
|
|
# chain should at least contain one element
|
|
if len(chain) == 0:
|
|
raise
|
|
|
|
inserted_elements = []
|
|
for rdep in rdeps:
|
|
if rdep in chain:
|
|
continue
|
|
else:
|
|
for i in range(0, len(chain)-1):
|
|
if chain[i] in alldeps[rdep] and rdep in alldeps[chain[i+1]]:
|
|
chain.insert(i+1, rdep)
|
|
inserted_elements.append(rdep)
|
|
break
|
|
if chain[-1] in alldeps[rdep] and rdep not in chain:
|
|
chain.append(rdep)
|
|
inserted_elements.append(rdep)
|
|
return inserted_elements
|
|
|
|
@staticmethod
|
|
def print_dep_chains(key, rdeps, alldeps):
|
|
rlist = rdeps.copy()
|
|
chain = []
|
|
removed_rdeps = [] # hold rdeps removed from rlist
|
|
|
|
chain.append(key)
|
|
while (len(rlist) != 0):
|
|
# insert chain from rlist
|
|
inserted_elements = Dot.insert_dep_chain(chain, rlist, alldeps)
|
|
if not inserted_elements:
|
|
if chain[-1] in rlist:
|
|
rlist.remove(chain[-1])
|
|
removed_rdeps.append(chain[-1])
|
|
chain.pop()
|
|
continue
|
|
else:
|
|
# insert chain from removed_rdeps
|
|
Dot.insert_dep_chain(chain, removed_rdeps, alldeps)
|
|
print(' -> '.join(list(reversed(chain))))
|
|
|
|
def main(self):
|
|
#print(self.args.dotfile[0])
|
|
# The format is {key: depends}
|
|
depends = {}
|
|
with open(self.args.dotfile[0], 'r') as f:
|
|
for line in f.readlines():
|
|
if ' -> ' not in line:
|
|
continue
|
|
line_no_quotes = line.replace('"', '')
|
|
m = re.match("(.*) -> (.*)", line_no_quotes)
|
|
if not m:
|
|
print('WARNING: Found unexpected line: %s' % line)
|
|
continue
|
|
key = m.group(1)
|
|
if key == "meta-world-pkgdata":
|
|
continue
|
|
dep = m.group(2)
|
|
if key in depends:
|
|
if not key in depends[key]:
|
|
depends[key].add(dep)
|
|
else:
|
|
print('WARNING: Fonud duplicated line: %s' % line)
|
|
else:
|
|
depends[key] = set()
|
|
depends[key].add(dep)
|
|
|
|
if self.args.remove:
|
|
reduced_depends = {}
|
|
for k, deps in depends.items():
|
|
child_deps = set()
|
|
added = set()
|
|
# Both direct and indirect depends are already in the dict, so
|
|
# we don't have to do this recursively.
|
|
for dep in deps:
|
|
if dep in depends:
|
|
child_deps |= depends[dep]
|
|
|
|
reduced_depends[k] = deps - child_deps
|
|
outfile= '%s-reduced%s' % (self.args.dotfile[0][:-4], self.args.dotfile[0][-4:])
|
|
with open(outfile, 'w') as f:
|
|
print('Saving reduced dot file to %s' % outfile)
|
|
f.write('digraph depends {\n')
|
|
for k, v in reduced_depends.items():
|
|
for dep in v:
|
|
f.write('"%s" -> "%s"\n' % (k, dep))
|
|
f.write('}\n')
|
|
sys.exit(0)
|
|
|
|
if self.args.key not in depends:
|
|
print("ERROR: Can't find key %s in %s" % (self.args.key, self.args.dotfile[0]))
|
|
sys.exit(1)
|
|
|
|
if self.args.depends:
|
|
if self.args.key in depends:
|
|
print('Depends: %s' % ' '.join(depends[self.args.key]))
|
|
|
|
reverse_deps = []
|
|
if self.args.why:
|
|
for k, v in depends.items():
|
|
if self.args.key in v and not k in reverse_deps:
|
|
reverse_deps.append(k)
|
|
print('Because: %s' % ' '.join(reverse_deps))
|
|
Dot.print_dep_chains(self.args.key, reverse_deps, depends)
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
dot = Dot()
|
|
ret = dot.main()
|
|
except Exception as esc:
|
|
ret = 1
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(ret)
|