-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathpatcher.py
More file actions
126 lines (113 loc) · 4.58 KB
/
patcher.py
File metadata and controls
126 lines (113 loc) · 4.58 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
import glob
import io
import os
import re
class ProjectConfigPatcher:
@classmethod
def _replace_file_content(cls, file_path, old_pattern, new_pattern, re_flags=0):
with io.open(file_path, "r", encoding="utf8") as f:
content = str(f.read())
new_content = re.sub(old_pattern, new_pattern, content, flags=re_flags)
with io.open(file_path, "w", encoding="utf8") as f:
f.write(new_content)
def _get_patched_packging_option(self, content):
"""Add libjsc.so exclusion from packagingOptions
NOTE(kudo): To keep implementation simple, here to use regexp instead of AST parsing.
The drawback is that the build.gradle format should be fixed.
Two cases:
1. If there's no packagingOptions, add the section directly.
2. If there is existing packagingOptions, append exclude libjsc.so and remove all libjsc.so lines.
"""
result = re.search(
r"(?P<head>.*)(?P<body>^android {.*?^}$)(?P<foot>.*)",
content,
(re.DOTALL | re.MULTILINE),
)
android_config_content = result.group("body")
packaging_options_result = re.search(
r"(?P<head>.*)^\s*?packagingOptions {\n(?P<body>.*?)\n\s*?}$(?P<foot>.*)",
android_config_content,
(re.DOTALL | re.MULTILINE),
)
if packaging_options_result is None:
packaging_options_content = """
packagingOptions {
// Make sure libjsc.so does not packed in APK
exclude "**/libjsc.so"
}
"""
new_android_config_content = (
android_config_content[:-1] + packaging_options_content + "}\n"
)
else:
packaging_options_lines = packaging_options_result.group("body").split("\n")
packaging_options_lines = [
line for line in packaging_options_lines if line.find("/libjsc.so") < 0
]
packaging_options_lines.append(' exclude "**/libjsc.so"')
packaging_options_content = (
" packagingOptions {\n"
+ "\n".join(packaging_options_lines)
+ "\n }"
)
new_android_config_content = (
packaging_options_result.group("head")
+ packaging_options_content
+ packaging_options_result.group("foot")
)
new_content = (
result.group("head") + new_android_config_content + result.group("foot")
)
return new_content
def _patch_app_gradle(self):
app_gradle_path = os.path.abspath("android/app/build.gradle")
with io.open(app_gradle_path, "r", encoding="utf8") as f:
content = str(f.read())
new_content = self._get_patched_packging_option(content)
new_content = new_content.replace("enableHermes: true", "enableHermes: false")
with io.open(app_gradle_path, "w", encoding="utf8") as f:
f.write(new_content)
def _patch_react_native_host(self):
main_app_files = glob.glob("android/**/MainApplication.kt", recursive=True)
v8_block = """
override fun getJavaScriptExecutorFactory(): com.facebook.react.bridge.JavaScriptExecutorFactory {
return io.csie.kudo.reactnative.v8.executor.V8ExecutorFactory(
applicationContext,
packageName,
com.facebook.react.modules.systeminfo.AndroidInfoHelpers.getFriendlyDeviceName(),
useDeveloperSupport
)
}
"""
for file in main_app_files:
self._replace_file_content(
file,
r'(override fun getJSMainModuleName\(\): String = "index")',
"\\1" + v8_block,
re_flags=(re.DOTALL | re.MULTILINE),
)
def _patch_appjs(self):
appjs_path = os.path.abspath("App.tsx")
v8log_block = """
if (global._v8runtime) {
console.log(`=== V8 version[${global._v8runtime().version}] ===`);
}"""
self._replace_file_content(
appjs_path,
r"(^export default App;$)",
"\\1" + v8log_block,
re_flags=re.MULTILINE,
)
def _disable_hermes(self):
self._replace_file_content(
os.path.abspath("android/gradle.properties"),
r'^hermesEnabled=true$',
'hermesEnabled=false',
re_flags=re.MULTILINE,
)
def add_v8_support(self):
self._patch_app_gradle()
self._patch_react_native_host()
self._disable_hermes()
def add_vm_hint(self):
self._patch_appjs()