1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5from __future__ import absolute_import 6 7import os 8from io import StringIO 9from datetime import date 10import re 11from distutils.version import StrictVersion 12 13from mozbuild.preprocessor import Preprocessor 14 15 16def rnp_source_update(rnp_root, version_str, revision, timestamp, bug_report): 17 """ 18 Update RNP source files: generate version.h and mangle config.h.in 19 :param rnp_root: 20 :type rnp_root: 21 :param string version_str: latest version 22 :param string revision: revision hash (short form) 23 :param float timestamp: UNIX timestamp from revision 24 :param string bug_report: where to report bugs for this RNP build 25 """ 26 version = StrictVersion(version_str) 27 version_major = version.version[0] 28 version_minor = version.version[1] 29 version_patch = version.version[2] 30 date_str = date.fromtimestamp(float(timestamp)).strftime("%Y%m%d") 31 revision_short = revision[:8] 32 version_full = "{}+git{}.{}.MZLA".format(version_str, date_str, revision_short) 33 34 defines = dict( 35 RNP_VERSION_MAJOR=version_major, 36 RNP_VERSION_MINOR=version_minor, 37 RNP_VERSION_PATCH=version_patch, 38 RNP_VERSION=version_str, 39 RNP_VERSION_FULL=version_full, 40 RNP_VERSION_COMMIT_TIMESTAMP=str(timestamp), 41 BUGREPORT_EMAIL=bug_report, 42 ) 43 src_lib = os.path.join(rnp_root, "src", "lib") 44 version_h_in = os.path.join(src_lib, "version.h.in") 45 version_h = os.path.join(src_lib, "version.h") 46 config_h_in = os.path.join(src_lib, "config.h.in") 47 readme_rnp = os.path.join(rnp_root, "..", "README.rnp") 48 49 generate_version_h(version_h_in, version_h, defines) 50 mangle_config_h_in(config_h_in, defines) 51 update_readme(readme_rnp, revision) 52 53 54def rnp_preprocess(tmpl, dest, defines): 55 """ 56 Generic preprocessing 57 :param BinaryIO tmpl: open filehandle (read) input 58 :param BinaryIO dest: open filehandle (write) output 59 :param dict defines: result of get_defines() 60 :return boolean: 61 """ 62 pp = Preprocessor() 63 pp.setMarker("%") 64 pp.addDefines(defines) 65 pp.do_filter("substitution") 66 pp.out = dest 67 pp.do_include(tmpl, True) 68 return True 69 70 71def generate_version_h(template, destination, defines): 72 """ 73 Generate version.h for rnp from a the template file, write the 74 result to destination. 75 :param string template: path to template file (version.h.in) 76 :param string destination: path to write generated file (version.h) 77 :param dict defines: result of get_defines() 78 """ 79 with open(template) as tmpl: 80 with open(destination, "w") as dest: 81 rnp_preprocess(tmpl, dest, defines) 82 83 84def mangle_config_h_in(template, defines): 85 """ 86 Mangle RNP's config.h.in so that it will work with CONFIGURE_DEFINE_FILES 87 :param string template: path to config.h.in 88 :param dict defines: result of get_defines() 89 """ 90 with open(template) as tmpl: 91 tmp_string = StringIO() 92 rnp_preprocess(tmpl, tmp_string, defines) 93 94 tmp_string.seek(0) 95 96 with open(template, "w") as dest: 97 for line in tmp_string: 98 if line.startswith("#cmakedefine"): 99 line = line.replace("#cmakedefine", "#undef") 100 dest.write(line) 101 dest.write("\n") 102 103 104def update_readme(path, revision): 105 """ 106 Updates the commit hash in README.rnp 107 :param string path: Path to README.rnp 108 :param string revision: revision to insert 109 """ 110 commit_re = re.compile(r"^\[commit [\da-f]{40}\]$") 111 with open(path) as orig: 112 tmp_string = StringIO() 113 tmp_string.write(orig.read()) 114 115 tmp_string.seek(0) 116 117 with open(path, "w") as dest: 118 for line in tmp_string: 119 if commit_re.match(line): 120 line = "[commit {}]\n".format(revision) 121 dest.write(line) 122