Commit 463d2290 authored by Gustavo Padovan's avatar Gustavo Padovan

initial commit

parents
## install
On a python3 environment:
```
pip install pygit2 jinja2
```
## run
Export the output of the git cmdline below to a csv file
```
git log --pretty='format:%h,"%s",,' <revision range>
```
then pass your csv file as arg to `main.py`
```
main.py <csv file> <name> <git cmdline> <git HEAD>
```
*csv file*: your csv file generated from the git log with the `--pretty='format:%h,"%s"`
*name*: the name for the output file, do not put a extension on it.
*git cmdline*: the cmd line used to generate the csv file
*git HEAD*: the current git HEAD used
`main.py` will output \<name>.html and \<name>.json
### scripts
The `scripts` folder has some ready to use scripts to generate the analysis for some trees.
#! /usr/bin/env python
import pygit2 as git
import sys
import csv
import json
from datetime import datetime
from jinja2 import Environment, FileSystemLoader
GIT_TREE="/home/gfpadovan/p/linux"
BASE_URL="https://chromium.googlesource.com/chromiumos/third_party/kernel/+/"
def classify_commit(fs_dict, commit):
diff = repo.diff(commit[0], commit[0] + "^")
for delta in diff.deltas:
path_l = delta.new_file.path.split('/')
partial_dict = fs_dict
for entry in path_l:
if entry == path_l[-1]:
if entry not in partial_dict.keys():
partial_dict[entry] = [[], 0]
partial_dict[entry][0].append(commit)
if entry not in partial_dict.keys():
partial_dict[entry] = [{}, 0]
partial_dict[entry][1] += 1
partial_dict = partial_dict[entry][0]
def upstream_status(status):
if not status:
return ""
if status == "upstream":
ret = '<span class="badge badge-pill badge-success m-1">'
else:
ret = '<span class="badge badge-pill badge-warning m-1">'
ret += status + '</span>'
return ret
def generate_html(repo, fs_dict, title, cmd, head):
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('backlog-tree.html.j2')
return template.render(data=fs_dict, baseurl=BASE_URL, title=title, cmdline=cmd, head=head, now=datetime.now())
if __name__ == "__main__":
repo = git.Repository(GIT_TREE)
name = sys.argv[2]
cmdline = sys.argv[3]
head = sys.argv[4]
fs_dict = {}
with open(sys.argv[1], newline='') as cvslog:
reader = csv.reader(cvslog, delimiter=',' )
for line in reader:
classify_commit(fs_dict, line)
with open(name + '.json', 'w') as json_file:
json.dump(fs_dict, json_file)
html = generate_html(repo, fs_dict, name, cmdline, head)
with open(name + '.html', 'w') as html_file:
html_file.write(html)
#!/bin/bash
GIT_TREE="/home/gfpadovan/p/linux"
BRANCH="chromeos/chromeos-5.4"
WORKDIR=`pwd`
RANGE="v5.4.19..chromeos/chromeos-5.4"
pushd $GIT_TREE > /dev/null
NAME="chromeos-backlog-5.4"
HEAD=`git rev-parse $BRANCH`
CMDLINE="git log --no-merges --pretty='format:%h,"%s",,' $RANGE | egrep -v 'UPSTREAM|FROMGIT|FROMLIST|BACKPORT'"
eval $CMDLINE > $NAME.csv
mv $NAME.csv $WORKDIR
popd > /dev/null
source .venv/bin/activate
./main.py $NAME.csv $NAME "$CMDLINE" $HEAD
\ No newline at end of file
<html>
<head>
<title>{{ title }} - backlog against mainline</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
</head>
{% macro add_commit(commit) -%}
<a href="{{ baseurl }}{{ commit[0] }}">{{ commit[0] }} - {{ commit[1] }}</a>
{% if commit[2] != '' %}
{% if commit[2] == 'upstream' %}
<span class="badge badge-pill badge-success m-1 p-2">
{% elif commit[2] == 'unmergeable' %}
<span class="badge badge-pill badge-secondary m-1 p-2">
{% else %}
<span class="badge badge-pill badge-warning m-1 p-2">
{% endif %}
{{ commit[2] }}
</span>
{% endif %}
{% if commit | length > 3 %}
<i> {{ commit[3] }}</i>
{% endif %}
{%- endmacro %}
{% macro class_id(path) -%}
{{ path|replace(".", "_") }}{% for n in [0,1,2,3,4,5] -%}
{{ [0,1,2,3,4,5,6,7,8,9]|random }}
{%- endfor %}-
{%- endmacro %}
<body>
<h1 class="m-3">{{ title }}</h1>
<h4><code class="badge badge-dark ml-3 p-2">{{ cmdline }}</code></h4>
<p class="m-3">HEAD: <code>{{ head }}</code></p>
<p class="text-monospace m-3">Generated on {{ now }} </p>
<ul>
{% for folder, content in data | dictsort recursive %}
<li>
{% set class_id = class_id(folder) %}
<a class="btn btn-outline-primary m-1 text-left" data-toggle="collapse" href="#{{ class_id }}"
role="button" aria-expanded="false"
aria-controls="{{ class_id }}">
{{folder}}<span class="badge badge-dark m-1">{{ content[1] }}</span>
</a>
<span class="badge badge-primary p-1" style="width: {{ content[1] * 1.5 }}px;">&nbsp;</span>
<div class="collapse" id="{{ class_id }}">
{% if content[0].items is defined %}
<ul>{{ loop(content[0] | dictsort) }}</ul>
{% else %}
<ul class="list-group">
{% for commit in content[0] %}
<li class="list-group-item">
{{ add_commit(commit) }}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</li>
{% endfor %}
</ul>
<p class="text-monospace m-3">* <span class="badge badge-dark m-1">nn</span>: number of commits that touches that folder tree or file</p>
</body>
</html>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment