1""" 2Generate header file with macros defining MicroPython version info. 3 4This script works with Python 2.6, 2.7, 3.3 and 3.4. 5""" 6 7from __future__ import print_function 8 9import sys 10import os 11import datetime 12import subprocess 13 14 15def get_version_info_from_git(): 16 # Python 2.6 doesn't have check_output, so check for that 17 try: 18 subprocess.check_output 19 subprocess.check_call 20 except AttributeError: 21 return None 22 23 # Note: git describe doesn't work if no tag is available 24 try: 25 git_tag = subprocess.check_output( 26 ["git", "describe", "--tags", "--dirty", "--always", "--match", "v[1-9].*"], 27 stderr=subprocess.STDOUT, 28 universal_newlines=True, 29 ).strip() 30 except subprocess.CalledProcessError as er: 31 if er.returncode == 128: 32 # git exit code of 128 means no repository found 33 return None 34 git_tag = "" 35 except OSError: 36 return None 37 try: 38 git_hash = subprocess.check_output( 39 ["git", "rev-parse", "--short", "HEAD"], 40 stderr=subprocess.STDOUT, 41 universal_newlines=True, 42 ).strip() 43 except subprocess.CalledProcessError: 44 git_hash = "unknown" 45 except OSError: 46 return None 47 48 try: 49 # Check if there are any modified files. 50 subprocess.check_call( 51 ["git", "diff", "--no-ext-diff", "--quiet", "--exit-code"], stderr=subprocess.STDOUT 52 ) 53 # Check if there are any staged files. 54 subprocess.check_call( 55 ["git", "diff-index", "--cached", "--quiet", "HEAD", "--"], stderr=subprocess.STDOUT 56 ) 57 except subprocess.CalledProcessError: 58 git_hash += "-dirty" 59 except OSError: 60 return None 61 62 return git_tag, git_hash 63 64 65def get_version_info_from_docs_conf(): 66 with open(os.path.join(os.path.dirname(sys.argv[0]), "..", "docs", "conf.py")) as f: 67 for line in f: 68 if line.startswith("version = release = '"): 69 ver = line.strip().split(" = ")[2].strip("'") 70 git_tag = "v" + ver 71 return git_tag, "<no hash>" 72 return None 73 74 75def make_version_header(filename): 76 # Get version info using git, with fallback to docs/conf.py 77 info = get_version_info_from_git() 78 if info is None: 79 info = get_version_info_from_docs_conf() 80 81 git_tag, git_hash = info 82 83 build_date = datetime.date.today() 84 if "SOURCE_DATE_EPOCH" in os.environ: 85 build_date = datetime.datetime.utcfromtimestamp( 86 int(os.environ["SOURCE_DATE_EPOCH"]) 87 ).date() 88 89 # Generate the file with the git and version info 90 file_data = """\ 91// This file was generated by py/makeversionhdr.py 92#define MICROPY_GIT_TAG "%s" 93#define MICROPY_GIT_HASH "%s" 94#define MICROPY_BUILD_DATE "%s" 95""" % ( 96 git_tag, 97 git_hash, 98 build_date.strftime("%Y-%m-%d"), 99 ) 100 101 # Check if the file contents changed from last time 102 write_file = True 103 if os.path.isfile(filename): 104 with open(filename, "r") as f: 105 existing_data = f.read() 106 if existing_data == file_data: 107 write_file = False 108 109 # Only write the file if we need to 110 if write_file: 111 print("GEN %s" % filename) 112 with open(filename, "w") as f: 113 f.write(file_data) 114 115 116if __name__ == "__main__": 117 make_version_header(sys.argv[1]) 118