##// END OF EJS Templates
largefiles: don't copy largefiles from working dir to the store while converting...
largefiles: don't copy largefiles from working dir to the store while converting Previously, if one or more largefiles for a repo being converted were not in the usercache, the convert would abort with a reference to the largefile being missing (as opposed to the previous patch, where the standin was referenced as missing). This is because commitctx() tries to copy all largefiles to the local store, first from the user cache, and if the file isn't found there, from the working directory. No files will exist in the working directory during a convert, however. It is not sufficient to force the source repo to be local before proceeding, because clone and pull do not download largefiles by default. This is slightly less than ideal because while the conversion will now complete, it won't be possible to update to revs with missing largefiles unless the user intervenes manually, because there is no default path pointing back to the source repo. Ideally these files would be cached during the conversion. This check could have been done in reposetup.commitctx() instead, but this ensures the local store directory is created, which is necessary to enable the standin matcher. The rm -> 'rm -f' change in the test is to temporarily suppress an error clearing the cache- as noted, the cache is is not repopulated during convert. When that is fixed, this can be changed back and the verification errors will disappear too.

File last commit:

r17537:31f32a96 merge default
r17878:d1d01402 stable
Show More
config.py
183 lines | 6.3 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
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Martin Geisler
config: add copyright and license header
r8229
Matt Mackall
ui: introduce new config parser
r8144 from i18n import _
Chad Dombrova
config: expand hgrc %include paths
r11224 import error, util
Bryan O'Sullivan
config: use util.compilere to compile regexps
r16944 import os, errno
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]
Sune Foldager
config.sortdict: override clear method...
r14696 def clear(self):
dict.clear(self)
self._list = []
Matt Mackall
ui: introduce new config parser
r8144 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)
Angel Ezquerra
config: make sortdict keys() and iterkeys() methods respect the item order...
r16865 def keys(self):
return self._list
def iterkeys(self):
return self._list.__iter__()
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)
Pierre-Yves David
config: have a way to backup and restore value in config...
r15919
def backup(self, section, item):
timeless@mozdev.org
spelling: value
r17527 """return a tuple allowing restore to reinstall a previous value
Pierre-Yves David
config: have a way to backup and restore value in config...
r15919
timeless@mozdev.org
grammar: it-handles
r17530 The main reason we need it is because it handles the "no data" case.
Pierre-Yves David
config: have a way to backup and restore value in config...
r15919 """
try:
value = self._data[section][item]
source = self.source(section, item)
return (section, item, value, source)
except KeyError:
return (section, item)
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
Pierre-Yves David
config: have a way to backup and restore value in config...
r15919 def restore(self, data):
"""restore data returned by self.backup"""
if len(data) == 4:
# restore old data
section, item, value, source = data
self._data[section][item] = value
self._source[(section, item)] = source
else:
# no data before, remove everything
section, item = data
if section in self._data:
del self._data[section][item]
self._source.pop((section, item), None)
Matt Mackall
config: add parse interface
r8265 def parse(self, src, data, sections=None, remap=None, include=None):
Bryan O'Sullivan
config: use util.compilere to compile regexps
r16944 sectionre = util.compilere(r'\[([^\[]+)\]')
itemre = util.compilere(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
contre = util.compilere(r'\s+(\S|\S.*\S)\s*$')
emptyre = util.compilere(r'(;|#|\s*$)')
commentre = util.compilere(r'(;|#)')
unsetre = util.compilere(r'%unset\s+(\S+)')
includere = util.compilere(r'%include\s+(\S|\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
Matt Mackall
config: discard UTF-8 BOM if found
r16348 if line == 1 and l.startswith('\xef\xbb\xbf'):
# Someone set us up the BOM
l = l[3:]
Matt Mackall
ui: introduce new config parser
r8144 if cont:
Matt Mackall
config: handle comment lines in continuations (issue2854)
r14642 if commentre.match(l):
continue
Matt Mackall
ui: introduce new config parser
r8144 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
Nicolas Dumazet
config: abort on indented non-continuation lines (issue1829)...
r9469 cont = False
Matt Mackall
config: allow including other config files
r8183 m = includere.match(l)
if m:
Chad Dombrova
config: expand hgrc %include paths
r11224 inc = util.expandpath(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:
Martin Geisler
config: raise ConfigError on non-existing include files...
r10042 try:
include(inc, remap=remap, sections=sections)
except IOError, inst:
Matt Mackall
config: ignore include errors for nonexistent files
r14486 if inst.errno != errno.ENOENT:
raise error.ParseError(_("cannot include %s (%s)")
% (inc, inst.strerror),
"%s:%s" % (src, line))
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
Martin Geisler
code style: prefer 'is' and 'is not' tests with singletons
r13031 if self.get(section, name) is not None:
Matt Mackall
config: add %unset name support
r8184 del self._data[section][name]
continue
Matt Mackall
error: add new ParseError for various parsing errors
r11288 raise error.ParseError(l.rstrip(), ("%s:%s" % (src, line)))
Matt Mackall
config: add parse interface
r8265
def read(self, path, fp=None, sections=None, remap=None):
if not fp:
Adrian Buehlmann
config: use util.posixfile
r13664 fp = util.posixfile(path)
Matt Mackall
config: add parse interface
r8265 self.parse(path, fp.read(), sections, remap, self.read)