-
Karl-Hermann Wieners authoredKarl-Hermann Wieners authored
setconfig 3.26 KiB
#! /usr/bin/env python
'''\
Change configuration using command line
$Id$
'''
from __future__ import print_function
import argparse
import io
import re
import sys
from expconfig import ConfigObj
from expargparse import assigns_to_dicts, get_key_chain
from feedback import die
import package_info
#
# Main routine
#
# Check command line
command_line = argparse.ArgumentParser(description=__doc__.split('\n', 1)[0])
command_line.add_argument('config', nargs='?', default='-',
help='original configuration file name [%(default)s]')
command_line.add_argument('assigns', metavar='key=value', nargs='*',
help='override configuration file settings')
command_line.add_argument('-V', '--version', action='version',
version=package_info.version)
command_line.add_argument('--delete', '-d', action='append', default=[],
help='remove given keys from configuration')
command_line.add_argument('--header', '-H', action='append', default=[],
help='append text to header (initial comment)')
command_line.add_argument('--add', '-a', action='append', default=[],
help='add settings from file')
command_line.add_argument('--inline-comments' , '-c', action='store_true',
help='compact white space before inline comments'
' (BETA)')
command_line.add_argument('--trailing-space' , '-t', action='store_true',
help='remove white space at end of lines')
command_line.add_argument('--keep-section-quotes', action='store_true',
help='do not remove quotes from section names')
args = command_line.parse_args()
# File handling
try:
config_file = args.config
if config_file == '-':
config_file = sys.stdin
config_data = ConfigObj(config_file, file_error=True,
write_empty_values=True)
# Add settings from other files
for add_file in args.add:
if add_file == '-':
add_file = sys.stdin
config_data.merge(ConfigObj(add_file, file_error=True))
except IOError as error:
die(error.message)
# Remove keys from --delete command line option
for current in args.delete:
config = config_data
chain = get_key_chain(current)
chain.reverse()
key = chain.pop()
for section in chain:
config = config[section]
del config[key]
# Merge key=value assignments from command line
if args.assigns:
for d in assigns_to_dicts(args):
config_data.merge(d)
# Add lines to header
back_plate = []
for line in reversed(config_data.initial_comment):
if re.match(r'^[\s#]*$', line):
back_plate.insert(0, config_data.initial_comment.pop())
else:
break
for line in args.header:
config_data.initial_comment.append(line)
for line in back_plate:
config_data.initial_comment.append(line)
# Ready to roll out
lines = io.BytesIO()
config_data.write(lines)
lines.seek(0)
for line in io.TextIOWrapper(lines):
if args.inline_comments: line = re.sub(r' = (.*?) #', r' = \1 #', line)
if not args.keep_section_quotes: line = re.sub(r'\["(.*?)"\]', r'[\1]', line)
if args.trailing_space:
print(line.rstrip())
else:
print(line, end='')