1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/gen_mach_buildprops.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,115 @@ 1.4 +#!/usr/bin/python 1.5 +# 1.6 +# This Source Code Form is subject to the terms of the Mozilla Public 1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 + 1.10 +import sys 1.11 +import os 1.12 +import hashlib 1.13 +import json 1.14 +import re 1.15 +import errno 1.16 +from argparse import ArgumentParser 1.17 + 1.18 +def getFileHashAndSize(filename): 1.19 + sha512Hash = 'UNKNOWN' 1.20 + size = 'UNKNOWN' 1.21 + 1.22 + try: 1.23 + # open in binary mode to make sure we get consistent results 1.24 + # across all platforms 1.25 + f = open(filename, "rb") 1.26 + shaObj = hashlib.sha512(f.read()) 1.27 + sha512Hash = shaObj.hexdigest() 1.28 + 1.29 + size = os.path.getsize(filename) 1.30 + except: 1.31 + pass 1.32 + 1.33 + return (sha512Hash, size) 1.34 + 1.35 +def getMarProperties(filename, partial=False): 1.36 + if not os.path.exists(filename): 1.37 + return {} 1.38 + (mar_hash, mar_size) = getFileHashAndSize(filename) 1.39 + martype = 'partial' if partial else 'complete' 1.40 + return { 1.41 + '%sMarFilename' % martype: os.path.basename(filename), 1.42 + '%sMarSize' % martype: mar_size, 1.43 + '%sMarHash' % martype: mar_hash, 1.44 + } 1.45 + 1.46 +def getUrlProperties(filename): 1.47 + # let's create a switch case using name-spaces/dict 1.48 + # rather than a long if/else with duplicate code 1.49 + property_conditions = [ 1.50 + # key: property name, value: condition 1.51 + ('symbolsUrl', lambda m: m.endswith('crashreporter-symbols.zip') or 1.52 + m.endswith('crashreporter-symbols-full.zip')), 1.53 + ('testsUrl', lambda m: m.endswith(('tests.tar.bz2', 'tests.zip'))), 1.54 + ('unsignedApkUrl', lambda m: m.endswith('apk') and 1.55 + 'unsigned-unaligned' in m), 1.56 + ('robocopApkUrl', lambda m: m.endswith('apk') and 'robocop' in m), 1.57 + ('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')), 1.58 + ('completeMarUrl', lambda m: m.endswith('.complete.mar')), 1.59 + ('partialMarUrl', lambda m: m.endswith('.mar') and '.partial.' in m), 1.60 + # packageUrl must be last! 1.61 + ('packageUrl', lambda m: True), 1.62 + ] 1.63 + url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz))$''') 1.64 + properties = {} 1.65 + 1.66 + try: 1.67 + with open(filename) as f: 1.68 + for line in f: 1.69 + m = url_re.match(line) 1.70 + if m: 1.71 + m = m.group(1) 1.72 + for prop, condition in property_conditions: 1.73 + if condition(m): 1.74 + properties.update({prop: m}) 1.75 + break 1.76 + except IOError as e: 1.77 + if e.errno != errno.ENOENT: 1.78 + raise 1.79 + properties = {prop: 'UNKNOWN' for prop, condition in property_conditions} 1.80 + return properties 1.81 + 1.82 +def getPartialInfo(props): 1.83 + return [{ 1.84 + "from_buildid": props.get("previous_buildid"), 1.85 + "size": props.get("partialMarSize"), 1.86 + "hash": props.get("partialMarHash"), 1.87 + "url": props.get("partialMarUrl"), 1.88 + }] 1.89 + 1.90 +if __name__ == '__main__': 1.91 + parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.') 1.92 + parser.add_argument("--complete-mar-file", required=True, 1.93 + action="store", dest="complete_mar_file", 1.94 + help="Path to the complete MAR file, relative to the objdir.") 1.95 + parser.add_argument("--partial-mar-file", required=False, 1.96 + action="store", dest="partial_mar_file", 1.97 + help="Path to the partial MAR file, relative to the objdir.") 1.98 + parser.add_argument("--upload-output", required=True, 1.99 + action="store", dest="upload_output", 1.100 + help="Path to the text output of 'make upload'") 1.101 + args = parser.parse_args() 1.102 + 1.103 + json_data = getMarProperties(args.complete_mar_file) 1.104 + json_data.update(getUrlProperties(args.upload_output)) 1.105 + if args.partial_mar_file: 1.106 + json_data.update(getMarProperties(args.partial_mar_file, partial=True)) 1.107 + 1.108 + # Pull the previous buildid from the partial mar filename. 1.109 + res = re.match(r'.*\.([0-9]+)-[0-9]+.mar', args.partial_mar_file) 1.110 + if res: 1.111 + json_data['previous_buildid'] = res.group(1) 1.112 + 1.113 + # Set partialInfo to be a collection of the partial mar properties 1.114 + # useful for balrog. 1.115 + json_data['partialInfo'] = getPartialInfo(json_data) 1.116 + 1.117 + with open('mach_build_properties.json', 'w') as outfile: 1.118 + json.dump(json_data, outfile, indent=4)