diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2012-01-30 16:25:52 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2012-02-01 15:08:41 +0000 |
commit | 526264e7d74c8b5fad4ab5ec3303b2edfea98e61 (patch) | |
tree | e98177bfe5cb186d1ba9f2baa959263994f853f2 /bitbake | |
parent | 3d2f6d56109fc3ebe9c8e7fe0d84d6cd01a9e2fb (diff) | |
download | poky-526264e7d74c8b5fad4ab5ec3303b2edfea98e61.tar.gz |
bitbake-layers: improve show-overlayed output
Make the following improvements to the show-overlayed subcommand:
* Show recipes that are overlayed when the version is higher or lower,
not just when it is the same. This gives a much better picture of the
influence each layer is having over the metadata used for building.
This can be disabled with the -s option if you just want to see
recipes with the same version as before.
* Default to showing name (PN), layer and version rather than the full
path and filename. The old style formatting can be used by specifying
the -f option.
* Mark skipped recipes as such in the output, and print them in the
correct sorted place in the list rather than at the end
* Prefix/suffix title line with === so it can be filtered out easily in
shell scripts if desired
(Bitbake rev: 43b473275d3cb2e60a14e4a52cdc4654b3f4e5e7)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rwxr-xr-x | bitbake/bin/bitbake-layers | 116 | ||||
-rw-r--r-- | bitbake/lib/bb/cooker.py | 14 | ||||
-rw-r--r-- | bitbake/lib/bb/providers.py | 36 |
3 files changed, 142 insertions, 24 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers index 65496b1674..151f87fd52 100755 --- a/bitbake/bin/bitbake-layers +++ b/bitbake/bin/bitbake-layers | |||
@@ -9,6 +9,7 @@ import logging | |||
9 | import os | 9 | import os |
10 | import sys | 10 | import sys |
11 | import fnmatch | 11 | import fnmatch |
12 | from collections import defaultdict | ||
12 | 13 | ||
13 | bindir = os.path.dirname(__file__) | 14 | bindir = os.path.dirname(__file__) |
14 | topdir = os.path.dirname(bindir) | 15 | topdir = os.path.dirname(bindir) |
@@ -121,22 +122,115 @@ class Commands(cmd.Cmd): | |||
121 | 122 | ||
122 | logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri)) | 123 | logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri)) |
123 | 124 | ||
125 | |||
126 | def version_str(self, pe, pv, pr = None): | ||
127 | verstr = "%s" % pv | ||
128 | if pr: | ||
129 | verstr = "%s-%s" % (verstr, pr) | ||
130 | if pe: | ||
131 | verstr = "%s:%s" % (pe, verstr) | ||
132 | return verstr | ||
133 | |||
134 | |||
124 | def do_show_overlayed(self, args): | 135 | def do_show_overlayed(self, args): |
125 | """list overlayed recipes (where there is a recipe in another layer that has a higher layer priority) | 136 | """list overlayed recipes (where the same recipe exists in another layer that has a higher layer priority) |
137 | |||
138 | usage: show-overlayed [-f] [-s] | ||
126 | 139 | ||
127 | usage: show-overlayed | 140 | Lists the names of overlayed recipes and the available versions in each |
141 | layer, with the preferred version first. Note that skipped recipes that | ||
142 | are overlayed will also be listed, with a " (skipped)" suffix. | ||
128 | 143 | ||
129 | Highest priority recipes are listed with the recipes they overlay as subitems. | 144 | Options: |
145 | -f instead of the default formatting, list filenames of higher priority | ||
146 | recipes with the ones they overlay indented underneath | ||
147 | -s only list overlayed recipes where the version is the same | ||
130 | """ | 148 | """ |
131 | self.check_prepare_cooker() | 149 | self.check_prepare_cooker() |
132 | if self.cooker.overlayed: | 150 | |
133 | logger.plain('Overlayed recipes:') | 151 | show_filenames = False |
134 | for f in self.cooker.overlayed.iterkeys(): | 152 | show_same_ver_only = False |
135 | logger.plain('%s' % f) | 153 | for arg in args.split(): |
136 | for of in self.cooker.overlayed[f]: | 154 | if arg == '-f': |
137 | logger.plain(' %s' % of) | 155 | show_filenames = True |
138 | else: | 156 | elif arg == '-s': |
139 | logger.plain('No overlayed recipes found') | 157 | show_same_ver_only = True |
158 | else: | ||
159 | sys.stderr.write("show-overlayed: invalid option %s\n" % arg) | ||
160 | self.do_help('') | ||
161 | return | ||
162 | |||
163 | pkg_pn = self.cooker.status.pkg_pn | ||
164 | (latest_versions, preferred_versions) = bb.providers.findProviders(self.cooker.configuration.data, self.cooker.status, pkg_pn) | ||
165 | allproviders = bb.providers.allProviders(self.cooker.status) | ||
166 | |||
167 | # Ensure we list skipped recipes | ||
168 | # We are largely guessing about PN, PV and the preferred version here, | ||
169 | # but we have no choice since skipped recipes are not fully parsed | ||
170 | skiplist = self.cooker.skiplist.keys() | ||
171 | skiplist.sort( key=lambda fileitem: self.cooker.calc_bbfile_priority(fileitem) ) | ||
172 | skiplist.reverse() | ||
173 | for fn in skiplist: | ||
174 | recipe_parts = os.path.splitext(os.path.basename(fn))[0].split('_') | ||
175 | p = recipe_parts[0] | ||
176 | if len(recipe_parts) > 1: | ||
177 | ver = (None, recipe_parts[1], None) | ||
178 | else: | ||
179 | ver = (None, 'unknown', None) | ||
180 | allproviders[p].append((ver, fn)) | ||
181 | if not p in pkg_pn: | ||
182 | pkg_pn[p] = 'dummy' | ||
183 | preferred_versions[p] = (ver, fn) | ||
184 | |||
185 | def print_item(f, pn, ver, layer, ispref): | ||
186 | if f in skiplist: | ||
187 | skipped = ' (skipped)' | ||
188 | else: | ||
189 | skipped = '' | ||
190 | if show_filenames: | ||
191 | if ispref: | ||
192 | logger.plain("%s%s", f, skipped) | ||
193 | else: | ||
194 | logger.plain(" %s%s", f, skipped) | ||
195 | else: | ||
196 | if ispref: | ||
197 | logger.plain("%s:", pn) | ||
198 | logger.plain(" %s %s%s", layer.ljust(20), ver, skipped) | ||
199 | |||
200 | preffiles = [] | ||
201 | items_listed = False | ||
202 | for p in sorted(pkg_pn): | ||
203 | if len(allproviders[p]) > 1: | ||
204 | pref = preferred_versions[p] | ||
205 | preffile = bb.cache.Cache.virtualfn2realfn(pref[1])[0] | ||
206 | if preffile not in preffiles: | ||
207 | preflayer = self.get_file_layer(preffile) | ||
208 | multilayer = False | ||
209 | same_ver = True | ||
210 | provs = [] | ||
211 | for prov in allproviders[p]: | ||
212 | provfile = bb.cache.Cache.virtualfn2realfn(prov[1])[0] | ||
213 | provlayer = self.get_file_layer(provfile) | ||
214 | provs.append((provfile, provlayer, prov[0])) | ||
215 | if provlayer != preflayer: | ||
216 | multilayer = True | ||
217 | if prov[0] != pref[0]: | ||
218 | same_ver = False | ||
219 | |||
220 | if multilayer and (same_ver or not show_same_ver_only): | ||
221 | if not items_listed: | ||
222 | logger.plain('=== Overlayed recipes ===') | ||
223 | items_listed = True | ||
224 | print_item(preffile, p, self.version_str(pref[0][0], pref[0][1]), preflayer, True) | ||
225 | for (provfile, provlayer, provver) in provs: | ||
226 | if provfile != preffile: | ||
227 | print_item(provfile, p, self.version_str(provver[0], provver[1]), provlayer, False) | ||
228 | # Ensure we don't show two entries for BBCLASSEXTENDed recipes | ||
229 | preffiles.append(preffile) | ||
230 | |||
231 | if not items_listed: | ||
232 | logger.note('No overlayed files found') | ||
233 | |||
140 | 234 | ||
141 | def do_flatten(self, args): | 235 | def do_flatten(self, args): |
142 | """flattens layer configuration into a separate output directory. | 236 | """flattens layer configuration into a separate output directory. |
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index b6bd7400fe..652cd5d5c2 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
@@ -259,20 +259,8 @@ class BBCooker: | |||
259 | # Need files parsed | 259 | # Need files parsed |
260 | self.updateCache() | 260 | self.updateCache() |
261 | 261 | ||
262 | # Need to ensure data store is expanded | ||
263 | localdata = data.createCopy(self.configuration.data) | ||
264 | bb.data.update_data(localdata) | ||
265 | bb.data.expandKeys(localdata) | ||
266 | |||
267 | pkg_pn = self.status.pkg_pn | 262 | pkg_pn = self.status.pkg_pn |
268 | preferred_versions = {} | 263 | (latest_versions, preferred_versions) = bb.providers.findProviders(self.configuration.data, self.status, pkg_pn) |
269 | latest_versions = {} | ||
270 | |||
271 | # Sort by priority | ||
272 | for pn in pkg_pn: | ||
273 | (last_ver, last_file, pref_ver, pref_file) = bb.providers.findBestProvider(pn, localdata, self.status) | ||
274 | preferred_versions[pn] = (pref_ver, pref_file) | ||
275 | latest_versions[pn] = (last_ver, last_file) | ||
276 | 264 | ||
277 | logger.plain("%-35s %25s %25s", "Package Name", "Latest Version", "Preferred Version") | 265 | logger.plain("%-35s %25s %25s", "Package Name", "Latest Version", "Preferred Version") |
278 | logger.plain("%-35s %25s %25s\n", "============", "==============", "=================") | 266 | logger.plain("%-35s %25s %25s\n", "============", "==============", "=================") |
diff --git a/bitbake/lib/bb/providers.py b/bitbake/lib/bb/providers.py index 398c8ea115..1dc6a8e8bf 100644 --- a/bitbake/lib/bb/providers.py +++ b/bitbake/lib/bb/providers.py | |||
@@ -24,6 +24,7 @@ | |||
24 | import re | 24 | import re |
25 | import logging | 25 | import logging |
26 | from bb import data, utils | 26 | from bb import data, utils |
27 | from collections import defaultdict | ||
27 | import bb | 28 | import bb |
28 | 29 | ||
29 | logger = logging.getLogger("BitBake.Provider") | 30 | logger = logging.getLogger("BitBake.Provider") |
@@ -35,6 +36,41 @@ class NoRProvider(bb.BBHandledException): | |||
35 | """Exception raised when no provider of a runtime dependency can be found""" | 36 | """Exception raised when no provider of a runtime dependency can be found""" |
36 | 37 | ||
37 | 38 | ||
39 | def findProviders(cfgData, dataCache, pkg_pn = None): | ||
40 | """ | ||
41 | Convenience function to get latest and preferred providers in pkg_pn | ||
42 | """ | ||
43 | |||
44 | if not pkg_pn: | ||
45 | pkg_pn = dataCache.pkg_pn | ||
46 | |||
47 | # Need to ensure data store is expanded | ||
48 | localdata = data.createCopy(cfgData) | ||
49 | bb.data.update_data(localdata) | ||
50 | bb.data.expandKeys(localdata) | ||
51 | |||
52 | preferred_versions = {} | ||
53 | latest_versions = {} | ||
54 | |||
55 | for pn in pkg_pn: | ||
56 | (last_ver, last_file, pref_ver, pref_file) = findBestProvider(pn, localdata, dataCache, pkg_pn) | ||
57 | preferred_versions[pn] = (pref_ver, pref_file) | ||
58 | latest_versions[pn] = (last_ver, last_file) | ||
59 | |||
60 | return (latest_versions, preferred_versions) | ||
61 | |||
62 | |||
63 | def allProviders(dataCache): | ||
64 | """ | ||
65 | Find all providers for each pn | ||
66 | """ | ||
67 | all_providers = defaultdict(list) | ||
68 | for (fn, pn) in dataCache.pkg_fn.items(): | ||
69 | ver = dataCache.pkg_pepvpr[fn] | ||
70 | all_providers[pn].append((ver, fn)) | ||
71 | return all_providers | ||
72 | |||
73 | |||
38 | def sortPriorities(pn, dataCache, pkg_pn = None): | 74 | def sortPriorities(pn, dataCache, pkg_pn = None): |
39 | """ | 75 | """ |
40 | Reorder pkg_pn by file priority and default preference | 76 | Reorder pkg_pn by file priority and default preference |