blob: 2f3b8b06a6610e08e9883085bb5eefecb4efaffc [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/usr/bin/env python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software Foundation.
15#
16# Copyright (C) 2013 Wind River Systems, Inc.
17# Copyright (C) 2014 Intel Corporation
18#
19# - list available recipes which have PACKAGECONFIG flags
20# - list available PACKAGECONFIG flags and all affected recipes
21# - list all recipes and PACKAGECONFIG information
22
23import sys
24import optparse
25import os
26
27
28scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
29lib_path = os.path.abspath(scripts_path + '/../lib')
30sys.path = sys.path + [lib_path]
31
32import scriptpath
33
34# For importing the following modules
35bitbakepath = scriptpath.add_bitbake_lib_path()
36if not bitbakepath:
37 sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
38 sys.exit(1)
39
40import bb.cache
41import bb.cooker
42import bb.providers
43import bb.tinfoil
44
45def get_fnlist(bbhandler, pkg_pn, preferred):
46 ''' Get all recipe file names '''
47 if preferred:
48 (latest_versions, preferred_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecache, pkg_pn)
49
50 fn_list = []
51 for pn in sorted(pkg_pn):
52 if preferred:
53 fn_list.append(preferred_versions[pn][1])
54 else:
55 fn_list.extend(pkg_pn[pn])
56
57 return fn_list
58
59def get_recipesdata(bbhandler, preferred):
60 ''' Get data of all available recipes which have PACKAGECONFIG flags '''
61 pkg_pn = bbhandler.cooker.recipecache.pkg_pn
62
63 data_dict = {}
64 for fn in get_fnlist(bbhandler, pkg_pn, preferred):
65 data = bb.cache.Cache.loadDataFull(fn, bbhandler.cooker.collection.get_file_appends(fn), bbhandler.config_data)
66 flags = data.getVarFlags("PACKAGECONFIG")
67 flags.pop('doc', None)
68 if flags:
69 data_dict[fn] = data
70
71 return data_dict
72
73def collect_pkgs(data_dict):
74 ''' Collect available pkgs in which have PACKAGECONFIG flags '''
75 # pkg_dict = {'pkg1': ['flag1', 'flag2',...]}
76 pkg_dict = {}
77 for fn in data_dict:
78 pkgconfigflags = data_dict[fn].getVarFlags("PACKAGECONFIG")
79 pkgconfigflags.pop('doc', None)
80 pkgname = data_dict[fn].getVar("P", True)
81 pkg_dict[pkgname] = sorted(pkgconfigflags.keys())
82
83 return pkg_dict
84
85def collect_flags(pkg_dict):
86 ''' Collect available PACKAGECONFIG flags and all affected pkgs '''
87 # flag_dict = {'flag': ['pkg1', 'pkg2',...]}
88 flag_dict = {}
89 for pkgname, flaglist in pkg_dict.iteritems():
90 for flag in flaglist:
91 if flag in flag_dict:
92 flag_dict[flag].append(pkgname)
93 else:
94 flag_dict[flag] = [pkgname]
95
96 return flag_dict
97
98def display_pkgs(pkg_dict):
99 ''' Display available pkgs which have PACKAGECONFIG flags '''
100 pkgname_len = len("RECIPE NAME") + 1
101 for pkgname in pkg_dict:
102 if pkgname_len < len(pkgname):
103 pkgname_len = len(pkgname)
104 pkgname_len += 1
105
106 header = '%-*s%s' % (pkgname_len, str("RECIPE NAME"), str("PACKAGECONFIG FLAGS"))
107 print header
108 print str("").ljust(len(header), '=')
109 for pkgname in sorted(pkg_dict):
110 print('%-*s%s' % (pkgname_len, pkgname, ' '.join(pkg_dict[pkgname])))
111
112
113def display_flags(flag_dict):
114 ''' Display available PACKAGECONFIG flags and all affected pkgs '''
115 flag_len = len("PACKAGECONFIG FLAG") + 5
116
117 header = '%-*s%s' % (flag_len, str("PACKAGECONFIG FLAG"), str("RECIPE NAMES"))
118 print header
119 print str("").ljust(len(header), '=')
120
121 for flag in sorted(flag_dict):
122 print('%-*s%s' % (flag_len, flag, ' '.join(sorted(flag_dict[flag]))))
123
124def display_all(data_dict):
125 ''' Display all pkgs and PACKAGECONFIG information '''
126 print str("").ljust(50, '=')
127 for fn in data_dict:
128 print('%s' % data_dict[fn].getVar("P", True))
129 print fn
130 packageconfig = data_dict[fn].getVar("PACKAGECONFIG", True) or ''
131 if packageconfig.strip() == '':
132 packageconfig = 'None'
133 print('PACKAGECONFIG %s' % packageconfig)
134
135 for flag,flag_val in data_dict[fn].getVarFlags("PACKAGECONFIG").iteritems():
136 if flag == "doc":
137 continue
138 print('PACKAGECONFIG[%s] %s' % (flag, flag_val))
139 print ''
140
141def main():
142 pkg_dict = {}
143 flag_dict = {}
144
145 # Collect and validate input
146 parser = optparse.OptionParser(
147 description = "Lists recipes and PACKAGECONFIG flags. Without -a or -f, recipes and their available PACKAGECONFIG flags are listed.",
148 usage = """
149 %prog [options]""")
150
151 parser.add_option("-f", "--flags",
152 help = "list available PACKAGECONFIG flags and affected recipes",
153 action="store_const", dest="listtype", const="flags", default="recipes")
154 parser.add_option("-a", "--all",
155 help = "list all recipes and PACKAGECONFIG information",
156 action="store_const", dest="listtype", const="all")
157 parser.add_option("-p", "--preferred-only",
158 help = "where multiple recipe versions are available, list only the preferred version",
159 action="store_true", dest="preferred", default=False)
160
161 options, args = parser.parse_args(sys.argv)
162
163 bbhandler = bb.tinfoil.Tinfoil()
164 bbhandler.prepare()
165 print("Gathering recipe data...")
166 data_dict = get_recipesdata(bbhandler, options.preferred)
167
168 if options.listtype == 'flags':
169 pkg_dict = collect_pkgs(data_dict)
170 flag_dict = collect_flags(pkg_dict)
171 display_flags(flag_dict)
172 elif options.listtype == 'recipes':
173 pkg_dict = collect_pkgs(data_dict)
174 display_pkgs(pkg_dict)
175 elif options.listtype == 'all':
176 display_all(data_dict)
177
178if __name__ == "__main__":
179 main()