rhodecode_config.py
138 lines
| 4.2 KiB
| text/x-python
|
PythonLexer
r4011 | """ | |||
config generator | ||||
""" | ||||
from __future__ import with_statement | ||||
import os | ||||
import sys | ||||
import uuid | ||||
import argparse | ||||
from mako.template import Template | ||||
TMPL = 'template.ini.mako' | ||||
here = os.path.dirname(os.path.abspath(__file__)) | ||||
def argparser(argv): | ||||
usage = ( | ||||
"rhodecode-config [-h] [--filename=FILENAME] [--template=TEMPLATE] \n" | ||||
"VARS optional specify extra template variable that will be available in " | ||||
"template. Use comma separated key=val format eg.\n" | ||||
"key1=val1,port=5000,host=127.0.0.1,elements='a\,b\,c'\n" | ||||
) | ||||
parser = argparse.ArgumentParser( | ||||
description='RhodeCode CONFIG generator with variable replacement', | ||||
usage=usage | ||||
) | ||||
## config | ||||
group = parser.add_argument_group('CONFIG') | ||||
group.add_argument('--filename', help='Output ini filename.') | ||||
group.add_argument('--template', help='Mako template file to use instead of ' | ||||
'the default builtin template') | ||||
group.add_argument('--raw', help='Store given mako template as raw without ' | ||||
'parsing. Use this to create custom template ' | ||||
'initially', action='store_true') | ||||
group.add_argument('--show-defaults', help='Show all default variables for ' | ||||
'builtin template', action='store_true') | ||||
args, other = parser.parse_known_args() | ||||
return parser, args, other | ||||
def _escape_split(text, sep): | ||||
""" | ||||
Allows for escaping of the separator: e.g. arg='foo\, bar' | ||||
It should be noted that the way bash et. al. do command line parsing, those | ||||
single quotes are required. a shameless ripoff from fabric project. | ||||
""" | ||||
escaped_sep = r'\%s' % sep | ||||
if escaped_sep not in text: | ||||
return text.split(sep) | ||||
before, _, after = text.partition(escaped_sep) | ||||
startlist = before.split(sep) # a regular split is fine here | ||||
unfinished = startlist[-1] | ||||
startlist = startlist[:-1] | ||||
# recurse because there may be more escaped separators | ||||
endlist = _escape_split(after, sep) | ||||
# finish building the escaped value. we use endlist[0] becaue the first | ||||
# part of the string sent in recursion is the rest of the escaped value. | ||||
unfinished += sep + endlist[0] | ||||
return startlist + [unfinished] + endlist[1:] # put together all the parts | ||||
def _run(argv): | ||||
parser, args, other = argparser(argv) | ||||
if not len(sys.argv) > 1: | ||||
print parser.print_help() | ||||
sys.exit(0) | ||||
# defaults that can be overwritten by arguments | ||||
tmpl_stored_args = { | ||||
'http_server': 'waitress', | ||||
'lang': 'en', | ||||
'database_engine': 'sqlite', | ||||
'host': '127.0.0.1', | ||||
'port': 5000, | ||||
'error_aggregation_service': None | ||||
} | ||||
if other: | ||||
# parse arguments, we assume only first is correct | ||||
kwargs = {} | ||||
for el in _escape_split(other[0], ','): | ||||
kv = _escape_split(el, '=') | ||||
if len(kv) == 2: | ||||
k, v = kv | ||||
kwargs[k] = v | ||||
# update our template stored args | ||||
tmpl_stored_args.update(kwargs) | ||||
# use default that cannot be replaced | ||||
tmpl_stored_args.update({ | ||||
'uuid': lambda: uuid.uuid4().hex, | ||||
'here': os.path.abspath(os.curdir), | ||||
}) | ||||
if args.show_defaults: | ||||
for k,v in tmpl_stored_args.iteritems(): | ||||
print '%s=%s' % (k, v) | ||||
sys.exit(0) | ||||
try: | ||||
# built in template | ||||
tmpl_file = os.path.join(here, TMPL) | ||||
if args.template: | ||||
tmpl_file = args.template | ||||
with open(tmpl_file, 'rb') as f: | ||||
tmpl_data = f.read() | ||||
if args.raw: | ||||
tmpl = tmpl_data | ||||
else: | ||||
tmpl = Template(tmpl_data).render(**tmpl_stored_args) | ||||
with open(args.filename, 'wb') as f: | ||||
f.write(tmpl) | ||||
print 'Wrote new config file in %s' % (os.path.abspath(args.filename)) | ||||
except Exception: | ||||
from mako import exceptions | ||||
print exceptions.text_error_template().render() | ||||
def main(argv=None): | ||||
""" | ||||
Main execution function for cli | ||||
:param argv: | ||||
""" | ||||
if argv is None: | ||||
argv = sys.argv | ||||
try: | ||||
return _run(argv) | ||||
except Exception: | ||||
raise | ||||
if __name__ == '__main__': | ||||
sys.exit(main(sys.argv)) | ||||