1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#!/bin/bash
# Generate code count plots by iterating over tagged revisions and running cloc.
# Requires cloc and gnuplot.
# Output images.
loc="`hg root`/docs/images/loc.png"
languages="`hg root`/docs/images/languages.png"
# Clone a temporary repository and generate code count data for gnuplot to plot.
tmp=/tmp/count
hg clone `hg root` $tmp && pushd $tmp
plotfile=gnuplot.dat
for rev in `hg tags | awk '{print $2}' | cut -d: -f1 | tac`; do
date=`hg log -r $rev | grep ^date | cut -d: -f2- | tr + - | cut -d- -f1`
hg update -r $rev -q
timestamp=`date -d "$date" "+%s"`
counts=`cloc --force-lang=C,h --quiet --csv \
--exclude-dir=doc,docs,scripts,themes,test,.github \
--not-match-f=adeptsensedoc\\|tadoc . \
| tail -n +3 | cut -d, -f2- | sort | tr '\n' ,`
echo $timestamp,$counts
done | lua -e "
-- Filter counts from cloc into a data format readable by gnuplot.
-- Input is of the form:
-- timestamp1,lang1,blanks1,comments1,code2,lang2,blanks2,comments2,code2,...
-- timestamp2,lang1,blanks1,comments1,code2,lang2,blanks2,comments2,code2,...
-- Output is of the form:
-- Lang1
-- Time Blanks Comments Code
-- ts1 bl1 cm1 co1
-- ts2 bl2 cm2 co2
-- ...
--
--
-- Lang2
-- Time Blanks Comments Code
-- ts1 bl1 cm1 co1
-- ts2 bl2 cm2 co2
-- ...
-- Read in counts.
local counts, langs = {}, {}
for line in io.lines() do
local time, data = line:match('^(%d+),(.+)$')
counts[#counts + 1], counts[time] = time, {}
for lang, data in data:gmatch('([^,]+),([^,]+,[^,]+,[^,]+)') do
lang = lang:match('%S+$')
if not langs[lang] then langs[#langs + 1], langs[lang] = lang, true end
counts[time][lang] = data
end
end
table.sort(langs)
-- Output a data series for each language counted.
for i = 1, #langs do
print(langs[i])
print('Time', 'Blanks', 'Comments', 'Code')
for j = 1, #counts do
local data = (counts[counts[j]][langs[i]] or '0,0,0'):gsub(',', '\t')
print(counts[j], data)
end
print('\n') -- double-newline needed to delimit gnuplot data series
end
-- Output a data series for code, comments, and blanks counted.
for i = 1, #counts do
local sum_code, sum_comments, sum_blanks = 0, 0, 0
for j = 1, #langs do
local data = counts[counts[i]][langs[j]] or '0,0,0'
local blanks, comments, code = data:match('([^,]+),([^,]+),([^,]+)')
sum_code = sum_code + tonumber(code)
sum_comments = sum_comments + tonumber(comments)
sum_blanks = sum_blanks + tonumber(blanks)
end
counts[counts[i]] = {sum_code, sum_comments, sum_blanks}
end
for i, measure in ipairs{'Code', 'Comments', 'Blanks'} do
print(measure)
print('Time', measure)
for j = 1, #counts do print(counts[j], counts[counts[j]][i]) end
print('\n') -- double-newline needed to delimit gnuplot data series
end
" > $plotfile
nlangs=$((`grep ^Time $plotfile | wc -l` - 3)) # ignore blanks, comments, code
# Define gnuplot plot settings and plot commands.
plotcmd=gnuplot.plt
echo "
set term png transparent font 'DejaVu Sans,10' size 450,275;
set border linewidth 1.5;
set style line 1 linecolor rgb '#99994d' linewidth 2;
set style line 2 linecolor rgb '#4d99e6' linewidth 2;
set style line 3 linecolor rgb '#994d4d' linewidth 2;
set style line 4 linecolor rgb '#4d994d' linewidth 2;
set style line 5 linecolor rgb '#994d99' linewidth 2;
set grid linecolor rgb '#cccccc' linetype 1;
set tics scale 0;
set key left top horizontal Left reverse samplen 1;
set xdata time; set timefmt '%s'; set format x \"%Y\n%b\";
set autoscale xfix;
set title 'Code Summary'
set output '$loc'
plot for [i=0:2] '$plotfile' index $nlangs+i using 1:2 with lines title columnhead(1) linestyle i+1
set title 'Code Line Counts'
set output '$languages'
plot for [i=0:$nlangs-1] '$plotfile' index i using 1:4 with lines title columnhead(1) linestyle i+1
" > $plotcmd
# Invoke gnuplot.
gnuplot $plotcmd
# Cleanup.
popd && rm -r $tmp
|