|
| 1 | +# create a new numerical tag number for the most recent git checkin |
| 2 | +# and advance the "mini" GSAS-II version number (from 5.X.Y to 5.X.Y+1) |
| 3 | +# or the minor GSAS-II version number (from 5.X.Y to 5.X+1.0) |
| 4 | +# Record the hash and version numbers in the git_version.py file. |
| 5 | + |
| 6 | +# This routine can only be used where HEAD and HEAD^1 have not been a tag |
| 7 | + |
| 8 | +import os |
| 9 | +import sys |
| 10 | +import datetime as dt |
| 11 | +import git |
| 12 | + |
| 13 | +mode = 'mini' |
| 14 | +if len(sys.argv) > 1: |
| 15 | + if sys.argv[1].lower() == 'minor': |
| 16 | + mode = 'minor' |
| 17 | + elif sys.argv[1].lower() == 'mini': |
| 18 | + mode = 'mini' |
| 19 | + else: |
| 20 | + mode = 'help' |
| 21 | + |
| 22 | +if mode == 'help': |
| 23 | + print('Use this command either as ') |
| 24 | + print(f'\t{sys.argv[0]} minor') |
| 25 | + print('or') |
| 26 | + print(f'\t{sys.argv[0]} mini') |
| 27 | + print('If no argument is supplied "mini" is assumed') |
| 28 | + sys.exit() |
| 29 | + |
| 30 | +# get location of the GSAS-II files |
| 31 | +# assumed to be the parent of location of this file |
| 32 | +path2GSAS2 = os.path.dirname(os.path.dirname( |
| 33 | + os.path.abspath(os.path.expanduser(__file__)))) |
| 34 | +# and the repo is in the parent of that |
| 35 | +path2repo = os.path.dirname(path2GSAS2) |
| 36 | + |
| 37 | +if __name__ == '__main__': |
| 38 | + |
| 39 | + try: |
| 40 | + g2repo = git.Repo(path2repo) |
| 41 | + except: |
| 42 | + print('Launch of gitpython for version file failed'+ |
| 43 | + f' with path {path2repo}') |
| 44 | + sys.exit() |
| 45 | + if g2repo.active_branch.name != 'main': |
| 46 | + print('Not on main branch') |
| 47 | + sys.exit() |
| 48 | + if g2repo.head.is_detached: |
| 49 | + print(f'Detached head {commit0[:7]!r}') |
| 50 | + sys.exit() |
| 51 | + # make a list of tags without a v; get the largest numeric tag |
| 52 | + # someday use the packaging module (but no more dependencies for now) |
| 53 | + numtag = [i for i in g2repo.tags if 'v' not in i.name] |
| 54 | + max_numeric = max([int(i.name) for i in numtag if i.name.isdecimal()]) |
| 55 | + commit = g2repo.head.commit |
| 56 | + now = dt.datetime.now().replace( |
| 57 | + tzinfo=commit.committed_datetime.tzinfo) |
| 58 | + commit0 = commit.hexsha |
| 59 | + # is the newest commit tagged? |
| 60 | + tags0 = g2repo.git.tag('--points-at',commit) |
| 61 | + if tags0: tags0 = tags0.split('\n') |
| 62 | + if tags0: |
| 63 | + print(f'Latest commit ({commit.hexsha[:7]}) is already tagged ({', '.join(tags0)}).') |
| 64 | + sys.exit() |
| 65 | + prev = g2repo.head.commit.parents |
| 66 | + if len(prev) == 1: |
| 67 | + tagsm1 = g2repo.git.tag('--points-at',prev[0]) |
| 68 | + if tagsm1: tagsm1 = tagsm1.split('\n') |
| 69 | + if tagsm1: |
| 70 | + print(f'Previous commit ({prev[0].hexsha[:7]}) is already tagged ({', '.join(tagsm1)}).') |
| 71 | + sys.exit() |
| 72 | + |
| 73 | + # get the latest version number |
| 74 | + releases = [i for i in g2repo.tags if '.' in i.name and i.name.startswith('v')] |
| 75 | + majors = [i.name.split('.')[0][1:] for i in releases] |
| 76 | + major = max([int(i) for i in majors if i.isdecimal()]) |
| 77 | + minors = [i.name.split('.')[1] for i in releases if i.name.startswith(f'v{major}.')] |
| 78 | + minor = max([int(i) for i in minors if i.isdecimal()]) |
| 79 | + minis = [i.name.split('.',2)[2] for i in releases if i.name.startswith(f'v{major}.{minor}')] |
| 80 | + # mini can be integer, float or even have letters (5.2.1.1rc1) |
| 81 | + # for now, ignore anything with letters or decimals |
| 82 | + mini = max([int(i) for i in minis if i.isdecimal()]) |
| 83 | + latest = f'{major}.{minor}.{mini}' |
| 84 | + if mode == 'mini': |
| 85 | + versiontag = f'v{major}.{minor}.{mini+1}' |
| 86 | + elif mode == 'minor': |
| 87 | + versiontag = f'v{major}.{minor+1}.0' |
| 88 | + else: |
| 89 | + print('unexpected mode',mode) |
| 90 | + sys.exit() |
| 91 | + if versiontag in releases: |
| 92 | + print(f'Versioning problem, generated next version {versiontag} already defined!') |
| 93 | + versiontag = '?' |
| 94 | + sys.exit() |
| 95 | + if versiontag != '?': |
| 96 | + g2repo.create_tag(str(versiontag),ref=commit) |
| 97 | + print(f'created version # {versiontag} for {commit.hexsha[:7]}') |
| 98 | + |
| 99 | + # add a numeric tag to the newest commit as well |
| 100 | + tagnum = max_numeric + 1 |
| 101 | + while str(tagnum) in g2repo.tags: |
| 102 | + print(f'Error: {tagnum} would be repeated') |
| 103 | + tagnum += 1 |
| 104 | + g2repo.create_tag(str(tagnum),ref=commit) |
| 105 | + print(f'created tag {tagnum} for {commit.hexsha[:7]}') |
| 106 | + |
| 107 | + tags0 = [i for i in g2repo.git.tag('--points-at',commit).split('\n') if i.isdecimal()] |
| 108 | + history = list(g2repo.iter_commits('HEAD')) |
| 109 | + for i in history[1:]: |
| 110 | + tags = g2repo.git.tag('--points-at',i) |
| 111 | + if not tags: continue |
| 112 | + commitm1 = i.hexsha |
| 113 | + tagsm1 = [i for i in tags.split('\n') if i.isdecimal()] |
| 114 | + if not tagsm1: continue |
| 115 | + break |
| 116 | + # create a file with GSAS-II version information |
| 117 | + pyfile = os.path.join(path2GSAS2,'git_verinfo.py') |
| 118 | + try: |
| 119 | + fp = open(pyfile,'w') |
| 120 | + except: |
| 121 | + print(f'Creation of git version file {pyfile} failed') |
| 122 | + sys.exit() |
| 123 | + fp.write('# -*- coding: utf-8 -*-\n') |
| 124 | + fp.write(f'# {os.path.split(pyfile)[1]} - GSAS-II version info from git\n') |
| 125 | + fp.write(f'# Do not edit, generated by {" ".join(sys.argv)!r} script\n') |
| 126 | + fp.write(f'# Created {now}\n\n') |
| 127 | + fp.write(f'git_version = {commit0!r}\n') |
| 128 | + if tags: |
| 129 | + fp.write(f'git_tags = {tags0}\n') |
| 130 | + else: |
| 131 | + fp.write('git_tags = []\n') |
| 132 | + fp.write(f'git_prevtaggedversion = {commitm1!r}\n') |
| 133 | + fp.write(f'git_prevtags = {tagsm1}\n') |
| 134 | + fp.write(f'git_versiontag = {versiontag!r}\n') |
| 135 | + fp.close() |
| 136 | + print(f'Created git version file {pyfile} at {now} for {commit0[:7]!r}') |
| 137 | + |
| 138 | + g2repo.index.add([pyfile]) |
| 139 | + g2repo.index.commit('increment {mode} version') |
| 140 | + print('committed',pyfile,'mode=',mode) |
| 141 | + g2repo.remote(name='origin').push() |
| 142 | + g2repo.remotes.origin.push(versiontag) |
| 143 | + g2repo.remotes.origin.push(str(tagnum)) |
| 144 | + print('pushed update and tags',versiontag,tagnum) |
| 145 | + |
| 146 | +# print('Now do:\n\t git add \n\t git commit \n\t git push \n\t git push --tags\n (try "git push origin HEAD --tags")') |
0 commit comments