Mercurial > hg
annotate mercurial/config.py @ 31827:220d4bffd23e
run-tests: prevent a (glob) declaration from reordering (?) lines
Previously, if a series of optional output lines marked with '(?)' had a (glob)
in one of the first lines, the output would be reordered such that it came last
if none of the lines were output. The (re) declaration wasn't affected, which
was helpful in figuring this out. There were no tests for '(re) (?)' so add
that to make sure everything plays nice.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Wed, 05 Apr 2017 22:00:33 -0400 |
parents | a7c687c35119 |
children | 6a773d3050c9 |
rev | line source |
---|---|
8229
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
1 # config.py - configuration parsing for Mercurial |
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
2 # |
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others |
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
4 # |
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
8229
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
7 |
25923
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
8 from __future__ import absolute_import |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
9 |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
10 import errno |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
11 import os |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
12 |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
13 from .i18n import _ |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
14 from . import ( |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
15 error, |
31306
c920efa9d34b
config: guard against setconfig specifying unicode values on py3
Augie Fackler <raf@durin42.com>
parents:
31176
diff
changeset
|
16 pycompat, |
25923
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
17 util, |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
18 ) |
8144 | 19 |
8186
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
20 class config(object): |
31374
d30fb3de4b40
config: avoid using a mutable default
Martijn Pieters <mjpieters@fb.com>
parents:
31306
diff
changeset
|
21 def __init__(self, data=None, includepaths=None): |
8144 | 22 self._data = {} |
8185
dc10a7a3f1d4
config: split source data out into separate map
Matt Mackall <mpm@selenic.com>
parents:
8184
diff
changeset
|
23 self._source = {} |
19087
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
24 self._unset = [] |
31374
d30fb3de4b40
config: avoid using a mutable default
Martijn Pieters <mjpieters@fb.com>
parents:
31306
diff
changeset
|
25 self._includepaths = includepaths or [] |
8144 | 26 if data: |
27 for k in data._data: | |
28 self._data[k] = data[k].copy() | |
8185
dc10a7a3f1d4
config: split source data out into separate map
Matt Mackall <mpm@selenic.com>
parents:
8184
diff
changeset
|
29 self._source = data._source.copy() |
8144 | 30 def copy(self): |
31 return config(self) | |
32 def __contains__(self, section): | |
33 return section in self._data | |
27696
e70c97cc9243
config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents:
25923
diff
changeset
|
34 def hasitem(self, section, item): |
e70c97cc9243
config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents:
25923
diff
changeset
|
35 return item in self._data.get(section, {}) |
8186
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
36 def __getitem__(self, section): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
37 return self._data.get(section, {}) |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
38 def __iter__(self): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
39 for d in self.sections(): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
40 yield d |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
41 def update(self, src): |
19087
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
42 for s, n in src._unset: |
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
43 if s in self and n in self._data[s]: |
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
44 del self._data[s][n] |
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
45 del self._source[(s, n)] |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
46 for s in src: |
8144 | 47 if s not in self: |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
20789
diff
changeset
|
48 self._data[s] = util.sortdict() |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
49 self._data[s].update(src._data[s]) |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
50 self._source.update(src._source) |
8144 | 51 def get(self, section, item, default=None): |
8185
dc10a7a3f1d4
config: split source data out into separate map
Matt Mackall <mpm@selenic.com>
parents:
8184
diff
changeset
|
52 return self._data.get(section, {}).get(item, default) |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
53 |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
54 def backup(self, section, item): |
17527 | 55 """return a tuple allowing restore to reinstall a previous value |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
56 |
17530 | 57 The main reason we need it is because it handles the "no data" case. |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
58 """ |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
59 try: |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
60 value = self._data[section][item] |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
61 source = self.source(section, item) |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
62 return (section, item, value, source) |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
63 except KeyError: |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
64 return (section, item) |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
65 |
8198
cf9accffd0b3
config: getsource -> source
Matt Mackall <mpm@selenic.com>
parents:
8193
diff
changeset
|
66 def source(self, section, item): |
8185
dc10a7a3f1d4
config: split source data out into separate map
Matt Mackall <mpm@selenic.com>
parents:
8184
diff
changeset
|
67 return self._source.get((section, item), "") |
8144 | 68 def sections(self): |
69 return sorted(self._data.keys()) | |
70 def items(self, section): | |
8185
dc10a7a3f1d4
config: split source data out into separate map
Matt Mackall <mpm@selenic.com>
parents:
8184
diff
changeset
|
71 return self._data.get(section, {}).items() |
8144 | 72 def set(self, section, item, value, source=""): |
31306
c920efa9d34b
config: guard against setconfig specifying unicode values on py3
Augie Fackler <raf@durin42.com>
parents:
31176
diff
changeset
|
73 if pycompat.ispy3: |
c920efa9d34b
config: guard against setconfig specifying unicode values on py3
Augie Fackler <raf@durin42.com>
parents:
31176
diff
changeset
|
74 assert not isinstance(value, str), ( |
c920efa9d34b
config: guard against setconfig specifying unicode values on py3
Augie Fackler <raf@durin42.com>
parents:
31176
diff
changeset
|
75 'config values may not be unicode strings on Python 3') |
8144 | 76 if section not in self: |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
20789
diff
changeset
|
77 self._data[section] = util.sortdict() |
8185
dc10a7a3f1d4
config: split source data out into separate map
Matt Mackall <mpm@selenic.com>
parents:
8184
diff
changeset
|
78 self._data[section][item] = value |
20789
d19c9bdbbf35
config: don't set source when no source is specified - don't overwrite with ''
Mads Kiilerich <madski@unity3d.com>
parents:
19087
diff
changeset
|
79 if source: |
d19c9bdbbf35
config: don't set source when no source is specified - don't overwrite with ''
Mads Kiilerich <madski@unity3d.com>
parents:
19087
diff
changeset
|
80 self._source[(section, item)] = source |
8144 | 81 |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
82 def restore(self, data): |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
83 """restore data returned by self.backup""" |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
84 if len(data) == 4: |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
85 # restore old data |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
86 section, item, value, source = data |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
87 self._data[section][item] = value |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
88 self._source[(section, item)] = source |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
89 else: |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
90 # no data before, remove everything |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
91 section, item = data |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
92 if section in self._data: |
22037
8665c647da6e
config: fix restoreconfig of non existing config
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21910
diff
changeset
|
93 self._data[section].pop(item, None) |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
94 self._source.pop((section, item), None) |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
95 |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
96 def parse(self, src, data, sections=None, remap=None, include=None): |
30349
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
97 sectionre = util.re.compile(br'\[([^\[]+)\]') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
98 itemre = util.re.compile(br'([^=\s][^=]*?)\s*=\s*(.*\S|)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
99 contre = util.re.compile(br'\s+(\S|\S.*\S)\s*$') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
100 emptyre = util.re.compile(br'(;|#|\s*$)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
101 commentre = util.re.compile(br'(;|#)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
102 unsetre = util.re.compile(br'%unset\s+(\S+)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
103 includere = util.re.compile(br'%include\s+(\S|\S.*\S)\s*$') |
8144 | 104 section = "" |
105 item = None | |
106 line = 0 | |
9339
9be91129c96e
config: improve code readability
Andrey <py4fun@gmail.com>
parents:
9136
diff
changeset
|
107 cont = False |
8180 | 108 |
9136
31177742f54a
for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
8312
diff
changeset
|
109 for l in data.splitlines(True): |
8144 | 110 line += 1 |
16348
f350021ee32e
config: discard UTF-8 BOM if found
Matt Mackall <mpm@selenic.com>
parents:
15919
diff
changeset
|
111 if line == 1 and l.startswith('\xef\xbb\xbf'): |
f350021ee32e
config: discard UTF-8 BOM if found
Matt Mackall <mpm@selenic.com>
parents:
15919
diff
changeset
|
112 # Someone set us up the BOM |
f350021ee32e
config: discard UTF-8 BOM if found
Matt Mackall <mpm@selenic.com>
parents:
15919
diff
changeset
|
113 l = l[3:] |
8144 | 114 if cont: |
14642
fdcdb221a922
config: handle comment lines in continuations (issue2854)
Matt Mackall <mpm@selenic.com>
parents:
14486
diff
changeset
|
115 if commentre.match(l): |
fdcdb221a922
config: handle comment lines in continuations (issue2854)
Matt Mackall <mpm@selenic.com>
parents:
14486
diff
changeset
|
116 continue |
8144 | 117 m = contre.match(l) |
118 if m: | |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
119 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
120 continue |
8144 | 121 v = self.get(section, item) + "\n" + m.group(1) |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
122 self.set(section, item, v, "%s:%d" % (src, line)) |
8144 | 123 continue |
124 item = None | |
9469
7f0f882af23d
config: abort on indented non-continuation lines (issue1829)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
8312
diff
changeset
|
125 cont = False |
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
126 m = includere.match(l) |
25095
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
127 |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
128 if m and include: |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
129 expanded = util.expandpath(m.group(1)) |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
130 includepaths = [os.path.dirname(src)] + self._includepaths |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
131 |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
132 for base in includepaths: |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
133 inc = os.path.normpath(os.path.join(base, expanded)) |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
134 |
10042
7cdd2a7db2c2
config: raise ConfigError on non-existing include files
Martin Geisler <mg@lazybytes.net>
parents:
9471
diff
changeset
|
135 try: |
7cdd2a7db2c2
config: raise ConfigError on non-existing include files
Martin Geisler <mg@lazybytes.net>
parents:
9471
diff
changeset
|
136 include(inc, remap=remap, sections=sections) |
25095
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
137 break |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25095
diff
changeset
|
138 except IOError as inst: |
14486
4e3eda05189b
config: ignore include errors for nonexistent files
Matt Mackall <mpm@selenic.com>
parents:
13664
diff
changeset
|
139 if inst.errno != errno.ENOENT: |
4e3eda05189b
config: ignore include errors for nonexistent files
Matt Mackall <mpm@selenic.com>
parents:
13664
diff
changeset
|
140 raise error.ParseError(_("cannot include %s (%s)") |
4e3eda05189b
config: ignore include errors for nonexistent files
Matt Mackall <mpm@selenic.com>
parents:
13664
diff
changeset
|
141 % (inc, inst.strerror), |
4e3eda05189b
config: ignore include errors for nonexistent files
Matt Mackall <mpm@selenic.com>
parents:
13664
diff
changeset
|
142 "%s:%s" % (src, line)) |
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
143 continue |
8144 | 144 if emptyre.match(l): |
145 continue | |
146 m = sectionre.match(l) | |
147 if m: | |
148 section = m.group(1) | |
8298
9542f4c3fa1b
config: make remap actually work
Matt Mackall <mpm@selenic.com>
parents:
8265
diff
changeset
|
149 if remap: |
9542f4c3fa1b
config: make remap actually work
Matt Mackall <mpm@selenic.com>
parents:
8265
diff
changeset
|
150 section = remap.get(section, section) |
8144 | 151 if section not in self: |
21813
c2262004c2e2
config: move config.sortdict class into util
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
20789
diff
changeset
|
152 self._data[section] = util.sortdict() |
8144 | 153 continue |
154 m = itemre.match(l) | |
155 if m: | |
156 item = m.group(1) | |
9339
9be91129c96e
config: improve code readability
Andrey <py4fun@gmail.com>
parents:
9136
diff
changeset
|
157 cont = True |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
158 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
159 continue |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
160 self.set(section, item, m.group(2), "%s:%d" % (src, line)) |
8144 | 161 continue |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
162 m = unsetre.match(l) |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
163 if m: |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
164 name = m.group(1) |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
165 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
166 continue |
13031
3da456d0c885
code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents:
11292
diff
changeset
|
167 if self.get(section, name) is not None: |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
168 del self._data[section][name] |
19087
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
169 self._unset.append((section, name)) |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
170 continue |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
171 |
11288
2123aad24d56
error: add new ParseError for various parsing errors
Matt Mackall <mpm@selenic.com>
parents:
11224
diff
changeset
|
172 raise error.ParseError(l.rstrip(), ("%s:%s" % (src, line))) |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
173 |
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
174 def read(self, path, fp=None, sections=None, remap=None): |
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
175 if not fp: |
31154
fd3f4bf9325e
config: load included config files in binary mode
Augie Fackler <raf@durin42.com>
parents:
30349
diff
changeset
|
176 fp = util.posixfile(path, 'rb') |
31176
99c5843b228d
config: add sanity assert that files are opened as binary
Augie Fackler <raf@durin42.com>
parents:
31155
diff
changeset
|
177 assert getattr(fp, 'mode', r'rb') == r'rb', ( |
99c5843b228d
config: add sanity assert that files are opened as binary
Augie Fackler <raf@durin42.com>
parents:
31155
diff
changeset
|
178 'config files must be opened in binary mode, got fp=%r mode=%r' % ( |
99c5843b228d
config: add sanity assert that files are opened as binary
Augie Fackler <raf@durin42.com>
parents:
31155
diff
changeset
|
179 fp, fp.mode)) |
31155
8266802f0fa4
config: pass some optional args as keywords
Augie Fackler <raf@durin42.com>
parents:
31154
diff
changeset
|
180 self.parse(path, fp.read(), |
8266802f0fa4
config: pass some optional args as keywords
Augie Fackler <raf@durin42.com>
parents:
31154
diff
changeset
|
181 sections=sections, remap=remap, include=self.read) |
31481
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
182 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
183 def parselist(value): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
184 """parse a configuration value as a list of comma/space separated strings |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
185 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
186 >>> parselist('this,is "a small" ,test') |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
187 ['this', 'is', 'a small', 'test'] |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
188 """ |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
189 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
190 def _parse_plain(parts, s, offset): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
191 whitespace = False |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
192 while offset < len(s) and (s[offset:offset + 1].isspace() |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
193 or s[offset:offset + 1] == ','): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
194 whitespace = True |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
195 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
196 if offset >= len(s): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
197 return None, parts, offset |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
198 if whitespace: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
199 parts.append('') |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
200 if s[offset:offset + 1] == '"' and not parts[-1]: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
201 return _parse_quote, parts, offset + 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
202 elif s[offset:offset + 1] == '"' and parts[-1][-1] == '\\': |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
203 parts[-1] = parts[-1][:-1] + s[offset:offset + 1] |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
204 return _parse_plain, parts, offset + 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
205 parts[-1] += s[offset:offset + 1] |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
206 return _parse_plain, parts, offset + 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
207 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
208 def _parse_quote(parts, s, offset): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
209 if offset < len(s) and s[offset:offset + 1] == '"': # "" |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
210 parts.append('') |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
211 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
212 while offset < len(s) and (s[offset:offset + 1].isspace() or |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
213 s[offset:offset + 1] == ','): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
214 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
215 return _parse_plain, parts, offset |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
216 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
217 while offset < len(s) and s[offset:offset + 1] != '"': |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
218 if (s[offset:offset + 1] == '\\' and offset + 1 < len(s) |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
219 and s[offset + 1:offset + 2] == '"'): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
220 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
221 parts[-1] += '"' |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
222 else: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
223 parts[-1] += s[offset:offset + 1] |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
224 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
225 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
226 if offset >= len(s): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
227 real_parts = _configlist(parts[-1]) |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
228 if not real_parts: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
229 parts[-1] = '"' |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
230 else: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
231 real_parts[0] = '"' + real_parts[0] |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
232 parts = parts[:-1] |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
233 parts.extend(real_parts) |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
234 return None, parts, offset |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
235 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
236 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
237 while offset < len(s) and s[offset:offset + 1] in [' ', ',']: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
238 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
239 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
240 if offset < len(s): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
241 if offset + 1 == len(s) and s[offset:offset + 1] == '"': |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
242 parts[-1] += '"' |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
243 offset += 1 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
244 else: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
245 parts.append('') |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
246 else: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
247 return None, parts, offset |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
248 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
249 return _parse_plain, parts, offset |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
250 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
251 def _configlist(s): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
252 s = s.rstrip(' ,') |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
253 if not s: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
254 return [] |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
255 parser, parts, offset = _parse_plain, [''], 0 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
256 while parser: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
257 parser, parts, offset = parser(parts, s, offset) |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
258 return parts |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
259 |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
260 if value is not None and isinstance(value, bytes): |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
261 result = _configlist(value.lstrip(' ,\n')) |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
262 else: |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
263 result = value |
a7c687c35119
ui: move configlist parser to config.py
Jun Wu <quark@fb.com>
parents:
31374
diff
changeset
|
264 return result or [] |