Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50629 views
#!/usr/bin/env python

print "NOT DONE -- just for testing"
sys.exit(1)

##################################################################
#
# This is a script that takes as input a branch and a path and outputs
# -- *very* efficiently via one git call -- two JSON strings.  The
# first contains information about all relevant commits, and the
# second gives for each file at least its status code and last commit
# to touch it.
#
# The path is *NOT* recursively walked, since it is important that
# the size of the output stay manageable.
#
# The information about given in each list may grow as our needs
# expand.
#
##################################################################

import json, os, subprocess, sys, uuid

if len(sys.argv) < 2:
    print "Usage: %s <path> [branch]"%(sys.argv[0])
    sys.exit(1)

path = sys.argv[1]
if not os.path.exists(path):
    print "path %s does not exist"%path
    sys.exit(1)

if len(sys.argv) >= 3:
    branch = sys.argv[2]
else:
    branch = ""

logs = {}
files = {}

def set_file(obj, components, commit):
    if len(components) == 1:
        c = components[0]
        if c not in obj: # only record this the *first* time we see a file
            obj[c] = commit
    else:
        if not obj.has_key(components[0]):
            obj[components[0]] = {}
        set_file(obj[components[0]], components[1:], commit) # recurse

def dir_exists(commits, files, d=None):
    """
    Return a dictionary directory_name:true/false, where the value is
    true if the directory contains any non-deleted files and false
    otherwise.
    """
    if d is None:
        d = {}
    for path, val in files.iteritems():
        if isinstance(val, dict):   # a directory
            d[path] = os.path.exists(path)
            dir_exists(commits, val, d)
    return d

def go():
    format = "--pretty=format:!%H|%an <%ae>|%ad|%s|"
    field_sep = str(uuid.uuid4())
    commit_sep = str(uuid.uuid4())
    format = format.replace('|',field_sep).replace("!",commit_sep)

    file_list = [os.path.listdir(path)

    log = subprocess.Popen(['git', 'log', '--name-status', format, branch, "--"] + file_list,
                     stdin=subprocess.PIPE, stdout = subprocess.PIPE,
                     stderr=subprocess.PIPE).stdout.read()
    commits = log.split(commit_sep)

    v = {}
    d = {}
    files[branch] = d
    commit_list = []
    for entry in commits:
        if len(entry.strip()) == 0 : continue
        commit, author, date, message, modified_files= entry.split(field_sep)
        # modified_files = list of pairs (filename, status)
        modified_files = [(str(x[2:]).replace('\\\\"','"').replace('\\"',''),x[0]) for x in modified_files.splitlines() if x]
        meta = {'author':author, 'date':date, 'message':message, 'modified_files':dict(modified_files)}
        v[commit] = meta
        commit_list.append(commit)
        commit_id = commit
        for filename, status in modified_files:
            set_file(d, filename.split('/'), commit_id)
    logs[branch] = {'commit_list':commit_list, 'commits':v, 'dir_exists':dir_exists(v, d)}


print json.dumps(logs,  separators=(',',':'))
print json.dumps(files,  separators=(',',':'))