Skip to content

Instantly share code, notes, and snippets.

@fabb
Forked from anonymous/gource-submodules.py
Created September 7, 2012 08:38
Show Gist options
  • Save fabb/3664396 to your computer and use it in GitHub Desktop.
Save fabb/3664396 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Generates Gource config file from git submodules, starts Gource.
# Place to /usr/local/bin and run at the main repository root.
#
# (c) 2010 Mikael Lammentausta
# License is the same as Gource (GPLv3)
import os
import re
from git import *
class GourceCustomLog():
"""
If you want to use Gource with something other than the supported systems, there is a pipe ('|') delimited custom log format:
timestamp - A unix timestamp of when the update occured.
username - The name of the user who made the update.
type - Single character for the update type - (A)dded, (M)odified or (D)eleted.
file - Path of the file updated.
colour - A colour for the file in hex (FFFFFF) format. Optional.
"""
file = None
entries = []
def __init__(self,filename,**kwargs):
self.file = open(filename,'w+')
def __del__(self):
if self.file and not self.file.closed:
self.file.close()
@staticmethod
def __update_type(commit,file):
"""Single character for the update type - (A)dded, (M)odified or (D)eleted.
This should be in GitPython, I could not find a method there.
"""
# if no parents, everything is new
if not commit.parents:
return 'A'
# if file is not found in parent tree..
elif not file in map(
lambda blob:
blob.path
, commit.parents[0].tree.traverse()
):
return 'A' # added
# if file is not found in tree..
elif not file in map(
lambda blob:
blob.path
, commit.tree.traverse()
):
return 'D' # deleted
else:
return 'M' # modified
@staticmethod
def __entry(commit,file,prefix=None):
"""Log entry.
@returns a tuple of (timestamp, username, type, file)
"""
if prefix:
_file = '/'.join([prefix,file])
else:
_file = file
return (
commit.authored_date,
commit.author,
GourceCustomLog.__update_type(commit,file),
_file,
#'colour'
)
@staticmethod
def __format(entry):
return '|'.join(map(str, entry)) + "\n"
def append(self,commit,**kwargs):
for file in commit.stats.files:
self.entries.append(
GourceCustomLog.__entry(commit,file,**kwargs)
)
def sort_by_timestamp(self):
self.entries = sorted(self.entries, key=lambda entry: entry[0])
def write(self):
for entry in self.entries:
self.file.write(GourceCustomLog.__format(entry))
def create_log(**kwargs):
log = GourceCustomLog(**kwargs)
# load from working directory
repo = Repo(
os.path.join(
os.getcwd()
))
print "Main repository: "+str(repo)
### main repo
commits = repo.iter_commits('master')
for commit in commits:
log.append(commit)
### submodules
fsubmodules = open(
os.path.join(
os.getcwd(),
'.gitmodules'
)
,'r')
submodules = re.findall('path = (.*)$', fsubmodules.read(), re.M)
fsubmodules.close()
for submodule in submodules:
subrepo = Repo(
os.path.join(
os.getcwd(),
submodule
))
print "Subrepository: "+str(subrepo)
commits = subrepo.iter_commits('master')
for commit in commits:
log.append(commit,prefix=submodule)
log.sort_by_timestamp()
log.write()
def create_conf(filename, logfile):
file = open(filename,'w')
file.write('[gource]\n')
file.write(' path=%s\n' % logfile)
file.close()
def launch_gource(configfile):
os.system('''gource --load-config %s -s 0.01''' % configfile)
if '__main__' == __name__:
logfilename = 'submodules.log'
create_log(filename=logfilename)
create_conf(filename='gource.conf', logfile=logfilename)
launch_gource(configfile='gource.conf')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment