-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathscript.py
More file actions
325 lines (294 loc) · 13.8 KB
/
Copy pathscript.py
File metadata and controls
325 lines (294 loc) · 13.8 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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
import os
import shutil
# README
# This script should be run from the root of the project with the command:
# python script.py or python3 script.py
#
# It will check operation constants, provided below, for information regarding what to erase or where to copy
# That information must be filles before running the script
#
# Versions
# 0.1
# - can remove files if relative path to the script is provided
# - can copy files if file and copy directory information is provided
# 0.2
# - can modify files
# 0.3
# - can change the package names in the example app
# OPERATION CONSTANTS
FILES_TO_ERASE = [
'../android/src/main/java/ly/count/dart/countly_flutter/CountlyMessagingService.java',
'../ios/countly_flutter.podspec',
'../ios/countly_flutter/Sources/countly_flutter/CountlyFLPushNotifications.h',
'../ios/countly_flutter/Sources/countly_flutter/CountlyFLPushNotifications.m'
] # array of string values. Relative path to the files. Something like: 'android/sth/sth.txt'
FILES_TO_MOVE = [
[
'no-push-files/AndroidManifest.xml',
'../android/src/main/AndroidManifest.xml'
],
[
'no-push-files/build.gradle',
'../android/build.gradle'
],
[
'no-push-files/pubspec.yaml',
'../pubspec.yaml'
],
[
'no-push-files/countly_flutter_np.podspec',
'../ios/countly_flutter_np.podspec'
],
[
'no-push-files/settings.gradle',
'../android/settings.gradle'
],
[
'no-push-files/README.md',
'../README.md'
]
] # array of, arrays of string tuples. Relative path to the file and the relative path to the copy directory. Something like ['android/sth/sth.txt','android2/folder']
# paths to modify
modPathAndroid = '../android/src/main/java/ly/count/dart/countly_flutter/CountlyFlutterPlugin.java'
modPathIos = '../ios/countly_flutter/Sources/countly_flutter/CountlyFlutterPlugin.m'
modPathCountly = '../lib/src/countly_flutter.dart'
modPathExampleYaml = '../example/pubspec.yaml'
# paths to change packages
packagePathExample = '../example/lib/'
packagePathExampleIntegrationTest = '../example/integration_test/'
packagePathExampleIntegrationTest_sc1 = '../example/integration_test/scenario_device_id_init/'
packagePathExampleIntegrationTest_sc2 = '../example/integration_test/sc-AP-appPerformanceMonit/'
packagePathLib = '../lib/'
packagePathLibInternal = '../lib/src/'
packagePathIntegrationTest = '../integration_test/'
# normal and np package names
packagePrefix = 'package:countly_flutter/'
packagePrefixToChange = 'package:countly_flutter_np/'
objectOfComModification = {
modPathAndroid: {
'modifications': {
'import com.google.firebase.iid.FirebaseInstanceId;': 'remove',
'import com.google.firebase.iid.InstanceIdResult;': 'remove',
'import com.google.android.gms.tasks.Task;': 'remove',
'import com.google.android.gms.tasks.OnCompleteListener;': 'remove',
'import com.google.firebase.FirebaseApp;': 'remove',
'private final boolean BUILDING_WITH_PUSH_DISABLED = false;': 'private final boolean BUILDING_WITH_PUSH_DISABLED = true;'
},
'consecutiveOmits': [
'FirebaseApp.initializeApp(context);',
'FirebaseInstanceId.getInstance().getInstanceId()',
'.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {',
'@Override',
'public void onComplete(@NonNull Task<InstanceIdResult> task) {',
'if (!task.isSuccessful()) {',
'log("getInstanceId failed", task.getException(), LogLevel.WARNING);',
'return;',
'}',
'String token = task.getResult().getToken();',
'CountlyPush.onTokenRefresh(token);',
'}',
'});'
]
},
modPathIos: {
'modifications': {
'BOOL BUILDING_WITH_PUSH_DISABLED = false;': 'BOOL BUILDING_WITH_PUSH_DISABLED = true;',
'// #define COUNTLY_EXCLUDE_PUSHNOTIFICATIONS': '#define COUNTLY_EXCLUDE_PUSHNOTIFICATIONS'
},
'consecutiveOmits': []
},
modPathCountly: {
'modifications': {
'static const bool BUILDING_WITH_PUSH_DISABLED = false;': 'static const bool BUILDING_WITH_PUSH_DISABLED = true;'
},
'consecutiveOmits': []
},
modPathExampleYaml: {
'modifications': {
' countly_flutter:': ' countly_flutter_np:',
},
'consecutiveOmits': []
}
} # 'modifications' is a map with keys are the lines to remove or modify. 'consecutiveOmits' are a block of lines to remove.
# walks through all files in the project and writes down the paths of the ones you are looking for. Can only work for unique files.
# TODO: Refactor so that it checks only the specified folder and files, like ['android-app', 'gradle']. Makes it easy to find files without the need of relative path information.
def findFilesTo(src, array):
paths = []
for root, dirs, files in os.walk(src):
for file in files:
for fileName in array:
if file == fileName:
path = os.path.join(root, file)
paths.append(path)
return paths
# loops through the provided array of relative paths and erases each file that exists
def removeFiles(paths, cwd):
for path in paths:
path = os.path.join(cwd, path)
if os.path.exists(path):
print('Removing:'+path)
os.remove(path)
# loops through the provided array of relative paths and copies each file that exists
def copyFiles(arrays, cwd):
for tuple in arrays:
file = os.path.join(cwd, tuple[0])
folder = os.path.join(cwd, tuple[1])
shutil.copy(file, folder)
# Modifies a given document
# (String) filePath - relative path to the file to modify
# (Obj) modificationInfo - object that contains file path as keys and modification and omittance info as values
# (String) modificationType - 'bloc' for block removal, 'mod' for modification
def modifyFile(filePath, modificationInfo, modificationType):
# reading operations
with open(filePath, 'r') as f:
content = f.readlines()
fileLines = []
for line in content:
if modificationType == 'mod':
if line.strip('\n') in modificationInfo[filePath]['modifications']:
if modificationInfo[filePath]['modifications'][line.strip('\n')] == 'remove':
print('Removing line: ', line)
else:
fileLines.append(
modificationInfo[filePath]['modifications'][line.strip('\n')] + '\n')
print('Replacing: ['+line+'] with: ['+modificationInfo[filePath]
['modifications'][line.strip('\n')]+']')
else:
fileLines.append(line)
elif modificationType == 'bloc':
if modificationInfo[filePath]['consecutiveOmits']:
if modificationInfo[filePath]['consecutiveOmits'][0] in line.strip('\n'):
modificationInfo[filePath]['consecutiveOmits'].pop(0)
print('Removing line: ', line)
else:
fileLines.append(line)
else:
fileLines.append(line)
f.close()
# writing operations
finalFile = open(filePath, 'w')
finalFile.writelines(fileLines)
finalFile.close()
print('Modified the file:'+filePath)
def update_package(directory_path, from_package, to_package):
for root, dirs, files in os.walk(directory_path):
for file_name in files:
file_path = os.path.join(root, file_name)
# Process only Dart files
if file_path.endswith('.dart'):
print(f'Processing file: {file_path}')
# Read the file content
with open(file_path, 'r') as file:
lines = file.readlines()
# Process only the first 30 lines as the package import statement is usually in the first 30 lines
for line_number, line in enumerate(lines[:30], start=1):
if from_package in line:
lines[line_number -
1] = line.replace(from_package, to_package)
# Write the modified content back to the file
with open(file_path, 'w') as file:
file.writelines(lines)
print(f'File processed: {file_path}')
# Renames the iOS Swift Package Manager package from countly_flutter to countly_flutter_np.
# Flutter discovers a plugin's SwiftPM package at ios/<package_name>/Package.swift, and the
# np flavor's package name is countly_flutter_np, so the package directory, target directory,
# public-header directory, and the names inside Package.swift must all be renamed to match.
# The Objective-C class (CountlyFlutterPlugin) and pluginClass in pubspec are unchanged.
def renameIosForNp(cwd):
iosDir = os.path.join(cwd, '../ios')
oldPkg = os.path.join(iosDir, 'countly_flutter')
newPkg = os.path.join(iosDir, 'countly_flutter_np')
if not os.path.exists(oldPkg):
print('iOS SwiftPM package dir not found, skipping rename:', oldPkg)
return
# Rename the inner target dir and its public-header dir before renaming the package dir.
srcOld = os.path.join(oldPkg, 'Sources', 'countly_flutter')
incOld = os.path.join(srcOld, 'include', 'countly_flutter')
if os.path.exists(incOld):
os.rename(incOld, os.path.join(srcOld, 'include', 'countly_flutter_np'))
if os.path.exists(srcOld):
os.rename(srcOld, os.path.join(oldPkg, 'Sources', 'countly_flutter_np'))
# Rewrite the SwiftPM manifest names (package, target, product/library, header search path).
pkgSwift = os.path.join(oldPkg, 'Package.swift')
if os.path.exists(pkgSwift):
with open(pkgSwift, 'r') as f:
content = f.read()
content = content.replace('name: "countly_flutter"', 'name: "countly_flutter_np"')
content = content.replace('["countly_flutter"]', '["countly_flutter_np"]')
content = content.replace('name: "countly-flutter"', 'name: "countly-flutter-np"')
content = content.replace('include/countly_flutter"', 'include/countly_flutter_np"')
with open(pkgSwift, 'w') as f:
f.write(content)
print('Rewrote Package.swift names for countly_flutter_np')
# The example app's AppDelegate imports the plugin module by name; the np pod's module
# is countly_flutter_np. (GeneratedPluginRegistrant is regenerated by flutter pub get.)
appDelegate = os.path.join(cwd, '../example/ios/Runner/AppDelegate.swift')
if os.path.exists(appDelegate):
with open(appDelegate, 'r') as f:
ad = f.read()
ad = ad.replace('import countly_flutter\n', 'import countly_flutter_np\n')
with open(appDelegate, 'w') as f:
f.write(ad)
print('Updated example AppDelegate import for countly_flutter_np')
# The example app's Notification Service Extension target references the vendored
# CountlyNotificationService files by path into the plugin; repoint it at the renamed dir.
pbxproj = os.path.join(cwd, '../example/ios/Runner.xcodeproj/project.pbxproj')
if os.path.exists(pbxproj):
with open(pbxproj, 'r') as f:
pbx = f.read()
pbx = pbx.replace('ios/countly_flutter/Sources/countly_flutter/',
'ios/countly_flutter_np/Sources/countly_flutter_np/')
with open(pbxproj, 'w') as f:
f.write(pbx)
print('Updated example NSE references for countly_flutter_np')
# Finally rename the package directory itself.
os.rename(oldPkg, newPkg)
print('Renamed iOS SwiftPM package directory to countly_flutter_np')
def main():
# give info about set constants
print('Paths to erase:')
for i in FILES_TO_ERASE:
print(i, end='\n')
print('Paths to copy:')
for i in FILES_TO_MOVE:
print(i, end='\n')
print('Paths to modify:')
print(modPathAndroid)
print(modPathIos)
print(modPathCountly)
print(modPathExampleYaml)
print('Paths to change packages:')
print(packagePathExample)
print(packagePathExampleIntegrationTest)
print(packagePathExampleIntegrationTest_sc1)
print(packagePathExampleIntegrationTest_sc2)
print(packagePathLib)
print(packagePathLibInternal)
print(packagePathIntegrationTest)
# ask for permission to run the script
start = input('Do you want to continue? (y/n)')
if start == 'y' or start == 'Y' or start == 'yes' or start == 'YES':
cwd = os.getcwd() # get current working directory
removeFiles(FILES_TO_ERASE, cwd) # remove files
copyFiles(FILES_TO_MOVE, cwd) # copies a file
# modify files
modifyFile(modPathAndroid, objectOfComModification, 'mod')
modifyFile(modPathAndroid, objectOfComModification, 'bloc')
modifyFile(modPathIos, objectOfComModification, 'mod')
modifyFile(modPathCountly, objectOfComModification, 'mod')
modifyFile(modPathExampleYaml, objectOfComModification, 'mod')
# np package update
update_package(packagePathExample, packagePrefix, packagePrefixToChange)
update_package(packagePathExampleIntegrationTest, packagePrefix, packagePrefixToChange)
update_package(packagePathExampleIntegrationTest_sc1, packagePrefix, packagePrefixToChange)
update_package(packagePathExampleIntegrationTest_sc2, packagePrefix, packagePrefixToChange)
update_package(packagePathLib, packagePrefix, packagePrefixToChange)
update_package(packagePathLibInternal, packagePrefix, packagePrefixToChange)
update_package(packagePathIntegrationTest, packagePrefix, packagePrefixToChange)
# rename the iOS SwiftPM package to match the np package name
renameIosForNp(cwd)
print('Done')
else:
print('Aborted')
if __name__ == '__main__':
main()