| OLD | NEW |
| 1 # Copyright 2013-2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2013-2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Recipe Configuration Meta DSL. | 5 """Recipe Configuration Meta DSL. |
| 6 | 6 |
| 7 This module contains, essentially, a DSL for writing composable configurations. | 7 This module contains, essentially, a DSL for writing composable configurations. |
| 8 You start by defining a schema which describes how your configuration blobs will | 8 You start by defining a schema which describes how your configuration blobs will |
| 9 be structured, and what data they can contain. For example: | 9 be structured, and what data they can contain. For example: |
| 10 | 10 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 I will get back a configuraton object whose schema is FakeSchema, and whose | 62 I will get back a configuraton object whose schema is FakeSchema, and whose |
| 63 data is the accumulation of cool(), gnarly(), and combo(). I can continue to | 63 data is the accumulation of cool(), gnarly(), and combo(). I can continue to |
| 64 manipulate this configuraton object, use its data, or render it to json. | 64 manipulate this configuraton object, use its data, or render it to json. |
| 65 | 65 |
| 66 Using this system should allow you to create rich, composible, | 66 Using this system should allow you to create rich, composible, |
| 67 modular configurations. See the documentation on config_item_context and the | 67 modular configurations. See the documentation on config_item_context and the |
| 68 BaseConfig derivatives for more info. | 68 BaseConfig derivatives for more info. |
| 69 """ | 69 """ |
| 70 | 70 |
| 71 from __future__ import absolute_import |
| 71 import collections | 72 import collections |
| 72 import functools | 73 import functools |
| 73 import types | 74 import types |
| 74 | 75 |
| 75 from infra.libs import infra_types | |
| 76 | |
| 77 class BadConf(Exception): | 76 class BadConf(Exception): |
| 78 pass | 77 pass |
| 79 | 78 |
| 80 def typeAssert(obj, typearg): | 79 def typeAssert(obj, typearg): |
| 81 if not isinstance(obj, typearg): | 80 if not isinstance(obj, typearg): |
| 82 raise TypeError("Expected %r to be of type %r" % (obj, typearg)) | 81 raise TypeError("Expected %r to be of type %r" % (obj, typearg)) |
| 83 | 82 |
| 84 | 83 |
| 85 class ConfigContext(object): | 84 class ConfigContext(object): |
| 86 """A configuration context for a recipe module. | 85 """A configuration context for a recipe module. |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 obj.set_val(val) | 366 obj.set_val(val) |
| 368 | 367 |
| 369 def __delattr__(self, name): | 368 def __delattr__(self, name): |
| 370 obj = object.__getattribute__(self, name) | 369 obj = object.__getattribute__(self, name) |
| 371 typeAssert(obj, ConfigBase) | 370 typeAssert(obj, ConfigBase) |
| 372 obj.reset() | 371 obj.reset() |
| 373 | 372 |
| 374 def set_val(self, val): | 373 def set_val(self, val): |
| 375 if isinstance(val, ConfigBase): | 374 if isinstance(val, ConfigBase): |
| 376 val = val.as_jsonish(include_hidden=True) | 375 val = val.as_jsonish(include_hidden=True) |
| 377 if isinstance(val, infra_types.FrozenDict): | 376 typeAssert(val, collections.Mapping) |
| 378 val = infra_types.thaw(val) | |
| 379 typeAssert(val, dict) | |
| 380 | 377 |
| 381 val = dict(val) # because we pop later. | 378 val = dict(val) # because we pop later. |
| 382 for name, config_obj in self._type_map.iteritems(): | 379 for name, config_obj in self._type_map.iteritems(): |
| 383 if name in val: | 380 if name in val: |
| 384 try: | 381 try: |
| 385 config_obj.set_val(val.pop(name)) | 382 config_obj.set_val(val.pop(name)) |
| 386 except Exception as e: | 383 except Exception as e: |
| 387 raise Exception('While assigning key %r: %s' % (name, e)) | 384 raise Exception('While assigning key %r: %s' % (name, e)) |
| 388 | 385 |
| 389 if val: | 386 if val: |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 | 512 |
| 516 def __iter__(self): | 513 def __iter__(self): |
| 517 return iter(self.data) | 514 return iter(self.data) |
| 518 | 515 |
| 519 def __len__(self): | 516 def __len__(self): |
| 520 return len(self.data) | 517 return len(self.data) |
| 521 | 518 |
| 522 def set_val(self, val): | 519 def set_val(self, val): |
| 523 if isinstance(val, Dict): | 520 if isinstance(val, Dict): |
| 524 val = val.data | 521 val = val.data |
| 525 if isinstance(val, infra_types.FrozenDict): | 522 typeAssert(val, collections.Mapping) |
| 526 val = dict(val) | |
| 527 | |
| 528 typeAssert(val, dict) | |
| 529 for v in val.itervalues(): | 523 for v in val.itervalues(): |
| 530 typeAssert(v, self.value_type) | 524 typeAssert(v, self.value_type) |
| 531 self.data = val | 525 self.data = val |
| 532 | 526 |
| 533 def as_jsonish(self, _include_hidden=None): | 527 def as_jsonish(self, _include_hidden=None): |
| 534 return self.jsonish_fn(map( | 528 return self.jsonish_fn(map( |
| 535 self.item_fn, sorted(self.data.iteritems(), key=lambda x: x[0]))) | 529 self.item_fn, sorted(self.data.iteritems(), key=lambda x: x[0]))) |
| 536 | 530 |
| 537 def reset(self): | 531 def reset(self): |
| 538 self.data.clear() | 532 self.data.clear() |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 return self.data | 721 return self.data |
| 728 | 722 |
| 729 def reset(self): | 723 def reset(self): |
| 730 assert False | 724 assert False |
| 731 | 725 |
| 732 def complete(self): | 726 def complete(self): |
| 733 return True | 727 return True |
| 734 | 728 |
| 735 def _is_default(self): | 729 def _is_default(self): |
| 736 return True | 730 return True |
| OLD | NEW |