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: Tue, 05 Jun 2012 17:30:33
Message-Id: 1338916714.85bca473d98e6c1e9217b299d54fa3499b407e3c.dywi@gentoo
1 commit: 85bca473d98e6c1e9217b299d54fa3499b407e3c
2 Author: André Erdmann <dywi <AT> mailerd <DOT> de>
3 AuthorDate: Tue Jun 5 17:18:34 2012 +0000
4 Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
5 CommitDate: Tue Jun 5 17:18:34 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=85bca473
7
8 config: comments and config entry map
9 modified: roverlay/config.py
10
11 ---
12 roverlay/config.py | 133 +++++++++++++++++++++++++++++++++++++++++++++-------
13 1 files changed, 116 insertions(+), 17 deletions(-)
14
15 diff --git a/roverlay/config.py b/roverlay/config.py
16 index ab6dfec..424e69f 100644
17 --- a/roverlay/config.py
18 +++ b/roverlay/config.py
19 @@ -2,7 +2,6 @@
20 # Copyright 2006-2012 Gentoo Foundation
21 # Distributed under the terms of the GNU General Public License v2
22
23 -import copy
24 import os.path
25 import re
26 import sys
27 @@ -89,13 +88,21 @@ class ConfigTree:
28 ),
29 ebuild_header = dict (
30 value_type = 'fs_file',
31 - )
32 + ),
33 + overlay_dir = dict (
34 + value_type = 'fs_dir',
35 + ),
36 + distfiles_dir = dict (
37 + value_type = 'fs_dir',
38 + ),
39
40 )
41
42 + # often used regexes
43 DEFAULT_LIST_REGEX = re.compile ( '\s*[,;]{1}\s*' )
44 WHITESPACE = re.compile ( '\s+' )
45
46 +
47 def __init__ ( self, import_const=True ):
48 """Initializes an ConfigTree, which is a container for options/config values.
49 values can be stored directly (such as the field_definitions) or in a
50 @@ -122,6 +129,17 @@ class ConfigTree:
51
52
53 def _findpath ( self, path, root=None, create=False, value=None ):
54 + """All-in-one method that searches for a config path.
55 + It is able to create the path if non-existent and to assign a
56 + value to it.
57 +
58 + arguments:
59 + * path -- config path as path list ([a,b,c]) or as path str (a.b.c)
60 + * root -- config root (dict expected). Uses self._config if None (the default)
61 + * create -- create path if nonexistent
62 + * value -- assign value to the last path element
63 + an empty dict will be created if this is None and create is True
64 + """
65 if path is None:
66 return root
67 elif isinstance ( path, str ):
68 @@ -166,10 +184,36 @@ class ConfigTree:
69 # --- end of get (...) ---
70
71 def _add_entry ( self, option, value=None, config_root=None ):
72 + """Adds an option to the config.
73 +
74 + arguments:
75 + * option -- name of the option as it appears in the (main) config file
76 + * value -- value to assign, defaults to None
77 + * config_root -- root of the config (a dict), defaults to None which is
78 + later understood as self._config
79 + """
80
81 def make_and_verify_value ( value_type, value, entryconfig_ref ):
82 + """Prepares the value of a config option so that it can be used
83 + in the ConfigTree.
84 +
85 + arguments:
86 + * value_type -- type of the value, look above for explanation concerning this
87 + * value -- value to verify and transform
88 + * entryconfig_ref -- reference to the config entry config
89 + """
90
91 def to_int ( val, fallback_value=-1 ):
92 + """Tries to convert val to an int, returning a fallback value
93 + on any error.
94 +
95 + arguments:
96 + * val --
97 + * fallback_value --
98 +
99 + catches: ValueError in case of an unsuccesful int conversion
100 + raises: nothing
101 + """
102 try:
103 ret = int ( val )
104 return ret
105 @@ -178,6 +222,13 @@ class ConfigTree:
106 # --- end of to_int (...) ---
107
108 def yesno ( val ):
109 + """Tries to canonize an yes or no value to its integer
110 + representation. Returns 1 if val means 'yes', 0 if 'no' and
111 + -1 otherwise.
112 +
113 + arguments:
114 + * val --
115 + """
116 if not val is None:
117 to_check = str ( val ) . lower ()
118 if to_check in [ 'y', 'yes', '1', 'true', 'enabled', 'on' ]:
119 @@ -190,10 +241,21 @@ class ConfigTree:
120 # --- end of yesno (...) ---
121
122 def fs_path ( val ):
123 + """val is a filesystem path - returns expanded path (~ -> HOME).
124 +
125 + arguments:
126 + * val --
127 + """
128 return os.path.expanduser ( val ) if val else None
129 # --- end of fs_path (...) ---
130
131 def fs_file ( val ):
132 + """"val is a file - returns expanded path if it is an existent
133 + file or it does not exist.
134 +
135 + arguments:
136 + * val --
137 + """
138 if val:
139 retval = os.path.expanduser ( val )
140 if os.path.isfile ( retval ) or not os.path.exists ( retval ):
141 @@ -202,8 +264,25 @@ class ConfigTree:
142 return None
143 # --- end of fs_file (...) ---
144
145 + def fs_dir ( val ):
146 + """val is a directory -- returns expanded path if it is an existent
147 + dir or it does not exist.
148 +
149 + arguments:
150 + * val --
151 + """
152 + if val:
153 + retval = os.path.expanduser ( val )
154 + if os.path.isdir ( retval ) or not os.path.exists ( retval ):
155 + return retval
156 +
157 + return None
158 + # --- end of fs_dir (...) ---
159 +
160 + # replace whitespace with a single ' '
161 value = ConfigTree.WHITESPACE.sub ( ' ', value )
162
163 + # convert value_type into a list of value types
164 if not value_type:
165 return value
166 elif isinstance ( value_type, list ):
167 @@ -227,7 +306,6 @@ class ConfigTree:
168 # dofunc ( function f, <list or str> v) calls f(x) for every str in v
169 dofunc = lambda f, v : [ f(x) for x in v ] if isinstance ( v, list ) else f(v)
170
171 -
172 retval = value
173
174 for vtype in vtypes:
175 @@ -236,26 +314,43 @@ class ConfigTree:
176 else:
177 self.logger.warning ( "unknown value type '" + vtype + "'." )
178
179 -
180 return retval
181 # --- end of make_and_verify_value (...) ---
182
183
184 real_option = option
185 low_option = option.lower()
186 +
187 + # known option?
188 if option and low_option in ConfigTree.CONFIG_ENTRY_MAP:
189 - cref = ConfigTree.CONFIG_ENTRY_MAP [low_option]
190
191 - if isinstance ( cref, str ) and cref in ConfigTree.CONFIG_ENTRY_MAP:
192 - option = low_option = cref
193 - cref = ConfigTree.CONFIG_ENTRY_MAP [cref]
194 + original_cref = cref = ConfigTree.CONFIG_ENTRY_MAP [low_option]
195 + cref_level = 0
196 +
197 + # check if cref is a link to another entry in CONFIG_ENTRY_MAP
198 + while isinstance ( cref, str ):
199 + if cref == original_cref and cref_level:
200 + self.logger.critical ( "CONFIG_ENTRY_MAP is invalid! circular cref detected." )
201 + raise Exception ( "CONFIG_ENTRY_MAP is invalid!" )
202 +
203 + elif cref in ConfigTree.CONFIG_ENTRY_MAP:
204 + option = low_option = cref
205 + cref = ConfigTree.CONFIG_ENTRY_MAP [cref]
206 + cref_level += 1
207 + else:
208 + self.logger.critical (
209 + "CONFIG_ENTRY_MAP is invalid! last cref = " + option +
210 + ", current cref = " + cref + "."
211 + )
212 + raise Exception ( "CONFIG_ENTRY_MAP is invalid!" )
213
214 + # check if config entry is disabled
215 if cref is None:
216 # deftly ignored
217 return True
218
219
220 -
221 + # determine the config path
222 path = None
223 if 'path' in cref:
224 path = cref ['path']
225 @@ -264,12 +359,14 @@ class ConfigTree:
226 for n in range ( len ( path ) - 1 ):
227 path [n] = path [n].upper()
228
229 -
230 + # need a valid path
231 if path:
232
233 + # verify and convert value if value_type is set
234 if 'value_type' in cref:
235 value = make_and_verify_value ( cref ['value_type'], value, cref )
236
237 + # need a valid value
238 if value:
239
240 self.logger.debug (
241 @@ -278,6 +375,7 @@ class ConfigTree:
242 " and value " + str ( value ) + "."
243 )
244
245 + # add option/value to the config
246 self._findpath ( path, config_root, True, value )
247
248 return True
249 @@ -286,7 +384,11 @@ class ConfigTree:
250 "Option '" + str ( real_option ) +
251 "' has an unusable value '" + str ( value ) + "'."
252 )
253 + return False
254 # ---
255 +
256 + self.logger.error ( "Option '" + str ( real_option ) + "' is unusable..." )
257 + return False
258 # ---
259
260 self.logger.warning ( "Option '" + str ( real_option ) + "' is unknown." )
261 @@ -313,10 +415,11 @@ class ConfigTree:
262 # load file
263
264 try:
265 - fh = open ( config_file, 'r' )
266 - reader = shlex.shlex ( fh )
267 + reader.wordchars += ' ./$()[]:+-@*~'
268 + fh = open ( config_file, 'r' )
269 + reader = shlex.shlex ( fh )
270 reader.whitespace_split = False
271 - reader.wordchars += ' ./$()[]:+-@*~'
272 +
273
274 nextline = lambda : ( reader.get_token() for n in range (3) )
275
276 @@ -333,13 +436,9 @@ class ConfigTree:
277
278 option, equal, value = nextline ()
279
280 -
281 -
282 if fh:
283 fh.close ()
284
285 - # <TODO>
286 -
287 except IOError as ioerr:
288 raise