summaryrefslogtreecommitdiffstats
path: root/scripts/lib/recipetool
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/recipetool')
-rw-r--r--scripts/lib/recipetool/append.py110
1 files changed, 104 insertions, 6 deletions
diff --git a/scripts/lib/recipetool/append.py b/scripts/lib/recipetool/append.py
index 0aca2cae66..9903871ab0 100644
--- a/scripts/lib/recipetool/append.py
+++ b/scripts/lib/recipetool/append.py
@@ -334,20 +334,95 @@ def appendfile(args):
334 return 3 334 return 3
335 335
336 336
337def appendsrc(args, files, rd):
338 import oe.recipeutils
339
340 srcdir = rd.getVar('S', True)
341 workdir = rd.getVar('WORKDIR', True)
342
343 import bb.fetch
344 simplified = {}
345 src_uri = rd.getVar('SRC_URI', True).split()
346 for uri in src_uri:
347 simple_uri = bb.fetch.URI(uri)
348 simple_uri.params = {}
349 simplified[simple_uri] = uri
350
351 copyfiles = {}
352 extralines = []
353 for newfile, srcfile in files.iteritems():
354 src_destdir = os.path.dirname(srcfile)
355 if not args.use_workdir:
356 src_destdir = os.path.join(os.path.relpath(srcdir, workdir), src_destdir)
357 src_destdir = os.path.normpath(src_destdir)
358
359 source_uri = 'file://{0}'.format(os.path.basename(srcfile))
360 if src_destdir and src_destdir != '.':
361 source_uri += ';subdir={0}'.format(src_destdir)
362
363 simple = bb.fetch.URI(source_uri)
364 simple.params = {}
365 if simple in simplified:
366 existing = simplified[simple]
367 if uri != existing:
368 logger.warn('{0!r} is already in SRC_URI, with different parameters: {1!r}, not adding'.format(source_uri, existing))
369 else:
370 logger.warn('{0!r} is already in SRC_URI, not adding'.format(source_uri))
371 else:
372 extralines.append('SRC_URI += {0}'.format(source_uri))
373 copyfiles[newfile] = srcfile
374
375 oe.recipeutils.bbappend_recipe(rd, args.destlayer, copyfiles, None, wildcardver=args.wildcard_version, machine=args.machine, extralines=extralines)
376
377
378def appendsrcfiles(parser, args):
379 recipedata = _parse_recipe(args.recipe, tinfoil)
380 if not recipedata:
381 parser.error('RECIPE must be a valid recipe name')
382
383 files = dict((f, os.path.join(args.destdir, os.path.basename(f)))
384 for f in args.files)
385 return appendsrc(args, files, recipedata)
386
387
388def appendsrcfile(parser, args):
389 recipedata = _parse_recipe(args.recipe, tinfoil)
390 if not recipedata:
391 parser.error('RECIPE must be a valid recipe name')
392
393 if not args.destfile:
394 args.destfile = os.path.basename(args.file)
395 elif args.destfile.endswith('/'):
396 args.destfile = os.path.join(args.destfile, os.path.basename(args.file))
397
398 return appendsrc(args, {args.file: args.destfile}, recipedata)
399
400
337def layer(layerpath): 401def layer(layerpath):
338 if not os.path.exists(os.path.join(layerpath, 'conf', 'layer.conf')): 402 if not os.path.exists(os.path.join(layerpath, 'conf', 'layer.conf')):
339 raise argparse.ArgumentTypeError('{0!r} must be a path to a valid layer'.format(layerpath)) 403 raise argparse.ArgumentTypeError('{0!r} must be a path to a valid layer'.format(layerpath))
340 return layerpath 404 return layerpath
341 405
342 406
343def existing_file(filepath): 407def existing_path(filepath):
344 if not os.path.exists(filepath): 408 if not os.path.exists(filepath):
345 raise argparse.ArgumentTypeError('{0!r} must be an existing path'.format(filepath)) 409 raise argparse.ArgumentTypeError('{0!r} must be an existing path'.format(filepath))
346 elif os.path.isdir(filepath): 410 return filepath
411
412
413def existing_file(filepath):
414 filepath = existing_path(filepath)
415 if os.path.isdir(filepath):
347 raise argparse.ArgumentTypeError('{0!r} must be a file, not a directory'.format(filepath)) 416 raise argparse.ArgumentTypeError('{0!r} must be a file, not a directory'.format(filepath))
348 return filepath 417 return filepath
349 418
350 419
420def destination_path(destpath):
421 if os.path.isabs(destpath):
422 raise argparse.ArgumentTypeError('{0!r} must be a relative path, not absolute'.format(destpath))
423 return destpath
424
425
351def target_path(targetpath): 426def target_path(targetpath):
352 if not os.path.isabs(targetpath): 427 if not os.path.isabs(targetpath):
353 raise argparse.ArgumentTypeError('{0!r} must be an absolute path, not relative'.format(targetpath)) 428 raise argparse.ArgumentTypeError('{0!r} must be an absolute path, not relative'.format(targetpath))
@@ -355,13 +430,36 @@ def target_path(targetpath):
355 430
356 431
357def register_command(subparsers): 432def register_command(subparsers):
433 common = argparse.ArgumentParser(add_help=False)
434 common.add_argument('-m', '--machine', help='Make bbappend changes specific to a machine only', metavar='MACHINE')
435 common.add_argument('-w', '--wildcard-version', help='Use wildcard to make the bbappend apply to any recipe version', action='store_true')
436 common.add_argument('destlayer', metavar='DESTLAYER', help='Base directory of the destination layer to write the bbappend to', type=layer)
437
358 parser_appendfile = subparsers.add_parser('appendfile', 438 parser_appendfile = subparsers.add_parser('appendfile',
359 help='Create/update a bbappend to replace a file', 439 parents=[common],
440 help='Create/update a bbappend to replace a target file',
360 description='Creates a bbappend (or updates an existing one) to replace the specified file that appears in the target system, determining the recipe that packages the file and the required path and name for the bbappend automatically. Note that the ability to determine the recipe packaging a particular file depends upon the recipe\'s do_packagedata task having already run prior to running this command (which it will have when the recipe has been built successfully, which in turn will have happened if one or more of the recipe\'s packages is included in an image that has been built successfully).') 441 description='Creates a bbappend (or updates an existing one) to replace the specified file that appears in the target system, determining the recipe that packages the file and the required path and name for the bbappend automatically. Note that the ability to determine the recipe packaging a particular file depends upon the recipe\'s do_packagedata task having already run prior to running this command (which it will have when the recipe has been built successfully, which in turn will have happened if one or more of the recipe\'s packages is included in an image that has been built successfully).')
361 parser_appendfile.add_argument('destlayer', help='Base directory of the destination layer to write the bbappend to', type=layer)
362 parser_appendfile.add_argument('targetpath', help='Path to the file to be replaced (as it would appear within the target image, e.g. /etc/motd)', type=target_path) 442 parser_appendfile.add_argument('targetpath', help='Path to the file to be replaced (as it would appear within the target image, e.g. /etc/motd)', type=target_path)
363 parser_appendfile.add_argument('newfile', help='Custom file to replace the target file with', type=existing_file) 443 parser_appendfile.add_argument('newfile', help='Custom file to replace the target file with', type=existing_file)
364 parser_appendfile.add_argument('-r', '--recipe', help='Override recipe to apply to (default is to find which recipe already packages the file)') 444 parser_appendfile.add_argument('-r', '--recipe', help='Override recipe to apply to (default is to find which recipe already packages the file)')
365 parser_appendfile.add_argument('-m', '--machine', help='Make bbappend changes specific to a machine only', metavar='MACHINE')
366 parser_appendfile.add_argument('-w', '--wildcard-version', help='Use wildcard to make the bbappend apply to any recipe version', action='store_true')
367 parser_appendfile.set_defaults(func=appendfile, parserecipes=True) 445 parser_appendfile.set_defaults(func=appendfile, parserecipes=True)
446
447 common_src = argparse.ArgumentParser(add_help=False, parents=[common])
448 common_src.add_argument('-W', '--workdir', help='Unpack file into WORKDIR rather than S', dest='use_workdir', action='store_true')
449 common_src.add_argument('recipe', metavar='RECIPE', help='Override recipe to apply to')
450
451 parser = subparsers.add_parser('appendsrcfiles',
452 parents=[common_src],
453 help='Create/update a bbappend to add or replace source files',
454 description='Creates a bbappend (or updates an existing one) to add or replace the specified file in the recipe sources, either those in WORKDIR or those in the source tree. This command lets you specify multiple files with a destination directory, so cannot specify the destination filename. See the `appendsrcfile` command for the other behavior.')
455 parser.add_argument('-d', '--destdir', help='Destination directory (relative to S or WORKDIR, defaults to ".")', default='', type=destination_path)
456 parser.add_argument('files', nargs='+', metavar='FILE', help='File(s) to be added to the recipe sources (WORKDIR or S)', type=existing_path)
457 parser.set_defaults(func=lambda a: appendsrcfiles(parser, a), parserecipes=True)
458
459 parser = subparsers.add_parser('appendsrcfile',
460 parents=[common_src],
461 help='Create/update a bbappend to add or replace a source file',
462 description='Creates a bbappend (or updates an existing one) to add or replace the specified files in the recipe sources, either those in WORKDIR or those in the source tree. This command lets you specify the destination filename, not just destination directory, but only works for one file. See the `appendsrcfiles` command for the other behavior.')
463 parser.add_argument('file', metavar='FILE', help='File to be added to the recipe sources (WORKDIR or S)', type=existing_path)
464 parser.add_argument('destfile', metavar='DESTFILE', nargs='?', help='Destination path (relative to S or WORKDIR, optional)', type=destination_path)
465 parser.set_defaults(func=lambda a: appendsrcfile(parser, a), parserecipes=True)