##// END OF EJS Templates
config: read configs from directories in lexicographical order...
Martin von Zweigbergk -
r42647:edbcf5b2 default
parent child Browse files
Show More
@@ -1,98 +1,99 b''
1 1 # rcutil.py - utilities about config paths, special config sections etc.
2 2 #
3 3 # Copyright Mercurial Contributors
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import os
11 11
12 12 from . import (
13 13 encoding,
14 14 pycompat,
15 15 util,
16 16 )
17 17
18 18 if pycompat.iswindows:
19 19 from . import scmwindows as scmplatform
20 20 else:
21 21 from . import scmposix as scmplatform
22 22
23 23 fallbackpager = scmplatform.fallbackpager
24 24 systemrcpath = scmplatform.systemrcpath
25 25 userrcpath = scmplatform.userrcpath
26 26
27 27 def _expandrcpath(path):
28 28 '''path could be a file or a directory. return a list of file paths'''
29 29 p = util.expandpath(path)
30 30 if os.path.isdir(p):
31 31 join = os.path.join
32 return [join(p, f) for f, k in util.listdir(p) if f.endswith('.rc')]
32 return sorted(join(p, f) for f, k in util.listdir(p)
33 if f.endswith('.rc'))
33 34 return [p]
34 35
35 36 def envrcitems(env=None):
36 37 '''Return [(section, name, value, source)] config items.
37 38
38 39 The config items are extracted from environment variables specified by env,
39 40 used to override systemrc, but not userrc.
40 41
41 42 If env is not provided, encoding.environ will be used.
42 43 '''
43 44 if env is None:
44 45 env = encoding.environ
45 46 checklist = [
46 47 ('EDITOR', 'ui', 'editor'),
47 48 ('VISUAL', 'ui', 'editor'),
48 49 ('PAGER', 'pager', 'pager'),
49 50 ]
50 51 result = []
51 52 for envname, section, configname in checklist:
52 53 if envname not in env:
53 54 continue
54 55 result.append((section, configname, env[envname], '$%s' % envname))
55 56 return result
56 57
57 58 def defaultrcpath():
58 59 '''return rc paths in default.d'''
59 60 path = []
60 61 defaultpath = os.path.join(util.datapath, 'default.d')
61 62 if os.path.isdir(defaultpath):
62 63 path = _expandrcpath(defaultpath)
63 64 return path
64 65
65 66 def rccomponents():
66 67 '''return an ordered [(type, obj)] about where to load configs.
67 68
68 69 respect $HGRCPATH. if $HGRCPATH is empty, only .hg/hgrc of current repo is
69 70 used. if $HGRCPATH is not set, the platform default will be used.
70 71
71 72 if a directory is provided, *.rc files under it will be used.
72 73
73 74 type could be either 'path' or 'items', if type is 'path', obj is a string,
74 75 and is the config file path. if type is 'items', obj is a list of (section,
75 76 name, value, source) that should fill the config directly.
76 77 '''
77 78 envrc = ('items', envrcitems())
78 79
79 80 if 'HGRCPATH' in encoding.environ:
80 81 # assume HGRCPATH is all about user configs so environments can be
81 82 # overridden.
82 83 _rccomponents = [envrc]
83 84 for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep):
84 85 if not p:
85 86 continue
86 87 _rccomponents.extend(('path', p) for p in _expandrcpath(p))
87 88 else:
88 89 normpaths = lambda paths: [('path', os.path.normpath(p)) for p in paths]
89 90 _rccomponents = normpaths(defaultrcpath() + systemrcpath())
90 91 _rccomponents.append(envrc)
91 92 _rccomponents.extend(normpaths(userrcpath()))
92 93 return _rccomponents
93 94
94 95 def defaultpagerenv():
95 96 '''return a dict of default environment variables and their values,
96 97 intended to be set before starting a pager.
97 98 '''
98 99 return {'LESS': 'FRX', 'LV': '-c'}
@@ -1,213 +1,222 b''
1 1 hide outer repo
2 2 $ hg init
3 3
4 4 Invalid syntax: no value
5 5
6 6 $ cat > .hg/hgrc << EOF
7 7 > novaluekey
8 8 > EOF
9 9 $ hg showconfig
10 10 hg: parse error at $TESTTMP/.hg/hgrc:1: novaluekey
11 11 [255]
12 12
13 13 Invalid syntax: no key
14 14
15 15 $ cat > .hg/hgrc << EOF
16 16 > =nokeyvalue
17 17 > EOF
18 18 $ hg showconfig
19 19 hg: parse error at $TESTTMP/.hg/hgrc:1: =nokeyvalue
20 20 [255]
21 21
22 22 Test hint about invalid syntax from leading white space
23 23
24 24 $ cat > .hg/hgrc << EOF
25 25 > key=value
26 26 > EOF
27 27 $ hg showconfig
28 28 hg: parse error at $TESTTMP/.hg/hgrc:1: key=value
29 29 unexpected leading whitespace
30 30 [255]
31 31
32 32 $ cat > .hg/hgrc << EOF
33 33 > [section]
34 34 > key=value
35 35 > EOF
36 36 $ hg showconfig
37 37 hg: parse error at $TESTTMP/.hg/hgrc:1: [section]
38 38 unexpected leading whitespace
39 39 [255]
40 40
41 41 Reset hgrc
42 42
43 43 $ echo > .hg/hgrc
44 44
45 45 Test case sensitive configuration
46 46
47 47 $ cat <<EOF >> $HGRCPATH
48 48 > [Section]
49 49 > KeY = Case Sensitive
50 50 > key = lower case
51 51 > EOF
52 52
53 53 $ hg showconfig Section
54 54 Section.KeY=Case Sensitive
55 55 Section.key=lower case
56 56
57 57 $ hg showconfig Section -Tjson
58 58 [
59 59 {
60 60 "name": "Section.KeY",
61 61 "source": "*.hgrc:*", (glob)
62 62 "value": "Case Sensitive"
63 63 },
64 64 {
65 65 "name": "Section.key",
66 66 "source": "*.hgrc:*", (glob)
67 67 "value": "lower case"
68 68 }
69 69 ]
70 70 $ hg showconfig Section.KeY -Tjson
71 71 [
72 72 {
73 73 "name": "Section.KeY",
74 74 "source": "*.hgrc:*", (glob)
75 75 "value": "Case Sensitive"
76 76 }
77 77 ]
78 78 $ hg showconfig -Tjson | tail -7
79 79 },
80 80 {
81 81 "name": "*", (glob)
82 82 "source": "*", (glob)
83 83 "value": "*" (glob)
84 84 }
85 85 ]
86 86
87 87 Test empty config source:
88 88
89 89 $ cat <<EOF > emptysource.py
90 90 > def reposetup(ui, repo):
91 91 > ui.setconfig(b'empty', b'source', b'value')
92 92 > EOF
93 93 $ cp .hg/hgrc .hg/hgrc.orig
94 94 $ cat <<EOF >> .hg/hgrc
95 95 > [extensions]
96 96 > emptysource = `pwd`/emptysource.py
97 97 > EOF
98 98
99 99 $ hg config --debug empty.source
100 100 read config from: * (glob)
101 101 none: value
102 102 $ hg config empty.source -Tjson
103 103 [
104 104 {
105 105 "name": "empty.source",
106 106 "source": "",
107 107 "value": "value"
108 108 }
109 109 ]
110 110
111 111 $ cp .hg/hgrc.orig .hg/hgrc
112 112
113 113 Test "%unset"
114 114
115 115 $ cat >> $HGRCPATH <<EOF
116 116 > [unsettest]
117 117 > local-hgrcpath = should be unset (HGRCPATH)
118 118 > %unset local-hgrcpath
119 119 >
120 120 > global = should be unset (HGRCPATH)
121 121 >
122 122 > both = should be unset (HGRCPATH)
123 123 >
124 124 > set-after-unset = should be unset (HGRCPATH)
125 125 > EOF
126 126
127 127 $ cat >> .hg/hgrc <<EOF
128 128 > [unsettest]
129 129 > local-hgrc = should be unset (.hg/hgrc)
130 130 > %unset local-hgrc
131 131 >
132 132 > %unset global
133 133 >
134 134 > both = should be unset (.hg/hgrc)
135 135 > %unset both
136 136 >
137 137 > set-after-unset = should be unset (.hg/hgrc)
138 138 > %unset set-after-unset
139 139 > set-after-unset = should be set (.hg/hgrc)
140 140 > EOF
141 141
142 142 $ hg showconfig unsettest
143 143 unsettest.set-after-unset=should be set (.hg/hgrc)
144 144
145 145 Test exit code when no config matches
146 146
147 147 $ hg config Section.idontexist
148 148 [1]
149 149
150 150 sub-options in [paths] aren't expanded
151 151
152 152 $ cat > .hg/hgrc << EOF
153 153 > [paths]
154 154 > foo = ~/foo
155 155 > foo:suboption = ~/foo
156 156 > EOF
157 157
158 158 $ hg showconfig paths
159 159 paths.foo:suboption=~/foo
160 160 paths.foo=$TESTTMP/foo
161 161
162 162 edit failure
163 163
164 164 $ HGEDITOR=false hg config --edit
165 165 abort: edit failed: false exited with status 1
166 166 [255]
167 167
168 168 config affected by environment variables
169 169
170 170 $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor'
171 171 $VISUAL: ui.editor=e2
172 172
173 173 $ VISUAL=e2 hg config --debug --config ui.editor=e3 | grep 'ui\.editor'
174 174 --config: ui.editor=e3
175 175
176 176 $ PAGER=p1 hg config --debug | grep 'pager\.pager'
177 177 $PAGER: pager.pager=p1
178 178
179 179 $ PAGER=p1 hg config --debug --config pager.pager=p2 | grep 'pager\.pager'
180 180 --config: pager.pager=p2
181 181
182 182 verify that aliases are evaluated as well
183 183
184 184 $ hg init aliastest
185 185 $ cd aliastest
186 186 $ cat > .hg/hgrc << EOF
187 187 > [ui]
188 188 > user = repo user
189 189 > EOF
190 190 $ touch index
191 191 $ unset HGUSER
192 192 $ hg ci -Am test
193 193 adding index
194 194 $ hg log --template '{author}\n'
195 195 repo user
196 196 $ cd ..
197 197
198 198 alias has lower priority
199 199
200 200 $ hg init aliaspriority
201 201 $ cd aliaspriority
202 202 $ cat > .hg/hgrc << EOF
203 203 > [ui]
204 204 > user = alias user
205 205 > username = repo user
206 206 > EOF
207 207 $ touch index
208 208 $ unset HGUSER
209 209 $ hg ci -Am test
210 210 adding index
211 211 $ hg log --template '{author}\n'
212 212 repo user
213 213 $ cd ..
214
215 configs should be read in lexicographical order
216
217 $ mkdir configs
218 $ for i in `$TESTDIR/seq.py 10 99`; do
219 > printf "[section]\nkey=$i" > configs/$i.rc
220 > done
221 $ HGRCPATH=configs hg config section.key
222 99
General Comments 0
You need to be logged in to leave comments. Login now