Commit 082afba1 authored by Christof Schulze's avatar Christof Schulze 😎
Browse files

functions to get git information

moved parsing.py to its own packagefolder
parent 0fa8cc34
Loading
Loading
Loading
Loading

git.py

0 → 100644
+101 −0
Original line number Diff line number Diff line

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---------')
+16 −10
Original line number Diff line number Diff line
@@ -17,6 +17,11 @@
# along with Ammsml.  If not, see <http://www.gnu.org/licenses/>.


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] != '\\'