6

I want to embed the git hash into the version number of a python module if that module is installed from the git repository using ./setup.py install. How do I do that?

My thought was to define a function in setup.py to insert the hash and arrange to have it called when setup has copied the module to its build/lib/ directory, but before it has installed it to its final destination. Is there any way to hook into the build process at that point?

Edit: I know how to get the hash of the current version from the command line, I am asking about how to get such a command to run at the right time during the build/install.

JanKanis
  • 6,346
  • 5
  • 38
  • 42
  • possible duplicate of [How can I rewrite python \_\_version\_\_ with git?](http://stackoverflow.com/questions/5581722/how-can-i-rewrite-python-version-with-git) – Sam Nicholls Jul 23 '13 at 13:55
  • Off the cuff: `git log -n 1 | grep commit` would be a useful command to execute in the root of your project. – yurisich Jul 23 '13 at 14:05
  • @SamStudio8: Not a duplicate, that question asks about how to get the hash at commit time. I want to do it when I build a package, so I'm asking about a hook in the `setup.py` machinery. – JanKanis Jul 23 '13 at 19:02
  • @Droogans I know that part, now how do I get to run it at the right time? – JanKanis Jul 23 '13 at 19:03
  • 1
    @Somejan The second answer in the question links to a relevant looking `setup.py`? – Sam Nicholls Jul 24 '13 at 09:52
  • You can also have a look on how we do it for one of our projects here: https://code.cor-lab.org/projects/rsb/repository/rsb-python/revisions/master/entry/setup.py. Definitely not a standard approach but works quite well. It preserves the hash also for sdists etc. – languitar Aug 22 '13 at 16:58

1 Answers1

2

Another, possibly simpler way to do it, using gitpython, as in dd/setup.py:

from pkg_resources import parse_version  # part of `setuptools`


def git_version(version):
    """Return version with local version identifier."""
    import git
    repo = git.Repo('.git')
    repo.git.status()
    # assert versions are increasing
    latest_tag = repo.git.describe(
        match='v[0-9]*', tags=True, abbrev=0)
    assert parse_version(latest_tag) <= parse_version(version), (
        latest_tag, version)
    sha = repo.head.commit.hexsha
    if repo.is_dirty():
        return f'{version}.dev0+{sha}.dirty'
    # commit is clean
    # is it release of `version` ?
    try:
        tag = repo.git.describe(
            match='v[0-9]*', exact_match=True,
            tags=True, dirty=True)
    except git.GitCommandError:
        return f'{version}.dev0+{sha}'
    assert tag == f'v{version}', (tag, version)
    return version

cf also the discussion at https://github.com/tulip-control/tulip-control/pull/145

0 _
  • 10,524
  • 11
  • 77
  • 109