diff options
Diffstat (limited to 'scripts/lib/recipetool/create.py')
-rw-r--r-- | scripts/lib/recipetool/create.py | 105 |
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 | ||
334 | def 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 | |||
330 | def create_recipe(args): | 341 | def 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 | ||
915 | def convert_debian(debpath): | 963 | def 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 | ||
1014 | def 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 | ||
954 | def register_commands(subparsers): | 1037 | def register_commands(subparsers): |
955 | parser_create = subparsers.add_parser('create', | 1038 | parser_create = subparsers.add_parser('create', |