conf: Add support to generate include statements in .conf files
This commit is contained in:
+33
-7
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright (C) 2014-2015 Tobias Brunner
|
# Copyright (C) 2014-2017 Tobias Brunner
|
||||||
# Hochschule fuer Technik Rapperswil
|
# HSR Hochschule fuer Technik Rapperswil
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public License as published by the
|
# under the terms of the GNU General Public License as published by the
|
||||||
@@ -49,6 +49,12 @@ full.section.name {[#]}
|
|||||||
If a # is added between the curly braces the section header will be commented
|
If a # is added between the curly braces the section header will be commented
|
||||||
out in the configuration file snippet, which is useful for example sections.
|
out in the configuration file snippet, which is useful for example sections.
|
||||||
|
|
||||||
|
To add include statements to generated config files (ignored when generating
|
||||||
|
man pages) the following format can be used:
|
||||||
|
|
||||||
|
full.section.name.include files/to/include
|
||||||
|
Description of this include statement
|
||||||
|
|
||||||
Dots in section/option names may be escaped with a backslash. For instance,
|
Dots in section/option names may be escaped with a backslash. For instance,
|
||||||
with the following section description
|
with the following section description
|
||||||
|
|
||||||
@@ -62,17 +68,18 @@ import sys
|
|||||||
import re
|
import re
|
||||||
from textwrap import TextWrapper
|
from textwrap import TextWrapper
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from operator import attrgetter
|
from functools import cmp_to_key
|
||||||
|
|
||||||
class ConfigOption:
|
class ConfigOption:
|
||||||
"""Representing a configuration option or described section in strongswan.conf"""
|
"""Representing a configuration option or described section in strongswan.conf"""
|
||||||
def __init__(self, path, default = None, section = False, commented = False):
|
def __init__(self, path, default = None, section = False, commented = False, include = False):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.name = path[-1]
|
self.name = path[-1]
|
||||||
self.fullname = '.'.join(path)
|
self.fullname = '.'.join(path)
|
||||||
self.default = default
|
self.default = default
|
||||||
self.section = section
|
self.section = section
|
||||||
self.commented = commented
|
self.commented = commented
|
||||||
|
self.include = include
|
||||||
self.desc = []
|
self.desc = []
|
||||||
self.options = []
|
self.options = []
|
||||||
|
|
||||||
@@ -99,6 +106,13 @@ class ConfigOption:
|
|||||||
self.commented = other.commented
|
self.commented = other.commented
|
||||||
self.desc = other.desc
|
self.desc = other.desc
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def cmp(a, b):
|
||||||
|
# order options before sections and includes last
|
||||||
|
if a.include or b.include:
|
||||||
|
return a.include - b.include
|
||||||
|
return a.section - b.section
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
"""Parses one or more files of configuration options"""
|
"""Parses one or more files of configuration options"""
|
||||||
def __init__(self, sort = True):
|
def __init__(self, sort = True):
|
||||||
@@ -135,6 +149,14 @@ class Parser:
|
|||||||
self.__current = ConfigOption(path, section = True,
|
self.__current = ConfigOption(path, section = True,
|
||||||
commented = m.group('comment'))
|
commented = m.group('comment'))
|
||||||
return
|
return
|
||||||
|
# include definition
|
||||||
|
m = re.match(r'^(?P<name>\S+\.include|include)\s+(?P<pattern>\S+)\s*$', line)
|
||||||
|
if m:
|
||||||
|
if self.__current:
|
||||||
|
self.__add_option(self.__current)
|
||||||
|
path = self.__split_name(m.group('name'))
|
||||||
|
self.__current = ConfigOption(path, m.group('pattern'), include = True)
|
||||||
|
return
|
||||||
# paragraph separator
|
# paragraph separator
|
||||||
m = re.match(r'^\s*$', line)
|
m = re.match(r'^\s*$', line)
|
||||||
if m and self.__current:
|
if m and self.__current:
|
||||||
@@ -248,7 +270,9 @@ class ConfFormatter:
|
|||||||
"""Print a single option with description and default value"""
|
"""Print a single option with description and default value"""
|
||||||
comment = "# " if commented or opt.commented else ""
|
comment = "# " if commented or opt.commented else ""
|
||||||
self.__print_description(opt, indent)
|
self.__print_description(opt, indent)
|
||||||
if opt.default:
|
if opt.include:
|
||||||
|
print('{0}{1} {2}'.format(self.__indent * indent, opt.name, opt.default))
|
||||||
|
elif opt.default:
|
||||||
print('{0}{1}{2} = {3}'.format(self.__indent * indent, comment, opt.name, opt.default))
|
print('{0}{1}{2} = {3}'.format(self.__indent * indent, comment, opt.name, opt.default))
|
||||||
else:
|
else:
|
||||||
print('{0}{1}{2} ='.format(self.__indent * indent, comment, opt.name))
|
print('{0}{1}{2} ='.format(self.__indent * indent, comment, opt.name))
|
||||||
@@ -261,7 +285,7 @@ class ConfFormatter:
|
|||||||
self.__print_description(section, indent)
|
self.__print_description(section, indent)
|
||||||
print('{0}{1}{2} {{'.format(self.__indent * indent, comment, section.name))
|
print('{0}{1}{2} {{'.format(self.__indent * indent, comment, section.name))
|
||||||
print('')
|
print('')
|
||||||
for o in sorted(section.options, key=attrgetter('section')):
|
for o in sorted(section.options, key=cmp_to_key(ConfigOption.cmp)):
|
||||||
if o.section:
|
if o.section:
|
||||||
self.__print_section(o, indent + 1, commented)
|
self.__print_section(o, indent + 1, commented)
|
||||||
else:
|
else:
|
||||||
@@ -273,7 +297,7 @@ class ConfFormatter:
|
|||||||
"""Print a list of options"""
|
"""Print a list of options"""
|
||||||
if not options:
|
if not options:
|
||||||
return
|
return
|
||||||
for option in sorted(options, key=attrgetter('section')):
|
for option in sorted(options, key=cmp_to_key(ConfigOption.cmp)):
|
||||||
if option.section:
|
if option.section:
|
||||||
self.__print_section(option, 0, False)
|
self.__print_section(option, 0, False)
|
||||||
else:
|
else:
|
||||||
@@ -297,6 +321,8 @@ class ManFormatter:
|
|||||||
"""Print a single option"""
|
"""Print a single option"""
|
||||||
if option.section and not len(option.desc):
|
if option.section and not len(option.desc):
|
||||||
return
|
return
|
||||||
|
if option.include:
|
||||||
|
return
|
||||||
if option.section:
|
if option.section:
|
||||||
print('.TP\n.B {0}\n.br'.format(option.fullname))
|
print('.TP\n.B {0}\n.br'.format(option.fullname))
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user