From 082afba1bd31ada9f1fe73284e81a45b13709611 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Sun, 20 Oct 2019 21:34:24 +0200 Subject: [PATCH] functions to get git information moved parsing.py to its own packagefolder --- git.py | 101 ++++++++++++++++++++++++++++++ parsing.py => parsing/__init__.py | 26 +++++--- 2 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 git.py rename parsing.py => parsing/__init__.py (95%) diff --git a/git.py b/git.py new file mode 100644 index 0000000..22360a0 --- /dev/null +++ b/git.py @@ -0,0 +1,101 @@ + +import os +import time +import yaml + +from ammsml.utils.path import unfrackpath + +__all__ = ['gitinfo'] + + +def _git_repo_info(repo_path): + """ + returns a string containing git branch, commit id and commit date + """ + result = None + if os.path.exists(repo_path): + # Check if the .git is a file. If it is a file, it means that we are in a submodule structure. + if os.path.isfile(repo_path): + try: + gitdir = yaml.safe_load(open(repo_path)).get('gitdir') + # There is a possibility the .git file to have an absolute path. + if os.path.isabs(gitdir): + repo_path = gitdir + else: + repo_path = os.path.join(repo_path[:-4], gitdir) + except (IOError, AttributeError): + return '' + with open(os.path.join(repo_path, "HEAD")) as f: + line = f.readline().rstrip("\n") + if line.startswith("ref:"): + branch_path = os.path.join(repo_path, line[5:]) + else: + branch_path = None + if branch_path and os.path.exists(branch_path): + branch = '/'.join(line.split('/')[2:]) + with open(branch_path) as f: + commit = f.readline()[:10] + else: + # detached HEAD + commit = line[:10] + branch = 'detached HEAD' + branch_path = os.path.join(repo_path, "HEAD") + + date = time.localtime(os.stat(branch_path).st_mtime) + if time.daylight == 0: + offset = time.timezone + else: + offset = time.altzone + result = "({0} {1}) last updated {2} (GMT {3:+04d})".format(branch, commit, + time.strftime("%Y/%m/%d %H:%M:%S", date), + int(offset / -36)) + else: + result = '' + return result + + +def gitinfo(path=None): + if path is None: + # for use in ammsml + basedir = os.path.join(os.path.dirname(__file__)) + else: + basedir = unfrackpath(path) + + repo_path = os.path.join(basedir, '.git') + print("repo_path", repo_path) + result = _git_repo_info(repo_path) + + submodules = os.path.join(basedir, '.gitmodules') + if not os.path.exists(submodules): + return result + + with open(submodules) as f: + for line in f: + tokens = line.strip().split(' ') + if tokens[0] == 'path': + submodule_path = tokens[2] + submodule_info = _git_repo_info(os.path.join(basedir, submodule_path, '.git')) + if not submodule_info: + submodule_info = ' not found - use git submodule update --init ' + submodule_path + result += "\n {0}: {1}".format(submodule_path, submodule_info) + return result + + +if __name__ == '__main__': + """ + Checks branch and version (commit) and last modified date from a git repository. + Shows (detached HEAD ref: refs/) on modified repository, + and the date of last commit. + FIXME does not work in terminal $>python git.py + """ + print('Testing Git\n===========') + print('None', __file__) + print(gitinfo(), '\n---------') + + testdir = unfrackpath(os.path.join(os.path.dirname(__file__), '..', 'config')) + print('path', testdir) + print(gitinfo(testdir), '\n---------') + + testdir = unfrackpath(os.path.join(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'file_utils'))) + print('path', testdir) + print(gitinfo(testdir), '\n---------') diff --git a/parsing.py b/parsing/__init__.py similarity index 95% rename from parsing.py rename to parsing/__init__.py index 79abeea..d356b39 100644 --- a/parsing.py +++ b/parsing/__init__.py @@ -17,6 +17,11 @@ # along with Ammsml. If not, see . +BOOLEANS_TRUE = frozenset(('y', 'yes', 'on', '1', 'true', 't', 1, 1.0, True)) +BOOLEANS_FALSE = frozenset(('n', 'no', 'off', '0', 'false', 'f', 0, 0.0, False)) +BOOLEANS = BOOLEANS_TRUE.union(BOOLEANS_FALSE) + + def to_text(obj, encoding='utf-8'): """ """ @@ -43,11 +48,6 @@ def to_text(obj, encoding='utf-8'): return to_text(value) -BOOLEANS_TRUE = frozenset(('y', 'yes', 'on', '1', 'true', 't', 1, 1.0, True)) -BOOLEANS_FALSE = frozenset(('n', 'no', 'off', '0', 'false', 'f', 0, 0.0, False)) -BOOLEANS = BOOLEANS_TRUE.union(BOOLEANS_FALSE) - - def boolean(value): if isinstance(value, bool): return value @@ -61,11 +61,8 @@ def boolean(value): elif normalized_value in BOOLEANS_FALSE: return False - raise TypeError("The value '%s' is not a valid boolean. Valid booleans include: %s" % (to_text(value), ', '.join(repr(i) for i in BOOLEANS))) - - -def is_quoted(data): - return len(data) > 1 and data[0] == data[-1] and data[0] in ('"', "'") and data[-2] != '\\' + raise TypeError("The value '%s' is not a valid boolean. Valid booleans include: %s" % ( + to_text(value), ', '.join(repr(i) for i in BOOLEANS))) def unquote(data): @@ -77,3 +74,12 @@ def unquote(data): return data[1:-1] return data + + +def is_quoted(data): + return len(data) > 1 and data[0] == data[-1] and data[0] in ('"', "'") and data[-2] != '\\' + + + + + -- GitLab