From: Huang Hao Date: Fri, 7 Sep 2012 05:11:07 +0000 (+0800) Subject: Support ini section header like [section "name"]. X-Git-Tag: 0.10~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fac40c04cebf673fd1bee0901e92eb7a52b5cd3a;p=tools%2Fgbs.git Support ini section header like [section "name"]. Add a class SectionPattern to support section header style like [section "name"]. It's also compatible with style like [section]. Change-Id: I6c35eb00a2f3be912cee34f421173fb0523aa191 --- diff --git a/gitbuildsys/conf.py b/gitbuildsys/conf.py index 3199608..49b7066 100644 --- a/gitbuildsys/conf.py +++ b/gitbuildsys/conf.py @@ -18,17 +18,70 @@ from __future__ import with_statement import os +import re +import ast import base64 from ConfigParser import SafeConfigParser, NoSectionError, NoOptionError, \ MissingSectionHeaderError from gitbuildsys import msger, errors + +class SectionPattern(object): + '''Pattern of section that support [section "name"] and [section]. + 1. If there is white-space in section header, it must obey the format like: + section_type white_spaces section_name, + section_name could be any string. + 2. otherwise section name is the whole string in brackets + ''' + + SECTCRE = re.compile( + r'\[' # [ + r'(?P
[^] \t]+)' # section name without any white-space + r'([ \t]+' # or + r'(?P[^]]+)' # section type and section name + r')?' # this section name is optional + r'\]' # ] + ) + + class MatchObject(object): + '''Match object for SectionPattern''' + + def __init__(self, match): + self.match = match + + def group(self, _group1): + '''return a tuple(type, name) if section has a name, + otherwise return a string as section name + ''' + type_ = self.match.group('header') + name = self.match.group('name') + if not name: + return type_ + + name = self.evalute_string(name) + return type_, name + + @staticmethod + def evalute_string(string): + '''safely evaluate string''' + if string.startswith('"') or string.startswith("'"): + return ast.literal_eval(string) + return string + + def match(self, string): + '''return MatchObject if string match the pattern''' + match = self.SECTCRE.match(string) + return self.MatchObject(match) if match else match + + class BrainConfigParser(SafeConfigParser): """Standard ConfigParser derived class which can reserve most of the comments, indents, and other user customized stuff inside the ini file. """ + SECTCRE = SectionPattern() + def read(self, filenames): """Limit the read() only support one input file. It's enough for current case. @@ -340,10 +393,10 @@ distconf = $build__distconf return self.DEFAULTS[section][opt] if not sect_found: - raise errors.ConfigError('no section %s' % section) + raise errors.ConfigError('no section %s' % str(section)) else: raise errors.ConfigError('no opt: %s in section %s' \ - % (opt, section)) + % (opt, str(section))) def check_opt(self, opt, section='general'): if section in self.DEFAULTS and \ diff --git a/tests/test_config.py b/tests/test_config.py index 79c3e82..87f799a 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -134,6 +134,33 @@ class ConfigGettingTest(unittest.TestCase): '''value can be overwrite if name is the same''' self.assertEqual('projv1', self.get('section', 'common_key')) + @Fixture(project='project1.ini') + def test_get_named_section(self): + '''get value from named section''' + self.assertEquals('projv4', self.get(('profile', 'rsa'), 'proj_only')) + + @Fixture(home='home1.ini', project='project1.ini') + def test_inherit_named_section(self): + '''value can be inherit from named section correctly''' + self.assertEquals('homev4', self.get(('profile', 'rsa'), 'home_only')) + + @Fixture(home='home1.ini', project='project1.ini') + def test_overwrite_named_section(self): + '''value can be overwrite from named section correctly''' + self.assertEquals('projv3', self.get(('profile', 'rsa'), 'common')) + + @Fixture(project='project1.ini') + def test_no_such_named_section(self): + '''test no such section''' + self.assertRaises(errors.ConfigError, + self.get, ('profile', 'NOT_EXISTS'), 'key') + + @Fixture(project='project1.ini') + def test_no_such_option_in_named_section(self): + '''test no such section''' + self.assertRaises(errors.ConfigError, + self.get, ('profile', 'rsa'), 'not_exists_option') + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/tests/testdata/ini/home1.ini b/tests/testdata/ini/home1.ini index c711620..39daae6 100644 --- a/tests/testdata/ini/home1.ini +++ b/tests/testdata/ini/home1.ini @@ -1,3 +1,7 @@ [section] common_key = homev1 -home_only_key = homev2 \ No newline at end of file +home_only_key = homev2 + +[profile "rsa"] +common = homev3 +home_only = homev4 diff --git a/tests/testdata/ini/project1.ini b/tests/testdata/ini/project1.ini index c60aceb..20eeb19 100644 --- a/tests/testdata/ini/project1.ini +++ b/tests/testdata/ini/project1.ini @@ -1,3 +1,7 @@ [section] common_key = projv1 -proj_only_key = projv2 \ No newline at end of file +proj_only_key = projv2 + +[profile "rsa"] +common = projv3 +proj_only = projv4