~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Vincent Ladeuil
  • Date: 2011-04-04 12:12:57 UTC
  • mto: (5743.5.1 config-concrete-stores)
  • mto: This revision was merged to the branch mainline in revision 5832.
  • Revision ID: v.ladeuil+lp@free.fr-20110404121257-m4htb561v7b4c2ur
Implement loading a config store from a string or a file. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
2029
2029
            self.orig[name] = self.get(name, None)
2030
2030
        del self.options[name]
2031
2031
 
 
2032
class Store(object):
 
2033
    """Abstract interface to persistent storage for configuration options."""
 
2034
 
 
2035
    def __init__(self):
 
2036
        self.loaded = False
 
2037
 
 
2038
    def load(self):
 
2039
        raise NotImplementedError(self.load)
 
2040
 
 
2041
 
 
2042
class ConfigObjStore(Store):
 
2043
 
 
2044
    def __init__(self, transport, file_name):
 
2045
        """A config Store using ConfigObj for storage.
 
2046
 
 
2047
        :param transport: The transport object where the config file is located.
 
2048
 
 
2049
        :param file_name: The config file basename in the transport directory.
 
2050
        """
 
2051
        super(ConfigObjStore, self).__init__()
 
2052
        self.transport = transport
 
2053
        self.file_name = file_name
 
2054
        # No transient content is known initially
 
2055
        self._content = None
 
2056
 
 
2057
    @classmethod
 
2058
    def from_string(cls, str_or_unicode, transport, file_name, save=False):
 
2059
        """Create a config store from a string.
 
2060
 
 
2061
        :param str_or_unicode: A string representing the file content. This will
 
2062
            be utf-8 encoded internally.
 
2063
 
 
2064
        :param transport: The transport object where the config file is located.
 
2065
 
 
2066
        :param file_name: The configuration file basename.
 
2067
 
 
2068
        :param _save: Whether the file should be saved upon creation.
 
2069
        """
 
2070
        conf = cls(transport=transport, file_name=file_name)
 
2071
        conf._create_from_string(str_or_unicode, save)
 
2072
        return conf
 
2073
 
 
2074
    def _create_from_string(self, str_or_unicode, save):
 
2075
        # We just keep record the content waiting for load() to be called when
 
2076
        # needed
 
2077
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
2078
        # Some tests use in-memory configs, some other always need the config
 
2079
        # file to exist on disk.
 
2080
        if save:
 
2081
            self.save()
 
2082
 
 
2083
    def load(self):
 
2084
        """Load the store from the associated file."""
 
2085
        if self.loaded:
 
2086
            return
 
2087
        if self._content is not None:
 
2088
            co_input = self._content
 
2089
        else:
 
2090
            # The config files are always stored utf8-encoded
 
2091
            co_input =  StringIO(self.transport.get_bytes(self.file_name))
 
2092
        try:
 
2093
            self._config_obj = ConfigObj(co_input, encoding='utf-8')
 
2094
        except configobj.ConfigObjError, e:
 
2095
            # FIXME: external_url should really accepts an optional relpath
 
2096
            # parameter (bug #750169) :-/ -- vila 2011-04-04
 
2097
            # The following will do in the interim but maybe we don't want to
 
2098
            # expose a path here but rather a config ID and its associated
 
2099
            # object (hand wawing).
 
2100
            file_path = os.path.join(self.transport.external_url(),
 
2101
                                     self.file_name)
 
2102
            raise errors.ParseConfigError(e.errors, file_path)
 
2103
        self.loaded = True
 
2104
 
2032
2105
 
2033
2106
class cmd_config(commands.Command):
2034
2107
    __doc__ = """Display, set or remove a configuration option.