1"""Validates classes in the deployed jar are all within the expected packages. 2 3 Usage: 4 python validate-jar-entry-prefixes.py <jar-file> <comma-separated-prefixes> 5""" 6import re 7import shutil 8import sys 9import tempfile 10import zipfile 11 12 13def main(argv): 14 if len(argv) > 3: 15 raise Exception('Expected only two arguments but got {0}'.format(len(argv))) 16 17 jar_file, prefixes = argv[-2:] 18 prefixes_pattern = re.compile('|'.join(prefixes.split(','))) 19 20 invalid_entries = [] 21 if jar_file.endswith('.jar'): 22 invalid_entries = _invalid_entries(jar_file, prefixes_pattern) 23 elif jar_file.endswith('.aar'): 24 dirpath = tempfile.mkdtemp() 25 with zipfile.ZipFile(jar_file, 'r') as zip_file: 26 class_file = zip_file.extract('classes.jar', dirpath) 27 invalid_entries = _invalid_entries(class_file, prefixes_pattern) 28 shutil.rmtree(dirpath) 29 else: 30 raise Exception('Invalid jar file: {0}'.format(jar_file)) 31 32 if invalid_entries: 33 raise Exception( 34 'Found invalid entries in {0} that do not match one of the allowed prefixes ({1}):\n {2}' 35 .format( 36 jar_file, 37 ', '.join(['"{0}"'.format(p) for p in prefixes.split(',')]), 38 '\n '.join(invalid_entries)) 39 ) 40 41 42def _invalid_entries(jar_file, prefixes_pattern): 43 invalid_entries = [] 44 with zipfile.ZipFile(jar_file, 'r') as zip_file: 45 for info in zip_file.infolist(): 46 if not info.is_dir(): 47 if not prefixes_pattern.match(info.filename): 48 invalid_entries.append(info.filename) 49 return invalid_entries 50 51 52if __name__ == '__main__': 53 main(sys.argv) 54