|
1 # rcutil.py - utilities about config paths, special config sections etc. |
|
2 # |
|
3 # Copyright Mercurial Contributors |
|
4 # |
|
5 # This software may be used and distributed according to the terms of the |
|
6 # GNU General Public License version 2 or any later version. |
|
7 |
|
8 from __future__ import annotations |
|
9 |
|
10 import os |
|
11 |
|
12 from .. import ( |
|
13 encoding, |
|
14 pycompat, |
|
15 util, |
|
16 ) |
|
17 |
|
18 from ..utils import resourceutil |
|
19 |
|
20 if pycompat.iswindows: |
|
21 from .. import scmwindows as scmplatform |
|
22 else: |
|
23 from .. import scmposix as scmplatform |
|
24 |
|
25 fallbackpager = scmplatform.fallbackpager |
|
26 systemrcpath = scmplatform.systemrcpath |
|
27 userrcpath = scmplatform.userrcpath |
|
28 |
|
29 |
|
30 def _expandrcpath(path): |
|
31 '''path could be a file or a directory. return a list of file paths''' |
|
32 p = util.expandpath(path) |
|
33 if os.path.isdir(p): |
|
34 join = os.path.join |
|
35 return sorted( |
|
36 join(p, f) for f, k in util.listdir(p) if f.endswith(b'.rc') |
|
37 ) |
|
38 return [p] |
|
39 |
|
40 |
|
41 def envrcitems(env=None): |
|
42 """Return [(section, name, value, source)] config items. |
|
43 |
|
44 The config items are extracted from environment variables specified by env, |
|
45 used to override systemrc, but not userrc. |
|
46 |
|
47 If env is not provided, encoding.environ will be used. |
|
48 """ |
|
49 if env is None: |
|
50 env = encoding.environ |
|
51 checklist = [ |
|
52 (b'EDITOR', b'ui', b'editor'), |
|
53 (b'VISUAL', b'ui', b'editor'), |
|
54 (b'PAGER', b'pager', b'pager'), |
|
55 ] |
|
56 result = [] |
|
57 for envname, section, configname in checklist: |
|
58 if envname not in env: |
|
59 continue |
|
60 result.append((section, configname, env[envname], b'$%s' % envname)) |
|
61 return result |
|
62 |
|
63 |
|
64 def default_rc_resources(): |
|
65 """return rc resource IDs in defaultrc""" |
|
66 rsrcs = resourceutil.contents(b'mercurial.defaultrc') |
|
67 return [ |
|
68 (b'mercurial.defaultrc', r) |
|
69 for r in sorted(rsrcs) |
|
70 if resourceutil.is_resource(b'mercurial.defaultrc', r) |
|
71 and r.endswith(b'.rc') |
|
72 ] |
|
73 |
|
74 |
|
75 def rccomponents(): |
|
76 """return an ordered [(type, obj)] about where to load configs. |
|
77 |
|
78 respect $HGRCPATH. if $HGRCPATH is empty, only .hg/hgrc of current repo is |
|
79 used. if $HGRCPATH is not set, the platform default will be used. |
|
80 |
|
81 if a directory is provided, *.rc files under it will be used. |
|
82 |
|
83 type could be either 'path', 'items' or 'resource'. If type is 'path', |
|
84 obj is a string, and is the config file path. if type is 'items', obj is a |
|
85 list of (section, name, value, source) that should fill the config directly. |
|
86 If type is 'resource', obj is a tuple of (package name, resource name). |
|
87 """ |
|
88 envrc = (b'items', envrcitems()) |
|
89 |
|
90 if b'HGRCPATH' in encoding.environ: |
|
91 # assume HGRCPATH is all about user configs so environments can be |
|
92 # overridden. |
|
93 _rccomponents = [envrc] |
|
94 for p in encoding.environ[b'HGRCPATH'].split(pycompat.ospathsep): |
|
95 if not p: |
|
96 continue |
|
97 _rccomponents.extend((b'path', p) for p in _expandrcpath(p)) |
|
98 else: |
|
99 _rccomponents = [(b'resource', r) for r in default_rc_resources()] |
|
100 |
|
101 normpaths = lambda paths: [ |
|
102 (b'path', os.path.normpath(p)) for p in paths |
|
103 ] |
|
104 _rccomponents.extend(normpaths(systemrcpath())) |
|
105 _rccomponents.append(envrc) |
|
106 _rccomponents.extend(normpaths(userrcpath())) |
|
107 return _rccomponents |
|
108 |
|
109 |
|
110 def defaultpagerenv(): |
|
111 """return a dict of default environment variables and their values, |
|
112 intended to be set before starting a pager. |
|
113 """ |
|
114 return {b'LESS': b'FRX', b'LV': b'-c'} |
|
115 |
|
116 |
|
117 def use_repo_hgrc(): |
|
118 """True if repositories `.hg/hgrc` config should be read""" |
|
119 return b'HGRCSKIPREPO' not in encoding.environ |