r171 - branches/rewrite/src

Nat Budin partial-mirror-devel@lists.alioth.debian.org
Sat, 10 Jul 2004 08:47:15 -0600


Author: natbudin-guest
Date: Sat Jul 10 08:47:15 2004
New Revision: 171

Modified:
   branches/rewrite/src/Config.py
Log:
Major refactoring of Config.py.  It passes the tests, too!  Yay!


Modified: branches/rewrite/src/Config.py
==============================================================================
--- branches/rewrite/src/Config.py	(original)
+++ branches/rewrite/src/Config.py	Sat Jul 10 08:47:15 2004
@@ -57,18 +57,96 @@
     def __init__(self, section):
         self.section = section
 
-### TODO: Rewrite the Config parser structure to use:
-###     Config
-###        ConfigGlobal
-###        ConfigBackend
-###           ConfigBackendMirror
-###           ConfigBackendMerge
-class Config(ConfigParser):
-    """
-    Store the configurations used by our system.
-    """
+class ConfigSection:
+    _required = []
+    _allowed = []
+    _options_with_type = {}
+    _allowed_in_filter_field = [
+        'subsection',
+        'priority',
+        'name'
+        ]
+    _name = ""
+
+    def __parseVariableOptions(self, item):
+        for allowed_key in self._allowed:
+            if allowed_key.find('@') != -1:
+                left_length = allowed_key.find('@')
+                right_length = allowed_key[left_length+1:].find('@') + left_length + 2
+                if (allowed_key[:left_length] == item[:left_length]
+                    and allowed_key[right_length:] == item[right_length:]):
+                    # found it!
+                    variable = allowed_key[left_length:right_length]
+                    match = item[left_length:len(item)-(len(allowed_key)-right_length)]
+                    return allowed_key, variable, match
 
