Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/tools/utils.py
4128 views
1
# Copyright 2020 The Emscripten Authors. All rights reserved.
2
# Emscripten is available under two separate licenses, the MIT license and the
3
# University of Illinois/NCSA Open Source License. Both these licenses can be
4
# found in the LICENSE file.
5
6
import os
7
import shutil
8
import sys
9
import functools
10
from pathlib import Path
11
12
from . import diagnostics
13
14
__rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
15
WINDOWS = sys.platform.startswith('win')
16
MACOS = sys.platform == 'darwin'
17
LINUX = sys.platform.startswith('linux')
18
19
20
def exit_with_error(msg, *args):
21
diagnostics.error(msg, *args)
22
23
24
def path_from_root(*pathelems):
25
return str(Path(__rootpath__, *pathelems))
26
27
28
def normalize_path(path):
29
"""Normalize path separators to UNIX-style forward slashes.
30
31
This can be useful when converting paths to URLs or JS strings,
32
or when trying to generate consistent output file contents
33
across all platforms. In most cases UNIX-style separators work
34
fine on windows.
35
"""
36
return path.replace('\\', '/').replace('//', '/')
37
38
39
def safe_ensure_dirs(dirname):
40
os.makedirs(dirname, exist_ok=True)
41
42
43
# TODO(sbc): Replace with str.removeprefix once we update to python3.9
44
def removeprefix(string, prefix):
45
if string.startswith(prefix):
46
return string[len(prefix):]
47
return string
48
49
50
def convert_line_endings_in_file(filename, to_eol):
51
if to_eol == os.linesep:
52
assert os.path.exists(filename)
53
return # No conversion needed
54
55
text = read_file(filename)
56
write_file(filename, text, line_endings=to_eol)
57
58
59
def read_file(file_path):
60
"""Read from a file opened in text mode"""
61
with open(file_path, encoding='utf-8') as fh:
62
return fh.read()
63
64
65
def read_binary(file_path):
66
"""Read from a file opened in binary mode"""
67
with open(file_path, 'rb') as fh:
68
return fh.read()
69
70
71
def write_file(file_path, text, line_endings=None):
72
"""Write to a file opened in text mode"""
73
if line_endings and line_endings != os.linesep:
74
text = text.replace('\n', line_endings)
75
write_binary(file_path, text.encode('utf-8'))
76
else:
77
with open(file_path, 'w', encoding='utf-8') as fh:
78
fh.write(text)
79
80
81
def write_binary(file_path, contents):
82
"""Write to a file opened in binary mode"""
83
with open(file_path, 'wb') as fh:
84
fh.write(contents)
85
86
87
def delete_file(filename):
88
"""Delete a file (if it exists)."""
89
if os.path.lexists(filename):
90
os.remove(filename)
91
92
93
def delete_dir(dirname):
94
"""Delete a directory (if it exists)."""
95
if not os.path.exists(dirname):
96
return
97
shutil.rmtree(dirname)
98
99
100
def delete_contents(dirname, exclude=None):
101
"""Delete the contents of a directory without removing
102
the directory itself."""
103
if not os.path.exists(dirname):
104
return
105
for entry in os.listdir(dirname):
106
if exclude and entry in exclude:
107
continue
108
entry = os.path.join(dirname, entry)
109
if os.path.isdir(entry):
110
delete_dir(entry)
111
else:
112
delete_file(entry)
113
114
115
# TODO(sbc): Replace with functools.cache, once we update to python 3.9
116
memoize = functools.lru_cache(maxsize=None)
117
118
119
# TODO: Move this back to shared.py once importing that file becoming side effect free (i.e. it no longer requires a config).
120
def set_version_globals():
121
global EMSCRIPTEN_VERSION, EMSCRIPTEN_VERSION_MAJOR, EMSCRIPTEN_VERSION_MINOR, EMSCRIPTEN_VERSION_TINY
122
filename = path_from_root('emscripten-version.txt')
123
EMSCRIPTEN_VERSION = read_file(filename).strip().strip('"')
124
parts = [int(x) for x in EMSCRIPTEN_VERSION.split('-')[0].split('.')]
125
EMSCRIPTEN_VERSION_MAJOR, EMSCRIPTEN_VERSION_MINOR, EMSCRIPTEN_VERSION_TINY = parts
126
127