1# -*- coding: utf-8 -*- 2# Author: Douglas Creager <dcreager@dcreager.net> 3# This file is placed into the public domain. 4 5# Calculates the current version number. If possible, this is the 6# output of “git describe”, modified to conform to the versioning 7# scheme that setuptools uses. If “git describe” returns an error 8# (most likely because we're in an unpacked copy of a release tarball, 9# rather than in a git working copy), then we fall back on reading the 10# contents of the RELEASE-VERSION file. 11# 12# To use this script, simply import it your setup.py file, and use the 13# results of get_git_version() as your package version: 14# 15# from version import * 16# 17# setup( 18# version=get_git_version(), 19# . 20# . 21# . 22# ) 23# 24# This will automatically update the RELEASE-VERSION file, if 25# necessary. Note that the RELEASE-VERSION file should *not* be 26# checked into git; please add it to your top-level .gitignore file. 27# 28# You'll probably want to distribute the RELEASE-VERSION file in your 29# sdist tarballs; to do this, just create a MANIFEST.in file that 30# contains the following line: 31# 32# include RELEASE-VERSION 33 34__all__ = ("get_git_version") 35 36from subprocess import Popen, PIPE 37 38 39def call_git_describe(abbrev=4): 40 try: 41 p = Popen(['git', 'describe', '--abbrev=%d' % abbrev], 42 stdout=PIPE, stderr=PIPE) 43 p.stderr.close() 44 line = p.stdout.readlines()[0] 45 return line.strip() 46 47 except: 48 return None 49 50 51def read_release_version(): 52 try: 53 f = open("RELEASE-VERSION", "r") 54 55 try: 56 version = f.readlines()[0] 57 return version.strip() 58 59 finally: 60 f.close() 61 62 except: 63 return None 64 65 66def write_release_version(version): 67 f = open("RELEASE-VERSION", "w") 68 f.write("%s\n" % version) 69 f.close() 70 71 72def get_git_version(abbrev=4): 73 # Read in the version that's currently in RELEASE-VERSION. 74 75 release_version = read_release_version() 76 77 # First try to get the current version using “git describe”. 78 79 version = call_git_describe(abbrev) 80 81 #adapt to PEP 386 compatible versioning scheme 82 version = pep386adapt(version) 83 84 # If that doesn't work, fall back on the value that's in 85 # RELEASE-VERSION. 86 87 if version is None: 88 version = release_version 89 90 # If we still don't have anything, that's an error. 91 92 if version is None: 93 raise ValueError("Cannot find the version number!") 94 95 # If the current version is different from what's in the 96 # RELEASE-VERSION file, update the file to be current. 97 98 if version != release_version: 99 write_release_version(version) 100 101 # Finally, return the current version. 102 103 return version 104 105 106def pep386adapt(version): 107 if version is not None: 108 if '-' in version: 109 # adapt git-describe version to be in line with PEP 386 110 parts = version.split('-') 111 parts[-2] = 'post'+parts[-2] 112 version = '.'.join(parts[:-1]) 113 elif version[0] == 'v': 114 version = version[1:] 115 116 return version 117 118 119if __name__ == "__main__": 120 print get_git_version()