diff options
| -rw-r--r-- | bitbake/lib/bb/command.py | 25 | ||||
| -rw-r--r-- | bitbake/lib/bb/data_smart.py | 29 | ||||
| -rw-r--r-- | bitbake/lib/bb/tests/data.py | 128 | ||||
| -rw-r--r-- | bitbake/lib/bb/tinfoil.py | 30 |
4 files changed, 192 insertions, 20 deletions
diff --git a/bitbake/lib/bb/command.py b/bitbake/lib/bb/command.py index 222a76e580..78a86ac4dc 100644 --- a/bitbake/lib/bb/command.py +++ b/bitbake/lib/bb/command.py | |||
| @@ -505,6 +505,31 @@ class CommandsSync: | |||
| 505 | raise CommandError('dataStoreConnectorRelease: invalid index %d' % dsindex) | 505 | raise CommandError('dataStoreConnectorRelease: invalid index %d' % dsindex) |
| 506 | command.remotedatastores.release(dsindex) | 506 | command.remotedatastores.release(dsindex) |
| 507 | 507 | ||
| 508 | def dataStoreConnectorSetVarFlag(self, command, params): | ||
| 509 | dsindex = params[0] | ||
| 510 | name = params[1] | ||
| 511 | flag = params[2] | ||
| 512 | value = params[3] | ||
| 513 | datastore = command.remotedatastores[dsindex] | ||
| 514 | datastore.setVarFlag(name, flag, value) | ||
| 515 | |||
| 516 | def dataStoreConnectorDelVar(self, command, params): | ||
| 517 | dsindex = params[0] | ||
| 518 | name = params[1] | ||
| 519 | datastore = command.remotedatastores[dsindex] | ||
| 520 | if len(params) > 2: | ||
| 521 | flag = params[2] | ||
| 522 | datastore.delVarFlag(name, flag) | ||
| 523 | else: | ||
| 524 | datastore.delVar(name) | ||
| 525 | |||
| 526 | def dataStoreConnectorRenameVar(self, command, params): | ||
| 527 | dsindex = params[0] | ||
| 528 | name = params[1] | ||
| 529 | newname = params[2] | ||
| 530 | datastore = command.remotedatastores[dsindex] | ||
| 531 | datastore.renameVar(name, newname) | ||
| 532 | |||
| 508 | def parseRecipeFile(self, command, params): | 533 | def parseRecipeFile(self, command, params): |
| 509 | """ | 534 | """ |
| 510 | Parse the specified recipe file (with or without bbappends) | 535 | Parse the specified recipe file (with or without bbappends) |
diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py index 5777d545a8..d6dd698eff 100644 --- a/bitbake/lib/bb/data_smart.py +++ b/bitbake/lib/bb/data_smart.py | |||
| @@ -609,6 +609,12 @@ class DataSmart(MutableMapping): | |||
| 609 | """ | 609 | """ |
| 610 | Rename the variable key to newkey | 610 | Rename the variable key to newkey |
| 611 | """ | 611 | """ |
| 612 | if '_remote_data' in self.dict: | ||
| 613 | connector = self.dict["_remote_data"]["_content"] | ||
| 614 | res = connector.renameVar(key, newkey) | ||
| 615 | if not res: | ||
| 616 | return | ||
| 617 | |||
| 612 | val = self.getVar(key, 0, parsing=True) | 618 | val = self.getVar(key, 0, parsing=True) |
| 613 | if val is not None: | 619 | if val is not None: |
| 614 | loginfo['variable'] = newkey | 620 | loginfo['variable'] = newkey |
| @@ -652,6 +658,12 @@ class DataSmart(MutableMapping): | |||
| 652 | self.setVar(var + "_prepend", value, ignore=True, parsing=True) | 658 | self.setVar(var + "_prepend", value, ignore=True, parsing=True) |
| 653 | 659 | ||
| 654 | def delVar(self, var, **loginfo): | 660 | def delVar(self, var, **loginfo): |
| 661 | if '_remote_data' in self.dict: | ||
| 662 | connector = self.dict["_remote_data"]["_content"] | ||
| 663 | res = connector.delVar(var) | ||
| 664 | if not res: | ||
| 665 | return | ||
| 666 | |||
| 655 | loginfo['detail'] = "" | 667 | loginfo['detail'] = "" |
| 656 | loginfo['op'] = 'del' | 668 | loginfo['op'] = 'del' |
| 657 | self.varhistory.record(**loginfo) | 669 | self.varhistory.record(**loginfo) |
| @@ -678,6 +690,12 @@ class DataSmart(MutableMapping): | |||
| 678 | override = None | 690 | override = None |
| 679 | 691 | ||
| 680 | def setVarFlag(self, var, flag, value, **loginfo): | 692 | def setVarFlag(self, var, flag, value, **loginfo): |
| 693 | if '_remote_data' in self.dict: | ||
| 694 | connector = self.dict["_remote_data"]["_content"] | ||
| 695 | res = connector.setVarFlag(var, flag, value) | ||
| 696 | if not res: | ||
| 697 | return | ||
| 698 | |||
| 681 | self.expand_cache = {} | 699 | self.expand_cache = {} |
| 682 | if 'op' not in loginfo: | 700 | if 'op' not in loginfo: |
| 683 | loginfo['op'] = "set" | 701 | loginfo['op'] = "set" |
| @@ -796,6 +814,12 @@ class DataSmart(MutableMapping): | |||
| 796 | return value | 814 | return value |
| 797 | 815 | ||
| 798 | def delVarFlag(self, var, flag, **loginfo): | 816 | def delVarFlag(self, var, flag, **loginfo): |
| 817 | if '_remote_data' in self.dict: | ||
| 818 | connector = self.dict["_remote_data"]["_content"] | ||
| 819 | res = connector.delVarFlag(var, flag) | ||
| 820 | if not res: | ||
| 821 | return | ||
| 822 | |||
| 799 | self.expand_cache = {} | 823 | self.expand_cache = {} |
| 800 | local_var, _ = self._findVar(var) | 824 | local_var, _ = self._findVar(var) |
| 801 | if not local_var: | 825 | if not local_var: |
| @@ -938,7 +962,10 @@ class DataSmart(MutableMapping): | |||
| 938 | 962 | ||
| 939 | if "_remote_data" in d: | 963 | if "_remote_data" in d: |
| 940 | connector = d["_remote_data"]["_content"] | 964 | connector = d["_remote_data"]["_content"] |
| 941 | klist |= connector.getKeys() | 965 | for key in connector.getKeys(): |
| 966 | if key in deleted: | ||
| 967 | continue | ||
| 968 | klist.add(key) | ||
| 942 | 969 | ||
| 943 | return klist | 970 | return klist |
| 944 | 971 | ||
diff --git a/bitbake/lib/bb/tests/data.py b/bitbake/lib/bb/tests/data.py index da3f4e66f8..fe947f5ba7 100644 --- a/bitbake/lib/bb/tests/data.py +++ b/bitbake/lib/bb/tests/data.py | |||
| @@ -460,26 +460,43 @@ class Serialize(unittest.TestCase): | |||
| 460 | self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet') | 460 | self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet') |
| 461 | 461 | ||
| 462 | 462 | ||
| 463 | # Remote datastore tests | ||
| 464 | # These really only test the interface, since in actual usage we have a | ||
| 465 | # tinfoil connector that does everything over RPC, and this doesn't test | ||
| 466 | # that. | ||
| 467 | |||
| 468 | class TestConnector: | ||
| 469 | d = None | ||
| 470 | def __init__(self, d): | ||
| 471 | self.d = d | ||
| 472 | def getVar(self, name): | ||
| 473 | return self.d._findVar(name) | ||
| 474 | def getKeys(self): | ||
| 475 | return set(self.d.keys()) | ||
| 476 | def getVarHistory(self, name): | ||
| 477 | return self.d.varhistory.variable(name) | ||
| 478 | def expandPythonRef(self, varname, expr, d): | ||
| 479 | localdata = self.d.createCopy() | ||
| 480 | for key in d.localkeys(): | ||
| 481 | localdata.setVar(d.getVar(key)) | ||
| 482 | varparse = bb.data_smart.VariableParse(varname, localdata) | ||
| 483 | return varparse.python_sub(expr) | ||
| 484 | def setVar(self, name, value): | ||
| 485 | self.d.setVar(name, value) | ||
| 486 | def setVarFlag(self, name, flag, value): | ||
| 487 | self.d.setVarFlag(name, flag, value) | ||
| 488 | def delVar(self, name): | ||
| 489 | self.d.delVar(name) | ||
| 490 | return False | ||
| 491 | def delVarFlag(self, name, flag): | ||
| 492 | self.d.delVarFlag(name, flag) | ||
| 493 | return False | ||
| 494 | def renameVar(self, name, newname): | ||
| 495 | self.d.renameVar(name, newname) | ||
| 496 | return False | ||
| 497 | |||
| 463 | class Remote(unittest.TestCase): | 498 | class Remote(unittest.TestCase): |
| 464 | def test_remote(self): | 499 | def test_remote(self): |
| 465 | class TestConnector: | ||
| 466 | d = None | ||
| 467 | def __init__(self, d): | ||
| 468 | self.d = d | ||
| 469 | def getVar(self, name): | ||
| 470 | return self.d._findVar(name) | ||
| 471 | def getKeys(self): | ||
| 472 | return self.d.localkeys() | ||
| 473 | def getVarHistory(self, name): | ||
| 474 | return self.d.varhistory.variable(name) | ||
| 475 | def expandPythonRef(self, varname, expr, d): | ||
| 476 | localdata = self.d.createCopy() | ||
| 477 | for key in d.localkeys(): | ||
| 478 | localdata.setVar(d.getVar(key)) | ||
| 479 | varparse = bb.data_smart.VariableParse(varname, localdata) | ||
| 480 | return varparse.python_sub(expr) | ||
| 481 | def setVar(self, name, value): | ||
| 482 | self.d.setVar(name, value) | ||
| 483 | 500 | ||
| 484 | d1 = bb.data.init() | 501 | d1 = bb.data.init() |
| 485 | d1.enableTracking() | 502 | d1.enableTracking() |
| @@ -500,6 +517,9 @@ class Remote(unittest.TestCase): | |||
| 500 | # Test setVar on client side affects server | 517 | # Test setVar on client side affects server |
| 501 | d2.setVar('HELLO', 'other-world') | 518 | d2.setVar('HELLO', 'other-world') |
| 502 | self.assertEqual(d1.getVar('HELLO'), 'other-world') | 519 | self.assertEqual(d1.getVar('HELLO'), 'other-world') |
| 520 | # Test setVarFlag on client side affects server | ||
| 521 | d2.setVarFlag('HELLO', 'flagname', 'flagvalue') | ||
| 522 | self.assertEqual(d1.getVarFlag('HELLO', 'flagname'), 'flagvalue') | ||
| 503 | # Test client side data is incorporated in python expansion (which is done on server) | 523 | # Test client side data is incorporated in python expansion (which is done on server) |
| 504 | d2.setVar('FOO', 'bar') | 524 | d2.setVar('FOO', 'bar') |
| 505 | self.assertEqual(d2.expand('${@d.getVar("FOO")}'), 'bar') | 525 | self.assertEqual(d2.expand('${@d.getVar("FOO")}'), 'bar') |
| @@ -507,3 +527,75 @@ class Remote(unittest.TestCase): | |||
| 507 | d1.setVar('FOO_test', 'baz') | 527 | d1.setVar('FOO_test', 'baz') |
| 508 | d1.appendVar('OVERRIDES', ':test') | 528 | d1.appendVar('OVERRIDES', ':test') |
| 509 | self.assertEqual(d2.getVar('FOO'), 'baz') | 529 | self.assertEqual(d2.getVar('FOO'), 'baz') |
| 530 | |||
| 531 | |||
| 532 | # Remote equivalents of local test classes | ||
| 533 | # Note that these aren't perfect since we only test in one direction | ||
| 534 | |||
| 535 | class RemoteDataExpansions(DataExpansions): | ||
| 536 | def setUp(self): | ||
| 537 | self.d1 = bb.data.init() | ||
| 538 | self.d = bb.data.init() | ||
| 539 | self.d1["foo"] = "value_of_foo" | ||
| 540 | self.d1["bar"] = "value_of_bar" | ||
| 541 | self.d1["value_of_foo"] = "value_of_'value_of_foo'" | ||
| 542 | connector = TestConnector(self.d1) | ||
| 543 | self.d.setVar('_remote_data', connector) | ||
| 544 | |||
| 545 | class TestRemoteNestedExpansions(TestNestedExpansions): | ||
| 546 | def setUp(self): | ||
| 547 | self.d1 = bb.data.init() | ||
| 548 | self.d = bb.data.init() | ||
| 549 | self.d1["foo"] = "foo" | ||
| 550 | self.d1["bar"] = "bar" | ||
| 551 | self.d1["value_of_foobar"] = "187" | ||
| 552 | connector = TestConnector(self.d1) | ||
| 553 | self.d.setVar('_remote_data', connector) | ||
| 554 | |||
| 555 | class TestRemoteConcat(TestConcat): | ||
| 556 | def setUp(self): | ||
| 557 | self.d1 = bb.data.init() | ||
| 558 | self.d = bb.data.init() | ||
| 559 | self.d1.setVar("FOO", "foo") | ||
| 560 | self.d1.setVar("VAL", "val") | ||
| 561 | self.d1.setVar("BAR", "bar") | ||
| 562 | connector = TestConnector(self.d1) | ||
| 563 | self.d.setVar('_remote_data', connector) | ||
| 564 | |||
| 565 | class TestRemoteConcatOverride(TestConcatOverride): | ||
| 566 | def setUp(self): | ||
| 567 | self.d1 = bb.data.init() | ||
| 568 | self.d = bb.data.init() | ||
| 569 | self.d1.setVar("FOO", "foo") | ||
| 570 | self.d1.setVar("VAL", "val") | ||
| 571 | self.d1.setVar("BAR", "bar") | ||
| 572 | connector = TestConnector(self.d1) | ||
| 573 | self.d.setVar('_remote_data', connector) | ||
| 574 | |||
| 575 | class TestRemoteOverrides(TestOverrides): | ||
| 576 | def setUp(self): | ||
| 577 | self.d1 = bb.data.init() | ||
| 578 | self.d = bb.data.init() | ||
| 579 | self.d1.setVar("OVERRIDES", "foo:bar:local") | ||
| 580 | self.d1.setVar("TEST", "testvalue") | ||
| 581 | connector = TestConnector(self.d1) | ||
| 582 | self.d.setVar('_remote_data', connector) | ||
| 583 | |||
| 584 | class TestRemoteKeyExpansion(TestKeyExpansion): | ||
| 585 | def setUp(self): | ||
| 586 | self.d1 = bb.data.init() | ||
| 587 | self.d = bb.data.init() | ||
| 588 | self.d1.setVar("FOO", "foo") | ||
| 589 | self.d1.setVar("BAR", "foo") | ||
| 590 | connector = TestConnector(self.d1) | ||
| 591 | self.d.setVar('_remote_data', connector) | ||
| 592 | |||
| 593 | class TestRemoteFlags(TestFlags): | ||
| 594 | def setUp(self): | ||
| 595 | self.d1 = bb.data.init() | ||
| 596 | self.d = bb.data.init() | ||
| 597 | self.d1.setVar("foo", "value of foo") | ||
| 598 | self.d1.setVarFlag("foo", "flag1", "value of flag1") | ||
| 599 | self.d1.setVarFlag("foo", "flag2", "value of flag2") | ||
| 600 | connector = TestConnector(self.d1) | ||
| 601 | self.d.setVar('_remote_data', connector) | ||
diff --git a/bitbake/lib/bb/tinfoil.py b/bitbake/lib/bb/tinfoil.py index 00cec59b83..19b41be46c 100644 --- a/bitbake/lib/bb/tinfoil.py +++ b/bitbake/lib/bb/tinfoil.py | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | # tinfoil: a simple wrapper around cooker for bitbake-based command-line utilities | 1 | # tinfoil: a simple wrapper around cooker for bitbake-based command-line utilities |
| 2 | # | 2 | # |
| 3 | # Copyright (C) 2012-2016 Intel Corporation | 3 | # Copyright (C) 2012-2017 Intel Corporation |
| 4 | # Copyright (C) 2011 Mentor Graphics Corporation | 4 | # Copyright (C) 2011 Mentor Graphics Corporation |
| 5 | # | 5 | # |
| 6 | # This program is free software; you can redistribute it and/or modify | 6 | # This program is free software; you can redistribute it and/or modify |
| @@ -84,6 +84,34 @@ class TinfoilDataStoreConnector: | |||
| 84 | # Not currently implemented - indicate that setting should | 84 | # Not currently implemented - indicate that setting should |
| 85 | # be redirected to local side | 85 | # be redirected to local side |
| 86 | return True | 86 | return True |
| 87 | def setVarFlag(self, varname, flagname, value): | ||
| 88 | if self.dsindex is None: | ||
| 89 | self.tinfoil.run_command('dataStoreConnectorSetVarFlag', self.dsindex, varname, flagname, value) | ||
| 90 | else: | ||
| 91 | # Not currently implemented - indicate that setting should | ||
| 92 | # be redirected to local side | ||
| 93 | return True | ||
| 94 | def delVar(self, varname): | ||
| 95 | if self.dsindex is None: | ||
| 96 | self.tinfoil.run_command('dataStoreConnectorDelVar', self.dsindex, varname) | ||
| 97 | else: | ||
| 98 | # Not currently implemented - indicate that setting should | ||
| 99 | # be redirected to local side | ||
| 100 | return True | ||
| 101 | def delVarFlag(self, varname, flagname): | ||
| 102 | if self.dsindex is None: | ||
| 103 | self.tinfoil.run_command('dataStoreConnectorDelVar', self.dsindex, varname, flagname) | ||
| 104 | else: | ||
| 105 | # Not currently implemented - indicate that setting should | ||
| 106 | # be redirected to local side | ||
| 107 | return True | ||
| 108 | def renameVar(self, name, newname): | ||
| 109 | if self.dsindex is None: | ||
| 110 | self.tinfoil.run_command('dataStoreConnectorRenameVar', self.dsindex, name, newname) | ||
| 111 | else: | ||
| 112 | # Not currently implemented - indicate that setting should | ||
| 113 | # be redirected to local side | ||
| 114 | return True | ||
| 87 | 115 | ||
| 88 | class TinfoilCookerAdapter: | 116 | class TinfoilCookerAdapter: |
| 89 | """ | 117 | """ |
