##// END OF EJS Templates
tags: don't crash if unable to write tag cache...
tags: don't crash if unable to write tag cache This happens with hgweb in real life, if the httpd user is unable to write in the repository directory. Another case is doing 'hg incoming' on a repository in the filesystem owned by someone else.

File last commit:

r9339:9be91129 default
r9366:9ff178e7 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
config: improve code readability
r9339 cont = False
Matt Mackall
hgweb: use config.config
r8180
Nicolas Dumazet
for calls expecting bool args, pass bool instead of int...
r9136 for l in data.splitlines(True):
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)
config: improve code readability
r9339 cont = True
Matt Mackall
config: add section filter to read...
r8193 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
config: improve code readability
r9339 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)