Gentoo Archives: gentoo-commits

From: "André Erdmann" <dywi@×××××××.de>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/
Date: Mon, 04 Jun 2012 15:43:27
Message-Id: 1338824570.346f15b80151811fb0813d5f14195ae8d73b4d61.dywi@gentoo
1 commit: 346f15b80151811fb0813d5f14195ae8d73b4d61
2 Author: André Erdmann <dywi <AT> mailerd <DOT> de>
3 AuthorDate: Mon Jun 4 15:42:50 2012 +0000
4 Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
5 CommitDate: Mon Jun 4 15:42:50 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=346f15b8
7
8 roverlay, config: fix typo and add main config reader
9
10 modified: config.py
11
12 ---
13 roverlay/config.py | 172 ++++++++++++++++++++++++++++++++++++++++++++++++----
14 1 files changed, 159 insertions(+), 13 deletions(-)
15
16 diff --git a/roverlay/config.py b/roverlay/config.py
17 index 41a98bf..bce721c 100644
18 --- a/roverlay/config.py
19 +++ b/roverlay/config.py
20 @@ -2,9 +2,11 @@
21 # Copyright 2006-2012 Gentoo Foundation
22 # Distributed under the terms of the GNU General Public License v2
23
24 +import copy
25 +import os
26 +import re
27 import sys
28 import shlex
29 -import copy
30
31 try:
32 import configparser
33 @@ -13,8 +15,6 @@ except ImportError as running_python2:
34 import ConfigParser as configparser
35
36
37 -
38 -
39 from roverlay import descriptionfields
40 from roverlay import const
41
42 @@ -51,8 +51,8 @@ class InitialLogger:
43 known from the logging module and its output goes directly to sys.stderr.
44 This can be used until the real logging has been configured.
45 """
46 - self.debug = lambda x : sys.stderr.write ( "DBG " + str ( x ) + "\n" )
47 - self.info = lambda x : sys.stderr.write ( "INFO " + str ( x ) + "\n" )
48 + self.debug = lambda x : sys.stdout.write ( "DBG " + str ( x ) + "\n" )
49 + self.info = lambda x : sys.stdout.write ( "INFO " + str ( x ) + "\n" )
50 self.warning = lambda x : sys.stderr.write ( "WARN " + str ( x ) + "\n" )
51 self.error = lambda x : sys.stderr.write ( "ERR " + str ( x ) + "\n" )
52 self.critical = lambda x : sys.stderr.write ( "CRIT " + str ( x ) + "\n" )
53 @@ -64,6 +64,25 @@ class ConfigTree:
54 # static access to the first created ConfigTree
55 instance = None
56
57 + # the list of 'normal' config entries (no special config path) (in lowercase)
58 + # the map of config entries
59 + CONFIG_ENTRY_MAP = dict (
60 + log_level = '',
61 + log_console = dict (
62 + value_type = 'yesno',
63 + ),
64 + log_file = dict (
65 + value_type = 'fs_file',
66 + ),
67 + ebuild_header = dict (
68 + value_type = 'fs_file',
69 + )
70 +
71 + )
72 +
73 + DEFAULT_LIST_REGEX = re.compile ( '\s*[,;]{1}\s*' )
74 + WHITESPACE = re.compile ( '\s+' )
75 +
76 def __init__ ( self, import_const=True ):
77 """Initializes an ConfigTree, which is a container for options/config values.
78 values can be stored directly (such as the field_definitions) or in a
79 @@ -89,19 +108,18 @@ class ConfigTree:
80 # --- end of __init__ (...) ---
81
82
83 - def _findpath ( self, path, root=None, create=False ):
84 + def _findpath ( self, path, root=None, create=False, value=None ):
85 if path is None:
86 return root
87 elif isinstance ( path, str ):
88 - path = path.split ( '.' ) if key else []
89 + path = path.split ( '.' ) if path else []
90
91 config_position = self._config if root is None else root
92
93 for k in path:
94 if not k in config_position:
95 if create:
96 - config_position [k] = dict ()
97 -
98 + config_position [k] = value if k == path [-1] and value else dict ()
99 else:
100 return None
101
102 @@ -134,22 +152,130 @@ class ConfigTree:
103
104 # --- end of get (...) ---
105
106 + def _add_entry ( self, option, value=None, config_root=None ):
107 +
108 + def make_and_verify_value ( value_type, value, entryconfig_ref ):
109 +
110 + def to_int ( val, fallback_value=-1 ):
111 + try:
112 + ret = int ( val )
113 + return ret
114 + except ValueError as verr:
115 + return fallback_value
116 + # --- end of to_int (...) ---
117 +
118 + def yesno ( val ):
119 + if not val is None:
120 + to_check = str ( val ) . lower ()
121 + if to_check in [ 'y', 'yes', '1', 'true', 'enabled', 'on' ]:
122 + return 1
123 + elif to_check in [ 'n', 'no', '0', 'false', 'disabled', 'off' ]:
124 + return 0
125 +
126 + self.logger.warning ( to_check + " is not a valid yesno value." )
127 + return -1
128 + # --- end of yesno (...) ---
129 +
130 + value = ConfigTree.WHITESPACE.sub ( ' ', value )
131 +
132 + if not value_type:
133 + return value
134 + elif isinstance ( value_type, list ):
135 + vtypes = value_type
136 + elif isinstance ( value_type, str ):
137 + vtypes = value_type.split ( ':' )
138 + else:
139 + self.logger.error ( "Unknown data type for value type." )
140 + return value
141 +
142 + retval = value
143 + is_list = False
144 + for vtype in vtypes:
145 + if vtype == 'list':
146 + retval = ConfigTree.DEFAULT_LIST_REGEX.split ( retval )
147 + is_list = True
148 + elif vtype == 'slist':
149 + retval = ConfigTree.WHITESPACE.split ( retval )
150 + is_list = True
151 + elif vtype == 'yesno':
152 + retval = [ yesno ( x ) for x in retval ] if is_list else yesno ( retval )
153 + elif vtype == 'int':
154 + retval = [ to_int ( x ) for x in retval ] if is_list else to_int ( retval )
155 +
156 + else:
157 + self.logger.warning ( "unknown value type '" + vtype + "'." )
158 +
159 + return retval
160 + # --- end of make_and_verify_value (...) ---
161 +
162 +
163 + real_option = option
164 + low_option = option.lower()
165 + if option and low_option in ConfigTree.CONFIG_ENTRY_MAP:
166 + cref = ConfigTree.CONFIG_ENTRY_MAP [low_option]
167 +
168 + if isinstance ( cref, str ) and cref in ConfigTree.CONFIG_ENTRY_MAP:
169 + option = low_option = cref
170 + cref = ConfigTree.CONFIG_ENTRY_MAP [cref]
171 +
172 + if cref is None:
173 + # deftly ignored
174 + return True
175 +
176 +
177 +
178 + path = None
179 + if 'path' in cref:
180 + path = cref ['path']
181 + else:
182 + path = low_option.split ( '_' )
183 + for n in range ( len ( path ) - 1 ):
184 + path [n] = path [n].upper()
185 +
186 +
187 + if path:
188 +
189 + if 'value_type' in cref:
190 + value = make_and_verify_value ( cref ['value_type'], value, cref )
191 +
192 + if value:
193 +
194 + self.logger.debug (
195 + "New config entry " + str ( option ) +
196 + " with path " + str ( path ) +
197 + " and value " + str ( value ) + "."
198 + )
199 +
200 + self._findpath ( path, config_root, True, value )
201 +
202 + return True
203 + else:
204 + self.logger.error (
205 + "Option '" + str ( real_option ) +
206 + "' has an unusable value '" + str ( value ) + "'."
207 + )
208 + # ---
209 + # ---
210 +
211 + self.logger.warning ( "Option '" + str ( real_option ) + "' is unknown." )
212 + return False
213 +
214 + # --- end of _add_entry (...) ---
215 +
216 def load_config ( self, config_file, start_section='' ):
217 """Loads a config file and integrates its content into the config tree.
218 Older config entries may be overwritten.
219
220 arguments:
221 config_file -- path to the file that should be read
222 - start_section -- relative root in the config tree as str or ref
223 + start_section -- relative root in the config tree as str
224 """
225
226 config_root = None
227 if start_section:
228 if isinstance ( start_section, str ):
229 config_root = self._findpath ( start_section, None, True )
230 - elif isinstance ( start_section, dict ):
231 - config_root = start_section
232 - else
233 + else:
234 raise Exception ("bad usage")
235
236 # load file
237 @@ -157,6 +283,26 @@ class ConfigTree:
238 try:
239 fh = open ( config_file, 'r' )
240 reader = shlex.shlex ( fh )
241 + reader.whitespace_split = False
242 + reader.wordchars += ' ./$()[]:+-@*~'
243 +
244 + nextline = lambda : ( reader.get_token() for n in range (3) )
245 +
246 + option, equal, value = nextline ()
247 +
248 + while equal == '=' or not ( option == value == reader.eof ):
249 + if equal == '=':
250 + self._add_entry ( option, value, config_root )
251 + else:
252 + self.logger.warning (
253 + "In '" + config_file + "', cannot parse this line: '" +
254 + str ( option ) + str ( equal ) + str ( value ) + "'."
255 + )
256 +
257 + option, equal, value = nextline ()
258 +
259 +
260 +
261 if fh:
262 fh.close ()