summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-11-20 17:11:16 +1300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-12-07 17:01:21 +0000
commit4de214f7529c1d9600dd2c0723d33d7241b3e0c8 (patch)
treecd16b5c216760c7992e11b60aee88665017a0096 /bitbake/lib/bb
parent0debb11883379c746f91eb8a5262f22a669fd16b (diff)
downloadpoky-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.py203
-rw-r--r--bitbake/lib/bb/utils.py78
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
381class 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
402BBPATH = "${TOPDIR}"
403BBFILES ?= ""
404BBLAYERS = " \
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
414BBPATH = "${TOPDIR}"
415BBFILES ?= ""
416BBLAYERS = " \
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
433BBPATH = "${TOPDIR}"
434BBFILES ?= ""
435BBLAYERS = " \
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
445BBPATH = "${TOPDIR}"
446BBFILES ?= ""
447BBLAYERS = " \
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
466BBPATH = "${TOPDIR}"
467BBFILES ?= ""
468BBLAYERS = " \
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
478BBPATH = "${TOPDIR}"
479BBFILES ?= ""
480BBLAYERS = " \
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
497BBPATH = "${TOPDIR}"
498BBFILES ?= ""
499BBLAYERS = " \
500 ~/path/layer1 \
501 ~/path/layer2 \
502 ~/otherpath/layer3 \
503 ~/path/layer4 \
504 "
505"""
506 after = r"""
507# A comment
508
509BBPATH = "${TOPDIR}"
510BBFILES ?= ""
511BBLAYERS = " \
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
528BBPATH = "${TOPDIR}"
529BBFILES ?= ""
530BBLAYERS += " \
531 /home/user/path/layer1 \
532 /home/user/path/layer2 \
533 "
534"""
535 after = r"""
536# A comment
537
538BBPATH = "${TOPDIR}"
539BBFILES ?= ""
540BBLAYERS += " \
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
556BBPATH = "${TOPDIR}"
557BBFILES ?= ""
558BBLAYERS += " \
559 /home/user/path/layer1 \
560 /home/user/path/layer2 \
561 /home/user/path/layer3 \
562 "
563BBLAYERS += "/home/user/path/layer4"
564BBLAYERS += "/home/user/path/layer5"
565"""
566 after = r"""
567# A comment
568
569BBPATH = "${TOPDIR}"
570BBFILES ?= ""
571BBLAYERS += " \
572 /home/user/path/layer2 \
573 /home/user/path/layer3 \
574 "
575BBLAYERS += "/home/user/path/layer5"
576BBLAYERS += "/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
1203def edit_bblayers_conf(bblayers_conf, add, remove): 1203def 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