1*4882a593Smuzhiyun#!/usr/bin/env python3 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun# Copyright (C) 2013 Wind River Systems, Inc. 4*4882a593Smuzhiyun# Copyright (C) 2014 Intel Corporation 5*4882a593Smuzhiyun# 6*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-or-later 7*4882a593Smuzhiyun# 8*4882a593Smuzhiyun# - list available recipes which have PACKAGECONFIG flags 9*4882a593Smuzhiyun# - list available PACKAGECONFIG flags and all affected recipes 10*4882a593Smuzhiyun# - list all recipes and PACKAGECONFIG information 11*4882a593Smuzhiyun 12*4882a593Smuzhiyunimport sys 13*4882a593Smuzhiyunimport optparse 14*4882a593Smuzhiyunimport os 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun 17*4882a593Smuzhiyunscripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0]))) 18*4882a593Smuzhiyunlib_path = os.path.abspath(scripts_path + '/../lib') 19*4882a593Smuzhiyunsys.path = sys.path + [lib_path] 20*4882a593Smuzhiyun 21*4882a593Smuzhiyunimport scriptpath 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun# For importing the following modules 24*4882a593Smuzhiyunbitbakepath = scriptpath.add_bitbake_lib_path() 25*4882a593Smuzhiyunif not bitbakepath: 26*4882a593Smuzhiyun sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n") 27*4882a593Smuzhiyun sys.exit(1) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyunimport bb.cooker 30*4882a593Smuzhiyunimport bb.providers 31*4882a593Smuzhiyunimport bb.tinfoil 32*4882a593Smuzhiyun 33*4882a593Smuzhiyundef get_fnlist(bbhandler, pkg_pn, preferred): 34*4882a593Smuzhiyun ''' Get all recipe file names ''' 35*4882a593Smuzhiyun if preferred: 36*4882a593Smuzhiyun (latest_versions, preferred_versions, required_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecaches[''], pkg_pn) 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun fn_list = [] 39*4882a593Smuzhiyun for pn in sorted(pkg_pn): 40*4882a593Smuzhiyun if preferred: 41*4882a593Smuzhiyun fn_list.append(preferred_versions[pn][1]) 42*4882a593Smuzhiyun else: 43*4882a593Smuzhiyun fn_list.extend(pkg_pn[pn]) 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun return fn_list 46*4882a593Smuzhiyun 47*4882a593Smuzhiyundef get_recipesdata(bbhandler, preferred): 48*4882a593Smuzhiyun ''' Get data of all available recipes which have PACKAGECONFIG flags ''' 49*4882a593Smuzhiyun pkg_pn = bbhandler.cooker.recipecaches[''].pkg_pn 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun data_dict = {} 52*4882a593Smuzhiyun for fn in get_fnlist(bbhandler, pkg_pn, preferred): 53*4882a593Smuzhiyun data = bbhandler.parse_recipe_file(fn) 54*4882a593Smuzhiyun flags = data.getVarFlags("PACKAGECONFIG") 55*4882a593Smuzhiyun flags.pop('doc', None) 56*4882a593Smuzhiyun if flags: 57*4882a593Smuzhiyun data_dict[fn] = data 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun return data_dict 60*4882a593Smuzhiyun 61*4882a593Smuzhiyundef collect_pkgs(data_dict): 62*4882a593Smuzhiyun ''' Collect available pkgs in which have PACKAGECONFIG flags ''' 63*4882a593Smuzhiyun # pkg_dict = {'pkg1': ['flag1', 'flag2',...]} 64*4882a593Smuzhiyun pkg_dict = {} 65*4882a593Smuzhiyun for fn in data_dict: 66*4882a593Smuzhiyun pkgconfigflags = data_dict[fn].getVarFlags("PACKAGECONFIG") 67*4882a593Smuzhiyun pkgconfigflags.pop('doc', None) 68*4882a593Smuzhiyun pkgname = data_dict[fn].getVar("PN") 69*4882a593Smuzhiyun pkg_dict[pkgname] = sorted(pkgconfigflags.keys()) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun return pkg_dict 72*4882a593Smuzhiyun 73*4882a593Smuzhiyundef collect_flags(pkg_dict): 74*4882a593Smuzhiyun ''' Collect available PACKAGECONFIG flags and all affected pkgs ''' 75*4882a593Smuzhiyun # flag_dict = {'flag': ['pkg1', 'pkg2',...]} 76*4882a593Smuzhiyun flag_dict = {} 77*4882a593Smuzhiyun for pkgname, flaglist in pkg_dict.items(): 78*4882a593Smuzhiyun for flag in flaglist: 79*4882a593Smuzhiyun if flag in flag_dict: 80*4882a593Smuzhiyun flag_dict[flag].append(pkgname) 81*4882a593Smuzhiyun else: 82*4882a593Smuzhiyun flag_dict[flag] = [pkgname] 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun return flag_dict 85*4882a593Smuzhiyun 86*4882a593Smuzhiyundef display_pkgs(pkg_dict): 87*4882a593Smuzhiyun ''' Display available pkgs which have PACKAGECONFIG flags ''' 88*4882a593Smuzhiyun pkgname_len = len("RECIPE NAME") + 1 89*4882a593Smuzhiyun for pkgname in pkg_dict: 90*4882a593Smuzhiyun if pkgname_len < len(pkgname): 91*4882a593Smuzhiyun pkgname_len = len(pkgname) 92*4882a593Smuzhiyun pkgname_len += 1 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun header = '%-*s%s' % (pkgname_len, str("RECIPE NAME"), str("PACKAGECONFIG FLAGS")) 95*4882a593Smuzhiyun print(header) 96*4882a593Smuzhiyun print(str("").ljust(len(header), '=')) 97*4882a593Smuzhiyun for pkgname in sorted(pkg_dict): 98*4882a593Smuzhiyun print('%-*s%s' % (pkgname_len, pkgname, ' '.join(pkg_dict[pkgname]))) 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun 101*4882a593Smuzhiyundef display_flags(flag_dict): 102*4882a593Smuzhiyun ''' Display available PACKAGECONFIG flags and all affected pkgs ''' 103*4882a593Smuzhiyun flag_len = len("PACKAGECONFIG FLAG") + 5 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun header = '%-*s%s' % (flag_len, str("PACKAGECONFIG FLAG"), str("RECIPE NAMES")) 106*4882a593Smuzhiyun print(header) 107*4882a593Smuzhiyun print(str("").ljust(len(header), '=')) 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun for flag in sorted(flag_dict): 110*4882a593Smuzhiyun print('%-*s%s' % (flag_len, flag, ' '.join(sorted(flag_dict[flag])))) 111*4882a593Smuzhiyun 112*4882a593Smuzhiyundef display_all(data_dict): 113*4882a593Smuzhiyun ''' Display all pkgs and PACKAGECONFIG information ''' 114*4882a593Smuzhiyun print(str("").ljust(50, '=')) 115*4882a593Smuzhiyun for fn in data_dict: 116*4882a593Smuzhiyun print('%s' % data_dict[fn].getVar("P")) 117*4882a593Smuzhiyun print(fn) 118*4882a593Smuzhiyun packageconfig = data_dict[fn].getVar("PACKAGECONFIG") or '' 119*4882a593Smuzhiyun if packageconfig.strip() == '': 120*4882a593Smuzhiyun packageconfig = 'None' 121*4882a593Smuzhiyun print('PACKAGECONFIG %s' % packageconfig) 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun for flag,flag_val in data_dict[fn].getVarFlags("PACKAGECONFIG").items(): 124*4882a593Smuzhiyun if flag == "doc": 125*4882a593Smuzhiyun continue 126*4882a593Smuzhiyun print('PACKAGECONFIG[%s] %s' % (flag, flag_val)) 127*4882a593Smuzhiyun print('') 128*4882a593Smuzhiyun 129*4882a593Smuzhiyundef main(): 130*4882a593Smuzhiyun pkg_dict = {} 131*4882a593Smuzhiyun flag_dict = {} 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun # Collect and validate input 134*4882a593Smuzhiyun parser = optparse.OptionParser( 135*4882a593Smuzhiyun description = "Lists recipes and PACKAGECONFIG flags. Without -a or -f, recipes and their available PACKAGECONFIG flags are listed.", 136*4882a593Smuzhiyun usage = """ 137*4882a593Smuzhiyun %prog [options]""") 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun parser.add_option("-f", "--flags", 140*4882a593Smuzhiyun help = "list available PACKAGECONFIG flags and affected recipes", 141*4882a593Smuzhiyun action="store_const", dest="listtype", const="flags", default="recipes") 142*4882a593Smuzhiyun parser.add_option("-a", "--all", 143*4882a593Smuzhiyun help = "list all recipes and PACKAGECONFIG information", 144*4882a593Smuzhiyun action="store_const", dest="listtype", const="all") 145*4882a593Smuzhiyun parser.add_option("-p", "--preferred-only", 146*4882a593Smuzhiyun help = "where multiple recipe versions are available, list only the preferred version", 147*4882a593Smuzhiyun action="store_true", dest="preferred", default=False) 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun options, args = parser.parse_args(sys.argv) 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun with bb.tinfoil.Tinfoil() as bbhandler: 152*4882a593Smuzhiyun bbhandler.prepare() 153*4882a593Smuzhiyun print("Gathering recipe data...") 154*4882a593Smuzhiyun data_dict = get_recipesdata(bbhandler, options.preferred) 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun if options.listtype == 'flags': 157*4882a593Smuzhiyun pkg_dict = collect_pkgs(data_dict) 158*4882a593Smuzhiyun flag_dict = collect_flags(pkg_dict) 159*4882a593Smuzhiyun display_flags(flag_dict) 160*4882a593Smuzhiyun elif options.listtype == 'recipes': 161*4882a593Smuzhiyun pkg_dict = collect_pkgs(data_dict) 162*4882a593Smuzhiyun display_pkgs(pkg_dict) 163*4882a593Smuzhiyun elif options.listtype == 'all': 164*4882a593Smuzhiyun display_all(data_dict) 165*4882a593Smuzhiyun 166*4882a593Smuzhiyunif __name__ == "__main__": 167*4882a593Smuzhiyun main() 168