diff options
| -rw-r--r-- | bitbake/lib/bb/data_smart.py | 156 |
1 files changed, 60 insertions, 96 deletions
diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py index 77d0c61da0..aefc0b980b 100644 --- a/bitbake/lib/bb/data_smart.py +++ b/bitbake/lib/bb/data_smart.py | |||
| @@ -296,12 +296,9 @@ class VariableHistory(object): | |||
| 296 | self.variables[var] = [] | 296 | self.variables[var] = [] |
| 297 | 297 | ||
| 298 | class DataSmart(MutableMapping): | 298 | class DataSmart(MutableMapping): |
| 299 | def __init__(self, special = None, seen = None ): | 299 | def __init__(self, seen = None): |
| 300 | self.dict = {} | 300 | self.dict = {} |
| 301 | self.overrides = [] | ||
| 302 | 301 | ||
| 303 | if special is None: | ||
| 304 | special = COWDictBase.copy() | ||
| 305 | if seen is None: | 302 | if seen is None: |
| 306 | seen = COWDictBase.copy() | 303 | seen = COWDictBase.copy() |
| 307 | 304 | ||
| @@ -310,11 +307,13 @@ class DataSmart(MutableMapping): | |||
| 310 | self._tracking = False | 307 | self._tracking = False |
| 311 | 308 | ||
| 312 | # cookie monster tribute | 309 | # cookie monster tribute |
| 313 | self._special_values = special | ||
| 314 | self._seen_overrides = seen | 310 | self._seen_overrides = seen |
| 315 | 311 | ||
| 316 | self.expand_cache = {} | 312 | self.expand_cache = {} |
| 317 | 313 | ||
| 314 | self.overridevars = set(["OVERRIDES", "FILE"]) | ||
| 315 | self.replaces = {} | ||
| 316 | |||
| 318 | def enableTracking(self): | 317 | def enableTracking(self): |
| 319 | self._tracking = True | 318 | self._tracking = True |
| 320 | 319 | ||
| @@ -361,11 +360,7 @@ class DataSmart(MutableMapping): | |||
| 361 | def internal_finalize(self, parent = False): | 360 | def internal_finalize(self, parent = False): |
| 362 | """Performs final steps upon the datastore, including application of overrides""" | 361 | """Performs final steps upon the datastore, including application of overrides""" |
| 363 | 362 | ||
| 364 | self.overrides = (self.getVar("OVERRIDES", True) or "").split(":") or [] | 363 | overrides = (self.getVar("OVERRIDES", True) or "").split(":") or [] |
| 365 | finalize_caller = { | ||
| 366 | 'op': 'finalize', | ||
| 367 | } | ||
| 368 | infer_caller_details(finalize_caller, parent = parent, varval = False) | ||
| 369 | 364 | ||
| 370 | # | 365 | # |
| 371 | # Well let us see what breaks here. We used to iterate | 366 | # Well let us see what breaks here. We used to iterate |
| @@ -383,10 +378,9 @@ class DataSmart(MutableMapping): | |||
| 383 | # information for later. | 378 | # information for later. |
| 384 | # | 379 | # |
| 385 | 380 | ||
| 386 | # We only want to report finalization once per variable overridden. | 381 | self.replaces = {} |
| 387 | finalizes_reported = {} | ||
| 388 | 382 | ||
| 389 | for o in self.overrides: | 383 | for o in overrides: |
| 390 | # calculate '_'+override | 384 | # calculate '_'+override |
| 391 | l = len(o) + 1 | 385 | l = len(o) + 1 |
| 392 | 386 | ||
| @@ -397,61 +391,7 @@ class DataSmart(MutableMapping): | |||
| 397 | vars = self._seen_overrides[o].copy() | 391 | vars = self._seen_overrides[o].copy() |
| 398 | for var in vars: | 392 | for var in vars: |
| 399 | name = var[:-l] | 393 | name = var[:-l] |
| 400 | try: | 394 | self.replaces[name] = var |
| 401 | # Report only once, even if multiple changes. | ||
| 402 | if name not in finalizes_reported: | ||
| 403 | finalizes_reported[name] = True | ||
| 404 | finalize_caller['variable'] = name | ||
| 405 | finalize_caller['detail'] = 'was: ' + str(self.getVar(name, False)) | ||
| 406 | self.varhistory.record(**finalize_caller) | ||
| 407 | # Copy history of the override over. | ||
| 408 | for event in self.varhistory.variable(var): | ||
| 409 | loginfo = event.copy() | ||
| 410 | loginfo['variable'] = name | ||
| 411 | loginfo['op'] = 'override[%s]:%s' % (o, loginfo['op']) | ||
| 412 | self.varhistory.record(**loginfo) | ||
| 413 | self.setVar(name, self.getVar(var, False), op = 'finalize', file = 'override[%s]' % o, line = '') | ||
| 414 | self.delVar(var) | ||
| 415 | except Exception: | ||
| 416 | logger.info("Untracked delVar") | ||
| 417 | |||
| 418 | # now on to the appends and prepends, and stashing the removes | ||
| 419 | for op in __setvar_keyword__: | ||
| 420 | if op in self._special_values: | ||
| 421 | appends = self._special_values[op] or [] | ||
| 422 | for append in appends: | ||
| 423 | self.handle_special_values(append, op) | ||
| 424 | |||
| 425 | def handle_special_values(self, append, op): | ||
| 426 | keep = [] | ||
| 427 | for (a, o) in self.getVarFlag(append, op) or []: | ||
| 428 | match = True | ||
| 429 | if o: | ||
| 430 | for o2 in o.split("_"): | ||
| 431 | if not o2 in self.overrides: | ||
| 432 | match = False | ||
| 433 | if not match: | ||
| 434 | keep.append((a ,o)) | ||
| 435 | continue | ||
| 436 | |||
| 437 | if op == "_append": | ||
| 438 | apps = self.getVarFlag(append, "_appendactive", False) or [] | ||
| 439 | apps.extend([a]) | ||
| 440 | self.setVarFlag(append, "_appendactive", apps, ignore=True) | ||
| 441 | elif op == "_prepend": | ||
| 442 | prepends = self.getVarFlag(append, "_prependactive", False) or [] | ||
| 443 | prepends.extend([a]) | ||
| 444 | self.setVarFlag(append, "_prependactive", prepends, ignore=True) | ||
| 445 | elif op == "_remove": | ||
| 446 | removes = self.getVarFlag(append, "_removeactive", False) or [] | ||
| 447 | removes.extend(a.split()) | ||
| 448 | self.setVarFlag(append, "_removeactive", removes, ignore=True) | ||
| 449 | |||
| 450 | # We save overrides that may be applied at some later stage | ||
| 451 | if keep: | ||
| 452 | self.setVarFlag(append, op, keep, ignore=True) | ||
| 453 | else: | ||
| 454 | self.delVarFlag(append, op, ignore=True) | ||
| 455 | 395 | ||
| 456 | def initVar(self, var): | 396 | def initVar(self, var): |
| 457 | self.expand_cache = {} | 397 | self.expand_cache = {} |
| @@ -503,22 +443,19 @@ class DataSmart(MutableMapping): | |||
| 503 | self.varhistory.record(**loginfo) | 443 | self.varhistory.record(**loginfo) |
| 504 | # todo make sure keyword is not __doc__ or __module__ | 444 | # todo make sure keyword is not __doc__ or __module__ |
| 505 | # pay the cookie monster | 445 | # pay the cookie monster |
| 506 | try: | ||
| 507 | self._special_values[keyword].add(base) | ||
| 508 | except KeyError: | ||
| 509 | self._special_values[keyword] = set() | ||
| 510 | self._special_values[keyword].add(base) | ||
| 511 | self.handle_special_values(base, keyword) | ||
| 512 | 446 | ||
| 447 | if base in self.overridevars: | ||
| 448 | self.overridevars.update(self.expandWithRefs(value, var).references) | ||
| 449 | self.internal_finalize(True) | ||
| 513 | return | 450 | return |
| 514 | 451 | ||
| 515 | if not var in self.dict: | 452 | if not var in self.dict: |
| 516 | self._makeShadowCopy(var) | 453 | self._makeShadowCopy(var) |
| 517 | 454 | ||
| 518 | if "_appendactive" in self.dict[var]: | 455 | if "_append" in self.dict[var]: |
| 519 | del self.dict[var]["_appendactive"] | 456 | del self.dict[var]["_append"] |
| 520 | if "_prependactive" in self.dict[var]: | 457 | if "_prepend" in self.dict[var]: |
| 521 | del self.dict[var]["_prependactive"] | 458 | del self.dict[var]["_prepend"] |
| 522 | 459 | ||
| 523 | # more cookies for the cookie monster | 460 | # more cookies for the cookie monster |
| 524 | if '_' in var: | 461 | if '_' in var: |
| @@ -528,7 +465,8 @@ class DataSmart(MutableMapping): | |||
| 528 | self.dict[var]["_content"] = value | 465 | self.dict[var]["_content"] = value |
| 529 | self.varhistory.record(**loginfo) | 466 | self.varhistory.record(**loginfo) |
| 530 | 467 | ||
| 531 | if var == "OVERRIDES": | 468 | if var in self.overridevars: |
| 469 | self.overridevars.update(self.expandWithRefs(value, var).references) | ||
| 532 | self.internal_finalize(True) | 470 | self.internal_finalize(True) |
| 533 | 471 | ||
| 534 | def _setvar_update_overrides(self, var): | 472 | def _setvar_update_overrides(self, var): |
| @@ -568,10 +506,6 @@ class DataSmart(MutableMapping): | |||
| 568 | dest.extend(src) | 506 | dest.extend(src) |
| 569 | self.setVarFlag(newkey, i, dest, ignore=True) | 507 | self.setVarFlag(newkey, i, dest, ignore=True) |
| 570 | 508 | ||
| 571 | if i in self._special_values and key in self._special_values[i]: | ||
| 572 | self._special_values[i].remove(key) | ||
| 573 | self._special_values[i].add(newkey) | ||
| 574 | |||
| 575 | loginfo['variable'] = key | 509 | loginfo['variable'] = key |
| 576 | loginfo['op'] = 'rename (to)' | 510 | loginfo['op'] = 'rename (to)' |
| 577 | loginfo['detail'] = newkey | 511 | loginfo['detail'] = newkey |
| @@ -623,22 +557,42 @@ class DataSmart(MutableMapping): | |||
| 623 | def getVarFlag(self, var, flag, expand=False, noweakdefault=False): | 557 | def getVarFlag(self, var, flag, expand=False, noweakdefault=False): |
| 624 | local_var = self._findVar(var) | 558 | local_var = self._findVar(var) |
| 625 | value = None | 559 | value = None |
| 626 | if local_var is not None: | 560 | |
| 561 | if flag == "_content" and var in self.replaces: | ||
| 562 | value = self.getVar(self.replaces[var]) | ||
| 563 | |||
| 564 | if local_var is not None and value is None: | ||
| 627 | if flag in local_var: | 565 | if flag in local_var: |
| 628 | value = copy.copy(local_var[flag]) | 566 | value = copy.copy(local_var[flag]) |
| 629 | elif flag == "_content" and "_defaultval" in local_var and not noweakdefault: | 567 | elif flag == "_content" and "_defaultval" in local_var and not noweakdefault: |
| 630 | value = copy.copy(local_var["_defaultval"]) | 568 | value = copy.copy(local_var["_defaultval"]) |
| 631 | 569 | ||
| 632 | if flag == "_content" and local_var is not None and "_appendactive" in local_var: | 570 | if flag == "_content" and local_var is not None and "_append" in local_var: |
| 633 | if not value: | 571 | if not value: |
| 634 | value = "" | 572 | value = "" |
| 635 | for r in local_var["_appendactive"]: | 573 | for (r, o) in local_var["_append"]: |
| 636 | value = value + r | 574 | match = True |
| 637 | if flag == "_content" and local_var is not None and "_prependactive" in local_var: | 575 | if o: |
| 576 | overrides = (self.getVar("OVERRIDES", True) or "").split(":") or [] | ||
| 577 | for o2 in o.split("_"): | ||
| 578 | if not o2 in overrides: | ||
| 579 | match = False | ||
| 580 | if match: | ||
| 581 | value = value + r | ||
| 582 | |||
| 583 | if flag == "_content" and local_var is not None and "_prepend" in local_var: | ||
| 638 | if not value: | 584 | if not value: |
| 639 | value = "" | 585 | value = "" |
| 640 | for r in local_var["_prependactive"]: | 586 | for (r, o) in local_var["_prepend"]: |
| 641 | value = r + value | 587 | match = True |
| 588 | if o: | ||
| 589 | overrides = (self.getVar("OVERRIDES", True) or "").split(":") or [] | ||
| 590 | for o2 in o.split("_"): | ||
| 591 | if not o2 in overrides: | ||
| 592 | match = False | ||
| 593 | if match: | ||
| 594 | value = r + value | ||
| 595 | |||
| 642 | if expand and value: | 596 | if expand and value: |
| 643 | # Only getvar (flag == _content) hits the expand cache | 597 | # Only getvar (flag == _content) hits the expand cache |
| 644 | cachename = None | 598 | cachename = None |
| @@ -647,9 +601,19 @@ class DataSmart(MutableMapping): | |||
| 647 | else: | 601 | else: |
| 648 | cachename = var + "[" + flag + "]" | 602 | cachename = var + "[" + flag + "]" |
| 649 | value = self.expand(value, cachename) | 603 | value = self.expand(value, cachename) |
| 650 | if value and flag == "_content" and local_var is not None and "_removeactive" in local_var: | 604 | |
| 651 | removes = [self.expand(r).split() for r in local_var["_removeactive"]] | 605 | if value and flag == "_content" and local_var is not None and "_remove" in local_var: |
| 652 | removes = reduce(lambda a, b: a+b, removes, []) | 606 | removes = [] |
| 607 | for (r, o) in local_var["_remove"]: | ||
| 608 | match = True | ||
| 609 | if o: | ||
| 610 | overrides = (self.getVar("OVERRIDES", True) or "").split(":") or [] | ||
| 611 | for o2 in o.split("_"): | ||
| 612 | if not o2 in overrides: | ||
| 613 | match = False | ||
| 614 | if match: | ||
| 615 | removes.extend(self.expand(r).split()) | ||
| 616 | |||
| 653 | filtered = filter(lambda v: v not in removes, | 617 | filtered = filter(lambda v: v not in removes, |
| 654 | value.split()) | 618 | value.split()) |
| 655 | value = " ".join(filtered) | 619 | value = " ".join(filtered) |
| @@ -735,21 +699,21 @@ class DataSmart(MutableMapping): | |||
| 735 | else: | 699 | else: |
| 736 | del self.dict[var] | 700 | del self.dict[var] |
| 737 | 701 | ||
| 738 | |||
| 739 | def createCopy(self): | 702 | def createCopy(self): |
| 740 | """ | 703 | """ |
| 741 | Create a copy of self by setting _data to self | 704 | Create a copy of self by setting _data to self |
| 742 | """ | 705 | """ |
| 743 | # we really want this to be a DataSmart... | 706 | # we really want this to be a DataSmart... |
| 744 | data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy()) | 707 | data = DataSmart(seen=self._seen_overrides.copy()) |
| 745 | data.dict["_data"] = self.dict | 708 | data.dict["_data"] = self.dict |
| 746 | data.overrides = copy.copy(self.overrides) | ||
| 747 | data.varhistory = self.varhistory.copy() | 709 | data.varhistory = self.varhistory.copy() |
| 748 | data.varhistory.datasmart = data | 710 | data.varhistory.datasmart = data |
| 749 | data.inchistory = self.inchistory.copy() | 711 | data.inchistory = self.inchistory.copy() |
| 750 | 712 | ||
| 751 | data._tracking = self._tracking | 713 | data._tracking = self._tracking |
| 752 | 714 | ||
| 715 | data.overridevars = copy.copy(self.overridevars) | ||
| 716 | |||
| 753 | return data | 717 | return data |
| 754 | 718 | ||
| 755 | def expandVarref(self, variable, parents=False): | 719 | def expandVarref(self, variable, parents=False): |
