summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2016-05-30 10:21:00 +1200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-06-01 12:38:41 +0100
commiteb097357374521324ef569d84a4b56c5879eb8ec (patch)
treefb67ba9a3e5a6ac056847bd1727185bc1e3f6abf /scripts
parent2b510f5e018fed5f0e679d887656a501a6a38aaa (diff)
downloadpoky-eb097357374521324ef569d84a4b56c5879eb8ec.tar.gz
recipetool: create: extract variable values from .deb/.ipk/.rpm
Extract the metadata from package files and use it to set variable values in the recipe (including recipe name and version, LICENSE, SUMMARY, DESCRIPTION, SECTION and HOMEPAGE). For LICENSE we take care not to step on any value determined by our license file scan; if there is one we simply add a comment above the LICENSE setting so the user can resolve it. (From OE-Core rev: 19e6b661d38c5ae9b19d6340762c289830baba59) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/lib/recipetool/create.py105
1 files changed, 94 insertions, 11 deletions
diff --git a/scripts/lib/recipetool/create.py b/scripts/lib/recipetool/create.py
index 66c881a17a..ad2618963d 100644
--- a/scripts/lib/recipetool/create.py
+++ b/scripts/lib/recipetool/create.py
@@ -261,7 +261,11 @@ def determine_from_filename(srcfile):
261 namepart = srcfile.split('.tar.')[0].lower() 261 namepart = srcfile.split('.tar.')[0].lower()
262 else: 262 else:
263 namepart = os.path.splitext(srcfile)[0].lower() 263 namepart = os.path.splitext(srcfile)[0].lower()
264 splitval = namepart.rsplit('_', 1) 264 if is_package(srcfile):
265 # Force getting the value from the package metadata
266 return None, None
267 else:
268 splitval = namepart.rsplit('_', 1)
265 if len(splitval) == 1: 269 if len(splitval) == 1:
266 splitval = namepart.rsplit('-', 1) 270 splitval = namepart.rsplit('-', 1)
267 pn = splitval[0].replace('_', '-') 271 pn = splitval[0].replace('_', '-')
@@ -327,6 +331,13 @@ def reformat_git_uri(uri):
327 return 'git://%s;protocol=%s%s' % (res.group(2), res.group(1), res.group(4) or '') 331 return 'git://%s;protocol=%s%s' % (res.group(2), res.group(1), res.group(4) or '')
328 return uri 332 return uri
329 333
334def is_package(url):
335 '''Check if a URL points to a package'''
336 checkurl = url.split(';', 1)[0]
337 if checkurl.endswith(('.deb', '.ipk', '.rpm', '.srpm')):
338 return True
339 return False
340
330def create_recipe(args): 341def create_recipe(args):
331 import bb.process 342 import bb.process
332 import tempfile 343 import tempfile
@@ -337,6 +348,7 @@ def create_recipe(args):
337 if args.machine: 348 if args.machine:
338 pkgarch = "${MACHINE_ARCH}" 349 pkgarch = "${MACHINE_ARCH}"
339 350
351 extravalues = {}
340 checksums = (None, None) 352 checksums = (None, None)
341 tempsrc = '' 353 tempsrc = ''
342 srcsubdir = '' 354 srcsubdir = ''
@@ -382,6 +394,33 @@ def create_recipe(args):
382 if '<html' in f.read(100).lower(): 394 if '<html' in f.read(100).lower():
383 logger.error('Fetching "%s" returned a single HTML page - check the URL is correct and functional' % fetchuri) 395 logger.error('Fetching "%s" returned a single HTML page - check the URL is correct and functional' % fetchuri)
384 sys.exit(1) 396 sys.exit(1)
397
398 if is_package(fetchuri):
399 tmpfdir = tempfile.mkdtemp(prefix='recipetool-')
400 try:
401 pkgfile = None
402 try:
403 fileuri = fetchuri + ';unpack=0'
404 scriptutils.fetch_uri(tinfoil.config_data, fileuri, tmpfdir, srcrev)
405 for root, _, files in os.walk(tmpfdir):
406 for f in files:
407 pkgfile = os.path.join(root, f)
408 break
409 except bb.fetch2.BBFetchException as e:
410 logger.warn('Second fetch to get metadata failed: %s' % str(e).rstrip())
411
412 if pkgfile:
413 if pkgfile.endswith(('.deb', '.ipk')):
414 stdout, _ = bb.process.run('ar x %s control.tar.gz' % pkgfile, cwd=tmpfdir)
415 stdout, _ = bb.process.run('tar xf control.tar.gz ./control', cwd=tmpfdir)
416 values = convert_debian(tmpfdir)
417 extravalues.update(values)
418 elif pkgfile.endswith(('.rpm', '.srpm')):
419 stdout, _ = bb.process.run('rpm -qp --xml %s > pkginfo.xml' % pkgfile, cwd=tmpfdir)
420 values = convert_rpm_xml(os.path.join(tmpfdir, 'pkginfo.xml'))
421 extravalues.update(values)
422 finally:
423 shutil.rmtree(tmpfdir)
385 else: 424 else:
386 # Assume we're pointing to an existing source tree 425 # Assume we're pointing to an existing source tree
387 if args.extract_to: 426 if args.extract_to:
@@ -458,6 +497,13 @@ def create_recipe(args):
458 lines_before.append('# will not be in most cases) you must specify the correct value before using this') 497 lines_before.append('# will not be in most cases) you must specify the correct value before using this')
459 lines_before.append('# recipe for anything other than initial testing/development!') 498 lines_before.append('# recipe for anything other than initial testing/development!')
460 licenses = ['CLOSED'] 499 licenses = ['CLOSED']
500 pkg_license = extravalues.pop('LICENSE', None)
501 if pkg_license:
502 if licenses == ['Unknown']:
503 lines_before.append('# NOTE: The following LICENSE value was determined from the original package metadata')
504 licenses = [pkg_license]
505 else:
506 lines_before.append('# NOTE: Original package metadata indicates license is: %s' % pkg_license)
461 lines_before.append('LICENSE = "%s"' % ' '.join(licenses)) 507 lines_before.append('LICENSE = "%s"' % ' '.join(licenses))
462 lines_before.append('LIC_FILES_CHKSUM = "%s"' % ' \\\n '.join(lic_files_chksum)) 508 lines_before.append('LIC_FILES_CHKSUM = "%s"' % ' \\\n '.join(lic_files_chksum))
463 lines_before.append('') 509 lines_before.append('')
@@ -558,7 +604,6 @@ def create_recipe(args):
558 classes.append('bin_package') 604 classes.append('bin_package')
559 handled.append('buildsystem') 605 handled.append('buildsystem')
560 606
561 extravalues = {}
562 for handler in handlers: 607 for handler in handlers:
563 handler.process(srctree_use, classes, lines_before, lines_after, handled, extravalues) 608 handler.process(srctree_use, classes, lines_before, lines_after, handled, extravalues)
564 609
@@ -665,6 +710,9 @@ def create_recipe(args):
665 outlines.extend(lines_after) 710 outlines.extend(lines_after)
666 711
667 if extravalues: 712 if extravalues:
713 if 'LICENSE' in extravalues and not licvalues:
714 # Don't blow away 'CLOSED' value that comments say we set
715 del extravalues['LICENSE']
668 _, outlines = oe.recipeutils.patch_recipe_lines(outlines, extravalues, trailing_newline=False) 716 _, outlines = oe.recipeutils.patch_recipe_lines(outlines, extravalues, trailing_newline=False)
669 717
670 if args.extract_to: 718 if args.extract_to:
@@ -913,6 +961,12 @@ def convert_pkginfo(pkginfofile):
913 return values 961 return values
914 962
915def convert_debian(debpath): 963def convert_debian(debpath):
964 value_map = {'Package': 'PN',
965 'Version': 'PV',
966 'Section': 'SECTION',
967 'License': 'LICENSE',
968 'Homepage': 'HOMEPAGE'}
969
916 # FIXME extend this mapping - perhaps use distro_alias.inc? 970 # FIXME extend this mapping - perhaps use distro_alias.inc?
917 depmap = {'libz-dev': 'zlib'} 971 depmap = {'libz-dev': 'zlib'}
918 972
@@ -922,34 +976,63 @@ def convert_debian(debpath):
922 indesc = False 976 indesc = False
923 for line in f: 977 for line in f:
924 if indesc: 978 if indesc:
925 if line.strip(): 979 if line.startswith(' '):
926 if line.startswith(' This package contains'): 980 if line.startswith(' This package contains'):
927 indesc = False 981 indesc = False
928 else: 982 else:
929 values['DESCRIPTION'] += ' ' + line.strip() 983 if 'DESCRIPTION' in values:
984 values['DESCRIPTION'] += ' ' + line.strip()
985 else:
986 values['DESCRIPTION'] = line.strip()
930 else: 987 else:
931 indesc = False 988 indesc = False
932 else: 989 if not indesc:
933 splitline = line.split(':', 1) 990 splitline = line.split(':', 1)
934 key = line[0] 991 if len(splitline) < 2:
935 value = line[1] 992 continue
993 key = splitline[0]
994 value = splitline[1].strip()
936 if key == 'Build-Depends': 995 if key == 'Build-Depends':
937 for dep in value.split(','): 996 for dep in value.split(','):
938 dep = dep.split()[0] 997 dep = dep.split()[0]
939 mapped = depmap.get(dep, '') 998 mapped = depmap.get(dep, '')
940 if mapped: 999 if mapped:
941 depends.append(mapped) 1000 depends.append(mapped)
942 elif key == 'Section':
943 values['SECTION'] = value
944 elif key == 'Description': 1001 elif key == 'Description':
945 values['SUMMARY'] = value 1002 values['SUMMARY'] = value
946 indesc = True 1003 indesc = True
1004 else:
1005 varname = value_map.get(key, None)
1006 if varname:
1007 values[varname] = value
947 1008
948 if depends: 1009 #if depends:
949 values['DEPENDS'] = ' '.join(depends) 1010 # values['DEPENDS'] = ' '.join(depends)
950 1011
951 return values 1012 return values
952 1013
1014def convert_rpm_xml(xmlfile):
1015 '''Converts the output from rpm -qp --xml to a set of variable values'''
1016 import xml.etree.ElementTree as ElementTree
1017 rpmtag_map = {'Name': 'PN',
1018 'Version': 'PV',
1019 'Summary': 'SUMMARY',
1020 'Description': 'DESCRIPTION',
1021 'License': 'LICENSE',
1022 'Url': 'HOMEPAGE'}
1023
1024 values = {}
1025 tree = ElementTree.parse(xmlfile)
1026 root = tree.getroot()
1027 for child in root:
1028 if child.tag == 'rpmTag':
1029 name = child.attrib.get('name', None)
1030 if name:
1031 varname = rpmtag_map.get(name, None)
1032 if varname:
1033 values[varname] = child[0].text
1034 return values
1035
953 1036
954def register_commands(subparsers): 1037def register_commands(subparsers):
955 parser_create = subparsers.add_parser('create', 1038 parser_create = subparsers.add_parser('create',