##// END OF EJS Templates
commit: move editor outside transaction...
commit: move editor outside transaction The commit editor is now invoked before files and manifest are committed. The editor is now run with only the wlock held and aborting an edit no longer requires rolling back a transaction. Changes to files during a commit still result in undefined behavior. (This is preliminary work for committing subrepositories)

File last commit:

r8312:b87a50b7 default
r8496:a21605de default
Show More
config.py
137 lines | 4.6 KiB | text/x-python | PythonLexer
Martin Geisler
config: add copyright and license header
r8229 # config.py - configuration parsing for Mercurial
#
# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.
Matt Mackall
ui: introduce new config parser
r8144 from i18n import _
Simon Heimberg
separate import lines from mercurial and general python modules
r8312 import error
import re, os
Matt Mackall
ui: introduce new config parser
r8144
class sortdict(dict):
Matt Mackall
config: add %unset name support
r8184 'a simple sorted dictionary'
Matt Mackall
ui: introduce new config parser
r8144 def __init__(self, data=None):
self._list = []
if data:
self.update(data)
def copy(self):
return sortdict(self)
def __setitem__(self, key, val):
if key in self:
self._list.remove(key)
self._list.append(key)
dict.__setitem__(self, key, val)
def __iter__(self):
return self._list.__iter__()
def update(self, src):
for k in src:
self[k] = src[k]
def items(self):
Dirkjan Ochtman
more whitespace cleanup and some other style nits
r8222 return [(k, self[k]) for k in self._list]
Matt Mackall
config: add %unset name support
r8184 def __delitem__(self, key):
dict.__delitem__(self, key)
self._list.remove(key)
Matt Mackall
ui: introduce new config parser
r8144
Matt Mackall
config: add some helper methods
r8186 class config(object):
Matt Mackall
ui: introduce new config parser
r8144 def __init__(self, data=None):
self._data = {}
Matt Mackall
config: split source data out into separate map
r8185 self._source = {}
Matt Mackall
ui: introduce new config parser
r8144 if data:
for k in data._data:
self._data[k] = data[k].copy()
Matt Mackall
config: split source data out into separate map
r8185 self._source = data._source.copy()
Matt Mackall
ui: introduce new config parser
r8144 def copy(self):
return config(self)
def __contains__(self, section):
return section in self._data
Matt Mackall
config: add some helper methods
r8186 def __getitem__(self, section):
return self._data.get(section, {})
def __iter__(self):
for d in self.sections():
yield d
Matt Mackall
config: add section filter to read...
r8193 def update(self, src):
for s in src:
Matt Mackall
ui: introduce new config parser
r8144 if s not in self:
self._data[s] = sortdict()
Matt Mackall
config: add section filter to read...
r8193 self._data[s].update(src._data[s])
self._source.update(src._source)
Matt Mackall
ui: introduce new config parser
r8144 def get(self, section, item, default=None):
Matt Mackall
config: split source data out into separate map
r8185 return self._data.get(section, {}).get(item, default)
Matt Mackall
config: getsource -> source
r8198 def source(self, section, item):
Matt Mackall
config: split source data out into separate map
r8185 return self._source.get((section, item), "")
Matt Mackall
ui: introduce new config parser
r8144 def sections(self):
return sorted(self._data.keys())
def items(self, section):
Matt Mackall
config: split source data out into separate map
r8185 return self._data.get(section, {}).items()
Matt Mackall
ui: introduce new config parser
r8144 def set(self, section, item, value, source=""):
if section not in self:
self._data[section] = sortdict()
Matt Mackall
config: split source data out into separate map
r8185 self._data[section][item] = value
self._source[(section, item)] = source
Matt Mackall
ui: introduce new config parser
r8144
Matt Mackall
config: add parse interface
r8265 def parse(self, src, data, sections=None, remap=None, include=None):
Matt Mackall
ui: introduce new config parser
r8144 sectionre = re.compile(r'\[([^\[]+)\]')
Matt Mackall
config: allow spaces in key portion of items
r8263 itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
Matt Mackall
config: deal with spaces at end of line more carefully
r8192 contre = re.compile(r'\s+(\S.*\S)')
Matt Mackall
ui: introduce new config parser
r8144 emptyre = re.compile(r'(;|#|\s*$)')
Matt Mackall
config: deal with spaces at end of line more carefully
r8192 unsetre = re.compile(r'%unset\s+(\S+)')
includere = re.compile(r'%include\s+(\S.*\S)')
Matt Mackall
ui: introduce new config parser
r8144 section = ""
item = None
line = 0
cont = 0
Matt Mackall
hgweb: use config.config
r8180
Matt Mackall
config: add parse interface
r8265 for l in data.splitlines(1):
Matt Mackall
ui: introduce new config parser
r8144 line += 1
if cont:
m = contre.match(l)
if m:
Matt Mackall
config: add section filter to read...
r8193 if sections and section not in sections:
continue
Matt Mackall
ui: introduce new config parser
r8144 v = self.get(section, item) + "\n" + m.group(1)
Matt Mackall
config: add parse interface
r8265 self.set(section, item, v, "%s:%d" % (src, line))
Matt Mackall
ui: introduce new config parser
r8144 continue
item = None
Matt Mackall
config: allow including other config files
r8183 m = includere.match(l)
if m:
inc = m.group(1)
Matt Mackall
config: add parse interface
r8265 base = os.path.dirname(src)
Matt Mackall
config: allow including other config files
r8183 inc = os.path.normpath(os.path.join(base, inc))
Matt Mackall
config: add parse interface
r8265 if include:
include(inc, remap=remap, sections=sections)
Matt Mackall
config: allow including other config files
r8183 continue
Matt Mackall
ui: introduce new config parser
r8144 if emptyre.match(l):
continue
m = sectionre.match(l)
if m:
section = m.group(1)
Matt Mackall
config: make remap actually work
r8298 if remap:
section = remap.get(section, section)
Matt Mackall
ui: introduce new config parser
r8144 if section not in self:
self._data[section] = sortdict()
continue
m = itemre.match(l)
if m:
item = m.group(1)
Matt Mackall
config: add section filter to read...
r8193 cont = 1
if sections and section not in sections:
continue
Matt Mackall
config: add parse interface
r8265 self.set(section, item, m.group(2), "%s:%d" % (src, line))
Matt Mackall
ui: introduce new config parser
r8144 continue
Matt Mackall
config: add %unset name support
r8184 m = unsetre.match(l)
if m:
name = m.group(1)
Matt Mackall
config: add section filter to read...
r8193 if sections and section not in sections:
continue
Matt Mackall
config: add %unset name support
r8184 if self.get(section, name) != None:
del self._data[section][name]
continue
Matt Mackall
ui: introduce new config parser
r8144 raise error.ConfigError(_('config error at %s:%d: \'%s\'')
Matt Mackall
config: add parse interface
r8265 % (src, line, l.rstrip()))
def read(self, path, fp=None, sections=None, remap=None):
if not fp:
fp = open(path)
self.parse(path, fp.read(), sections, remap, self.read)