Mercurial > hg > configuration
annotate configuration/configuration.py @ 126:82151d79e117
configuration/configuration.py
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Tue, 17 Sep 2013 23:35:26 -0700 |
parents | c6a41a60afc0 |
children | 1c3ba645a69b |
rev | line source |
---|---|
0 | 1 #!/usr/bin/env python |
2 | |
3 """ | |
66 | 4 unified configuration with serialization/deserialization |
0 | 5 """ |
6 | |
34
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
7 import copy |
37
a1f8dec4d4f9
we has another broken test
Jeff Hammel <jhammel@mozilla.com>
parents:
36
diff
changeset
|
8 import os |
0 | 9 import sys |
10 import optparse | |
11 | |
67 | 12 # imports for configuration providers |
4 | 13 try: |
14 import json | |
15 except ImportError: | |
16 try: | |
17 import simplejson as json | |
18 except ImportError: | |
19 json = None | |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
20 try: |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
21 import yaml |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
22 except ImportError: |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
23 yaml = None |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
24 |
67 | 25 __all__ = ['Configuration', |
26 'configuration_providers', | |
27 'types', | |
28 'UnknownOptionException', | |
29 'MissingValueException', | |
30 'ConfigurationProviderException', | |
31 'TypeCastException', | |
32 'ConfigurationOption'] | |
36
d218df4d0b4c
add test for missing values
Jeff Hammel <jhammel@mozilla.com>
parents:
35
diff
changeset
|
33 |
d218df4d0b4c
add test for missing values
Jeff Hammel <jhammel@mozilla.com>
parents:
35
diff
changeset
|
34 ### exceptions |
d218df4d0b4c
add test for missing values
Jeff Hammel <jhammel@mozilla.com>
parents:
35
diff
changeset
|
35 |
67 | 36 class UnknownOptionException(Exception): |
37 """exception raised when a non-configuration value is present in the configuration""" | |
38 | |
36
d218df4d0b4c
add test for missing values
Jeff Hammel <jhammel@mozilla.com>
parents:
35
diff
changeset
|
39 class MissingValueException(Exception): |
d218df4d0b4c
add test for missing values
Jeff Hammel <jhammel@mozilla.com>
parents:
35
diff
changeset
|
40 """exception raised when a required value is missing""" |
6 | 41 |
41
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
42 class ConfigurationProviderException(Exception): |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
43 """exception raised when a configuration provider is missing, etc""" |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
44 |
46 | 45 class TypeCastException(Exception): |
46 """exception raised when a configuration item cannot be coerced to a type""" | |
47 | |
67 | 48 |
26
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
49 ### configuration providers for serialization/deserialization |
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
50 |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
51 configuration_providers = [] |
26
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
52 |
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
53 class ConfigurationProvider(object): |
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
54 """ |
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
55 abstract base class for configuration providers for |
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
56 serialization/deserialization |
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
57 """ |
27 | 58 def read(self, filename): |
59 raise NotImplementedError("Abstract base class") | |
60 | |
61 def write(self, config, filename): | |
62 if isinstance(filename, basestring): | |
63 f = file(filename, 'w') | |
64 newfile = True | |
65 else: | |
66 f = filename | |
67 newfile = False | |
110
b9fdae6a536a
make python 2.4 compatible :(
Jeff Hammel <jhammel@mozilla.com>
parents:
109
diff
changeset
|
68 exception = None |
27 | 69 try: |
70 self._write(f, config) | |
110
b9fdae6a536a
make python 2.4 compatible :(
Jeff Hammel <jhammel@mozilla.com>
parents:
109
diff
changeset
|
71 except Exception, exception: |
b9fdae6a536a
make python 2.4 compatible :(
Jeff Hammel <jhammel@mozilla.com>
parents:
109
diff
changeset
|
72 pass |
b9fdae6a536a
make python 2.4 compatible :(
Jeff Hammel <jhammel@mozilla.com>
parents:
109
diff
changeset
|
73 if newfile: |
b9fdae6a536a
make python 2.4 compatible :(
Jeff Hammel <jhammel@mozilla.com>
parents:
109
diff
changeset
|
74 f.close() |
b9fdae6a536a
make python 2.4 compatible :(
Jeff Hammel <jhammel@mozilla.com>
parents:
109
diff
changeset
|
75 if exception: |
b9fdae6a536a
make python 2.4 compatible :(
Jeff Hammel <jhammel@mozilla.com>
parents:
109
diff
changeset
|
76 raise exception |
27 | 77 def _write(self, fp, config): |
78 raise NotImplementedError("Abstract base class") | |
26
4fd88b1b08d5
ABC-ing configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
25
diff
changeset
|
79 |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
80 if json: |
38
8909ae1cc4ea
fix serialization (stub) tests
Jeff Hammel <jhammel@mozilla.com>
parents:
37
diff
changeset
|
81 class JSON(ConfigurationProvider): |
27 | 82 indent = 2 |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
83 extensions = ['json'] |
7 | 84 def read(self, filename): |
9 | 85 return json.loads(file(filename).read()) |
27 | 86 def _write(self, fp, config): |
38
8909ae1cc4ea
fix serialization (stub) tests
Jeff Hammel <jhammel@mozilla.com>
parents:
37
diff
changeset
|
87 fp.write(json.dumps(config, indent=self.indent, sort_keys=True)) |
27 | 88 # TODO: could use templates to get order down, etc |
30
b27a7cb2dd5b
stub test for configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
29
diff
changeset
|
89 configuration_providers.append(JSON()) |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
90 |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
91 if yaml: |
38
8909ae1cc4ea
fix serialization (stub) tests
Jeff Hammel <jhammel@mozilla.com>
parents:
37
diff
changeset
|
92 class YAML(ConfigurationProvider): |
30
b27a7cb2dd5b
stub test for configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
29
diff
changeset
|
93 extensions = ['yml', 'yaml'] |
87
928654373755
change default flow style for yaml, http://pyyaml.org/wiki/PyYAMLDocumentation
Jeff Hammel <jhammel@mozilla.com>
parents:
86
diff
changeset
|
94 dump_args = {'default_flow_style': False} |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
95 def read(self, filename): |
6 | 96 f = file(filename) |
97 config = yaml.load(f) | |
98 f.close() | |
99 return config | |
27 | 100 def _write(self, fp, config): |
87
928654373755
change default flow style for yaml, http://pyyaml.org/wiki/PyYAMLDocumentation
Jeff Hammel <jhammel@mozilla.com>
parents:
86
diff
changeset
|
101 fp.write(yaml.dump(config, **self.dump_args)) |
27 | 102 # TODO: could use templates to get order down, etc |
6 | 103 |
30
b27a7cb2dd5b
stub test for configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
29
diff
changeset
|
104 configuration_providers.append(YAML()) |
b27a7cb2dd5b
stub test for configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
29
diff
changeset
|
105 |
113 | 106 # TODO: add configuration providers |
107 # - for taking command-line arguments from a file | |
108 # - for .ini files | |
50
113e8c2f7cab
start to hook up deserializers
Jeff Hammel <jhammel@mozilla.com>
parents:
49
diff
changeset
|
109 |
30
b27a7cb2dd5b
stub test for configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
29
diff
changeset
|
110 __all__.extend([i.__class__.__name__ for i in configuration_providers]) |
4 | 111 |
125
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
112 |
44
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
113 ### optparse interface |
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
114 |
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
115 class ConfigurationOption(optparse.Option): |
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
116 """option that keeps track if it is seen""" |
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
117 # TODO: this should be configurable or something |
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
118 def take_action(self, action, dest, opt, value, values, parser): |
108
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
119 |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
120 # switch on types |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
121 formatter = getattr(parser, 'cli_formatter') |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
122 if formatter: |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
123 formatter = formatter(dest) |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
124 if formatter: |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
125 value = formatter(value) |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
126 |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
127 # call the optparse front-end |
44
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
128 optparse.Option.take_action(self, action, dest, opt, value, values, parser) |
82 | 129 |
130 # add the parsed option to the set of things parsed | |
44
b3db38b14567
stub adding an option of keeping track of what is parsed
Jeff Hammel <jhammel@mozilla.com>
parents:
43
diff
changeset
|
131 if not hasattr(parser, 'parsed'): |
109
09642528be02
keep track of parsed values as well as individual instances
Jeff Hammel <jhammel@mozilla.com>
parents:
108
diff
changeset
|
132 parser.parsed = dict() |
09642528be02
keep track of parsed values as well as individual instances
Jeff Hammel <jhammel@mozilla.com>
parents:
108
diff
changeset
|
133 parser.parsed[dest] = value |
82 | 134 |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
135 ### plugins for option types |
80
35416ad14098
notes to self about how to make this better; still needs a little thought
Jeff Hammel <jhammel@mozilla.com>
parents:
78
diff
changeset
|
136 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
137 class BaseCLI(object): |
80
35416ad14098
notes to self about how to make this better; still needs a little thought
Jeff Hammel <jhammel@mozilla.com>
parents:
78
diff
changeset
|
138 """base_cli for all option types""" |
35416ad14098
notes to self about how to make this better; still needs a little thought
Jeff Hammel <jhammel@mozilla.com>
parents:
78
diff
changeset
|
139 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
140 def __call__(self, name, value): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
141 """return args, kwargs needed to instantiate an optparse option""" |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
142 |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
143 args = value.get('flags', ['--%s' % name]) |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
144 if not args: |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
145 # No CLI interface |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
146 return (), {} |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
147 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
148 kw = {'dest': name} |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
149 help = value.get('help', name) |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
150 if 'default' in value: |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
151 kw['default'] = value['default'] |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
152 help += ' [DEFAULT: %s]' % value['default'] |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
153 kw['help'] = help |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
154 kw['action'] = 'store' |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
155 return args, kw |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
156 |
82 | 157 def take_action(self, value): |
158 return value | |
159 | |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
160 class BoolCLI(BaseCLI): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
161 |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
162 def __call__(self, name, value): |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
163 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
164 # preserve the default values |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
165 help = value.get('help') |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
166 flags = value.get('flags') |
23 | 167 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
168 args, kw = BaseCLI.__call__(self, name, value) |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
169 kw['help'] = help # reset |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
170 if value.get('default'): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
171 kw['action'] = 'store_false' |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
172 if not flags: |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
173 args = ['--no-%s' % name] |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
174 if not help: |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
175 kw['help'] = 'disable %s' % name |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
176 else: |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
177 kw['action'] = 'store_true' |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
178 if not help: |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
179 kw['help'] = 'enable %s' % name |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
180 return args, kw |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
181 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
182 class ListCLI(BaseCLI): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
183 |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
184 def __call__(self, name, value): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
185 args, kw = BaseCLI.__call__(self, name, value) |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
186 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
187 # TODO: could use 'extend' |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
188 # - http://hg.mozilla.org/build/mozharness/file/5f44ba08f4be/mozharness/base/config.py#l41 |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
189 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
190 kw['action'] = 'append' |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
191 return args, kw |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
192 |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
193 class IntCLI(BaseCLI): |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
194 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
195 def __call__(self, name, value): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
196 args, kw = BaseCLI.__call__(self, name, value) |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
197 kw['type'] = 'int' |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
198 return args, kw |
23 | 199 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
200 class FloatCLI(BaseCLI): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
201 |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
202 def __call__(self, name, value): |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
203 args, kw = BaseCLI.__call__(self, name, value) |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
204 kw['type'] = 'float' |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
205 return args, kw |
23 | 206 |
82 | 207 class DictCLI(ListCLI): |
208 | |
209 delimeter = '=' | |
210 | |
108
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
211 def __call__(self, name, value): |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
212 |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
213 # optparse can't handle dict types OOTB |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
214 default = value.get('default') |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
215 if isinstance(default, dict): |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
216 value = copy.deepcopy(value) |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
217 value['default'] = default.items() |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
218 |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
219 return ListCLI.__call__(self, name, value) |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
220 |
82 | 221 def take_action(self, value): |
108
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
222 if self.delimeter not in value: |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
223 raise AssertionError("Each value must be delimited by '%s': %s" % (self.delimeter, value)) |
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
224 return value.split(self.delimeter, 1) |
82 | 225 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
226 types = {bool: BoolCLI(), |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
227 int: IntCLI(), |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
228 float: FloatCLI(), |
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
229 list: ListCLI(), |
82 | 230 dict: DictCLI(), |
88
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
231 str: BaseCLI(), |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
232 None: BaseCLI()} # default |
82 | 233 |
81
f3b2563b2a91
move to a class-based architecture
Jeff Hammel <jhammel@mozilla.com>
parents:
80
diff
changeset
|
234 __all__ += [i.__class__.__name__ for i in types.values()] |
4 | 235 |
59
b8f066b8ab62
begin migration path towards inheriting from ConfigParser; ideally, Configuration should live in its own class and the CLI class should inherit from that
Jeff Hammel <jhammel@mozilla.com>
parents:
54
diff
changeset
|
236 class Configuration(optparse.OptionParser): |
29
fadcc6ab51d4
more (de/)serialization stubbing
Jeff Hammel <jhammel@mozilla.com>
parents:
28
diff
changeset
|
237 """declarative configuration object""" |
fadcc6ab51d4
more (de/)serialization stubbing
Jeff Hammel <jhammel@mozilla.com>
parents:
28
diff
changeset
|
238 |
101
f4590492cb4c
handle load option a bit better
Jeff Hammel <jhammel@mozilla.com>
parents:
100
diff
changeset
|
239 options = {} # configuration basis definition |
118 | 240 extend = set() # which dicts/lists should be extended |
101
f4590492cb4c
handle load option a bit better
Jeff Hammel <jhammel@mozilla.com>
parents:
100
diff
changeset
|
241 load_option = 'load' # where to put the load option |
118 | 242 load_help = "load configuration from a file" |
1 | 243 |
125
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
244 @classmethod |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
245 def parse(cls, args, *_args, **_kwargs): |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
246 """get the resultant config dictionary in a single call""" |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
247 conf = cls(*_args, **_kwargs) |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
248 conf.parse_args(*_args, **_kwargs) |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
249 return conf.config |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
250 |
75
c119eb07a378
rename/shuffle options to make more sense
Jeff Hammel <jhammel@mozilla.com>
parents:
67
diff
changeset
|
251 def __init__(self, configuration_providers=configuration_providers, types=types, load=None, dump='--dump', **parser_args): |
61
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
252 |
84
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
253 # sanity check |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
254 if isinstance(self.options, dict): |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
255 self.option_dict = self.options |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
256 elif isinstance(self.options, list): |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
257 # XXX could also be tuple, etc |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
258 self.option_dict = dict(self.options) |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
259 else: |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
260 raise NotImplementedError |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
261 |
61
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
262 # setup configuration |
2 | 263 self.config = {} |
6 | 264 self.configuration_providers = configuration_providers |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
265 self.types = types |
116
9d19ed8fd883
https://bugzilla.mozilla.org/show_bug.cgi?id=796196
Jeff Hammel <jhammel@mozilla.com>
parents:
115
diff
changeset
|
266 self.added = set() # set of items added to the configuration |
61
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
267 |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
268 # setup optionparser |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
269 if 'description' not in parser_args: |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
270 parser_args['description'] = getattr(self, '__doc__', '') |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
271 if 'formatter' not in parser_args: |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
272 class PlainDescriptionFormatter(optparse.IndentedHelpFormatter): |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
273 """description formatter for console script entry point""" |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
274 def format_description(self, description): |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
275 if description: |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
276 return description.strip() + '\n' |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
277 else: |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
278 return '' |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
279 parser_args['formatter'] = PlainDescriptionFormatter() |
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
280 parser_args.setdefault('option_class', ConfigurationOption) |
59
b8f066b8ab62
begin migration path towards inheriting from ConfigParser; ideally, Configuration should live in its own class and the CLI class should inherit from that
Jeff Hammel <jhammel@mozilla.com>
parents:
54
diff
changeset
|
281 optparse.OptionParser.__init__(self, **parser_args) |
109
09642528be02
keep track of parsed values as well as individual instances
Jeff Hammel <jhammel@mozilla.com>
parents:
108
diff
changeset
|
282 self.parsed = dict() |
61
ef2d1c6211b9
more stubbing to make Configuration an OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
60
diff
changeset
|
283 self.optparse_options(self) |
63 | 284 # add option(s) for configuration_providers |
75
c119eb07a378
rename/shuffle options to make more sense
Jeff Hammel <jhammel@mozilla.com>
parents:
67
diff
changeset
|
285 if load: |
c119eb07a378
rename/shuffle options to make more sense
Jeff Hammel <jhammel@mozilla.com>
parents:
67
diff
changeset
|
286 self.add_option(load, |
118 | 287 dest=self.load_option, |
288 action='append', | |
289 help=self.load_help) | |
63 | 290 |
291 # add an option for dumping | |
292 formats = self.formats() | |
293 if formats and dump: | |
90 | 294 if isinstance(dump, basestring): |
295 dump = [dump] | |
296 dump = list(dump) | |
107 | 297 self.add_option(*dump, **dict(dest='dump', |
298 help="Output configuration file; Formats: %s" % formats)) | |
63 | 299 |
2 | 300 |
29
fadcc6ab51d4
more (de/)serialization stubbing
Jeff Hammel <jhammel@mozilla.com>
parents:
28
diff
changeset
|
301 ### methods for iteration |
67 | 302 ### TODO: make the class a real iterator |
29
fadcc6ab51d4
more (de/)serialization stubbing
Jeff Hammel <jhammel@mozilla.com>
parents:
28
diff
changeset
|
303 |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
304 def items(self): |
112 | 305 # allow options to be a list of 2-tuples |
84
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
306 if isinstance(self.options, dict): |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
307 return self.options.items() |
34c13cde0255
move towards dict or items system
Jeff Hammel <jhammel@mozilla.com>
parents:
82
diff
changeset
|
308 return self.options |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
309 |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
310 ### methods for validating configuration |
2 | 311 |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
312 def check(self, config): |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
313 """ |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
314 check validity of configuration to be added |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
315 """ |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
316 |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
317 # ensure options in configuration are in self.options |
86 | 318 unknown_options = [i for i in config if i not in self.option_dict] |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
319 if unknown_options: |
67 | 320 raise UnknownOptionException("Unknown options: %s" % ', '.join(unknown_options)) |
6 | 321 |
67 | 322 # ensure options are of the right type (if specified) |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
323 for key, value in config.items(): |
86 | 324 _type = self.option_dict[key].get('type') |
325 if _type is None and 'default' in self.option_dict[key]: | |
326 _type = type(self.option_dict[key]['default']) | |
115 | 327 if _type is not None: |
328 tocast = True | |
46 | 329 try: |
115 | 330 if isinstance(value, _type): |
331 tocast = False | |
332 except TypeError: | |
333 # type is a type-casting function, not a proper type | |
334 pass | |
335 if tocast: | |
336 try: | |
337 config[key] = _type(value) | |
338 except BaseException, e: | |
339 raise TypeCastException("Could not coerce %s, %s, to type %s: %s" % (key, value, _type.__name__, e)) | |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
340 |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
341 return config |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
342 |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
343 def validate(self): |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
344 """validate resultant configuration""" |
67 | 345 |
78 | 346 for key, value in self.items(): |
35
321fe58a9eae
flush out validate function
Jeff Hammel <jhammel@mozilla.com>
parents:
34
diff
changeset
|
347 if key not in self.config: |
321fe58a9eae
flush out validate function
Jeff Hammel <jhammel@mozilla.com>
parents:
34
diff
changeset
|
348 required = value.get('required') |
321fe58a9eae
flush out validate function
Jeff Hammel <jhammel@mozilla.com>
parents:
34
diff
changeset
|
349 if required: |
321fe58a9eae
flush out validate function
Jeff Hammel <jhammel@mozilla.com>
parents:
34
diff
changeset
|
350 if isinstance(required, basestring): |
321fe58a9eae
flush out validate function
Jeff Hammel <jhammel@mozilla.com>
parents:
34
diff
changeset
|
351 required_message = required |
321fe58a9eae
flush out validate function
Jeff Hammel <jhammel@mozilla.com>
parents:
34
diff
changeset
|
352 else: |
321fe58a9eae
flush out validate function
Jeff Hammel <jhammel@mozilla.com>
parents:
34
diff
changeset
|
353 required_message = "Parameter %s is required but not present" % key |
67 | 354 # TODO: this should probably raise all missing values vs |
37
a1f8dec4d4f9
we has another broken test
Jeff Hammel <jhammel@mozilla.com>
parents:
36
diff
changeset
|
355 # one by one |
36
d218df4d0b4c
add test for missing values
Jeff Hammel <jhammel@mozilla.com>
parents:
35
diff
changeset
|
356 raise MissingValueException(required_message) |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
357 # TODO: configuration should be locked after this is called |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
358 |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
359 ### methods for adding configuration |
6 | 360 |
102
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
361 def default_config(self): |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
362 """configuration defaults""" |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
363 defaults = {} |
103 | 364 for key, value in self.items(): |
102
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
365 if 'default' in value: |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
366 defaults[key] = value['default'] |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
367 return copy.deepcopy(defaults) |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
368 |
125
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
369 def get(self, key, default=None): |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
370 return self.config.get(key, default) |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
371 |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
372 def __getitem__(self, key): |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
373 return self.config[key] |
c6a41a60afc0
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
124
diff
changeset
|
374 |
2 | 375 def __call__(self, *args): |
376 """add items to configuration and check it""" | |
116
9d19ed8fd883
https://bugzilla.mozilla.org/show_bug.cgi?id=796196
Jeff Hammel <jhammel@mozilla.com>
parents:
115
diff
changeset
|
377 # TODO: configuration should be locked after this is called |
67 | 378 |
102
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
379 # start with defaults |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
380 self.config = self.default_config() |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
381 |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
382 # add the configuration |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
383 for config in args: |
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
384 self.add(config) |
34
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
385 |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
386 # validate total configuration |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
387 self.validate() |
116
9d19ed8fd883
https://bugzilla.mozilla.org/show_bug.cgi?id=796196
Jeff Hammel <jhammel@mozilla.com>
parents:
115
diff
changeset
|
388 |
9d19ed8fd883
https://bugzilla.mozilla.org/show_bug.cgi?id=796196
Jeff Hammel <jhammel@mozilla.com>
parents:
115
diff
changeset
|
389 # return the configuration |
9d19ed8fd883
https://bugzilla.mozilla.org/show_bug.cgi?id=796196
Jeff Hammel <jhammel@mozilla.com>
parents:
115
diff
changeset
|
390 return self.config |
2 | 391 |
24
39f2611db9be
rename a bunch of things and begin to work on the sanity of validation
Jeff Hammel <jhammel@mozilla.com>
parents:
23
diff
changeset
|
392 def add(self, config, check=True): |
2 | 393 """update configuration: not undoable""" |
6 | 394 |
102
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
395 # check config to be added |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
396 self.check(config) |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
397 |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
398 # add the configuration |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
399 for key, value in config.items(): |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
400 value = copy.deepcopy(value) |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
401 if key in self.extend and key in self.config: |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
402 type1 = type(self.config[key]) |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
403 type2 = type(value) |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
404 assert type1 == type2 # XXX hack |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
405 if type1 == dict: |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
406 self.config[key].update(value) |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
407 elif type1 == list: |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
408 self.config[key].extend(value) |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
409 else: |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
410 raise NotImplementedError |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
411 else: |
c530f6265deb
allow extensible configuration; also start using deepcopy heavily since otherwise you have artefacts
Jeff Hammel <jhammel@mozilla.com>
parents:
101
diff
changeset
|
412 self.config[key] = value |
116
9d19ed8fd883
https://bugzilla.mozilla.org/show_bug.cgi?id=796196
Jeff Hammel <jhammel@mozilla.com>
parents:
115
diff
changeset
|
413 self.added.add(key) |
9d19ed8fd883
https://bugzilla.mozilla.org/show_bug.cgi?id=796196
Jeff Hammel <jhammel@mozilla.com>
parents:
115
diff
changeset
|
414 |
2 | 415 |
18
d8871956536e
remove cruft and start to organize
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
416 ### methods for optparse |
d8871956536e
remove cruft and start to organize
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
417 ### XXX could go in a subclass |
d8871956536e
remove cruft and start to organize
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
418 |
82 | 419 def cli_formatter(self, option): |
99
17001bceec8f
only use formatters for options we actually know about from self.options; the rest should be handled from the client
Jeff Hammel <jhammel@mozilla.com>
parents:
98
diff
changeset
|
420 if option in self.option_dict: |
108
a2184db43fe2
fix dict command line processing
Jeff Hammel <jhammel@mozilla.com>
parents:
107
diff
changeset
|
421 handler = self.types[self.option_type(option)] |
99
17001bceec8f
only use formatters for options we actually know about from self.options; the rest should be handled from the client
Jeff Hammel <jhammel@mozilla.com>
parents:
98
diff
changeset
|
422 return getattr(handler, 'take_action', lambda x: x) |
82 | 423 |
88
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
424 def option_type(self, name): |
98
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
425 """get the type of an option named `name`""" |
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
426 |
88
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
427 value = self.option_dict[name] |
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
428 if 'type' in value: |
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
429 return value['type'] |
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
430 if 'default' in value: |
98
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
431 default = value['default'] |
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
432 if default is None: |
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
433 return None |
88
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
434 return type(value['default']) |
36cf1d9bf40b
slightly improve type system
Jeff Hammel <jhammel@mozilla.com>
parents:
87
diff
changeset
|
435 |
17
a78ab14ae376
separate thing to add options to its own function
Jeff Hammel <jhammel@mozilla.com>
parents:
15
diff
changeset
|
436 def optparse_options(self, parser): |
a78ab14ae376
separate thing to add options to its own function
Jeff Hammel <jhammel@mozilla.com>
parents:
15
diff
changeset
|
437 """add optparse options to a OptionParser instance""" |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
438 for key, value in self.items(): |
98
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
439 try: |
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
440 handler = self.types[self.option_type(key)] |
114
d1911d9b5b19
if an option cannot be coerced to a type we should just not add a CLI handler for it
Jeff Hammel <jhammel@mozilla.com>
parents:
113
diff
changeset
|
441 except KeyError: |
d1911d9b5b19
if an option cannot be coerced to a type we should just not add a CLI handler for it
Jeff Hammel <jhammel@mozilla.com>
parents:
113
diff
changeset
|
442 # if an option can't be coerced to a type |
98
91e213025769
handle None type (though its probably a bogus case) and note on future failure upon coercion
Jeff Hammel <jhammel@mozilla.com>
parents:
96
diff
changeset
|
443 # we should just not add a CLI handler for it |
114
d1911d9b5b19
if an option cannot be coerced to a type we should just not add a CLI handler for it
Jeff Hammel <jhammel@mozilla.com>
parents:
113
diff
changeset
|
444 continue |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
445 args, kw = handler(key, value) |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
446 if not args: |
21
0fe74db6a56c
a hacky way to do CLI types handlers
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
447 # No CLI interface |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
448 continue |
12 | 449 parser.add_option(*args, **kw) |
17
a78ab14ae376
separate thing to add options to its own function
Jeff Hammel <jhammel@mozilla.com>
parents:
15
diff
changeset
|
450 |
119 | 451 def configuration_files(self, options, args): |
452 """configuration files to read""" | |
63 | 453 |
101
f4590492cb4c
handle load option a bit better
Jeff Hammel <jhammel@mozilla.com>
parents:
100
diff
changeset
|
454 configuration_files = getattr(options, self.load_option, args) |
f4590492cb4c
handle load option a bit better
Jeff Hammel <jhammel@mozilla.com>
parents:
100
diff
changeset
|
455 if not configuration_files: |
f4590492cb4c
handle load option a bit better
Jeff Hammel <jhammel@mozilla.com>
parents:
100
diff
changeset
|
456 configuration_files = [] |
f4590492cb4c
handle load option a bit better
Jeff Hammel <jhammel@mozilla.com>
parents:
100
diff
changeset
|
457 if isinstance(configuration_files, basestring): |
f4590492cb4c
handle load option a bit better
Jeff Hammel <jhammel@mozilla.com>
parents:
100
diff
changeset
|
458 configuration_files = [configuration_files] |
119 | 459 return configuration_files |
460 | |
120
4c7f93ce302a
separate loading configuration files to its own method for consumers
Jeff Hammel <jhammel@mozilla.com>
parents:
119
diff
changeset
|
461 def load_configuration_file(self, filename): |
4c7f93ce302a
separate loading configuration files to its own method for consumers
Jeff Hammel <jhammel@mozilla.com>
parents:
119
diff
changeset
|
462 """load a configuration file""" |
4c7f93ce302a
separate loading configuration files to its own method for consumers
Jeff Hammel <jhammel@mozilla.com>
parents:
119
diff
changeset
|
463 return self.deserialize(filename) |
4c7f93ce302a
separate loading configuration files to its own method for consumers
Jeff Hammel <jhammel@mozilla.com>
parents:
119
diff
changeset
|
464 |
119 | 465 def read_configuration_files(self, options, args): |
466 """deserialize configuration""" | |
467 | |
468 configuration_files = self.configuration_files(options, args) | |
63 | 469 missing = [i for i in configuration_files |
470 if not os.path.exists(i)] | |
471 if missing: | |
64 | 472 self.error("Missing files: %s" % ', '.join(missing)) |
63 | 473 config = [] |
474 for f in configuration_files: | |
475 try: | |
120
4c7f93ce302a
separate loading configuration files to its own method for consumers
Jeff Hammel <jhammel@mozilla.com>
parents:
119
diff
changeset
|
476 loaded_config = self.load_configuration_file(f) |
104
9dd0ebcdbc62
be more forgiving of blank configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
103
diff
changeset
|
477 if loaded_config: |
9dd0ebcdbc62
be more forgiving of blank configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
103
diff
changeset
|
478 config.append(loaded_config) |
63 | 479 except BaseException, e: |
480 parser.error(str(e)) | |
117 | 481 return config |
482 | |
483 def parse_args(self, *args, **kw): | |
484 | |
120
4c7f93ce302a
separate loading configuration files to its own method for consumers
Jeff Hammel <jhammel@mozilla.com>
parents:
119
diff
changeset
|
485 # parse command line options |
117 | 486 self.parsed = dict() |
487 options, args = optparse.OptionParser.parse_args(self, *args, **kw) | |
488 | |
489 # get CLI configuration options | |
490 cli_config = dict([(key, value) for key, value in options.__dict__.items() | |
491 if key in self.option_dict and key in self.parsed]) | |
492 | |
493 # deserialize configuration | |
494 config = self.read_configuration_files(options, args) | |
63 | 495 config.append(cli_config) |
496 | |
497 missingvalues = None | |
498 try: | |
499 # generate configuration | |
500 self(*config) | |
501 except MissingValueException, missingvalues: | |
89
0804a706d6bf
handle CLI errors with optparse
Jeff Hammel <jhammel@mozilla.com>
parents:
88
diff
changeset
|
502 # errors are handled below |
63 | 503 pass |
504 | |
94
291fbbeb6e1e
actually dump configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
93
diff
changeset
|
505 # dump configuration |
106
a929a7331069
remove extraneous assignment
Jeff Hammel <jhammel@mozilla.com>
parents:
104
diff
changeset
|
506 self.dump(options, missingvalues) |
63 | 507 |
64 | 508 # update options from config |
509 options.__dict__.update(self.config) | |
510 | |
63 | 511 # return parsed arguments |
512 return options, args | |
513 | |
95
290c40224e5d
improved abstraction; sadly doesnt seem to work
Jeff Hammel <jhammel@mozilla.com>
parents:
94
diff
changeset
|
514 def dump(self, options, missingvalues): |
90 | 515 """dump configuration, if specified""" |
91
1e06fd17b8ad
make dump method configurable
Jeff Hammel <jhammel@mozilla.com>
parents:
90
diff
changeset
|
516 |
96
bfe4234ee6f4
better ordering of processing for dump()
Jeff Hammel <jhammel@mozilla.com>
parents:
95
diff
changeset
|
517 if missingvalues: |
bfe4234ee6f4
better ordering of processing for dump()
Jeff Hammel <jhammel@mozilla.com>
parents:
95
diff
changeset
|
518 self.error(str(missingvalues)) |
bfe4234ee6f4
better ordering of processing for dump()
Jeff Hammel <jhammel@mozilla.com>
parents:
95
diff
changeset
|
519 |
90 | 520 dump = getattr(options, 'dump') |
521 if dump: | |
522 # TODO: have a way of specifying format other than filename | |
523 self.serialize(dump) | |
524 | |
28
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
525 ### serialization/deserialization |
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
526 |
43 | 527 def formats(self): |
528 """formats for deserialization""" | |
529 retval = [] | |
530 for provider in self.configuration_providers: | |
531 if provider.extensions and hasattr(provider, 'write'): | |
532 retval.append(provider.extensions[0]) | |
533 return retval | |
534 | |
28
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
535 def configuration_provider(self, format): |
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
536 """configuration provider guess for a given filename""" |
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
537 for provider in self.configuration_providers: |
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
538 if format in provider.extensions: |
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
539 return provider |
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
540 |
34
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
541 def filename2format(self, filename): |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
542 extension = os.path.splitext(filename)[-1] |
38
8909ae1cc4ea
fix serialization (stub) tests
Jeff Hammel <jhammel@mozilla.com>
parents:
37
diff
changeset
|
543 return extension.lstrip('.') or None |
34
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
544 |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
545 def serialize(self, filename, format=None, full=False): |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
546 """ |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
547 serialize configuration to a file |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
548 - filename: path of file to serialize to |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
549 - format: format of configuration provider |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
550 - full: whether to serialize non-set optional strings [TODO] |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
551 """ |
29
fadcc6ab51d4
more (de/)serialization stubbing
Jeff Hammel <jhammel@mozilla.com>
parents:
28
diff
changeset
|
552 # TODO: allow file object vs file name |
28
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
553 |
34
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
554 if not format: |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
555 format = self.filename2format(filename) |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
556 if not format: |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
557 raise Exception('Please specify a format') |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
558 # TODO: more specific exception type |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
559 |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
560 provider = self.configuration_provider(format) |
38
8909ae1cc4ea
fix serialization (stub) tests
Jeff Hammel <jhammel@mozilla.com>
parents:
37
diff
changeset
|
561 if not provider: |
8909ae1cc4ea
fix serialization (stub) tests
Jeff Hammel <jhammel@mozilla.com>
parents:
37
diff
changeset
|
562 raise Exception("Provider not found for format: %s" % format) |
34
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
563 |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
564 config = copy.deepcopy(self.config) |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
565 |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
566 provider.write(config, filename) |
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
567 |
28
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
568 def deserialize(self, filename, format=None): |
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
569 """load configuration from a file""" |
29
fadcc6ab51d4
more (de/)serialization stubbing
Jeff Hammel <jhammel@mozilla.com>
parents:
28
diff
changeset
|
570 # TODO: allow file object vs file name |
28
c516ab813079
begin stubbing serialization/deserialization
Jeff Hammel <jhammel@mozilla.com>
parents:
27
diff
changeset
|
571 |
50
113e8c2f7cab
start to hook up deserializers
Jeff Hammel <jhammel@mozilla.com>
parents:
49
diff
changeset
|
572 assert os.path.exists(filename) |
113e8c2f7cab
start to hook up deserializers
Jeff Hammel <jhammel@mozilla.com>
parents:
49
diff
changeset
|
573 |
41
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
574 # get the format |
29
fadcc6ab51d4
more (de/)serialization stubbing
Jeff Hammel <jhammel@mozilla.com>
parents:
28
diff
changeset
|
575 if not format: |
41
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
576 format = self.filename2format(filename) |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
577 |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
578 # get the providers in some sensible order |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
579 providers = self.configuration_providers[:] |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
580 if format: |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
581 providers.sort(key=lambda x: int(format in x.extensions), reverse=True) |
34
79aca36abd9a
fill in defaults if not present
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
582 |
41
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
583 # deserialize the data |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
584 for provider in providers: |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
585 try: |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
586 return provider.read(filename) |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
587 except: |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
588 continue |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
589 else: |
1bd4ddf2e81d
deserialization should work now
Jeff Hammel <jhammel@mozilla.com>
parents:
38
diff
changeset
|
590 raise ConfigurationProviderException("Could not load %s" % filename) |
122
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
591 |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
592 class UserConfiguration(Configuration): |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
593 """`Configuration` class driven by a config file in user-space""" |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
594 |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
595 # configuration items to interpolate as paths |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
596 # TODO: moar bettur! |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
597 paths = [] |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
598 |
123
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
599 def __init__(self, config=None, load='--config'): |
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
600 |
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
601 # default configuration file |
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
602 self.config_name = config or '.' + os.path.splitext(sys.argv[0])[0] |
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
603 self.default_config_file = os.path.join('~', self.config_name) |
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
604 self.default_config_file_path = os.path.expanduser(self.default_config_file) |
124 | 605 if os.path.exists(self.default_config_file_path): |
126
82151d79e117
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
125
diff
changeset
|
606 self.load_help += ' [DEFAULT: %s]' % self.default_config_file |
123
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
607 |
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
608 Configuration.__init__(self, usage=self.usage, load=load) |
122
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
609 |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
610 def validate(self): |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
611 Configuration.validate(self) |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
612 for path in self.paths: |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
613 self.config[path] = os.path.expanduser(self.config[path]) |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
614 |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
615 def configuration_files(self, options, args): |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
616 configuration_files = Configuration.configuration_files(self, options, args) |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
617 if not configuration_files: |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
618 # load user config only if no config provided |
123
bb0f58ae318e
configuration/configuration.py
Jeff Hammel <jhammel@mozilla.com>
parents:
122
diff
changeset
|
619 if os.path.exists(self.default_config_file_path): |
122
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
620 configuration_files = [default_config] |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
621 return configuration_files |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
622 |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
623 def load_configuration_file(self, filename): |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
624 config = Configuration.load_configuration_file(self, filename) |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
625 |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
626 # ignore options that we don't care about |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
627 config = dict([(key, value) for key, value in config.items() |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
628 if key in self.option_dict]) |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
629 |
90cb8aedecbb
< http://k0s.org/mozilla/hg/MozillaTry/raw-file/582f3571ab33/mozillatry.py
Jeff Hammel <jhammel@mozilla.com>
parents:
120
diff
changeset
|
630 return config |