From c6da0d201830ccbd0c843b13c169675631b520d9 Mon Sep 17 00:00:00 2001 From: Hayden Metsky Date: Mon, 5 Aug 2019 17:51:20 -0400 Subject: [PATCH 1/3] Improve comments in version.py --- catch/utils/version.py | 59 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/catch/utils/version.py b/catch/utils/version.py index 5898d5d45..fb9161079 100644 --- a/catch/utils/version.py +++ b/catch/utils/version.py @@ -1,29 +1,53 @@ #!/usr/bin/python -''' This gets the git version into python-land -''' +"""This determines the catch package version, primarily based on git. + +If git is available, we use the version specified by git. This can indicate +commits on top of the last numbered version and can also indicate if the +working directory is dirty (i.e., has local modifications). If git is not +available but some version from git was stored in a file, we use that. Finally, +if none of these are available, we resort to the numbered version manually +specified in the variable VERSION. +""" -__author__ = "dpark@broadinstitute.org" -__version__ = None import subprocess import os import re import time, datetime +__author__ = ['Danny Park ', + 'Hayden Metsky '] + +# Set __version__ lazily below +__version__ = None + def get_project_path(): - '''Return the absolute path of the top-level project, assumed to be the - parent of the directory containing this script.''' + """Determine absolute path to the top-level of the catch project. + + This is assumed to be the parent of the directory containing this script. + + Returns: + path (string) to top-level of the catch project + """ # abspath converts relative to absolute path; expanduser interprets ~ path = __file__ # path to this script path = os.path.expanduser(path) # interpret ~ path = os.path.abspath(path) # convert to absolute path - path = os.path.dirname(path) # containing directory: util - path = os.path.dirname(path) # containing directory: main project dir + path = os.path.dirname(path) # containing directory: utils + path = os.path.dirname(path) # containing directory: catch project dir return path def call_git_describe(): + """Determine a version according to git. + + This calls `git describe`, if git is available. + + Returns: + version from `git describe --tags --always --dirty` if git is + available; otherwise, None + """ cwd = os.getcwd() try: os.chdir(get_project_path()) @@ -39,10 +63,20 @@ def call_git_describe(): def release_file(): + """Obtain path to file storing version, according to git. + + Returns: + path to VERSION file + """ return os.path.join(get_project_path(), 'VERSION') def read_release_version(): + """Read VERSION file, containing git version. + + Returns: + if VERSION file exists, version stored in it; otherwise, None + """ try: with open(release_file(), 'rt') as inf: version = inf.readlines()[0].strip() @@ -52,6 +86,11 @@ def read_release_version(): def write_release_version(version): + """Save version, according to git, into VERSION file. + + Args: + version: version to save + """ with open(release_file(), 'wt') as outf: outf.write(version + '\n') @@ -94,7 +133,10 @@ def approx_version_number(): return version + def get_version(): + """Determine version from git, and save if available. + """ global __version__ if __version__ is None: from_git = call_git_describe() @@ -114,4 +156,5 @@ def get_version(): if __name__ == "__main__": + # Determine and print the package version print(get_version()) From 7550a1fc7fe95819ab015d518c0c9828d23bce2b Mon Sep 17 00:00:00 2001 From: Hayden Metsky Date: Mon, 5 Aug 2019 18:09:45 -0400 Subject: [PATCH 2/3] Simplify determination of package version This simplifies the tool that determines the package version. It no longer uses the modification or current time as fallbacks. Instead, the script contains a manually-specified numbered release version and uses this as a fallback. The primary choice for determining a version is still via `git describe`. --- catch/utils/version.py | 65 ++++++++++++------------------------------ 1 file changed, 18 insertions(+), 47 deletions(-) diff --git a/catch/utils/version.py b/catch/utils/version.py index fb9161079..eb50a1de8 100644 --- a/catch/utils/version.py +++ b/catch/utils/version.py @@ -5,15 +5,16 @@ commits on top of the last numbered version and can also indicate if the working directory is dirty (i.e., has local modifications). If git is not available but some version from git was stored in a file, we use that. Finally, -if none of these are available, we resort to the numbered version manually -specified in the variable VERSION. +if none of these are available, we resort to the numbered release version +manually specified in the variable RELEASE_VERSION. """ +# Manually specify a numbered release version to use as a fallback +RELEASE_VERSION = 'v1.3.0' + import subprocess import os -import re -import time, datetime __author__ = ['Danny Park ', 'Hayden Metsky '] @@ -39,7 +40,7 @@ def get_project_path(): return path -def call_git_describe(): +def get_version_from_git_describe(): """Determine a version according to git. This calls `git describe`, if git is available. @@ -95,62 +96,32 @@ def write_release_version(version): outf.write(version + '\n') -def approx_version_number(): - """ - In the event that git is unavailable and the VERSION file is not present - this returns a "version number" in the following precedence: - - version number from path - downloads from GitHub tagged releases - might be extracted into directories containing - the version number. If they contain a version number - in the form d.d.d, we can use it - - modification time of this file (unix timestamp) - file modification time for github releases corresponds to - when the release archives were created, a rough way to ballpark - the release date. If we can't get the version number from the path - we can at least use the modification time of this file as a proxy - for the true version number - - the current time (unix timestamp) - the current time is better than not having any version number - """ - version_re = re.compile(r"(?:(\d+)\.)?(?:(\d+)\.)?(?:(\d+))") - # path relative to version.py - relative_path = os.path.basename(get_project_path()) - - # for tagged releases, the version number might be part of - # the root directory name - matches = version_re.search(relative_path) - - if matches and len([n for n in matches.groups() if n]) == 3: - version = ".".join(map(str, matches.groups())) - else: - try: - # Try to use modification time of the current file - version = str(int(os.path.getmtime(__file__))) - except OSError: - # Just use the current time - version = str(int(time.time())) - - return version - - def get_version(): """Determine version from git, and save if available. """ + # Allow modifying the global __version__ variable global __version__ + if __version__ is None: - from_git = call_git_describe() + from_git = get_version_from_git_describe() from_file = read_release_version() if from_git: + # A version is available from git; use this if from_file != from_git: + # Update the version stored in the VERSION file write_release_version(from_git) __version__ = from_git else: - __version__ = from_file + if from_file: + # No version is available from git but one is in the + # VERSION file; use this + __version__ = from_file if __version__ is None: - __version__ = approx_version_number() + # No version is available from git and there is no VERSION + # file; use the manually set release version + __version__ = RELEASE_VERSION return __version__ From dfff03ed79070e3df874b9aa8ca839f3a1a5a211 Mon Sep 17 00:00:00 2001 From: Hayden Metsky Date: Mon, 5 Aug 2019 18:12:01 -0400 Subject: [PATCH 3/3] Update release version to v1.3.1 --- catch/utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catch/utils/version.py b/catch/utils/version.py index eb50a1de8..cd0495a20 100644 --- a/catch/utils/version.py +++ b/catch/utils/version.py @@ -10,7 +10,7 @@ """ # Manually specify a numbered release version to use as a fallback -RELEASE_VERSION = 'v1.3.0' +RELEASE_VERSION = 'v1.3.1' import subprocess