-    _required_in_global = [
+    def __castOption(self, option, value):
+        if option not in self._options_with_type:
+            try:
+                allowed_key, variable, match = self.__parseVariableOptions(option)
+                option = allowed_key
+            except TypeError:
+                pass
+        if option in self._options_with_type:
+            if self._options_with_type[option] == 'list':
+                return value.split()
+            elif self._options_with_type[option] == 'boolean':
+                return bool(value)
+            elif self._options_with_type[option] == 'filter':
+                opts = value.split()
+                ret = {}
+                for opt in opts:
+                    key, val = opt.split(':')
+                    if key not in self._allowed_in_filter_field:
+                        debug("[%s] is not a filter field (found in option [%s] in section [%s])." % (key, option, self.section))
+                        raise InvalidOption(self.section, option)
+                    ret[key] = val
+                return ret
+        else:
+            return value
+
+    def __init__(self, config, section):
+        self.config = config
+        self.section = section
+
+        # fix up self._allowed to include all required options too
+        for item in self._required:
+            if item not in self._allowed:
+                self._allowed.append(item)
+
+        self.confs = {}
+
+        for item, value in self.config.items(self.section):
+            value = self.__castOption(item, value)
+            if item not in self._allowed:
+                rv = self.__parseVariableOptions(item)
+                if hasattr(rv, '__len__'):
+                    allowed_key, variable, match = rv
+                    if variable == '@BACKEND@':
+                        if match not in self.config.sections():
+                            debug("[%s] is not the name of a backend (found in [%s] option in [%s]"
+                                  % (match, item, self.section))
+                            raise InvalidOption(self.section, item)
+                    else:
+                        print("You found a bug: [%s] matches unknown variable [%s]! "
+                              "Please report it." % (item, variable))
+                        exit(1)
+                else:
+                    # __parseVariableOptions didn't return a sequence
+                    debug("[%s] is not allowed in a %s section (it was found in [%s])."
+                          % (item, self._name, self.section))
+                    raise InvalidOption(self.section, item)
+            self.confs[item] = value
+
+        for item in self._required:
+            if not self.confs.has_key(item):
+                rv = self.__parseVariableOptions(item)
+                if not hasattr(rv, '__len__'):
+                    debug("Required option [%s] not found in [%s] section." % (item, self.section))
+                    raise RequiredOptionMissing(self.section, item)
+                    
+class ConfigGlobal(ConfigSection):
+    _required = [
         'mirror_dir',
         'architectures',
         'sections',
@@ -78,12 +156,26 @@
         'get_provides',
         ]
 
-    _allowed_in_global = [
+    _allowed = [
         'debug',
         ]
 
-    ### HACK.  Split out later to generalize section types better.
-    _allowed_in_mirror_backend = [
+    _options_with_type = {
+        'architectures': 'list',
+        'distributions': 'list',
+        'get_provides': 'boolean',
+        'get_recommends': 'boolean',
+        'get_suggests': 'boolean',
+        'sections': 'list',
+        }
+
+    _name = "global"
+
+class ConfigBackend(ConfigSection):
+    _name = "backend"
+
+class ConfigBackendMirror(ConfigSection):
+    _allowed = [
         'server',
         'architectures',
         'sections',
@@ -97,134 +189,62 @@
 	'resolve_deps_using',
         ]
 
-    _allowed_in_merge_backend = [
-        'filter_@BACKEND@',
-	'backends',
-	'name',
-        ]
-
-    _allowed_in_filter_field = [
-        'subsection',
-        'priority',
-        'name'
-        ]
-
-    # if not included here, it's string
     _options_with_type = {
         'architectures': 'list',
-        'backends': 'list',
         'distributions': 'list',
         'filter': 'filter',
-        'filter_@BACKEND@': 'filter',
         'get_provides': 'boolean',
         'get_recommends': 'boolean',
         'get_suggests': 'boolean',
         'sections': 'list',
         }
 
+    _name = "mirror backend"
+
+class ConfigBackendMerge(ConfigSection):
+    _allowed = [
+        'filter_@BACKEND@',
+	'backends',
+	'name',
+        ]
+
+    _options_with_type = {
+        'backends': 'list',
+        'filter_@BACKEND@': 'filter',
+        }
+
+    _name = "merge backend"
+    
+class Config(ConfigParser):
+    """
+    Store the configurations used by our system.
+    """
+
     def __getSectionType(self, section):
         # detect which config type this is
-        if 'backends' in self.options(section):
-            return 'merge'
+        if section == 'GLOBAL':
+            return ConfigGlobal
+        elif 'backends' in self.options(section):
+            return ConfigBackendMerge
         elif 'server' in self.options(section):
-            return 'mirror'
+            return ConfigBackendMirror
         else:
             debug("Unknown section type in section [%s]." % (section))
             raise InvalidSection(section)
 
-    def __allowedInSection(self, section):
-        ### MAJOR HACK.  Remove this when refactoring.
-        sect_type = self.__getSectionType(section)
-        if sect_type == 'mirror':
-            allowed_in_section = self._allowed_in_mirror_backend
-        elif sect_type == 'merge':
-            allowed_in_section = self._allowed_in_merge_backend
-        return allowed_in_section
-        
-    def __parseVariableOptions(self, section, item):
-        allowed_in_section = self.__allowedInSection(section)
-        for allowed_key in allowed_in_section:
-            if allowed_key.find('@') != -1:
-                left_length = allowed_key.find('@')
-                right_length = allowed_key[left_length+1:].find('@') + left_length + 2
-                if (allowed_key[:left_length] == item[:left_length]
-                    and allowed_key[right_length:] == item[right_length:]):
-                    # found it!
-                    variable = allowed_key[left_length:right_length]
-                    match = item[left_length:len(item)-(len(allowed_key)-right_length)]
-                    return allowed_key, variable, match
-                                
-    def __castOption(self, section, option, value):
-        if option not in self._options_with_type:
-            try:
-                allowed_key, variable, match = self.__parseVariableOptions(section, option)
-                option = allowed_key
-            except TypeError:
-                pass
-        if option in self._options_with_type:
-            if self._options_with_type[option] == 'list':
-                return value.split()
-            elif self._options_with_type[option] == 'boolean':
-                return bool(value)
-            elif self._options_with_type[option] == 'filter':
-                opts = value.split()
-                ret = {}
-                for opt in opts:
-                    key, val = opt.split(':')
-                    if key not in self._allowed_in_filter_field:
-                        debug("[%s] is not a filter field (found in option [%s] in section [%s])." % (key, option, section))
-                        raise InvalidOption(section, option)
-                    ret[key] = val
-                return ret
-        else:
-            return value
-
     def __init__(self, filename):
         ConfigParser.__init__(self)
         self.read(filename)
 
-	# Read the global section.
         self.confs = {}
-        self.confs['GLOBAL'] = {}
-        global_items = self._allowed_in_global + self._required_in_global
-        for item, value in self.items('GLOBAL'):
-            if item not in global_items:
-                debug("[%s] is not allowed in global section." % (item))
-                raise InvalidOption('GLOBAL', item)
-            self.confs['GLOBAL'][item] = value
-
-        for item in self._required_in_global:
-            if not self.confs['GLOBAL'].has_key(item):
-                debug("Required option [%s] not found in global section." % (item))
-                raise RequiredOptionMissing('GLOBAL', item)
-
-	for section in self.sections():
-            if section == 'GLOBAL': continue
-	    self.confs[section] = {}
+        self.sectionObjs = {}
 
-            allowed_in_section = self.__allowedInSection(section)
+        for section in self.sections():
+            sectionType = self.__getSectionType(section)
+            sectionObj = sectionType(self, section)
+            self.sectionObjs[section] = sectionObj
+            self.confs[section] = sectionObj.confs
             
-	    for item, value in self.items(section):
-                value = self.__castOption(section, item, value)
-		if item not in allowed_in_section:
-                    try:
-                        allowed_key, variable, match = self.__parseVariableOptions(section, item)
-                        if variable == '@BACKEND@':
-                            if match not in self.sections():
-                                # oh god this is such a hack.  going to
-                                # refactor this soon
-                                raise TypeError
-                        else:
-                            print("You found a bug: [%s] matches unknown variable [%s]! "
-                                  "Please report it." % (item, variable))
-                            exit(1)
-                    except TypeError:
-                        # __parseVariableOptions didn't return a sequence
-			debug("[%s] is not allowed in a backend section (it was found in [%s])."
-                              % (item, section))
-                        raise InvalidOption(section, item)
-		self.confs[section][item] = value
-
     def getOption(self, option, section='GLOBAL'):
 	# get a config value for a certain section.  if it's not
 	# specified, fall back to GLOBAL