mirror of
https://github.com/micropython/micropython.git
synced 2026-01-04 11:10:14 +01:00
The Git hash is embedded in the version number. The hash is abbreviated by Git. This commit changes the length of the Git hash abbreviation to a fixed number, so that the length of the version string no longer varies based on external factors (it can still vary, but will now be at least 10 characters). This change is made because builds of the same MicroPython commit on multiple machines were sometimes giving a version string with different lengths, eg due to commits on other local branches having a clashing abbreviated hash. This change may also help the code size report to be more consistent, because it will less often be impacted by random changes in the version string length, at the cost of always being a few bytes longer. Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
179 lines
5.8 KiB
Python
179 lines
5.8 KiB
Python
"""
|
|
Generate header file with macros defining MicroPython version info.
|
|
|
|
This script works with Python 2.6, 2.7, 3.3 and 3.4.
|
|
"""
|
|
|
|
from __future__ import print_function
|
|
|
|
import argparse
|
|
import sys
|
|
import os
|
|
import datetime
|
|
import subprocess
|
|
|
|
|
|
# The MicroPython repository tags a release commit as "vX.Y.Z", and the commit
|
|
# immediately following as "vX.(Y+1).Z-preview".
|
|
# This function will return:
|
|
# "vX.Y.Z" -- building at the release commit
|
|
# "vX.Y.Z-preview" -- building at the first commit in the next cycle
|
|
# "vX.Y.Z-preview.N.gHASH" -- building at any subsequent commit in the cycle
|
|
# "vX.Y.Z-preview.N.gHASH.dirty" -- building at any subsequent commit in the cycle
|
|
# with local changes
|
|
def get_version_info_from_git(repo_path):
|
|
# Python 2.6 doesn't have check_output, so check for that
|
|
try:
|
|
subprocess.check_output
|
|
except AttributeError:
|
|
return None
|
|
|
|
# Note: git describe doesn't work if no tag is available
|
|
try:
|
|
git_tag = subprocess.check_output(
|
|
[
|
|
"git",
|
|
"describe",
|
|
"--tags",
|
|
"--dirty",
|
|
"--always",
|
|
"--match",
|
|
"v[1-9].*",
|
|
"--abbrev=10",
|
|
],
|
|
cwd=repo_path,
|
|
stderr=subprocess.STDOUT,
|
|
universal_newlines=True,
|
|
).strip()
|
|
# Turn git-describe's output into semver compatible (dot-separated
|
|
# identifiers inside the prerelease field).
|
|
git_tag = git_tag.split("-", 1)
|
|
if len(git_tag) == 1:
|
|
return git_tag[0]
|
|
else:
|
|
return git_tag[0] + "-" + git_tag[1].replace("-", ".")
|
|
except (subprocess.CalledProcessError, OSError):
|
|
return None
|
|
|
|
|
|
def get_hash_from_git(repo_path):
|
|
# Python 2.6 doesn't have check_output, so check for that.
|
|
try:
|
|
subprocess.check_output
|
|
except AttributeError:
|
|
return None
|
|
|
|
try:
|
|
return subprocess.check_output(
|
|
["git", "rev-parse", "--short", "HEAD"],
|
|
cwd=repo_path,
|
|
stderr=subprocess.STDOUT,
|
|
universal_newlines=True,
|
|
).strip()
|
|
except (subprocess.CalledProcessError, OSError):
|
|
return None
|
|
|
|
|
|
# When building from a source tarball (or any situation where the git repo
|
|
# isn't available), this function will use the info in mpconfig.h as a
|
|
# fallback. The release commit sets MICROPY_VERSION_PRERELEASE to 0, and the
|
|
# commit immediately following increments MICROPY_VERSION_MINOR and sets
|
|
# MICROPY_VERSION_PRERELEASE back to 1.
|
|
# This function will return:
|
|
# "vX.Y.Z" -- building at the release commit
|
|
# "vX.Y.Z-preview" -- building at any other commit
|
|
def get_version_info_from_mpconfig(repo_path):
|
|
print(
|
|
"makeversionhdr.py: Warning: No git repo or tag info available, falling back to mpconfig.h version info.",
|
|
file=sys.stderr,
|
|
)
|
|
|
|
with open(os.path.join(repo_path, "py", "mpconfig.h")) as f:
|
|
for line in f:
|
|
if line.startswith("#define MICROPY_VERSION_MAJOR "):
|
|
ver_major = int(line.strip().split()[2])
|
|
elif line.startswith("#define MICROPY_VERSION_MINOR "):
|
|
ver_minor = int(line.strip().split()[2])
|
|
elif line.startswith("#define MICROPY_VERSION_MICRO "):
|
|
ver_micro = int(line.strip().split()[2])
|
|
elif line.startswith("#define MICROPY_VERSION_PRERELEASE "):
|
|
ver_prerelease = int(line.strip().split()[2])
|
|
git_tag = "v%d.%d.%d%s" % (
|
|
ver_major,
|
|
ver_minor,
|
|
ver_micro,
|
|
"-preview" if ver_prerelease else "",
|
|
)
|
|
return git_tag
|
|
return None
|
|
|
|
|
|
def make_version_header(repo_path, filename):
|
|
git_tag = None
|
|
git_hash = None
|
|
if "MICROPY_GIT_TAG" in os.environ:
|
|
git_tag = os.environ["MICROPY_GIT_TAG"]
|
|
git_hash = os.environ.get("MICROPY_GIT_HASH")
|
|
if git_tag is None:
|
|
git_tag = get_version_info_from_git(repo_path)
|
|
git_hash = get_hash_from_git(repo_path)
|
|
if git_tag is None:
|
|
git_tag = get_version_info_from_mpconfig(repo_path)
|
|
|
|
if not git_tag:
|
|
print("makeversionhdr.py: Error: No version information available.")
|
|
sys.exit(1)
|
|
|
|
build_date = datetime.date.today()
|
|
if "SOURCE_DATE_EPOCH" in os.environ:
|
|
build_date = datetime.datetime.fromtimestamp(
|
|
int(os.environ["SOURCE_DATE_EPOCH"]), datetime.timezone.utc
|
|
).date()
|
|
|
|
# Generate the file with the git and version info
|
|
# Note: MICROPY_GIT_HASH may be used by third-party code.
|
|
file_data = """\
|
|
// This file was generated by py/makeversionhdr.py
|
|
#define MICROPY_GIT_TAG "%s"
|
|
#define MICROPY_GIT_HASH "%s"
|
|
#define MICROPY_BUILD_DATE "%s"
|
|
""" % (
|
|
git_tag,
|
|
git_hash or "<no hash>",
|
|
build_date.strftime("%Y-%m-%d"),
|
|
)
|
|
|
|
# Check if the file contents changed from last time
|
|
write_file = True
|
|
if os.path.isfile(filename):
|
|
with open(filename, "r") as f:
|
|
existing_data = f.read()
|
|
if existing_data == file_data:
|
|
write_file = False
|
|
|
|
# Only write the file if we need to
|
|
if write_file:
|
|
print("GEN %s" % filename)
|
|
with open(filename, "w") as f:
|
|
f.write(file_data)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
# makeversionheader.py lives in repo/py, so default repo_path to the
|
|
# parent of sys.argv[0]'s directory.
|
|
parser.add_argument(
|
|
"-r",
|
|
"--repo-path",
|
|
default=os.path.join(os.path.dirname(sys.argv[0]), ".."),
|
|
help="path to MicroPython Git repo to query for version",
|
|
)
|
|
parser.add_argument("dest", nargs=1, help="output file path")
|
|
args = parser.parse_args()
|
|
|
|
make_version_header(args.repo_path, args.dest[0])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|