diff options
Diffstat (limited to 'scripts/lib/recipetool/append.py')
-rw-r--r-- | scripts/lib/recipetool/append.py | 84 |
1 files changed, 57 insertions, 27 deletions
diff --git a/scripts/lib/recipetool/append.py b/scripts/lib/recipetool/append.py index e9d52bb67b..10945d6008 100644 --- a/scripts/lib/recipetool/append.py +++ b/scripts/lib/recipetool/append.py | |||
@@ -18,6 +18,7 @@ import shutil | |||
18 | import scriptutils | 18 | import scriptutils |
19 | import errno | 19 | import errno |
20 | from collections import defaultdict | 20 | from collections import defaultdict |
21 | import difflib | ||
21 | 22 | ||
22 | logger = logging.getLogger('recipetool') | 23 | logger = logging.getLogger('recipetool') |
23 | 24 | ||
@@ -49,7 +50,7 @@ def find_target_file(targetpath, d, pkglist=None): | |||
49 | '/etc/group': '/etc/group should be managed through the useradd and extrausers classes', | 50 | '/etc/group': '/etc/group should be managed through the useradd and extrausers classes', |
50 | '/etc/shadow': '/etc/shadow should be managed through the useradd and extrausers classes', | 51 | '/etc/shadow': '/etc/shadow should be managed through the useradd and extrausers classes', |
51 | '/etc/gshadow': '/etc/gshadow should be managed through the useradd and extrausers classes', | 52 | '/etc/gshadow': '/etc/gshadow should be managed through the useradd and extrausers classes', |
52 | '${sysconfdir}/hostname': '${sysconfdir}/hostname contents should be set by setting hostname_pn-base-files = "value" in configuration',} | 53 | '${sysconfdir}/hostname': '${sysconfdir}/hostname contents should be set by setting hostname:pn-base-files = "value" in configuration',} |
53 | 54 | ||
54 | for pthspec, message in invalidtargets.items(): | 55 | for pthspec, message in invalidtargets.items(): |
55 | if fnmatch.fnmatchcase(targetpath, d.expand(pthspec)): | 56 | if fnmatch.fnmatchcase(targetpath, d.expand(pthspec)): |
@@ -72,15 +73,15 @@ def find_target_file(targetpath, d, pkglist=None): | |||
72 | # This does assume that PN comes before other values, but that's a fairly safe assumption | 73 | # This does assume that PN comes before other values, but that's a fairly safe assumption |
73 | for line in f: | 74 | for line in f: |
74 | if line.startswith('PN:'): | 75 | if line.startswith('PN:'): |
75 | pn = line.split(':', 1)[1].strip() | 76 | pn = line.split(': ', 1)[1].strip() |
76 | elif line.startswith('FILES_INFO:'): | 77 | elif line.startswith('FILES_INFO'): |
77 | val = line.split(':', 1)[1].strip() | 78 | val = line.split(': ', 1)[1].strip() |
78 | dictval = json.loads(val) | 79 | dictval = json.loads(val) |
79 | for fullpth in dictval.keys(): | 80 | for fullpth in dictval.keys(): |
80 | if fnmatch.fnmatchcase(fullpth, targetpath): | 81 | if fnmatch.fnmatchcase(fullpth, targetpath): |
81 | recipes[targetpath].append(pn) | 82 | recipes[targetpath].append(pn) |
82 | elif line.startswith('pkg_preinst_') or line.startswith('pkg_postinst_'): | 83 | elif line.startswith('pkg_preinst:') or line.startswith('pkg_postinst:'): |
83 | scriptval = line.split(':', 1)[1].strip().encode('utf-8').decode('unicode_escape') | 84 | scriptval = line.split(': ', 1)[1].strip().encode('utf-8').decode('unicode_escape') |
84 | if 'update-alternatives --install %s ' % targetpath in scriptval: | 85 | if 'update-alternatives --install %s ' % targetpath in scriptval: |
85 | recipes[targetpath].append('?%s' % pn) | 86 | recipes[targetpath].append('?%s' % pn) |
86 | elif targetpath_re.search(scriptval): | 87 | elif targetpath_re.search(scriptval): |
@@ -100,7 +101,7 @@ def determine_file_source(targetpath, rd): | |||
100 | import oe.recipeutils | 101 | import oe.recipeutils |
101 | 102 | ||
102 | # See if it's in do_install for the recipe | 103 | # See if it's in do_install for the recipe |
103 | workdir = rd.getVar('WORKDIR') | 104 | unpackdir = rd.getVar('UNPACKDIR') |
104 | src_uri = rd.getVar('SRC_URI') | 105 | src_uri = rd.getVar('SRC_URI') |
105 | srcfile = '' | 106 | srcfile = '' |
106 | modpatches = [] | 107 | modpatches = [] |
@@ -112,9 +113,9 @@ def determine_file_source(targetpath, rd): | |||
112 | if not srcpath.startswith('/'): | 113 | if not srcpath.startswith('/'): |
113 | # Handle non-absolute path | 114 | # Handle non-absolute path |
114 | srcpath = os.path.abspath(os.path.join(rd.getVarFlag('do_install', 'dirs').split()[-1], srcpath)) | 115 | srcpath = os.path.abspath(os.path.join(rd.getVarFlag('do_install', 'dirs').split()[-1], srcpath)) |
115 | if srcpath.startswith(workdir): | 116 | if srcpath.startswith(unpackdir): |
116 | # OK, now we have the source file name, look for it in SRC_URI | 117 | # OK, now we have the source file name, look for it in SRC_URI |
117 | workdirfile = os.path.relpath(srcpath, workdir) | 118 | workdirfile = os.path.relpath(srcpath, unpackdir) |
118 | # FIXME this is where we ought to have some code in the fetcher, because this is naive | 119 | # FIXME this is where we ought to have some code in the fetcher, because this is naive |
119 | for item in src_uri.split(): | 120 | for item in src_uri.split(): |
120 | localpath = bb.fetch2.localpath(item, rd) | 121 | localpath = bb.fetch2.localpath(item, rd) |
@@ -299,7 +300,10 @@ def appendfile(args): | |||
299 | if st.st_mode & stat.S_IXUSR: | 300 | if st.st_mode & stat.S_IXUSR: |
300 | perms = '0755' | 301 | perms = '0755' |
301 | install = {args.newfile: (args.targetpath, perms)} | 302 | install = {args.newfile: (args.targetpath, perms)} |
302 | oe.recipeutils.bbappend_recipe(rd, args.destlayer, {args.newfile: sourcepath}, install, wildcardver=args.wildcard_version, machine=args.machine) | 303 | if sourcepath: |
304 | sourcepath = os.path.basename(sourcepath) | ||
305 | oe.recipeutils.bbappend_recipe(rd, args.destlayer, {args.newfile: {'newname' : sourcepath}}, install, wildcardver=args.wildcard_version, machine=args.machine) | ||
306 | tinfoil.modified_files() | ||
303 | return 0 | 307 | return 0 |
304 | else: | 308 | else: |
305 | if alternative_pns: | 309 | if alternative_pns: |
@@ -327,6 +331,7 @@ def appendsrc(args, files, rd, extralines=None): | |||
327 | 331 | ||
328 | copyfiles = {} | 332 | copyfiles = {} |
329 | extralines = extralines or [] | 333 | extralines = extralines or [] |
334 | params = [] | ||
330 | for newfile, srcfile in files.items(): | 335 | for newfile, srcfile in files.items(): |
331 | src_destdir = os.path.dirname(srcfile) | 336 | src_destdir = os.path.dirname(srcfile) |
332 | if not args.use_workdir: | 337 | if not args.use_workdir: |
@@ -337,25 +342,46 @@ def appendsrc(args, files, rd, extralines=None): | |||
337 | src_destdir = os.path.join(os.path.relpath(srcdir, workdir), src_destdir) | 342 | src_destdir = os.path.join(os.path.relpath(srcdir, workdir), src_destdir) |
338 | src_destdir = os.path.normpath(src_destdir) | 343 | src_destdir = os.path.normpath(src_destdir) |
339 | 344 | ||
340 | source_uri = 'file://{0}'.format(os.path.basename(srcfile)) | ||
341 | if src_destdir and src_destdir != '.': | 345 | if src_destdir and src_destdir != '.': |
342 | source_uri += ';subdir={0}'.format(src_destdir) | 346 | params.append({'subdir': src_destdir}) |
343 | |||
344 | simple = bb.fetch.URI(source_uri) | ||
345 | simple.params = {} | ||
346 | simple_str = str(simple) | ||
347 | if simple_str in simplified: | ||
348 | existing = simplified[simple_str] | ||
349 | if source_uri != existing: | ||
350 | logger.warning('{0!r} is already in SRC_URI, with different parameters: {1!r}, not adding'.format(source_uri, existing)) | ||
351 | else: | ||
352 | logger.warning('{0!r} is already in SRC_URI, not adding'.format(source_uri)) | ||
353 | else: | 347 | else: |
354 | extralines.append('SRC_URI += {0}'.format(source_uri)) | 348 | params.append({}) |
355 | copyfiles[newfile] = srcfile | 349 | |
356 | 350 | copyfiles[newfile] = {'newname' : os.path.basename(srcfile)} | |
357 | oe.recipeutils.bbappend_recipe(rd, args.destlayer, copyfiles, None, wildcardver=args.wildcard_version, machine=args.machine, extralines=extralines) | 351 | |
358 | 352 | dry_run_output = None | |
353 | dry_run_outdir = None | ||
354 | if args.dry_run: | ||
355 | import tempfile | ||
356 | dry_run_output = tempfile.TemporaryDirectory(prefix='devtool') | ||
357 | dry_run_outdir = dry_run_output.name | ||
358 | |||
359 | appendfile, _ = oe.recipeutils.bbappend_recipe(rd, args.destlayer, copyfiles, None, wildcardver=args.wildcard_version, machine=args.machine, extralines=extralines, params=params, | ||
360 | redirect_output=dry_run_outdir, update_original_recipe=args.update_recipe) | ||
361 | if not appendfile: | ||
362 | return | ||
363 | if args.dry_run: | ||
364 | output = '' | ||
365 | appendfilename = os.path.basename(appendfile) | ||
366 | newappendfile = appendfile | ||
367 | if appendfile and os.path.exists(appendfile): | ||
368 | with open(appendfile, 'r') as f: | ||
369 | oldlines = f.readlines() | ||
370 | else: | ||
371 | appendfile = '/dev/null' | ||
372 | oldlines = [] | ||
373 | |||
374 | with open(os.path.join(dry_run_outdir, appendfilename), 'r') as f: | ||
375 | newlines = f.readlines() | ||
376 | diff = difflib.unified_diff(oldlines, newlines, appendfile, newappendfile) | ||
377 | difflines = list(diff) | ||
378 | if difflines: | ||
379 | output += ''.join(difflines) | ||
380 | if output: | ||
381 | logger.info('Diff of changed files:\n%s' % output) | ||
382 | else: | ||
383 | logger.info('No changed files') | ||
384 | tinfoil.modified_files() | ||
359 | 385 | ||
360 | def appendsrcfiles(parser, args): | 386 | def appendsrcfiles(parser, args): |
361 | recipedata = _parse_recipe(args.recipe, tinfoil) | 387 | recipedata = _parse_recipe(args.recipe, tinfoil) |
@@ -435,6 +461,8 @@ def register_commands(subparsers): | |||
435 | help='Create/update a bbappend to add or replace source files', | 461 | help='Create/update a bbappend to add or replace source files', |
436 | 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.') | 462 | 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.') |
437 | parser.add_argument('-D', '--destdir', help='Destination directory (relative to S or WORKDIR, defaults to ".")', default='', type=destination_path) | 463 | parser.add_argument('-D', '--destdir', help='Destination directory (relative to S or WORKDIR, defaults to ".")', default='', type=destination_path) |
464 | parser.add_argument('-u', '--update-recipe', help='Update recipe instead of creating (or updating) a bbapend file. DESTLAYER must contains the recipe to update', action='store_true') | ||
465 | parser.add_argument('-n', '--dry-run', help='Dry run mode', action='store_true') | ||
438 | parser.add_argument('files', nargs='+', metavar='FILE', help='File(s) to be added to the recipe sources (WORKDIR or S)', type=existing_path) | 466 | parser.add_argument('files', nargs='+', metavar='FILE', help='File(s) to be added to the recipe sources (WORKDIR or S)', type=existing_path) |
439 | parser.set_defaults(func=lambda a: appendsrcfiles(parser, a), parserecipes=True) | 467 | parser.set_defaults(func=lambda a: appendsrcfiles(parser, a), parserecipes=True) |
440 | 468 | ||
@@ -442,6 +470,8 @@ def register_commands(subparsers): | |||
442 | parents=[common_src], | 470 | parents=[common_src], |
443 | help='Create/update a bbappend to add or replace a source file', | 471 | help='Create/update a bbappend to add or replace a source file', |
444 | 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.') | 472 | 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.') |
473 | parser.add_argument('-u', '--update-recipe', help='Update recipe instead of creating (or updating) a bbapend file. DESTLAYER must contains the recipe to update', action='store_true') | ||
474 | parser.add_argument('-n', '--dry-run', help='Dry run mode', action='store_true') | ||
445 | parser.add_argument('file', metavar='FILE', help='File to be added to the recipe sources (WORKDIR or S)', type=existing_path) | 475 | parser.add_argument('file', metavar='FILE', help='File to be added to the recipe sources (WORKDIR or S)', type=existing_path) |
446 | parser.add_argument('destfile', metavar='DESTFILE', nargs='?', help='Destination path (relative to S or WORKDIR, optional)', type=destination_path) | 476 | parser.add_argument('destfile', metavar='DESTFILE', nargs='?', help='Destination path (relative to S or WORKDIR, optional)', type=destination_path) |
447 | parser.set_defaults(func=lambda a: appendsrcfile(parser, a), parserecipes=True) | 477 | parser.set_defaults(func=lambda a: appendsrcfile(parser, a), parserecipes=True) |