summaryrefslogtreecommitdiffstats
path: root/scripts/oe-pkgdata-util
diff options
context:
space:
mode:
authorTudor Florea <tudor.florea@enea.com>2015-10-09 22:59:03 +0200
committerTudor Florea <tudor.florea@enea.com>2015-10-09 22:59:03 +0200
commit972dcfcdbfe75dcfeb777150c136576cf1a71e99 (patch)
tree97a61cd7e293d7ae9d56ef7ed0f81253365bb026 /scripts/oe-pkgdata-util
downloadpoky-972dcfcdbfe75dcfeb777150c136576cf1a71e99.tar.gz
initial commit for Enea Linux 5.0 arm
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'scripts/oe-pkgdata-util')
-rwxr-xr-xscripts/oe-pkgdata-util338
1 files changed, 338 insertions, 0 deletions
diff --git a/scripts/oe-pkgdata-util b/scripts/oe-pkgdata-util
new file mode 100755
index 0000000000..28a9f8362b
--- /dev/null
+++ b/scripts/oe-pkgdata-util
@@ -0,0 +1,338 @@
1#!/usr/bin/env python
2
3# OpenEmbedded pkgdata utility
4#
5# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
6#
7# Copyright 2012-2013 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21#
22
23import sys
24import os
25import os.path
26import fnmatch
27import re
28import optparse
29from collections import defaultdict
30
31def glob(args, usage, debug=False, exclude=""):
32 if len(args) < 3:
33 usage()
34 sys.exit(1)
35
36 pkgdata_dir = args[0]
37 pkglist_file = args[1]
38 globs = args[2].split()
39
40 if not os.path.exists(pkgdata_dir):
41 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
42 sys.exit(1)
43
44 if not os.path.exists(pkglist_file):
45 print('ERROR: Unable to find package list file %s' % pkglist_file)
46 sys.exit(1)
47
48 skipval = "-locale-|^locale-base-|-dev$|-doc$|-dbg$|-staticdev$|^kernel-module-"
49 if exclude:
50 skipval += "|" + exclude
51 skipregex = re.compile(skipval)
52
53 mappedpkgs = set()
54 with open(pkglist_file, 'r') as f:
55 for line in f:
56 fields = line.rstrip().split()
57 if not fields:
58 continue
59 pkg = fields[0]
60 # We don't care about other args (used to need the package architecture but the
61 # new pkgdata structure avoids the need for that)
62
63 # Skip packages for which there is no point applying globs
64 if skipregex.search(pkg):
65 if debug:
66 print("%s -> !!" % pkg)
67 continue
68
69 # Skip packages that already match the globs, so if e.g. a dev package
70 # is already installed and thus in the list, we don't process it any further
71 # Most of these will be caught by skipregex already, but just in case...
72 already = False
73 for g in globs:
74 if fnmatch.fnmatchcase(pkg, g):
75 already = True
76 break
77 if already:
78 if debug:
79 print("%s -> !" % pkg)
80 continue
81
82 # Define some functions
83 def revpkgdata(pkgn):
84 return os.path.join(pkgdata_dir, "runtime-reverse", pkgn)
85 def fwdpkgdata(pkgn):
86 return os.path.join(pkgdata_dir, "runtime", pkgn)
87 def readpn(pkgdata_file):
88 pn = ""
89 with open(pkgdata_file, 'r') as f:
90 for line in f:
91 if line.startswith("PN:"):
92 pn = line.split(': ')[1].rstrip()
93 return pn
94 def readrenamed(pkgdata_file):
95 renamed = ""
96 pn = os.path.basename(pkgdata_file)
97 with open(pkgdata_file, 'r') as f:
98 for line in f:
99 if line.startswith("PKG_%s:" % pn):
100 renamed = line.split(': ')[1].rstrip()
101 return renamed
102
103 # Main processing loop
104 for g in globs:
105 mappedpkg = ""
106 # First just try substitution (i.e. packagename -> packagename-dev)
107 newpkg = g.replace("*", pkg)
108 revlink = revpkgdata(newpkg)
109 if os.path.exists(revlink):
110 mappedpkg = os.path.basename(os.readlink(revlink))
111 fwdfile = fwdpkgdata(mappedpkg)
112 if os.path.exists(fwdfile):
113 mappedpkg = readrenamed(fwdfile)
114 if not os.path.exists(fwdfile + ".packaged"):
115 mappedpkg = ""
116 else:
117 revlink = revpkgdata(pkg)
118 if os.path.exists(revlink):
119 # Check if we can map after undoing the package renaming (by resolving the symlink)
120 origpkg = os.path.basename(os.readlink(revlink))
121 newpkg = g.replace("*", origpkg)
122 fwdfile = fwdpkgdata(newpkg)
123 if os.path.exists(fwdfile):
124 mappedpkg = readrenamed(fwdfile)
125 else:
126 # That didn't work, so now get the PN, substitute that, then map in the other direction
127 pn = readpn(revlink)
128 newpkg = g.replace("*", pn)
129 fwdfile = fwdpkgdata(newpkg)
130 if os.path.exists(fwdfile):
131 mappedpkg = readrenamed(fwdfile)
132 if not os.path.exists(fwdfile + ".packaged"):
133 mappedpkg = ""
134 else:
135 # Package doesn't even exist...
136 if debug:
137 print "%s is not a valid package!" % (pkg)
138 break
139
140 if mappedpkg:
141 if debug:
142 print "%s (%s) -> %s" % (pkg, g, mappedpkg)
143 mappedpkgs.add(mappedpkg)
144 else:
145 if debug:
146 print "%s (%s) -> ?" % (pkg, g)
147
148 if debug:
149 print "------"
150
151 print("\n".join(mappedpkgs))
152
153def read_value(args, usage, debug=False):
154 if len(args) < 3:
155 usage()
156 sys.exit(1)
157
158 pkgdata_dir = args[0]
159 var = args[1]
160 packages = args[2].split()
161
162 if not os.path.exists(pkgdata_dir):
163 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
164 sys.exit(1)
165
166 def readvar(pkgdata_file, var):
167 val = ""
168 with open(pkgdata_file, 'r') as f:
169 for line in f:
170 if line.startswith(var + ":"):
171 val = line.split(': ')[1].rstrip()
172 return val
173
174 if debug:
175 print "read-value('%s', '%s' '%s'" % (pkgdata_dir, var, packages)
176 for package in packages:
177 pkg_split = package.split('_')
178 pkg_name = pkg_split[0]
179 if debug:
180 print "package: '%s'" % pkg_name
181 revlink = os.path.join(pkgdata_dir, "runtime-reverse", pkg_name)
182 if debug:
183 print(revlink)
184 if os.path.exists(revlink):
185 mappedpkg = os.path.basename(os.readlink(revlink))
186 qvar = var
187 if qvar == "PKGSIZE":
188 # append packagename
189 qvar = "%s_%s" % (var, mappedpkg)
190 # PKGSIZE is now in bytes, but we we want it in KB
191 pkgsize = (int(readvar(revlink, qvar)) + 1024 // 2) // 1024
192 print("%d" % pkgsize)
193 else:
194 print(readvar(revlink, qvar))
195
196def lookup_pkg(args, usage, debug=False):
197 if len(args) < 2:
198 usage()
199 sys.exit(1)
200
201 pkgdata_dir = args[0]
202 pkgs = args[1].split()
203
204 if not os.path.exists(pkgdata_dir):
205 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
206 sys.exit(1)
207
208 mappings = defaultdict(list)
209 for pkg in pkgs:
210 pkgfile = os.path.join(pkgdata_dir, 'runtime', pkg)
211 if os.path.exists(pkgfile):
212 with open(pkgfile, 'r') as f:
213 for line in f:
214 fields = line.rstrip().split(': ')
215 if fields[0] == 'PKG_%s' % pkg:
216 mappings[pkg].append(fields[1])
217 break
218 if len(mappings) < len(pkgs):
219 missing = list(set(pkgs) - set(mappings.keys()))
220 sys.stderr.write("ERROR: the following packages could not be found: %s\n" % ', '.join(missing))
221 sys.exit(1)
222
223 items = []
224 for pkg in pkgs:
225 items.extend(mappings.get(pkg, []))
226 print '\n'.join(items)
227
228def lookup_recipe(args, usage, debug=False):
229 if len(args) < 2:
230 usage()
231 sys.exit(1)
232
233 pkgdata_dir = args[0]
234 pkgs = args[1].split()
235
236 if not os.path.exists(pkgdata_dir):
237 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
238 sys.exit(1)
239
240 mappings = defaultdict(list)
241 for pkg in pkgs:
242 pkgfile = os.path.join(pkgdata_dir, 'runtime-reverse', pkg)
243 if os.path.exists(pkgfile):
244 with open(pkgfile, 'r') as f:
245 for line in f:
246 fields = line.rstrip().split(': ')
247 if fields[0] == 'PN':
248 mappings[pkg].append(fields[1])
249 break
250 if len(mappings) < len(pkgs):
251 missing = list(set(pkgs) - set(mappings.keys()))
252 sys.stderr.write("ERROR: the following packages could not be found: %s\n" % ', '.join(missing))
253 sys.exit(1)
254
255 items = []
256 for pkg in pkgs:
257 items.extend(mappings.get(pkg, []))
258 print '\n'.join(items)
259
260def find_path(args, usage, debug=False):
261 if len(args) < 2:
262 usage()
263 sys.exit(1)
264
265 pkgdata_dir = args[0]
266 targetpath = args[1]
267
268 if not os.path.exists(pkgdata_dir):
269 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
270 sys.exit(1)
271
272 import json
273 import fnmatch
274
275 for root, dirs, files in os.walk(os.path.join(pkgdata_dir, 'runtime')):
276 for fn in files:
277 with open(os.path.join(root,fn)) as f:
278 for line in f:
279 if line.startswith('FILES_INFO:'):
280 val = line.split(':', 1)[1].strip()
281 dictval = json.loads(val)
282 for fullpth in dictval.keys():
283 if fnmatch.fnmatchcase(fullpth, targetpath):
284 print("%s: %s" % (fn, fullpth))
285 break
286
287
288def main():
289 parser = optparse.OptionParser(
290 usage = '''%prog [options] <command> <arguments>
291
292Available commands:
293 glob <pkgdatadir> <pkglistfile> "<globs>"
294 expand one or more glob expressions over the packages listed in
295 pkglistfile (one package per line)
296 lookup-pkg <pkgdatadir> "<recipe-pkgs>"
297 look up the specified recipe-space package name(s) to see what the
298 final runtime package name is (e.g. eglibc becomes libc6)
299 lookup-recipe <pkgdatadir> "<pkgs>"
300 look up the specified package(s) to see which recipe they were
301 produced by
302 find-path <pkgdatadir> <path>
303 find the package providing the specified path (wildcards * ? allowed)
304 read-value <pkgdatadir> <value-name> "<pkgs>"
305 read the named value from the pkgdata files for the specified
306 packages''')
307
308 parser.add_option("-d", "--debug",
309 help = "Enable debug output",
310 action="store_true", dest="debug", default=False)
311 parser.add_option("-x", "--exclude",
312 help = "Exclude packages matching specified regex from the glob operation",
313 action="store", type="string", dest="exclude", default="")
314
315 options, args = parser.parse_args(sys.argv)
316 args = args[1:]
317
318 if len(args) < 1:
319 parser.print_help()
320 sys.exit(1)
321
322 if args[0] == "glob":
323 glob(args[1:], parser.print_help, options.debug, options.exclude)
324 elif args[0] == "lookup-pkg":
325 lookup_pkg(args[1:], parser.print_help, options.debug)
326 elif args[0] == "lookup-recipe":
327 lookup_recipe(args[1:], parser.print_help, options.debug)
328 elif args[0] == "find-path":
329 find_path(args[1:], parser.print_help, options.debug)
330 elif args[0] == "read-value":
331 read_value(args[1:], parser.print_help, options.debug)
332 else:
333 parser.print_help()
334 sys.exit(1)
335
336
337if __name__ == "__main__":
338 main()