Mercurial > hg
annotate mercurial/config.py @ 52095:3e7b9357bbb8
tests: add coverage to for `HGCB_BUNDLE_BASENAME` with special characters
Per request on IRC, to show the behavior of dropping the quoting of
`HGCB_BUNDLE_BASENAME` in the next commit. This current failure is basically
the same error and output that currently happens on Windows with any path (even
without the embedded quote). The only difference is Windows doesn't print the
`cp: cannot stat ...` line.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Mon, 21 Oct 2024 15:24:55 -0400 |
parents | f4733654f144 |
children |
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 # |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
46622
diff
changeset
|
3 # Copyright 2009 Olivia Mackall <olivia@selenic.com> and others |
8229
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 |
51863
f4733654f144
typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents:
51289
diff
changeset
|
8 from __future__ import annotations |
25923
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 |
51289
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
13 from typing import ( |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
14 List, |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
15 Tuple, |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
16 ) |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
17 |
25923
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
18 from .i18n import _ |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
19 from . import ( |
43276
d201a637c971
py3: encode underlying error message during parse error of %include
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43106
diff
changeset
|
20 encoding, |
25923
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 error, |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 util, |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
23 ) |
8144 | 24 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
25 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48920
diff
changeset
|
26 class config: |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
27 def __init__(self, data=None): |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
28 self._current_source_level = 0 |
8144 | 29 self._data = {} |
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
|
30 self._unset = [] |
8144 | 31 if data: |
32 for k in data._data: | |
33 self._data[k] = data[k].copy() | |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
34 self._current_source_level = data._current_source_level + 1 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
35 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
36 def new_source(self): |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
37 """increment the source counter |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
38 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
39 This is used to define source priority when reading""" |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
40 self._current_source_level += 1 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
41 |
8144 | 42 def copy(self): |
43 return config(self) | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
44 |
8144 | 45 def __contains__(self, section): |
46 return section in self._data | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
47 |
27696
e70c97cc9243
config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents:
25923
diff
changeset
|
48 def hasitem(self, section, item): |
e70c97cc9243
config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents:
25923
diff
changeset
|
49 return item in self._data.get(section, {}) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
50 |
8186
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
51 def __getitem__(self, section): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
52 return self._data.get(section, {}) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
53 |
8186
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
54 def __iter__(self): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
55 for d in self.sections(): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
56 yield d |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
57 |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
58 def update(self, src): |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
59 current_level = self._current_source_level |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
60 current_level += 1 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
61 max_level = self._current_source_level |
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
|
62 for s, n in src._unset: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
63 ds = self._data.get(s, None) |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
64 if ds is not None and n in ds: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
65 self._data[s] = ds.preparewrite() |
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
|
66 del self._data[s][n] |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
67 for s in src: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
68 ds = self._data.get(s, None) |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
69 if ds: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
70 self._data[s] = ds.preparewrite() |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
71 else: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
72 self._data[s] = util.cowsortdict() |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
73 for k, v in src._data[s].items(): |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
74 value, source, level = v |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
75 level += current_level |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
76 max_level = max(level, current_level) |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
77 self._data[s][k] = (value, source, level) |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
78 self._current_source_level = max_level |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
79 |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
80 def _get(self, section, item): |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
81 return self._data.get(section, {}).get(item) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
82 |
8144 | 83 def get(self, section, item, default=None): |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
84 result = self._get(section, item) |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
85 if result is None: |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
86 return default |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
87 return result[0] |
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
|
88 |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
89 def backup(self, section, key): |
17527 | 90 """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
|
91 |
17530 | 92 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
|
93 """ |
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 try: |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
95 item = self._data[section][key] |
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
|
96 except KeyError: |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
97 return (section, key) |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
98 else: |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
99 return (section, key) + item |
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
|
100 |
8198
cf9accffd0b3
config: getsource -> source
Matt Mackall <mpm@selenic.com>
parents:
8193
diff
changeset
|
101 def source(self, section, item): |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
102 result = self._get(section, item) |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
103 if result is None: |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
104 return b"" |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
105 return result[1] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
106 |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
107 def level(self, section, item): |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
108 result = self._get(section, item) |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
109 if result is None: |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
110 return None |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
111 return result[2] |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
112 |
8144 | 113 def sections(self): |
114 return sorted(self._data.keys()) | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
115 |
51289
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
116 def items(self, section: bytes) -> List[Tuple[bytes, bytes]]: |
48920
b4ab4fd23199
config: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48890
diff
changeset
|
117 items = self._data.get(section, {}).items() |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
118 return [(k, v[0]) for (k, v) in items] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
119 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
120 def set(self, section, item, value, source=b""): |
48890
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
121 assert not isinstance( |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
122 section, str |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
123 ), b'config section may not be unicode strings on Python 3' |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
124 assert not isinstance( |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
125 item, str |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
126 ), b'config item may not be unicode strings on Python 3' |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
127 assert not isinstance( |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
128 value, str |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
129 ), b'config values may not be unicode strings on Python 3' |
8144 | 130 if section not in self: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
131 self._data[section] = util.cowsortdict() |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
132 else: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
133 self._data[section] = self._data[section].preparewrite() |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
134 self._data[section][item] = (value, source, self._current_source_level) |
8144 | 135 |
46620
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
136 def alter(self, section, key, new_value): |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
137 """alter a value without altering its source or level |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
138 |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
139 This method is meant to be used by `ui.fixconfig` only.""" |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
140 item = self._data[section][key] |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
141 size = len(item) |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
142 new_item = (new_value,) + item[1:] |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
143 assert len(new_item) == size |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
144 self._data[section][key] = new_item |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
145 |
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
|
146 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
|
147 """restore data returned by self.backup""" |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
148 if len(data) != 2: |
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
|
149 # restore old data |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
150 section, key = data[:2] |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
151 item = data[2:] |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
152 self._data[section] = self._data[section].preparewrite() |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
153 self._data[section][key] = item |
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
|
154 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
|
155 # 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
|
156 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
|
157 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
|
158 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
|
159 |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
160 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
|
161 sectionre = util.re.compile(br'\[([^\[]+)\]') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
162 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
|
163 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
|
164 emptyre = util.re.compile(br'(;|#|\s*$)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
165 commentre = util.re.compile(br'(;|#)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
166 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
|
167 includere = util.re.compile(br'%include\s+(\S|\S.*\S)\s*$') |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
168 section = b"" |
8144 | 169 item = None |
170 line = 0 | |
9339
9be91129c96e
config: improve code readability
Andrey <py4fun@gmail.com>
parents:
9136
diff
changeset
|
171 cont = False |
8180 | 172 |
34713
e5a2cfc524d4
config: allow remapping the default section
Yuya Nishihara <yuya@tcha.org>
parents:
34454
diff
changeset
|
173 if remap: |
e5a2cfc524d4
config: allow remapping the default section
Yuya Nishihara <yuya@tcha.org>
parents:
34454
diff
changeset
|
174 section = remap.get(section, section) |
e5a2cfc524d4
config: allow remapping the default section
Yuya Nishihara <yuya@tcha.org>
parents:
34454
diff
changeset
|
175 |
9136
31177742f54a
for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
8312
diff
changeset
|
176 for l in data.splitlines(True): |
8144 | 177 line += 1 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
178 if line == 1 and l.startswith(b'\xef\xbb\xbf'): |
16348
f350021ee32e
config: discard UTF-8 BOM if found
Matt Mackall <mpm@selenic.com>
parents:
15919
diff
changeset
|
179 # Someone set us up the BOM |
f350021ee32e
config: discard UTF-8 BOM if found
Matt Mackall <mpm@selenic.com>
parents:
15919
diff
changeset
|
180 l = l[3:] |
8144 | 181 if cont: |
14642
fdcdb221a922
config: handle comment lines in continuations (issue2854)
Matt Mackall <mpm@selenic.com>
parents:
14486
diff
changeset
|
182 if commentre.match(l): |
fdcdb221a922
config: handle comment lines in continuations (issue2854)
Matt Mackall <mpm@selenic.com>
parents:
14486
diff
changeset
|
183 continue |
8144 | 184 m = contre.match(l) |
185 if m: | |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
186 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
187 continue |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
188 v = self.get(section, item) + b"\n" + m.group(1) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
189 self.set(section, item, v, b"%s:%d" % (src, line)) |
8144 | 190 continue |
191 item = None | |
9469
7f0f882af23d
config: abort on indented non-continuation lines (issue1829)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
8312
diff
changeset
|
192 cont = False |
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
193 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
|
194 |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
195 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
|
196 expanded = util.expandpath(m.group(1)) |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
197 try: |
45257
668af67bfd18
config: remove now-unused `abs` argument from `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45256
diff
changeset
|
198 include(expanded, remap=remap, sections=sections) |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
199 except IOError as inst: |
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
200 if inst.errno != errno.ENOENT: |
45894
9dc1351d0b5f
errors: raise ConfigError on failure to parse config file
Martin von Zweigbergk <martinvonz@google.com>
parents:
45777
diff
changeset
|
201 raise error.ConfigError( |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
202 _(b"cannot include %s (%s)") |
45257
668af67bfd18
config: remove now-unused `abs` argument from `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45256
diff
changeset
|
203 % (expanded, encoding.strtolocal(inst.strerror)), |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
204 b"%s:%d" % (src, line), |
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
205 ) |
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
206 continue |
8144 | 207 if emptyre.match(l): |
208 continue | |
209 m = sectionre.match(l) | |
210 if m: | |
211 section = m.group(1) | |
8298
9542f4c3fa1b
config: make remap actually work
Matt Mackall <mpm@selenic.com>
parents:
8265
diff
changeset
|
212 if remap: |
9542f4c3fa1b
config: make remap actually work
Matt Mackall <mpm@selenic.com>
parents:
8265
diff
changeset
|
213 section = remap.get(section, section) |
8144 | 214 if section not in self: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
215 self._data[section] = util.cowsortdict() |
8144 | 216 continue |
217 m = itemre.match(l) | |
218 if m: | |
219 item = m.group(1) | |
9339
9be91129c96e
config: improve code readability
Andrey <py4fun@gmail.com>
parents:
9136
diff
changeset
|
220 cont = True |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
221 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
222 continue |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
223 self.set(section, item, m.group(2), b"%s:%d" % (src, line)) |
8144 | 224 continue |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
225 m = unsetre.match(l) |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
226 if m: |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
227 name = m.group(1) |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
228 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
229 continue |
13031
3da456d0c885
code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents:
11292
diff
changeset
|
230 if self.get(section, name) is not None: |
34454
0efdfb57b05c
config: add a missing preparewrite() call
Jun Wu <quark@fb.com>
parents:
34357
diff
changeset
|
231 self._data[section] = self._data[section].preparewrite() |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
232 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
|
233 self._unset.append((section, name)) |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
234 continue |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
235 |
45777
0883413e09bc
config: move message about leading spaces in config to config.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
45257
diff
changeset
|
236 message = l.rstrip() |
0883413e09bc
config: move message about leading spaces in config to config.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
45257
diff
changeset
|
237 if l.startswith(b' '): |
0883413e09bc
config: move message about leading spaces in config to config.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
45257
diff
changeset
|
238 message = b"unexpected leading whitespace: %s" % message |
45894
9dc1351d0b5f
errors: raise ConfigError on failure to parse config file
Martin von Zweigbergk <martinvonz@google.com>
parents:
45777
diff
changeset
|
239 raise error.ConfigError(message, (b"%s:%d" % (src, line))) |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
240 |
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
241 def read(self, path, fp=None, sections=None, remap=None): |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
242 self.new_source() |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
243 if not fp: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
244 fp = util.posixfile(path, b'rb') |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
245 assert ( |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
246 getattr(fp, 'mode', 'rb') == 'rb' |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
247 ), b'config files must be opened in binary mode, got fp=%r mode=%r' % ( |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
248 fp, |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
249 fp.mode, |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
250 ) |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
251 |
45256
83ca8d6f3206
config: re-calculate absolute %include path in `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45254
diff
changeset
|
252 dir = os.path.dirname(path) |
83ca8d6f3206
config: re-calculate absolute %include path in `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45254
diff
changeset
|
253 |
45257
668af67bfd18
config: remove now-unused `abs` argument from `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45256
diff
changeset
|
254 def include(rel, remap, sections): |
45256
83ca8d6f3206
config: re-calculate absolute %include path in `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45254
diff
changeset
|
255 abs = os.path.normpath(os.path.join(dir, rel)) |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
256 self.read(abs, remap=remap, sections=sections) |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
257 # anything after the include has a higher level |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
258 self.new_source() |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
259 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
260 self.parse( |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
261 path, fp.read(), sections=sections, remap=remap, include=include |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
262 ) |