forked from aboutcode-org/commoncode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsystem.py
More file actions
158 lines (125 loc) · 4.25 KB
/
system.py
File metadata and controls
158 lines (125 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#
# Copyright (c) nexB Inc. and others. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
# See https://github.com/nexB/commoncode for support or download.
# See https://aboutcode.org for more information about nexB OSS projects.
#
import os
import sys
from commoncode.distro import parse_os_release
def os_arch():
"""
Return a tuple for the current the OS and architecture.
"""
if sys.maxsize > 2 ** 32:
arch = '64'
else:
arch = '32'
sys_platform = str(sys.platform).lower()
if sys_platform.startswith('linux'):
os = 'linux'
elif 'win32' in sys_platform:
os = 'win'
elif 'darwin' in sys_platform:
os = 'mac'
elif 'freebsd' in sys_platform:
os = 'freebsd'
else:
raise Exception('Unsupported OS/platform %r' % sys_platform)
return os, arch
#
# OS/Arch
#
current_os, current_arch = os_arch()
on_windows = current_os == 'win'
on_windows_32 = on_windows and current_arch == '32'
on_windows_64 = on_windows and current_arch == '64'
on_mac = current_os == 'mac'
on_linux = current_os == 'linux'
on_freebsd = current_os == 'freebsd'
on_posix = not on_windows and (on_mac or on_linux or on_freebsd)
current_os_arch = '%(current_os)s-%(current_arch)s' % locals()
noarch = 'noarch'
current_os_noarch = '%(current_os)s-%(noarch)s' % locals()
del os_arch
def is_on_macos_14_or_higher():
"""
Return True if the current OS is macOS 14 or higher.
It uses APFS by default and has a different behavior wrt. unicode and
filesystem encodings.
"""
import platform
macos_ver = platform.mac_ver()
macos_ver = macos_ver[0]
macos_ver = macos_ver.split('.')
return macos_ver > ['10', '14']
on_macos_14_or_higher = is_on_macos_14_or_higher()
del is_on_macos_14_or_higher
def is_on_macos_arm64():
"""
Return True if the current OS is macOS running on Apple Silicon.
"""
import platform
return on_mac and platform.machine() == 'arm64'
on_macos_arm64 = is_on_macos_arm64()
del is_on_macos_arm64
def is_on_ubuntu_22(os_release_location='/etc/os-release'):
"""
Return True if the current OS is Ubuntu 22.XX.
"""
if not on_linux:
return False
os_release_info = parse_os_release(os_release_location)
return os_release_info['ID'] == 'ubuntu' and '22' in os_release_info['VERSION_ID']
on_ubuntu_22 = is_on_ubuntu_22()
del is_on_ubuntu_22
def has_case_sensitive_fs():
"""
Return True if the current FS is case sensitive.
Windows is not case sensitive, and while older macOS HPFS+ were POSIX and
case sensitive by default, newer macOS use APFS which is no longer case
sensitive by default.
From https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/APFS_Guide/FAQ/FAQ.html
How does Apple File System handle filenames?
APFS accepts only valid UTF-8 encoded filenames for creation, and preserves
both case and normalization of the filename on disk in all variants. APFS,
like HFS+, is case-sensitive on iOS and is available in case-sensitive and
case-insensitive variants on macOS, with case-insensitive being the default.
"""
return not os.path.exists(__file__.upper())
is_case_sensitive_fs = has_case_sensitive_fs()
#
# Shared library file extensions
#
if on_windows:
lib_ext = '.dll'
if on_mac:
lib_ext = '.dylib'
if on_linux or on_freebsd:
lib_ext = '.so'
#
# Python versions
#
_sys_v0 = sys.version_info[0]
py2 = _sys_v0 == 2
py3 = _sys_v0 == 3
_sys_v1 = sys.version_info[1]
py36 = py3 and _sys_v1 == 6
py37 = py3 and _sys_v1 == 7
py38 = py3 and _sys_v1 == 8
py39 = py3 and _sys_v1 == 9
py310 = py3 and _sys_v1 == 10
# Do not let Windows error pop up messages with default SetErrorMode
# See http://msdn.microsoft.com/en-us/library/ms680621(VS100).aspx
#
# SEM_FAILCRITICALERRORS:
# The system does not display the critical-error-handler message box.
# Instead, the system sends the error to the calling process.
#
# SEM_NOGPFAULTERRORBOX:
# The system does not display the Windows Error Reporting dialog.
if on_windows:
import ctypes
# 3 is SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX
ctypes.windll.kernel32.SetErrorMode(3) # @UndefinedVariable