Edgewall Software

Ticket #3037: fixed-config+cleaner.diff

File fixed-config+cleaner.diff, 5.3 KB (added by athomas, 3 years ago)

Previous patch plus save() now only saves modified values

  • trac/config.py

     
    6565    """ 
    6666    def __init__(self, filename): 
    6767        self._sections = {} 
    68         self._defaults = {} 
    6968        self.filename = filename 
    7069        self.parser = ConfigParser() 
    7170        self._lastmtime = 0 
     
    149148 
    150149    def sections(self): 
    151150        """Return a list of section names.""" 
    152         return self.parser.sections() 
     151        sections = self.site_parser.sections() 
     152        site_sections = [s.lower() for s in sections] 
     153        sections.extend([s for s in self.parser.sections()  
     154                         if s not in site_sections]) 
     155        return sections 
    153156 
    154157    def save(self): 
    155158        """Write the configuration options to the primary file.""" 
    156159        if not self.filename: 
    157160            return 
    158161        fileobj = file(self.filename, 'w') 
     162        # Only save options that differ from the defaults 
     163        clean_config = ConfigParser() 
     164        for section in self.sections(): 
     165            for option in self[section]: 
     166                default = self.site_parser.has_option(section, option) and \ 
     167                          self.site_parser.get(section, option) or None 
     168                current = self.parser.has_option(section, option) and \ 
     169                          self.parser.get(section, option) or None 
     170                if current is not None and default != current: 
     171                    if not clean_config.has_section(section): 
     172                        clean_config.add_section(section) 
     173                    clean_config.set(section, option, current) 
     174 
    159175        try: 
    160             self.parser.write(fileobj) 
     176            clean_config.write(fileobj) 
    161177        finally: 
    162178            fileobj.close() 
    163179 
    164180    def parse_if_needed(self): 
    165         # Merge global configuration option into _defaults 
     181        # Load global configuration 
    166182        if os.path.isfile(self.site_filename): 
    167183            modtime = os.path.getmtime(self.site_filename) 
    168184            if modtime > self._lastsitemtime: 
    169185                self.site_parser.read(self.site_filename) 
    170                 for section in self.site_parser.sections(): 
    171                     for option in self.site_parser.options(section): 
    172                         value = self.site_parser.get(section, option) 
    173                         self._defaults[(section, option)] = value 
    174186                self._lastsitemtime = modtime 
    175187 
    176188        if not self.filename or not os.path.isfile(self.filename): 
     
    193205        self.name = name 
    194206 
    195207    def __contains__(self, name): 
    196         return self.config.parser.has_option(self.name, name) 
     208        return self.config.parser.has_option(self.name, name) or \ 
     209               self.config.site_parser.has_option(self.name, name) 
     210             
    197211 
    198212    def __iter__(self): 
    199213        options = [] 
    200214        if self.config.parser.has_section(self.name): 
    201215            for option in self.config.parser.options(self.name): 
    202                 options.append(option) 
     216                options.append(option.lower()) 
    203217                yield option 
    204         for section, option in self.config._defaults: 
    205             if section == self.name and option not in options: 
    206                 yield option 
     218        if self.config.site_parser.has_section(self.name): 
     219            for option in self.config.site_parser.options(self.name): 
     220                if option.lower() not in options: 
     221                    yield option 
    207222 
    208223    def get(self, name, default=None): 
    209224        """Return the value of the specified option.""" 
    210         if not name in self: 
    211             if default is None: 
    212                 return self.config._defaults.get((self.name, name), '') 
    213             return default 
    214         return to_unicode(self.config.parser.get(self.name, name)) 
     225        if self.config.parser.has_option(self.name, name): 
     226            return to_unicode(self.config.parser.get(self.name, name)) 
     227        elif self.config.site_parser.has_option(self.name, name): 
     228            return to_unicode(self.config.site_parser.get(self.name, name)) 
     229        else: 
     230            return default or '' 
    215231 
    216232    def getbool(self, name, default=None): 
    217233        """Return the value of the specified option as boolean. 
     
    258274 
    259275    def setdefault(self, name, value): 
    260276        """Set the default value of a specific option.""" 
    261         if (self.name, name) not in self.config._defaults: 
    262             self.config._defaults[(self.name, name)] = value 
     277        if not self.config.site_parser.has_option(self.name, name): 
     278            if not self.config.site_parser.has_section(self.name): 
     279                self.config.site_parser.add_section(self.name) 
     280            self.config.site_parser.set(self.name, name, value.encode('utf-8')) 
    263281 
    264282    def set(self, name, value): 
    265283        """Change a configuration value. 
  • trac/tests/config.py

     
    116116    def test_sections(self): 
    117117        self._write(['[a]', 'option = x', '[b]', 'option = y']) 
    118118        config = Configuration(self.filename) 
     119        from ConfigParser import ConfigParser 
     120        config.site_parser = ConfigParser() 
    119121        self.assertEquals(['a', 'b'], config.sections()) 
    120122 
    121123    def test_options(self):