viernes, 9 de diciembre de 2011

GIT Rev number on Python Package with SetupTool

Is very common to see on python projects a VERSION.py file or a VERSION string on setup.py. Every time the project has a new version, the you have to modify and push it. Personally, I don't like hardcoded version on the code, that responsibility should be share by the repository and the packager script. So after google it and not find something useful, I coded something, not so elegant, but works for me. Well first, setup your git repo and add tag in it. The way to get a cool revision number is:
git describe --abbrev=4 HEAD 
you will get something like :
0.0.1-29-gad35
Thats means, from the tag 0.0.1 there are 29 commits and the last one is gad35. In setup.py there is a field "version" so you can put a DEFAULT version mean while like '0.0.1' OR we can create a function that actually call the git command:
def get_version():
    git_call = subprocess.Popen(['git','describe','--abbrev=4','HEAD'], stdout=subprocess.PIPE)
    return git_call.stdout.read().strip()
and call it from the setup
setup( name='test'
    ,version=get_version()
    ,description=("Test blabla babla ........
That works, if the setup.py is called from the GIT repo. But what happen if it is called from the production environment, well will fail, because there is no GIT repo. So the change is kind of tricky.
def get_version(argv):
    if "install" in argv or "egg_info" in argv:
        #means setup.py is called from deployment process
        return "0.0.0"
    else:
        try:
            git_call = subprocess.Popen(['git','describe','--abbrev=4','HEAD'],
                                        stdout=subprocess.PIPE)
            return git_call.stdout.read().strip()
        except OSError:
            return "0.0.0"

The arg is added to the function, so the setup must provide them:
setup( name='test'
    ,version=get_version(sys.arg)
    ,description=("Test blabla babla ........
Now we need to create a packager script and get the revision number (from GIT or from the package created by setuptools). Then replace that REVISION number in the setup.py generated in the package. Repackage again and voila.
FILENAME=`python setup.py build sdist 2>/dev/null| grep Writing | cut -d' ' -f2 | cut -d/ -f1`

VERSION=${FILENAME#*lbsc-};
VERSION=${VERSION%/*}

pushd dist; tar xzf $FILENAME.tar.gz; rm $FILENAME.tar.gz;
pushd $FILENAME;
sed -i "s/return .0.0.0./return '$VERSION'/g" setup.py;
popd; tar czf $FILENAME.tar.gz $FILENAME;rm $FILENAME -rf;popd
Also we can create a get_version function on __init__.py and replace the VERSION on the code for the current one:
sed -i "s/^VERSION =.*$/VERSION = '$VERSION'/g" lbsc/__init__.py;
Now after install you can do:
import test; test.get_version()
Hope this was helpful.

1 comentario:

  1. Pesan baju seragam tk sekarang semakin mudah karena bisa pesan baju seragam dengan Motif dan model sesuai selera kita

    ResponderEliminar