65
65
66
66
def get_files_from_directory (dirpath , file_extension , file_name = None ,
67
67
absolute_paths = True ):
68
- """ Helper function to filter files in directories.
68
+ """Helper function to filter files in directories.
69
69
70
70
Args:
71
71
dirpath (str): Root directory to search in.
@@ -96,14 +96,36 @@ def get_files_from_directory(dirpath, file_extension, file_name=None,
96
96
return files
97
97
98
98
99
+ def get_files (dirs_and_files , file_extension , file_name = None ):
100
+ """Get final list of files after searching directories.
101
+ If a directory is passed, it is searched recursively.
102
+
103
+ Args:
104
+ dirs_and_files (iterable(str)): List of paths which could be files or
105
+ directories.
106
+
107
+ Returns:
108
+ iterable(str): Final list of files after recursively searching dirs.
109
+ """
110
+ files = []
111
+ for entry in dirs_and_files :
112
+ abspath = os .path .abspath (entry )
113
+ if not os .path .exists (abspath ):
114
+ continue
115
+ if os .path .isdir (abspath ):
116
+ files = files + get_files_from_directory (abspath ,
117
+ file_extension = file_extension ,
118
+ file_name = file_name )
119
+ elif os .path .isfile (abspath ):
120
+ files .append (abspath )
121
+ return files
122
+
123
+
124
+ ########## iOS pods versions update #######################################
125
+
99
126
# Cocoapods github repo from where we scan available pods and their versions.
100
127
PODSPEC_REPOSITORY = 'https://github.com/CocoaPods/Specs.git'
101
128
102
- # Android gMaven repostiory from where we scan available android packages
103
- # and their versions
104
- GMAVEN_MASTER_INDEX = "https://dl.google.com/dl/android/maven2/master-index.xml"
105
- GMAVEN_GROUP_INDEX = "https://dl.google.com/dl/android/maven2/{0}/group-index.xml"
106
-
107
129
# List of Pods that we are interested in.
108
130
PODS = (
109
131
'FirebaseCore' ,
@@ -124,7 +146,7 @@ def get_files_from_directory(dirpath, file_extension, file_name=None,
124
146
125
147
126
148
def get_pod_versions (specs_repo , pods = PODS ):
127
- """ Get available pods and their versions from the specs repo
149
+ """Get available pods and their versions from the specs repo
128
150
129
151
Args:
130
152
local_repo_dir (str): Directory mirroring Cocoapods specs repo
@@ -195,7 +217,7 @@ def get_latest_pod_versions(specs_repo=None, pods=PODS):
195
217
196
218
197
219
def get_pod_files (dirs_and_files ):
198
- """ Get final list of podfiles to update.
220
+ """Get final list of podfiles to update.
199
221
If a directory is passed, it is searched recursively.
200
222
201
223
Args:
@@ -223,7 +245,7 @@ def get_pod_files(dirs_and_files):
223
245
RE_PODFILE_VERSION = re .compile ("\s+pod '(?P<pod_name>.+)', '(?P<version>.+)'\n " )
224
246
225
247
def modify_pod_file (pod_file , pod_version_map , dryrun = True ):
226
- """ Update pod versions in specified podfile.
248
+ """Update pod versions in specified podfile.
227
249
228
250
Args:
229
251
pod_file (str): Absolute path to a podfile.
@@ -236,9 +258,9 @@ def modify_pod_file(pod_file, pod_version_map, dryrun=True):
236
258
with open (pod_file , "r" ) as podfile :
237
259
existing_lines = podfile .readlines ()
238
260
if not existing_lines :
239
- logging .debug ('Update failed. ' +
261
+ logging .fatal ('Update failed. ' +
240
262
'Could not read contents from pod file {0}.' .format (podfile ))
241
- return
263
+
242
264
logging .debug ('Checking if update is required for {0}' .format (pod_file ))
243
265
244
266
substituted_pairs = []
@@ -266,14 +288,152 @@ def modify_pod_file(pod_file, pod_version_map, dryrun=True):
266
288
podfile .writelines (existing_lines )
267
289
print ()
268
290
291
+ ########## END: iOS pods versions update #####################################
292
+
293
+ ########## Android versions update #############################
294
+
295
+ # Android gMaven repostiory from where we scan available android packages
296
+ # and their versions
297
+ GMAVEN_MASTER_INDEX = "https://dl.google.com/dl/android/maven2/master-index.xml"
298
+ GMAVEN_GROUP_INDEX = "https://dl.google.com/dl/android/maven2/{0}/group-index.xml"
299
+
300
+
301
+ def get_latest_maven_versions ():
302
+ latest_versions = {}
303
+ response = requests .get (GMAVEN_MASTER_INDEX )
304
+ index_xml = ElementTree .fromstring (response .content )
305
+ for index_child in index_xml :
306
+ group_name = index_child .tag
307
+ group_path = group_name .replace ('.' , '/' )
308
+ response = requests .get (GMAVEN_GROUP_INDEX .format (group_path ))
309
+ group_xml = ElementTree .fromstring (response .content )
310
+ for group_child in group_xml :
311
+ package_name = group_child .tag .replace ('-' , '_' )
312
+ package_full_name = group_name + "." + package_name
313
+ package_version = group_child .attrib ['versions' ].split (',' )[- 1 ]
314
+ latest_versions [package_full_name ] = package_version
315
+ return latest_versions
316
+
317
+
318
+ # Regex to match lines like:
319
+ # 'com.google.firebase:firebase-auth:1.2.3'
320
+ RE_GENERIC_DEPENDENCY_MODULE = re .compile (
321
+ r"(?P<quote>[\'\"])(?P<pkg>[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+):([0-9.]+)[\'\"]"
322
+ )
323
+
324
+ def modify_dependency_file (dependency_filepath , version_map , dryrun = True ):
325
+ """Modify a dependency file to reference the correct module versions.
326
+
327
+ Looks for lines like: 'com.google.firebase:firebase-auth:1.2.3'
328
+ for modules matching the ones in the version map, and modifies them in-place.
329
+
330
+ Args:
331
+ dependency_filename: Relative path to the dependency file to edit.
332
+ version_map: Dictionary of packages to version numbers, e.g. {
333
+ 'com.google.firebase.firebase_auth': '15.0.0' }
334
+ dryrun (bool, optional): Just print the substitutions.
335
+ Do not write to file. Defaults to True.
336
+ """
337
+ logging .debug ('Reading dependency file: {0}' .format (dependency_filepath ))
338
+ lines = None
339
+ with open (dependency_filepath , "r" ) as dependency_file :
340
+ lines = dependency_file .readlines ()
341
+ if not lines :
342
+ logging .fatal ('Update failed. ' +
343
+ 'Could not read contents from file {0}.' .format (dependency_filepath ))
344
+
345
+ output_lines = []
346
+
347
+ # Replacement function, look up the version number of the given pkg.
348
+ def replace_dependency (m ):
349
+ if not m .group ('pkg' ):
350
+ return m .group (0 )
351
+ pkg = m .group ('pkg' ).replace ('-' , '_' ).replace (':' , '.' )
352
+ if pkg not in version_map :
353
+ return m .group (0 )
354
+ quote_type = m .group ('quote' )
355
+ if not quote_type :
356
+ quote_type = "'"
357
+ return '%s%s:%s%s' % (quote_type , m .group ('pkg' ), version_map [pkg ],
358
+ quote_type )
359
+
360
+ substituted_pairs = []
361
+ for line in lines :
362
+ substituted_line = re .sub (RE_GENERIC_DEPENDENCY_MODULE , replace_dependency ,
363
+ line )
364
+ output_lines .append (substituted_line )
365
+ if substituted_line != line :
366
+ substituted_pairs .append ((line , substituted_line ))
367
+ to_update = True
368
+
369
+ if to_update :
370
+ print ('Updating contents of {0}' .format (dependency_filepath ))
371
+ for original , substituted in substituted_pairs :
372
+ print ('(-) ' + original + '(+) ' + substituted )
373
+
374
+ if not dryrun :
375
+ with open (dependency_filepath , 'w' ) as dependency_file :
376
+ dependency_file .writelines (output_lines )
377
+ print ()
378
+
379
+
380
+ RE_README_ANDROID_VERSION = re .compile (
381
+ r"<br>(?P<pkg>[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+):([0-9.]+)<br>" )
382
+
383
+
384
+ def modify_readme_file (readme_filepath , version_map , dryrun = True ):
385
+ """Modify a readme Markdown file to reference correct module versions.
386
+
387
+ Looks for lines like:
388
+ <br>com.google.firebase:firebase-core:15.0.0<br>
389
+ for modules matching the ones in the version map, and modifies them in-place.
390
+
391
+ Args:
392
+ readme_filepath: Path to readme file to edit.
393
+ version_map: Dictionary of packages to version numbers, e.g. {
394
+ 'com.google.firebase.firebase_auth': '15.0.0' }
395
+ dryrun (bool, optional): Just print the substitutions.
396
+ Do not write to file. Defaults to True.
397
+ """
398
+ logging .debug ('Reading readme file: {0}' .format (readme_filepath ))
399
+
400
+ lines = None
401
+ with open (readme_filepath , "r" ) as readme_file :
402
+ lines = readme_file .readlines ()
403
+ if not lines :
404
+ logging .fatal ('Could not read contents of file %s' , readme_filepath )
405
+
406
+ output_lines = []
407
+
408
+ # Replacement function, look up the version number of the given pkg.
409
+ def replace_module_line (m ):
410
+ if not m .group ('pkg' ):
411
+ return m .group (0 )
412
+ pkg = m .group ('pkg' ).replace ('-' , '_' ).replace (':' , '.' )
413
+ if pkg not in version_map :
414
+ return m .group (0 )
415
+ repl = '%s:%s' % (m .group ('pkg' ), version_map [pkg ])
416
+ return '<br>{0}<br>' .format (repl )
417
+
418
+ substituted_pairs = []
419
+ for line in lines :
420
+ substituted_line = re .sub (RE_README_ANDROID_VERSION , replace_module_line ,
421
+ line )
422
+ output_lines .append (substituted_line )
423
+ if substituted_line != line :
424
+ substituted_pairs .append ((line , substituted_line ))
425
+ to_update = True
426
+
427
+ if to_update :
428
+ print ('Updating contents of {0}' .format (readme_filepath ))
429
+ for original , substituted in substituted_pairs :
430
+ print ('(-) ' + original + '(+) ' + substituted )
431
+
432
+ if not dryrun :
433
+ with open (readme_filepath , 'w' ) as readme_file :
434
+ readme_file .writelines (output_lines )
435
+ print ()
269
436
270
- def main ():
271
- args = parse_cmdline_args ()
272
- latest_versions_map = get_latest_pod_versions (args .specs_repo , PODS )
273
- #latest_versions_map = {'FirebaseAuth': '8.0.0', 'FirebaseRemoteConfig':'9.9.9'}
274
- pod_files = get_pod_files (args .podfiles )
275
- for pod_file in pod_files :
276
- modify_pod_file (pod_file , latest_versions_map , args .dryrun )
277
437
278
438
def parse_cmdline_args ():
279
439
parser = argparse .ArgumentParser (description = 'Update pod files with '
@@ -283,11 +443,15 @@ def parse_cmdline_args():
283
443
parser .add_argument ( "--log_level" , default = "info" ,
284
444
help = "Logging level (debug, warning, info)" )
285
445
# iOS options
446
+ parser .add_argument ('--skip_ios' , action = 'store_true' ,
447
+ help = 'Skip iOS pod version update.' )
286
448
parser .add_argument ('--podfiles' , nargs = '+' , default = (os .getcwd (),),
287
449
help = 'List of pod files or directories containing podfiles' )
288
450
parser .add_argument ('--specs_repo' ,
289
451
help = 'Local checkout of github Cocoapods Specs repository' )
290
452
# Android options
453
+ parser .add_argument ('--skip_android' , action = 'store_true' ,
454
+ help = 'Skip Android libraries version update.' )
291
455
parser .add_argument ('--depfiles' , nargs = '+' ,
292
456
default = ('Android/firebase_dependencies.gradle' ,),
293
457
help = 'List of android dependency files or directories'
@@ -316,7 +480,33 @@ def parse_cmdline_args():
316
480
logger = logging .getLogger (__name__ )
317
481
return args
318
482
483
+
484
+ def main ():
485
+ args = parse_cmdline_args ()
486
+ if not args .skip_ios :
487
+ #latest_pod_versions_map = get_latest_pod_versions(args.specs_repo, PODS)
488
+ latest_pod_versions_map = {'FirebaseAuth' : '8.0.0' , 'FirebaseRemoteConfig' :'9.9.9' }
489
+ pod_files = get_files (args .podfiles , file_extension = '' , file_name = 'Podfile' )
490
+ for pod_file in pod_files :
491
+ modify_pod_file (pod_file , latest_pod_versions_map , args .dryrun )
492
+
493
+ if not args .skip_android :
494
+ #latest_android_versions_map = get_latest_maven_versions()
495
+ latest_android_versions_map = {
496
+ 'com.google.firebase.firebase_auth' : '6.6.6' ,
497
+ 'com.google.firebase.firebase_database' : '9.9.9' ,
498
+ }
499
+
500
+ dep_files = get_files (args .depfiles , file_extension = '.gradle' ,
501
+ file_name = 'firebase_dependencies.gradle' )
502
+ for dep_file in dep_files :
503
+ modify_dependency_file (dep_file , latest_android_versions_map , args .dryrun )
504
+
505
+ readme_files = get_files (args .readmefiles , file_extension = '.md' ,
506
+ file_name = 'readme' )
507
+ for readme_file in readme_files :
508
+ modify_readme_file (readme_file , latest_android_versions_map , args .dryrun )
509
+
510
+
319
511
if __name__ == '__main__' :
320
512
main ()
321
- # from IPython import embed
322
- # embed()
0 commit comments