Mercurial > hg > configuration
annotate configuration/config.py @ 15:0df4bfdc2c96
make --help work
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Mon, 26 Mar 2012 10:41:38 -0700 |
parents | 0f8115a41ad6 |
children | a78ab14ae376 |
rev | line source |
---|---|
0 | 1 #!/usr/bin/env python |
2 | |
3 """ | |
4 multi-level unified configuration | |
5 """ | |
6 | |
7 import sys | |
8 import optparse | |
9 | |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
10 # imports for contigent configuration providers |
4 | 11 try: |
12 import json | |
13 except ImportError: | |
14 try: | |
15 import simplejson as json | |
16 except ImportError: | |
17 json = None | |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
18 try: |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
19 import yaml |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
20 except ImportError: |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
21 yaml = None |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
22 |
6 | 23 __all__ = ['Configuration', 'configuration_providers'] |
24 | |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
25 configuration_providers = [] |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
26 if json: |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
27 class JSON(object): |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
28 extensions = ['json'] |
7 | 29 def read(self, filename): |
9 | 30 return json.loads(file(filename).read()) |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
31 configuration_providers.append(JSON) |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
32 |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
33 if yaml: |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
34 class YAML(object): |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
35 extensions = ['yml'] |
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
36 def read(self, filename): |
6 | 37 f = file(filename) |
38 config = yaml.load(f) | |
39 f.close() | |
40 return config | |
41 | |
5
7910b0ef0bab
stub configuration providers
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
42 configuration_providers.append(YAML) |
4 | 43 |
44 | |
1 | 45 class Configuration(object): |
46 options = {} | |
47 | |
6 | 48 def __init__(self, configuration_providers=configuration_providers): |
2 | 49 self.config = {} |
6 | 50 self.configuration_providers = configuration_providers |
2 | 51 |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
52 def items(self): |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
53 # TODO: allow options to be a list of 2-tuples |
13 | 54 return self.options.items() |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
55 |
6 | 56 def check(self, config): |
2 | 57 """check validity of configuration""" |
58 | |
6 | 59 # TODO: ensure options in configuration are in self.options |
60 unknown_options = [] | |
61 | |
10 | 62 # TODO: ensure options are of the right type (if specified) |
6 | 63 |
2 | 64 def __call__(self, *args): |
65 """add items to configuration and check it""" | |
66 | |
67 def add(self, config): | |
68 """update configuration: not undoable""" | |
6 | 69 |
70 self.check(config) | |
71 | |
2 | 72 self.config.update(config) |
73 # TODO: option to extend; augment lists/dicts | |
74 | |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
75 def parser(self, configuration_provider_option=None, **parser_args): |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
76 """ |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
77 return OptionParser for this Configuration instance |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
78 - configuration_provider_options : option for configuration files [TODO] |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
79 (also TODO: a special value that equates to the first file extension value |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
80 for the configuration_providers) |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
81 - parser_args : arguments to the OptionParser constructor |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
82 """ |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
83 if 'description' not in parser_args: |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
84 parser_args['description'] = getattr(self, '__doc__', '') |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
85 if 'formatter' not in parser_args: |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
86 class PlainDescriptionFormatter(optparse.IndentedHelpFormatter): |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
87 """description formatter for console script entry point""" |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
88 def format_description(self, description): |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
89 if description: |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
90 return description.strip() + '\n' |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
91 else: |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
92 return '' |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
93 parser_args['formatter'] = PlainDescriptionFormatter() |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
94 parser = optparse.OptionParser(**parser_args) |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
95 for key, value in self.items(): |
15 | 96 # TODO: move adding options to a separate function |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
97 |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
98 # CLI arguments |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
99 args = value.get('flags', ['--%s' % key]) |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
100 if not args: |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
101 continue |
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
102 |
12 | 103 kw = {'dest': key} |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
104 help = value.get('help', key) |
12 | 105 if 'default' in value: |
11
e00afe2c83bf
stubbing configuration parser
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
106 |
12 | 107 kw['default'] = value['default'] |
108 # TODO: use default pattern a la | |
109 # - http://hg.mozilla.org/build/talos/file/c6013a2f09ce/talos/PerfConfigurator.py#l358 | |
110 # - http://k0s.org/mozilla/hg/bzconsole/file/d5e88dadde69/bzconsole/command.py#l12 | |
111 | |
112 help += ' [DEFAULT: %s]' % value['default'] | |
15 | 113 kw['help'] = help |
12 | 114 kw['action'] = 'store' # TODO: types |
115 parser.add_option(*args, **kw) | |
15 | 116 return parser |
8
975fbc45cfcd
note TODO: returning OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
117 |
0 | 118 def main(args=sys.argv[:]): |
119 | |
120 # parse command line options | |
121 usage = '%prog [options]' | |
122 parser = optparse.OptionParser(usage=usage, description=__doc__, formatter=PlainDescriptionFormatter()) | |
123 options, args = parser.parse_args(args) | |
124 | |
125 if __name__ == '__main__': | |
126 main() | |
127 |