diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2015-11-20 17:11:16 +1300 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-12-07 17:01:21 +0000 |
commit | 4de214f7529c1d9600dd2c0723d33d7241b3e0c8 (patch) | |
tree | cd16b5c216760c7992e11b60aee88665017a0096 /bitbake/lib/bb | |
parent | 0debb11883379c746f91eb8a5262f22a669fd16b (diff) | |
download | poky-4de214f7529c1d9600dd2c0723d33d7241b3e0c8.tar.gz |
bitbake: lib/bb/utils: improve edit_bblayers_conf() handling of bblayers.conf formatting
Make the following improvements to edit_bblayers_conf():
* Support ~ in BBLAYERS entries
* Handle where BBLAYERS items are added over multiple lines with +=
instead of one single long item
Also add some comments documenting the function arguments and return
values as well as a set of bitbake-selftest tests.
(This function is used by the bitbake-layers add, remove and
layerindex-fetch subcommands, as well as devtool when adding the
workspace layer).
(Bitbake rev: e9a0858023c7671e30cc8ebb08496304b7f26b31)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb')
-rw-r--r-- | bitbake/lib/bb/tests/utils.py | 203 | ||||
-rw-r--r-- | bitbake/lib/bb/utils.py | 78 |
2 files changed, 267 insertions, 14 deletions
diff --git a/bitbake/lib/bb/tests/utils.py b/bitbake/lib/bb/tests/utils.py index 9171509a62..a035ccf179 100644 --- a/bitbake/lib/bb/tests/utils.py +++ b/bitbake/lib/bb/tests/utils.py | |||
@@ -376,3 +376,206 @@ do_functionname() { | |||
376 | (updated, newlines) = bb.utils.edit_metadata(self._origfile.splitlines(True), varlist, handle_var) | 376 | (updated, newlines) = bb.utils.edit_metadata(self._origfile.splitlines(True), varlist, handle_var) |
377 | self.assertTrue(updated, 'List should be updated but isn\'t') | 377 | self.assertTrue(updated, 'List should be updated but isn\'t') |
378 | self.assertEqual(newlines, newfile5.splitlines(True)) | 378 | self.assertEqual(newlines, newfile5.splitlines(True)) |
379 | |||
380 | |||
381 | class EditBbLayersConf(unittest.TestCase): | ||
382 | |||
383 | def _test_bblayers_edit(self, before, after, add, remove, notadded, notremoved): | ||
384 | with tempfile.NamedTemporaryFile('w', delete=False) as tf: | ||
385 | tf.write(before) | ||
386 | tf.close() | ||
387 | try: | ||
388 | actual_notadded, actual_notremoved = bb.utils.edit_bblayers_conf(tf.name, add, remove) | ||
389 | with open(tf.name) as f: | ||
390 | actual_after = f.readlines() | ||
391 | self.assertEqual(after.splitlines(True), actual_after) | ||
392 | self.assertEqual(notadded, actual_notadded) | ||
393 | self.assertEqual(notremoved, actual_notremoved) | ||
394 | finally: | ||
395 | os.remove(tf.name) | ||
396 | |||
397 | |||
398 | def test_bblayers_remove(self): | ||
399 | before = r""" | ||
400 | # A comment | ||
401 | |||
402 | BBPATH = "${TOPDIR}" | ||
403 | BBFILES ?= "" | ||
404 | BBLAYERS = " \ | ||
405 | /home/user/path/layer1 \ | ||
406 | /home/user/path/layer2 \ | ||
407 | /home/user/path/subpath/layer3 \ | ||
408 | /home/user/path/layer4 \ | ||
409 | " | ||
410 | """ | ||
411 | after = r""" | ||
412 | # A comment | ||
413 | |||
414 | BBPATH = "${TOPDIR}" | ||
415 | BBFILES ?= "" | ||
416 | BBLAYERS = " \ | ||
417 | /home/user/path/layer1 \ | ||
418 | /home/user/path/subpath/layer3 \ | ||
419 | /home/user/path/layer4 \ | ||
420 | " | ||
421 | """ | ||
422 | self._test_bblayers_edit(before, after, | ||
423 | None, | ||
424 | '/home/user/path/layer2', | ||
425 | [], | ||
426 | []) | ||
427 | |||
428 | |||
429 | def test_bblayers_add(self): | ||
430 | before = r""" | ||
431 | # A comment | ||
432 | |||
433 | BBPATH = "${TOPDIR}" | ||
434 | BBFILES ?= "" | ||
435 | BBLAYERS = " \ | ||
436 | /home/user/path/layer1 \ | ||
437 | /home/user/path/layer2 \ | ||
438 | /home/user/path/subpath/layer3 \ | ||
439 | /home/user/path/layer4 \ | ||
440 | " | ||
441 | """ | ||
442 | after = r""" | ||
443 | # A comment | ||
444 | |||
445 | BBPATH = "${TOPDIR}" | ||
446 | BBFILES ?= "" | ||
447 | BBLAYERS = " \ | ||
448 | /home/user/path/layer1 \ | ||
449 | /home/user/path/layer2 \ | ||
450 | /home/user/path/subpath/layer3 \ | ||
451 | /home/user/path/layer4 \ | ||
452 | /other/path/to/layer5 \ | ||
453 | " | ||
454 | """ | ||
455 | self._test_bblayers_edit(before, after, | ||
456 | '/other/path/to/layer5/', | ||
457 | None, | ||
458 | [], | ||
459 | []) | ||
460 | |||
461 | |||
462 | def test_bblayers_add_remove(self): | ||
463 | before = r""" | ||
464 | # A comment | ||
465 | |||
466 | BBPATH = "${TOPDIR}" | ||
467 | BBFILES ?= "" | ||
468 | BBLAYERS = " \ | ||
469 | /home/user/path/layer1 \ | ||
470 | /home/user/path/layer2 \ | ||
471 | /home/user/path/subpath/layer3 \ | ||
472 | /home/user/path/layer4 \ | ||
473 | " | ||
474 | """ | ||
475 | after = r""" | ||
476 | # A comment | ||
477 | |||
478 | BBPATH = "${TOPDIR}" | ||
479 | BBFILES ?= "" | ||
480 | BBLAYERS = " \ | ||
481 | /home/user/path/layer1 \ | ||
482 | /home/user/path/layer2 \ | ||
483 | /home/user/path/layer4 \ | ||
484 | /other/path/to/layer5 \ | ||
485 | " | ||
486 | """ | ||
487 | self._test_bblayers_edit(before, after, | ||
488 | ['/other/path/to/layer5', '/home/user/path/layer2/'], '/home/user/path/subpath/layer3/', | ||
489 | ['/home/user/path/layer2'], | ||
490 | []) | ||
491 | |||
492 | |||
493 | def test_bblayers_add_remove_home(self): | ||
494 | before = r""" | ||
495 | # A comment | ||
496 | |||
497 | BBPATH = "${TOPDIR}" | ||
498 | BBFILES ?= "" | ||
499 | BBLAYERS = " \ | ||
500 | ~/path/layer1 \ | ||
501 | ~/path/layer2 \ | ||
502 | ~/otherpath/layer3 \ | ||
503 | ~/path/layer4 \ | ||
504 | " | ||
505 | """ | ||
506 | after = r""" | ||
507 | # A comment | ||
508 | |||
509 | BBPATH = "${TOPDIR}" | ||
510 | BBFILES ?= "" | ||
511 | BBLAYERS = " \ | ||
512 | ~/path/layer2 \ | ||
513 | ~/path/layer4 \ | ||
514 | ~/path2/layer5 \ | ||
515 | " | ||
516 | """ | ||
517 | self._test_bblayers_edit(before, after, | ||
518 | [os.environ['HOME'] + '/path/layer4', '~/path2/layer5'], | ||
519 | [os.environ['HOME'] + '/otherpath/layer3', '~/path/layer1', '~/path/notinlist'], | ||
520 | [os.environ['HOME'] + '/path/layer4'], | ||
521 | ['~/path/notinlist']) | ||
522 | |||
523 | |||
524 | def test_bblayers_add_remove_plusequals(self): | ||
525 | before = r""" | ||
526 | # A comment | ||
527 | |||
528 | BBPATH = "${TOPDIR}" | ||
529 | BBFILES ?= "" | ||
530 | BBLAYERS += " \ | ||
531 | /home/user/path/layer1 \ | ||
532 | /home/user/path/layer2 \ | ||
533 | " | ||
534 | """ | ||
535 | after = r""" | ||
536 | # A comment | ||
537 | |||
538 | BBPATH = "${TOPDIR}" | ||
539 | BBFILES ?= "" | ||
540 | BBLAYERS += " \ | ||
541 | /home/user/path/layer2 \ | ||
542 | /home/user/path/layer3 \ | ||
543 | " | ||
544 | """ | ||
545 | self._test_bblayers_edit(before, after, | ||
546 | '/home/user/path/layer3', | ||
547 | '/home/user/path/layer1', | ||
548 | [], | ||
549 | []) | ||
550 | |||
551 | |||
552 | def test_bblayers_add_remove_plusequals2(self): | ||
553 | before = r""" | ||
554 | # A comment | ||
555 | |||
556 | BBPATH = "${TOPDIR}" | ||
557 | BBFILES ?= "" | ||
558 | BBLAYERS += " \ | ||
559 | /home/user/path/layer1 \ | ||
560 | /home/user/path/layer2 \ | ||
561 | /home/user/path/layer3 \ | ||
562 | " | ||
563 | BBLAYERS += "/home/user/path/layer4" | ||
564 | BBLAYERS += "/home/user/path/layer5" | ||
565 | """ | ||
566 | after = r""" | ||
567 | # A comment | ||
568 | |||
569 | BBPATH = "${TOPDIR}" | ||
570 | BBFILES ?= "" | ||
571 | BBLAYERS += " \ | ||
572 | /home/user/path/layer2 \ | ||
573 | /home/user/path/layer3 \ | ||
574 | " | ||
575 | BBLAYERS += "/home/user/path/layer5" | ||
576 | BBLAYERS += "/home/user/otherpath/layer6" | ||
577 | """ | ||
578 | self._test_bblayers_edit(before, after, | ||
579 | ['/home/user/otherpath/layer6', '/home/user/path/layer3'], ['/home/user/path/layer1', '/home/user/path/layer4', '/home/user/path/layer7'], | ||
580 | ['/home/user/path/layer3'], | ||
581 | ['/home/user/path/layer7']) | ||
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index 9b28952231..31ec2b7c9a 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py | |||
@@ -1201,7 +1201,19 @@ def edit_metadata_file(meta_file, variables, varfunc): | |||
1201 | 1201 | ||
1202 | 1202 | ||
1203 | def edit_bblayers_conf(bblayers_conf, add, remove): | 1203 | def edit_bblayers_conf(bblayers_conf, add, remove): |
1204 | """Edit bblayers.conf, adding and/or removing layers""" | 1204 | """Edit bblayers.conf, adding and/or removing layers |
1205 | Parameters: | ||
1206 | bblayers_conf: path to bblayers.conf file to edit | ||
1207 | add: layer path (or list of layer paths) to add; None or empty | ||
1208 | list to add nothing | ||
1209 | remove: layer path (or list of layer paths) to remove; None or | ||
1210 | empty list to remove nothing | ||
1211 | Returns a tuple: | ||
1212 | notadded: list of layers specified to be added but weren't | ||
1213 | (because they were already in the list) | ||
1214 | notremoved: list of layers that were specified to be removed | ||
1215 | but weren't (because they weren't in the list) | ||
1216 | """ | ||
1205 | 1217 | ||
1206 | import fnmatch | 1218 | import fnmatch |
1207 | 1219 | ||
@@ -1210,6 +1222,13 @@ def edit_bblayers_conf(bblayers_conf, add, remove): | |||
1210 | pth = pth[:-1] | 1222 | pth = pth[:-1] |
1211 | return pth | 1223 | return pth |
1212 | 1224 | ||
1225 | approved = bb.utils.approved_variables() | ||
1226 | def canonicalise_path(pth): | ||
1227 | pth = remove_trailing_sep(pth) | ||
1228 | if 'HOME' in approved and '~' in pth: | ||
1229 | pth = os.path.expanduser(pth) | ||
1230 | return pth | ||
1231 | |||
1213 | def layerlist_param(value): | 1232 | def layerlist_param(value): |
1214 | if not value: | 1233 | if not value: |
1215 | return [] | 1234 | return [] |
@@ -1218,49 +1237,80 @@ def edit_bblayers_conf(bblayers_conf, add, remove): | |||
1218 | else: | 1237 | else: |
1219 | return [remove_trailing_sep(value)] | 1238 | return [remove_trailing_sep(value)] |
1220 | 1239 | ||
1221 | notadded = [] | ||
1222 | notremoved = [] | ||
1223 | |||
1224 | addlayers = layerlist_param(add) | 1240 | addlayers = layerlist_param(add) |
1225 | removelayers = layerlist_param(remove) | 1241 | removelayers = layerlist_param(remove) |
1226 | 1242 | ||
1227 | # Need to use a list here because we can't set non-local variables from a callback in python 2.x | 1243 | # Need to use a list here because we can't set non-local variables from a callback in python 2.x |
1228 | bblayercalls = [] | 1244 | bblayercalls = [] |
1245 | removed = [] | ||
1246 | plusequals = False | ||
1247 | orig_bblayers = [] | ||
1248 | |||
1249 | def handle_bblayers_firstpass(varname, origvalue, op, newlines): | ||
1250 | bblayercalls.append(op) | ||
1251 | if op == '=': | ||
1252 | del orig_bblayers[:] | ||
1253 | orig_bblayers.extend([canonicalise_path(x) for x in origvalue.split()]) | ||
1254 | return (origvalue, None, 2, False) | ||
1229 | 1255 | ||
1230 | def handle_bblayers(varname, origvalue, op, newlines): | 1256 | def handle_bblayers(varname, origvalue, op, newlines): |
1231 | bblayercalls.append(varname) | ||
1232 | updated = False | 1257 | updated = False |
1233 | bblayers = [remove_trailing_sep(x) for x in origvalue.split()] | 1258 | bblayers = [remove_trailing_sep(x) for x in origvalue.split()] |
1234 | if removelayers: | 1259 | if removelayers: |
1235 | for removelayer in removelayers: | 1260 | for removelayer in removelayers: |
1236 | matched = False | ||
1237 | for layer in bblayers: | 1261 | for layer in bblayers: |
1238 | if fnmatch.fnmatch(layer, removelayer): | 1262 | if fnmatch.fnmatch(canonicalise_path(layer), canonicalise_path(removelayer)): |
1239 | updated = True | 1263 | updated = True |
1240 | matched = True | ||
1241 | bblayers.remove(layer) | 1264 | bblayers.remove(layer) |
1265 | removed.append(removelayer) | ||
1242 | break | 1266 | break |
1243 | if not matched: | 1267 | if addlayers and not plusequals: |
1244 | notremoved.append(removelayer) | ||
1245 | if addlayers: | ||
1246 | for addlayer in addlayers: | 1268 | for addlayer in addlayers: |
1247 | if addlayer not in bblayers: | 1269 | if addlayer not in bblayers: |
1248 | updated = True | 1270 | updated = True |
1249 | bblayers.append(addlayer) | 1271 | bblayers.append(addlayer) |
1250 | else: | ||
1251 | notadded.append(addlayer) | ||
1252 | del addlayers[:] | 1272 | del addlayers[:] |
1253 | 1273 | ||
1254 | if updated: | 1274 | if updated: |
1275 | if op == '+=' and not bblayers: | ||
1276 | bblayers = None | ||
1255 | return (bblayers, None, 2, False) | 1277 | return (bblayers, None, 2, False) |
1256 | else: | 1278 | else: |
1257 | return (origvalue, None, 2, False) | 1279 | return (origvalue, None, 2, False) |
1258 | 1280 | ||
1259 | edit_metadata_file(bblayers_conf, ['BBLAYERS'], handle_bblayers) | 1281 | with open(bblayers_conf, 'r') as f: |
1282 | (_, newlines) = edit_metadata(f, ['BBLAYERS'], handle_bblayers_firstpass) | ||
1260 | 1283 | ||
1261 | if not bblayercalls: | 1284 | if not bblayercalls: |
1262 | raise Exception('Unable to find BBLAYERS in %s' % bblayers_conf) | 1285 | raise Exception('Unable to find BBLAYERS in %s' % bblayers_conf) |
1263 | 1286 | ||
1287 | # Try to do the "smart" thing depending on how the user has laid out | ||
1288 | # their bblayers.conf file | ||
1289 | if bblayercalls.count('+=') > 1: | ||
1290 | plusequals = True | ||
1291 | |||
1292 | removelayers_canon = [canonicalise_path(layer) for layer in removelayers] | ||
1293 | notadded = [] | ||
1294 | for layer in addlayers: | ||
1295 | layer_canon = canonicalise_path(layer) | ||
1296 | if layer_canon in orig_bblayers and not layer_canon in removelayers_canon: | ||
1297 | notadded.append(layer) | ||
1298 | notadded_canon = [canonicalise_path(layer) for layer in notadded] | ||
1299 | addlayers[:] = [layer for layer in addlayers if canonicalise_path(layer) not in notadded_canon] | ||
1300 | |||
1301 | (updated, newlines) = edit_metadata(newlines, ['BBLAYERS'], handle_bblayers) | ||
1302 | if addlayers: | ||
1303 | # Still need to add these | ||
1304 | for addlayer in addlayers: | ||
1305 | newlines.append('BBLAYERS += "%s"\n' % addlayer) | ||
1306 | updated = True | ||
1307 | |||
1308 | if updated: | ||
1309 | with open(bblayers_conf, 'w') as f: | ||
1310 | f.writelines(newlines) | ||
1311 | |||
1312 | notremoved = list(set(removelayers) - set(removed)) | ||
1313 | |||
1264 | return (notadded, notremoved) | 1314 | return (notadded, notremoved) |
1265 | 1315 | ||
1266 | 1316 | ||