| #!/usr/bin/env python3 |
| ######################################################################## |
| # Generates a new release. |
| ######################################################################## |
| import sys |
| import re |
| import subprocess |
| import io |
| import os |
| import fileinput |
| |
| if sys.version_info < (3, 0): |
| sys.stdout.write("Sorry, requires Python 3.x or better\n") |
| sys.exit(1) |
| |
| |
| def colored(r, g, b, text): |
| return f"\033[38;2;{r};{g};{b}m{text} \033[38;2;255;255;255m" |
| |
| |
| def extractnumbers(s): |
| return tuple(map(int, re.findall(r"(\d+)\.(\d+)\.(\d+)", str(s))[0])) |
| |
| |
| def toversionstring(major, minor, rev): |
| return f"{major}.{minor}.{rev}" |
| |
| |
| print("Calling git rev-parse --abbrev-ref HEAD") |
| pipe = subprocess.Popen( |
| ["git", "rev-parse", "--abbrev-ref", "HEAD"], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.STDOUT, |
| ) |
| branchresult = pipe.communicate()[0].decode().strip() |
| |
| if branchresult != "main": |
| print( |
| colored( |
| 255, |
| 0, |
| 0, |
| f"We recommend that you release on main, you are on '{branchresult}'", |
| ) |
| ) |
| |
| ret = subprocess.call(["git", "remote", "update"]) |
| |
| if ret != 0: |
| sys.exit(ret) |
| print("Calling git log HEAD.. --oneline") |
| pipe = subprocess.Popen( |
| ["git", "log", "HEAD..", "--oneline"], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.STDOUT, |
| ) |
| uptodateresult = pipe.communicate()[0].decode().strip() |
| |
| if len(uptodateresult) != 0: |
| print(uptodateresult) |
| sys.exit(-1) |
| |
| pipe = subprocess.Popen( |
| ["git", "rev-parse", "--show-toplevel"], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.STDOUT, |
| ) |
| maindir = pipe.communicate()[0].decode().strip() |
| scriptlocation = os.path.dirname(os.path.abspath(__file__)) |
| |
| print(f"repository: {maindir}") |
| |
| pipe = subprocess.Popen( |
| ["git", "describe", "--abbrev=0", "--tags"], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.STDOUT, |
| ) |
| versionresult = pipe.communicate()[0].decode().strip() |
| |
| print(f"last version: {versionresult}") |
| try: |
| currentv = extractnumbers(versionresult) |
| except: |
| currentv = [0, 0, 0] |
| if len(sys.argv) != 2: |
| nextv = (currentv[0], currentv[1], currentv[2] + 1) |
| print(f"please specify version number, e.g. {toversionstring(*nextv)}") |
| sys.exit(-1) |
| try: |
| newversion = extractnumbers(sys.argv[1]) |
| print(newversion) |
| except: |
| print(f"can't parse version number {sys.argv[1]}") |
| sys.exit(-1) |
| |
| print("checking that new version is valid") |
| if newversion[0] != currentv[0]: |
| assert newversion[0] == currentv[0] + 1 |
| assert newversion[1] == 0 |
| assert newversion[2] == 0 |
| elif newversion[1] != currentv[1]: |
| assert newversion[1] == currentv[1] + 1 |
| assert newversion[2] == 0 |
| else: |
| assert newversion[2] == currentv[2] + 1 |
| |
| atleastminor = (currentv[0] != newversion[0]) or (currentv[1] != newversion[1]) |
| |
| newmajorversionstring = str(newversion[0]) |
| newminorversionstring = str(newversion[1]) |
| newpatchversionstring = str(newversion[2]) |
| newversionstring = f"{newversion[0]}.{newversion[1]}.{newversion[2]}" |
| cmakefile = f"{maindir}{os.sep}CMakeLists.txt" |
| |
| for line in fileinput.input(cmakefile, inplace=1, backup=".bak"): |
| line = re.sub( |
| r"project\(fast_float VERSION \d+\.\d+\.\d+ LANGUAGES CXX\)", |
| f"project(fast_float VERSION {newversionstring} LANGUAGES CXX)", |
| line.rstrip(), |
| ) |
| print(line) |
| |
| print(f"modified {cmakefile}, a backup was made") |
| |
| versionfilerel = f"{os.sep}include{os.sep}fast_float{os.sep}float_common.h" |
| versionfile = f"{maindir}{versionfilerel}" |
| |
| for line in fileinput.input(versionfile, inplace=1, backup=".bak"): |
| line = re.sub( |
| r"#define FASTFLOAT_VERSION_MAJOR \d+", |
| f"#define FASTFLOAT_VERSION_MAJOR {newmajorversionstring}", |
| line.rstrip(), |
| ) |
| line = re.sub( |
| r"#define FASTFLOAT_VERSION_MINOR \d+", |
| f"#define FASTFLOAT_VERSION_MINOR {newminorversionstring}", |
| line.rstrip(), |
| ) |
| line = re.sub( |
| r"#define FASTFLOAT_VERSION_PATCH \d+", |
| f"#define FASTFLOAT_VERSION_PATCH {newpatchversionstring}", |
| line.rstrip(), |
| ) |
| print(line) |
| |
| print(f"{versionfile} modified") |
| |
| readmefile = f"{maindir}{os.sep}README.md" |
| |
| for line in fileinput.input(readmefile, inplace=1, backup=".bak"): |
| line = re.sub( |
| r"https://github.com/fastfloat/fast_float/releases/download/v(\d+\.\d+\.\d+)/fast_float.h", |
| f"https://github.com/fastfloat/fast_float/releases/download/v{newversionstring}/fast_float.h", |
| line.rstrip(), |
| ) |
| line = re.sub( |
| r"GIT_TAG tags/v(\d+\.\d+\.\d+)", |
| f"GIT_TAG tags/v{newversionstring}", |
| line.rstrip(), |
| ) |
| line = re.sub( |
| r"GIT_TAG v(\d+\.\d+\.\d+)\)", f"GIT_TAG v{newversionstring})", line.rstrip() |
| ) |
| print(line) |
| |
| print(f"modified {readmefile}, a backup was made") |
| |
| print("running amalgamate.py") |
| with open(f"{maindir}{os.sep}fast_float.h", "w") as outfile: |
| cp = subprocess.run( |
| [f"python3", f"{maindir}{os.sep}script{os.sep}amalgamate.py"], stdout=outfile |
| ) |
| |
| if cp.returncode != 0: |
| print("Failed to run amalgamate") |
| else: |
| print("amalgamate.py ran successfully") |
| print(f"You should upload {maindir}{os.sep}fast_float.h") |
| |
| print("Please run the tests before issuing a release.\n") |
| print( |
| f'to issue release, enter\n git commit -a && git push && git tag -a v{toversionstring(*newversion)} -m "version {toversionstring(*newversion)}" && git push --tags\n' |
| ) |