summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2017-05-15 11:48:44 +1000
committerChris Johns <chrisj@rtems.org>2017-05-15 11:48:44 +1000
commitef38b5d7c22b163a557172b50497af6eec624127 (patch)
tree0946132d4a6f21af1212d446c0373fc70b3b90e7
parentrtems-bsp-builder: Add all architectures and BSPs. (diff)
downloadrtems-tools-ef38b5d7c22b163a557172b50497af6eec624127.tar.bz2
rtemstoolkit: Add Python INI configuration support.
-rw-r--r--rtemstoolkit/configuration.py137
-rwxr-xr-xtester/rt/check.py133
2 files changed, 161 insertions, 109 deletions
diff --git a/rtemstoolkit/configuration.py b/rtemstoolkit/configuration.py
new file mode 100644
index 0000000..71ab3ca
--- /dev/null
+++ b/rtemstoolkit/configuration.py
@@ -0,0 +1,137 @@
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2017 Chris Johns (chrisj@rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Host specifics.
+#
+
+from __future__ import print_function
+
+import os
+import re
+
+try:
+ import configparser
+except:
+ import ConfigParser as configparser
+
+from rtemstoolkit import error
+from rtemstoolkit import path
+
+class configuration:
+
+ def __init__(self):
+ self.config = configparser.ConfigParser()
+ self.ini = None
+ self.macro_filter = re.compile('\$\{.+\}')
+
+ def get_item(self, section, label, err = True):
+ try:
+ rec = self.config.get(section, label).replace(os.linesep, ' ')
+ except:
+ if err:
+ raise error.general('config: no "%s" found in "%s"' % (label, section))
+ return None
+ #
+ # On Python 2.7 there is no extended interpolation so add support here.
+ # On Python 3 this should happen automatically and so the findall
+ # should find nothing.
+ #
+ for m in self.macro_filter.findall(rec):
+ if ':' not in m:
+ raise error.general('config: interpolation is ${section:value}: %s' % (m))
+ section_value = m[2:-1].split(':')
+ if len(section_value) != 2:
+ raise error.general('config: interpolation is ${section:value}: %s' % (m))
+ try:
+ ref = self.config.get(section_value[0],
+ section_value[1]).replace(os.linesep, ' ')
+ rec = rec.replace(m, ref)
+ except:
+ pass
+ return rec
+
+ def get_items(self, section, err = True):
+ try:
+ items = [(name, key.replace(os.linesep, ' ')) \
+ for name, key in self.config.items(section)]
+ return items
+ except:
+ if err:
+ raise error.general('config: section "%s" not found' % (section))
+ return []
+
+ def comma_list(self, section, label, err = True):
+ items = self.get_item(section, label, err)
+ if items is None:
+ return []
+ return sorted(set([a.strip() for a in items.split(',')]))
+
+ def get_item_names(self, section, err = True):
+ try:
+ return [item[0] for item in self.config.items(section)]
+ except:
+ if err:
+ raise error.general('config: section "%s" not found' % (section))
+ return []
+
+ def load(self, name):
+ #
+ # Load all the files.
+ #
+ self.ini = { 'base' : path.dirname(name),
+ 'files' : [] }
+ includes = [name]
+ still_loading = True
+ while still_loading:
+ still_loading = False
+ for include in includes:
+ if not path.exists(include):
+ rebased_inc = path.join(self.ini['base'],
+ path.basename(include))
+ if not path.exists(rebased_inc):
+ e = 'config: cannot find configuration: %s' % (include)
+ raise error.general(e)
+ include = rebased_inc
+ if include not in self.ini['files']:
+ try:
+ self.config.read(include)
+ except configparser.ParsingError as ce:
+ raise error.general('config: %s' % (ce))
+ still_loading = True
+ self.ini['files'] += [include]
+ includes = []
+ if still_loading:
+ for section in self.config.sections():
+ includes += self.comma_list(section, 'include', err = False)
+
+
+ def files(self):
+ return self.ini['files']
diff --git a/tester/rt/check.py b/tester/rt/check.py
index 31a3e7e..581f246 100755
--- a/tester/rt/check.py
+++ b/tester/rt/check.py
@@ -41,11 +41,7 @@ import textwrap
import pprint
-try:
- import configparser
-except:
- import ConfigParser as configparser
-
+from rtemstoolkit import configuration
from rtemstoolkit import execute
from rtemstoolkit import error
from rtemstoolkit import host
@@ -440,17 +436,13 @@ class results:
log.output(' %s (%5d):' % (self._arch_bsp(f[0], f[1]), f[3]))
log.output(wrap([' ' * 6, config_cmd], lineend = '\\', width = 75))
-class configuration:
+class configuration_:
def __init__(self):
- self.config = configparser.ConfigParser()
- self.name = None
- self.ini = None
+ self.config = configuration.configuration()
self.archs = { }
self.builds_ = { }
self.profiles = { }
- self.configurations = { }
- self.macro_filter = re.compile('\$\{.+\}')
def __str__(self):
import pprint
@@ -463,90 +455,10 @@ class configuration:
pprint.pformat(self.profiles, indent = 1, width = 80) + os.linesep
return s
- def _get_item(self, section, label, err = True):
- try:
- rec = self.config.get(section, label).replace(os.linesep, ' ')
- except:
- if err:
- raise error.general('config: no "%s" found in "%s"' % (label, section))
- return None
- #
- # On Python 2.7 there is no extended interpolation so add support here.
- # On Python 3 this should happen automatically and so the findall
- # should find nothing.
- #
- for m in self.macro_filter.findall(rec):
- if ':' not in m:
- raise error.general('config: interpolation is ${section:value}: %s' % (m))
- section_value = m[2:-1].split(':')
- if len(section_value) != 2:
- raise error.general('config: interpolation is ${section:value}: %s' % (m))
- try:
- ref = self.config.get(section_value[0],
- section_value[1]).replace(os.linesep, ' ')
- rec = rec.replace(m, ref)
- except:
- pass
- return rec
-
- def _get_items(self, section, err = True):
- try:
- items = [(name, key.replace(os.linesep, ' ')) \
- for name, key in self.config.items(section)]
- return items
- except:
- if err:
- raise error.general('config: section "%s" not found' % (section))
- return []
-
- def _comma_list(self, section, label, err = True):
- items = self._get_item(section, label, err)
- if items is None:
- return []
- return sorted(set([a.strip() for a in items.split(',')]))
-
- def _get_item_names(self, section, err = True):
- try:
- return [item[0] for item in self.config.items(section)]
- except:
- if err:
- raise error.general('config: section "%s" not found' % (section))
- return []
-
- def _load(self, name):
- #
- # Load all the files.
- #
- self.ini = { 'base' : path.dirname(name),
- 'files' : [] }
- includes = [name]
- still_loading = True
- while still_loading:
- still_loading = False
- for include in includes:
- if not path.exists(include):
- rebased_inc = path.join(self.ini['base'],
- path.basename(include))
- if not path.exists(rebased_inc):
- e = 'config: cannot find configuration: %s' % (include)
- raise error.general(e)
- include = rebased_inc
- if include not in self.ini['files']:
- try:
- self.config.read(include)
- except configparser.ParsingError as ce:
- raise error.general('config: %s' % (ce))
- still_loading = True
- self.ini['files'] += [include]
- includes = []
- if still_loading:
- for section in self.config.sections():
- includes += self._comma_list(section, 'include', err = False)
-
def _build_options(self, build, nesting = 0):
if ':' in build:
section, name = build.split(':', 1)
- opts = [self._get_item(section, name)]
+ opts = [self.config.get_item(section, name)]
return opts
builds = self.builds_['builds']
if build not in builds:
@@ -557,57 +469,60 @@ class configuration:
for option in self.builds_['builds'][build]:
if ':' in option:
section, name = option.split(':', 1)
- opts = [self._get_item(section, name)]
+ opts = [self.config.get_item(section, name)]
else:
- opts = self._options(option, nesting + 1)
+ opts = self._build_options(option, nesting + 1)
for opt in opts:
if opt not in options:
options += [opt]
return options
def load(self, name, build):
- self._load(name)
+ self.config.load(name)
archs = []
- self.profiles['profiles'] = self._comma_list('profiles', 'profiles', err = False)
+ self.profiles['profiles'] = \
+ self.config.comma_list('profiles', 'profiles', err = False)
if len(self.profiles['profiles']) == 0:
self.profiles['profiles'] = ['tier-%d' % (t) for t in range(1,4)]
for p in self.profiles['profiles']:
profile = {}
profile['name'] = p
- profile['archs'] = self._comma_list(profile['name'], 'archs')
+ profile['archs'] = self.config.comma_list(profile['name'], 'archs')
archs += profile['archs']
for arch in profile['archs']:
bsps = 'bsps_%s' % (arch)
- profile[bsps] = self._comma_list(profile['name'], bsps)
+ profile[bsps] = self.config.comma_list(profile['name'], bsps)
self.profiles[profile['name']] = profile
for a in set(archs):
arch = {}
arch['excludes'] = {}
- for exclude in self._comma_list(a, 'exclude', err = False):
+ for exclude in self.config.comma_list(a, 'exclude', err = False):
arch['excludes'][exclude] = ['all']
- for i in self._get_items(a, False):
+ for i in self.config.get_items(a, False):
if i[0].startswith('exclude-'):
exclude = i[0][len('exclude-'):]
if exclude not in arch['excludes']:
arch['excludes'][exclude] = []
- arch['excludes'][exclude] += sorted(set([b.strip() for b in i[1].split(',')]))
- arch['bsps'] = self._comma_list(a, 'bsps', err = False)
+ arch['excludes'][exclude] += \
+ sorted(set([b.strip() for b in i[1].split(',')]))
+ arch['bsps'] = self.config.comma_list(a, 'bsps', err = False)
for b in arch['bsps']:
arch[b] = {}
- arch[b]['bspopts'] = self._comma_list(a, 'bspopts_%s' % (b), err = False)
+ arch[b]['bspopts'] = \
+ self.config.comma_list(a, 'bspopts_%s' % (b), err = False)
self.archs[a] = arch
builds = {}
- builds['default'] = self._get_item('builds', 'default')
+ builds['default'] = self.config.get_item('builds', 'default')
if build is None:
build = builds['default']
builds['config'] = { }
- for config in self._get_items('config'):
+ for config in self.config.get_items('config'):
builds['config'][config[0]] = config[1]
builds['build'] = build
- builds_ = self._get_item_names('builds')
+ builds_ = self.config.get_item_names('builds')
builds['builds'] = {}
for build in builds_:
- build_builds = self._comma_list('builds', build)
+ build_builds = self.config.comma_list('builds', build)
has_config = False
has_build = False
for b in build_builds:
@@ -681,7 +596,7 @@ class configuration:
cols_2 = [10, width - 10]
s = textbox.line(cols_1, line = '=', marker = '+', indent = 1)
s1 = ' File(s)'
- for f in self.ini['files']:
+ for f in self.config.files():
colon = ':'
for l in textwrap.wrap(f, width = cols_2[1] - 3):
s += textbox.row(cols_2, [s1, ' ' + l], marker = colon, indent = 1)
@@ -1161,7 +1076,7 @@ def run_args(args):
log.notice(title())
log.output(command_line())
- config = configuration()
+ config = configuration_()
config.load(config_file, opts.build)
if opts.config_report: