Mercurial > piecrust2
annotate piecrust/configuration.py @ 38:091f99bfbe44
Fix running `chef` outside of a website. Slightly better error reporting.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 21 Aug 2014 10:56:17 -0700 |
parents | 474c9882decf |
children | 563ce5dd02af |
rev | line source |
---|---|
0 | 1 import re |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
2 import logging |
0 | 3 import yaml |
4 | |
5 | |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
6 logger = logging.getLogger(__name__) |
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
7 |
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
8 |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
9 class ConfigurationError(Exception): |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
10 pass |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
11 |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
12 |
0 | 13 class Configuration(object): |
14 def __init__(self, values=None, validate=True): | |
15 if values is not None: | |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
16 self.setAll(values, validate) |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
17 else: |
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
18 self._values = None |
0 | 19 |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
20 def setAll(self, values, validate=True): |
0 | 21 if validate: |
22 self._validateAll(values) | |
23 self._values = values | |
24 | |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
25 def getAll(self): |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
26 return self.get() |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
27 |
0 | 28 def get(self, key_path=None): |
29 self._ensureLoaded() | |
30 if key_path is None: | |
31 return self._values | |
32 bits = key_path.split('/') | |
33 cur = self._values | |
34 for b in bits: | |
35 cur = cur.get(b) | |
36 if cur is None: | |
37 return None | |
38 return cur | |
39 | |
40 def set(self, key_path, value): | |
41 self._ensureLoaded() | |
42 value = self._validateValue(key_path, value) | |
43 bits = key_path.split('/') | |
44 bitslen = len(bits) | |
45 cur = self._values | |
46 for i, b in enumerate(bits): | |
47 if i == bitslen - 1: | |
48 cur[b] = value | |
49 else: | |
50 if b not in cur: | |
51 cur[b] = {} | |
52 cur = cur[b] | |
53 | |
54 def has(self, key_path): | |
55 self._ensureLoaded() | |
56 bits = key_path.split('/') | |
57 cur = self._values | |
58 for b in bits: | |
59 cur = cur.get(b) | |
60 if cur is None: | |
61 return False | |
62 return True | |
63 | |
64 def merge(self, other): | |
65 self._ensureLoaded() | |
66 merge_dicts(self._values, other._values, | |
67 validator=self._validateValue) | |
68 | |
69 def _ensureLoaded(self): | |
70 if self._values is None: | |
71 self._load() | |
72 | |
73 def _load(self): | |
74 self._values = self._validateAll({}) | |
75 | |
76 def _validateAll(self, values): | |
77 return values | |
78 | |
79 def _validateValue(self, key_path, value): | |
80 return value | |
81 | |
82 | |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
83 def merge_dicts(source, merging, validator=None, *args): |
0 | 84 if validator is None: |
85 validator = lambda k, v: v | |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
86 _recurse_merge_dicts(source, merging, None, validator) |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
87 for other in args: |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
88 _recurse_merge_dicts(source, other, None, validator) |
0 | 89 |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
90 |
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
91 def _recurse_merge_dicts(local_cur, incoming_cur, parent_path, validator): |
5 | 92 for k, v in incoming_cur.items(): |
0 | 93 key_path = k |
94 if parent_path is not None: | |
95 key_path = parent_path + '/' + k | |
96 | |
97 local_v = local_cur.get(k) | |
98 if local_v is not None: | |
99 if isinstance(v, dict) and isinstance(local_v, dict): | |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
100 _recurse_merge_dicts(local_v, v, key_path, validator) |
0 | 101 elif isinstance(v, list) and isinstance(local_v, list): |
102 local_cur[k] = v + local_v | |
103 else: | |
104 local_cur[k] = validator(key_path, v) | |
105 else: | |
106 local_cur[k] = validator(key_path, v) | |
107 | |
108 | |
109 header_regex = re.compile( | |
110 r'(---\s*\n)(?P<header>(.*\n)*?)^(---\s*\n)', re.MULTILINE) | |
111 | |
112 | |
113 def parse_config_header(text): | |
114 m = header_regex.match(text) | |
115 if m is not None: | |
5 | 116 header = str(m.group('header')) |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
117 config = yaml.load(header, Loader=yaml.BaseLoader) |
0 | 118 offset = m.end() |
119 else: | |
120 config = {} | |
121 offset = 0 | |
122 return config, offset | |
123 |