Skip to content

Commit

Permalink
update pycorrfit/_version.py with git_cast_file2repos.py
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmueller committed Nov 6, 2019
1 parent 7e6186d commit 7f203ed
Showing 1 changed file with 75 additions and 21 deletions.
96 changes: 75 additions & 21 deletions pycorrfit/_version.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,52 @@
#!/usr/bin/env python
"""Determine package version for git repositories from tags
"""Determine package version from git repository tag
Each time this file is imported it checks if the ".git" folder is
present and if so, obtains the version from the git history using
`git describe`. This information is then stored in the file
`_version_save.py` which is not versioned by git, but distributed
along e.g. on PyPI.
Each time this file is imported it checks whether the package version
can be determined using `git describe`. If this fails (because either
this file is not located at the 1st level down the repository root or
it is not under version control), the version is read from the script
"_version_save.py" which is not versioned by git, but always included
in the final distribution archive (e.g. via PyPI). If the git version
does not match the saved version, then "_version_save.py" is updated.
Usage
-----
1. Put this file in your main module directory:
REPO_ROOT/package_name/_version.py
2. Add this line to REPO_ROOT/package_name/__init__.py
from ._version import version as __version__ # noqa: F401
3. (Optional) Add this line to REPO_ROOT/.gitignore
_version_save.py
Features
--------
- supports Python 2 and 3
- supports frozen applications (e.g. PyInstaller)
- supports installing into a virtual environment that is located in
a git repository
- saved version is located in a python file and therefore no other
files (e.g. MANIFEST.in) need be edited
- fallback version is the creation date
- excluded from code coverage via "pragma: no cover"
Changelog
---------
2019-11-06
- remove deprecated imp dependency (replace with parser)
- check whether this file is versioned and its location is correct
- code cleanup and docs update
"""
from __future__ import print_function

# Put the entire script into a `True` statement and add the hint
# `pragma: no cover` to ignore code coverage here.
if True: # pragma: no cover
import imp
import os
from os.path import abspath, basename, dirname, join
import subprocess
Expand All @@ -33,7 +67,7 @@ def git_describe():
ourdir = dirname(abspath(__file__))

def _minimal_ext_cmd(cmd):
# construct minimal environment
# Construct minimal environment
env = {}
for k in ['SYSTEMROOT', 'PATH']:
v = os.environ.get(k)
Expand All @@ -48,19 +82,33 @@ def _minimal_ext_cmd(cmd):
stderr=subprocess.PIPE,
env=env)
out = pop.communicate()[0]
return out
return out.strip().decode('ascii', errors="ignore")

# change directory
olddir = abspath(os.curdir)
os.chdir(ourdir)

# Make sure that we are getting "git describe" from our own
# repository (and not from a repository where we just happen
# to be in the directory tree).
git_revision = ""
try:
out = _minimal_ext_cmd(['git', 'describe', '--tags', 'HEAD'])
git_revision = out.strip().decode('ascii')
# If this file is not under version control, "loc" will
# be empty.
loc = _minimal_ext_cmd(['git', 'ls-files', '--full-name',
__file__])
# If it is under version control, it should be located
# one hierarchy down from the repository root (either
# __file__ is "docs/conf.py" or "package_name/_version.py".
if loc.count(os.path.sep) == 1:
try:
git_revision = _minimal_ext_cmd(['git', 'describe',
'--tags', 'HEAD'])
except OSError:
pass
except OSError:
git_revision = ""

# go back to original directory
pass
# Go back to original directory
os.chdir(olddir)

return git_revision
Expand All @@ -69,8 +117,11 @@ def load_version(versionfile):
"""load version from version_save.py"""
longversion = ""
try:
_version_save = imp.load_source("_version_save", versionfile)
longversion = _version_save.longversion
with open(versionfile, "r") as fd:
data = fd.readlines()
for line in data:
if line.startswith("longversion"):
longversion = line.split("=")[1].strip().strip("'")
except BaseException:
try:
from ._version_save import longversion
Expand All @@ -82,7 +133,7 @@ def load_version(versionfile):

return longversion

def save_version(version, versionfile):
def write_version(version, versionfile):
"""save version to version_save.py"""
data = "#!/usr/bin/env python\n" \
+ "# This file was created automatically\n" \
Expand All @@ -91,8 +142,11 @@ def save_version(version, versionfile):
with open(versionfile, "w") as fd:
fd.write(data.format(VERSION=version))
except BaseException:
msg = "Could not write package version to {}.".format(versionfile)
warnings.warn(msg)
if not os.path.exists(versionfile):
# Only issue a warning if the file does not exist.
msg = "Could not write package version to {}.".format(
versionfile)
warnings.warn(msg)

hdir = dirname(abspath(__file__))
if basename(__file__) == "conf.py" and "name" in locals():
Expand All @@ -116,7 +170,7 @@ def save_version(version, versionfile):

# 2. previously created version file
if longversion == "":
# Either this is this is not a git repository or we are in the
# Either this is not a git repository or we are in the
# wrong git repository.
# Get the version from the previously generated `_version_save.py`
longversion = load_version(versionfile)
Expand All @@ -135,7 +189,7 @@ def save_version(version, versionfile):
# This is only done if the program is not frozen (with e.g.
# pyinstaller),
if longversion != load_version(versionfile):
save_version(longversion, versionfile)
write_version(longversion, versionfile)

# PEP 440-conform development version:
version = ".post".join(longversion.split("-")[:2])

0 comments on commit 7f203ed

Please sign in to comment.