##// END OF EJS Templates
typing: add type hints to the platform specific scm modules...
Matt Harbison -
r50703:7a414342 default
parent child Browse files
Show More
@@ -1,95 +1,103 b''
1 import array
1 import array
2 import errno
2 import errno
3 import fcntl
3 import fcntl
4 import os
4 import os
5 import sys
5 import sys
6
6
7 from typing import (
8 List,
9 Tuple,
10 )
11
7 from .pycompat import getattr
12 from .pycompat import getattr
8 from . import (
13 from . import (
9 encoding,
14 encoding,
10 pycompat,
15 pycompat,
11 util,
16 util,
12 )
17 )
13
18
19 if pycompat.TYPE_CHECKING:
20 from . import ui as uimod
21
14 # BSD 'more' escapes ANSI color sequences by default. This can be disabled by
22 # BSD 'more' escapes ANSI color sequences by default. This can be disabled by
15 # $MORE variable, but there's no compatible option with Linux 'more'. Given
23 # $MORE variable, but there's no compatible option with Linux 'more'. Given
16 # OS X is widely used and most modern Unix systems would have 'less', setting
24 # OS X is widely used and most modern Unix systems would have 'less', setting
17 # 'less' as the default seems reasonable.
25 # 'less' as the default seems reasonable.
18 fallbackpager = b'less'
26 fallbackpager = b'less'
19
27
20
28
21 def _rcfiles(path):
29 def _rcfiles(path: bytes) -> List[bytes]:
22 rcs = [os.path.join(path, b'hgrc')]
30 rcs = [os.path.join(path, b'hgrc')]
23 rcdir = os.path.join(path, b'hgrc.d')
31 rcdir = os.path.join(path, b'hgrc.d')
24 try:
32 try:
25 rcs.extend(
33 rcs.extend(
26 [
34 [
27 os.path.join(rcdir, f)
35 os.path.join(rcdir, f)
28 for f, kind in sorted(util.listdir(rcdir))
36 for f, kind in sorted(util.listdir(rcdir))
29 if f.endswith(b".rc")
37 if f.endswith(b".rc")
30 ]
38 ]
31 )
39 )
32 except OSError:
40 except OSError:
33 pass
41 pass
34 return rcs
42 return rcs
35
43
36
44
37 def systemrcpath():
45 def systemrcpath() -> List[bytes]:
38 path = []
46 path = []
39 if pycompat.sysplatform == b'plan9':
47 if pycompat.sysplatform == b'plan9':
40 root = b'lib/mercurial'
48 root = b'lib/mercurial'
41 else:
49 else:
42 root = b'etc/mercurial'
50 root = b'etc/mercurial'
43 # old mod_python does not set sys.argv
51 # old mod_python does not set sys.argv
44 if len(getattr(sys, 'argv', [])) > 0:
52 if len(getattr(sys, 'argv', [])) > 0:
45 p = os.path.dirname(os.path.dirname(pycompat.sysargv[0]))
53 p = os.path.dirname(os.path.dirname(pycompat.sysargv[0]))
46 if p != b'/':
54 if p != b'/':
47 path.extend(_rcfiles(os.path.join(p, root)))
55 path.extend(_rcfiles(os.path.join(p, root)))
48 path.extend(_rcfiles(b'/' + root))
56 path.extend(_rcfiles(b'/' + root))
49 return path
57 return path
50
58
51
59
52 def userrcpath():
60 def userrcpath() -> List[bytes]:
53 if pycompat.sysplatform == b'plan9':
61 if pycompat.sysplatform == b'plan9':
54 return [encoding.environ[b'home'] + b'/lib/hgrc']
62 return [encoding.environ[b'home'] + b'/lib/hgrc']
55 elif pycompat.isdarwin:
63 elif pycompat.isdarwin:
56 return [os.path.expanduser(b'~/.hgrc')]
64 return [os.path.expanduser(b'~/.hgrc')]
57 else:
65 else:
58 confighome = encoding.environ.get(b'XDG_CONFIG_HOME')
66 confighome = encoding.environ.get(b'XDG_CONFIG_HOME')
59 if confighome is None or not os.path.isabs(confighome):
67 if confighome is None or not os.path.isabs(confighome):
60 confighome = os.path.expanduser(b'~/.config')
68 confighome = os.path.expanduser(b'~/.config')
61
69
62 return [
70 return [
63 os.path.expanduser(b'~/.hgrc'),
71 os.path.expanduser(b'~/.hgrc'),
64 os.path.join(confighome, b'hg', b'hgrc'),
72 os.path.join(confighome, b'hg', b'hgrc'),
65 ]
73 ]
66
74
67
75
68 def termsize(ui):
76 def termsize(ui: "uimod.ui") -> Tuple[int, int]:
69 try:
77 try:
70 import termios
78 import termios
71
79
72 TIOCGWINSZ = termios.TIOCGWINSZ # unavailable on IRIX (issue3449)
80 TIOCGWINSZ = termios.TIOCGWINSZ # unavailable on IRIX (issue3449)
73 except (AttributeError, ImportError):
81 except (AttributeError, ImportError):
74 return 80, 24
82 return 80, 24
75
83
76 for dev in (ui.ferr, ui.fout, ui.fin):
84 for dev in (ui.ferr, ui.fout, ui.fin):
77 try:
85 try:
78 try:
86 try:
79 fd = dev.fileno()
87 fd = dev.fileno()
80 except AttributeError:
88 except AttributeError:
81 continue
89 continue
82 if not os.isatty(fd):
90 if not os.isatty(fd):
83 continue
91 continue
84 arri = fcntl.ioctl(fd, TIOCGWINSZ, b'\0' * 8)
92 arri = fcntl.ioctl(fd, TIOCGWINSZ, b'\0' * 8)
85 height, width = array.array('h', arri)[:2]
93 height, width = array.array('h', arri)[:2]
86 if width > 0 and height > 0:
94 if width > 0 and height > 0:
87 return width, height
95 return width, height
88 except ValueError:
96 except ValueError:
89 pass
97 pass
90 except IOError as e:
98 except IOError as e:
91 if e.errno == errno.EINVAL:
99 if e.errno == errno.EINVAL:
92 pass
100 pass
93 else:
101 else:
94 raise
102 raise
95 return 80, 24
103 return 80, 24
@@ -1,115 +1,123 b''
1 import os
1 import os
2
2
3 from typing import (
4 List,
5 Tuple,
6 )
7
3 from . import (
8 from . import (
4 encoding,
9 encoding,
5 pycompat,
10 pycompat,
6 util,
11 util,
7 win32,
12 win32,
8 )
13 )
9
14
15 if pycompat.TYPE_CHECKING:
16 from . import ui as uimod
17
10 try:
18 try:
11 import _winreg as winreg # pytype: disable=import-error
19 import _winreg as winreg # pytype: disable=import-error
12
20
13 winreg.CloseKey
21 winreg.CloseKey
14 except ImportError:
22 except ImportError:
15 # py2 only
23 # py2 only
16 import winreg # pytype: disable=import-error
24 import winreg # pytype: disable=import-error
17
25
18 # MS-DOS 'more' is the only pager available by default on Windows.
26 # MS-DOS 'more' is the only pager available by default on Windows.
19 fallbackpager = b'more'
27 fallbackpager = b'more'
20
28
21
29
22 def systemrcpath():
30 def systemrcpath() -> List[bytes]:
23 '''return default os-specific hgrc search path'''
31 '''return default os-specific hgrc search path'''
24 rcpath = []
32 rcpath = []
25 filename = win32.executablepath()
33 filename = win32.executablepath()
26 # Use mercurial.ini found in directory with hg.exe
34 # Use mercurial.ini found in directory with hg.exe
27 progrc = os.path.join(os.path.dirname(filename), b'mercurial.ini')
35 progrc = os.path.join(os.path.dirname(filename), b'mercurial.ini')
28 rcpath.append(progrc)
36 rcpath.append(progrc)
29
37
30 def _processdir(progrcd):
38 def _processdir(progrcd: bytes) -> None:
31 if os.path.isdir(progrcd):
39 if os.path.isdir(progrcd):
32 for f, kind in sorted(util.listdir(progrcd)):
40 for f, kind in sorted(util.listdir(progrcd)):
33 if f.endswith(b'.rc'):
41 if f.endswith(b'.rc'):
34 rcpath.append(os.path.join(progrcd, f))
42 rcpath.append(os.path.join(progrcd, f))
35
43
36 # Use hgrc.d found in directory with hg.exe
44 # Use hgrc.d found in directory with hg.exe
37 _processdir(os.path.join(os.path.dirname(filename), b'hgrc.d'))
45 _processdir(os.path.join(os.path.dirname(filename), b'hgrc.d'))
38
46
39 # treat a PROGRAMDATA directory as equivalent to /etc/mercurial
47 # treat a PROGRAMDATA directory as equivalent to /etc/mercurial
40 programdata = encoding.environ.get(b'PROGRAMDATA')
48 programdata = encoding.environ.get(b'PROGRAMDATA')
41 if programdata:
49 if programdata:
42 programdata = os.path.join(programdata, b'Mercurial')
50 programdata = os.path.join(programdata, b'Mercurial')
43 _processdir(os.path.join(programdata, b'hgrc.d'))
51 _processdir(os.path.join(programdata, b'hgrc.d'))
44
52
45 ini = os.path.join(programdata, b'mercurial.ini')
53 ini = os.path.join(programdata, b'mercurial.ini')
46 if os.path.isfile(ini):
54 if os.path.isfile(ini):
47 rcpath.append(ini)
55 rcpath.append(ini)
48
56
49 ini = os.path.join(programdata, b'hgrc')
57 ini = os.path.join(programdata, b'hgrc')
50 if os.path.isfile(ini):
58 if os.path.isfile(ini):
51 rcpath.append(ini)
59 rcpath.append(ini)
52
60
53 # next look for a system rcpath in the registry
61 # next look for a system rcpath in the registry
54 value = util.lookupreg(
62 value = util.lookupreg(
55 # pytype: disable=module-attr
63 # pytype: disable=module-attr
56 b'SOFTWARE\\Mercurial',
64 b'SOFTWARE\\Mercurial',
57 None,
65 None,
58 winreg.HKEY_LOCAL_MACHINE
66 winreg.HKEY_LOCAL_MACHINE
59 # pytype: enable=module-attr
67 # pytype: enable=module-attr
60 )
68 )
61 if value and isinstance(value, bytes):
69 if value and isinstance(value, bytes):
62 value = util.localpath(value)
70 value = util.localpath(value)
63 for p in value.split(pycompat.ospathsep):
71 for p in value.split(pycompat.ospathsep):
64 if p.lower().endswith(b'mercurial.ini'):
72 if p.lower().endswith(b'mercurial.ini'):
65 rcpath.append(p)
73 rcpath.append(p)
66 else:
74 else:
67 _processdir(p)
75 _processdir(p)
68 return rcpath
76 return rcpath
69
77
70
78
71 def userrcpath():
79 def userrcpath() -> List[bytes]:
72 '''return os-specific hgrc search path to the user dir'''
80 '''return os-specific hgrc search path to the user dir'''
73 home = _legacy_expanduser(b'~')
81 home = _legacy_expanduser(b'~')
74 path = [os.path.join(home, b'mercurial.ini'), os.path.join(home, b'.hgrc')]
82 path = [os.path.join(home, b'mercurial.ini'), os.path.join(home, b'.hgrc')]
75 userprofile = encoding.environ.get(b'USERPROFILE')
83 userprofile = encoding.environ.get(b'USERPROFILE')
76 if userprofile and userprofile != home:
84 if userprofile and userprofile != home:
77 path.append(os.path.join(userprofile, b'mercurial.ini'))
85 path.append(os.path.join(userprofile, b'mercurial.ini'))
78 path.append(os.path.join(userprofile, b'.hgrc'))
86 path.append(os.path.join(userprofile, b'.hgrc'))
79 return path
87 return path
80
88
81
89
82 def _legacy_expanduser(path):
90 def _legacy_expanduser(path: bytes) -> bytes:
83 """Expand ~ and ~user constructs in the pre 3.8 style"""
91 """Expand ~ and ~user constructs in the pre 3.8 style"""
84
92
85 # Python 3.8+ changed the expansion of '~' from HOME to USERPROFILE. See
93 # Python 3.8+ changed the expansion of '~' from HOME to USERPROFILE. See
86 # https://bugs.python.org/issue36264. It also seems to capitalize the drive
94 # https://bugs.python.org/issue36264. It also seems to capitalize the drive
87 # letter, as though it was processed through os.path.realpath().
95 # letter, as though it was processed through os.path.realpath().
88 if not path.startswith(b'~'):
96 if not path.startswith(b'~'):
89 return path
97 return path
90
98
91 i, n = 1, len(path)
99 i, n = 1, len(path)
92 while i < n and path[i] not in b'\\/':
100 while i < n and path[i] not in b'\\/':
93 i += 1
101 i += 1
94
102
95 if b'HOME' in encoding.environ:
103 if b'HOME' in encoding.environ:
96 userhome = encoding.environ[b'HOME']
104 userhome = encoding.environ[b'HOME']
97 elif b'USERPROFILE' in encoding.environ:
105 elif b'USERPROFILE' in encoding.environ:
98 userhome = encoding.environ[b'USERPROFILE']
106 userhome = encoding.environ[b'USERPROFILE']
99 elif b'HOMEPATH' not in encoding.environ:
107 elif b'HOMEPATH' not in encoding.environ:
100 return path
108 return path
101 else:
109 else:
102 try:
110 try:
103 drive = encoding.environ[b'HOMEDRIVE']
111 drive = encoding.environ[b'HOMEDRIVE']
104 except KeyError:
112 except KeyError:
105 drive = b''
113 drive = b''
106 userhome = os.path.join(drive, encoding.environ[b'HOMEPATH'])
114 userhome = os.path.join(drive, encoding.environ[b'HOMEPATH'])
107
115
108 if i != 1: # ~user
116 if i != 1: # ~user
109 userhome = os.path.join(os.path.dirname(userhome), path[1:i])
117 userhome = os.path.join(os.path.dirname(userhome), path[1:i])
110
118
111 return userhome + path[i:]
119 return userhome + path[i:]
112
120
113
121
114 def termsize(ui):
122 def termsize(ui: "uimod.ui") -> Tuple[int, int]:
115 return win32.termsize()
123 return win32.termsize()
General Comments 0
You need to be logged in to leave comments. Login now