/usr/share/pepper/data.lua is in pepper 0.3.3-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | --[[
pepper - SCM statistics report generator
Copyright (C) 2010-present Jonas Gehring
Released under the GNU General Public License, version 3.
Please see the COPYING file in the source distribution for license
terms and conditions, or see http://www.gnu.org/licenses/.
file: data.lua
Dumps commit data
--]]
require "pepper.datetime"
-- Describes the report
function describe(self)
local r = {}
r.title = "Data dump"
r.description = "Dumps commit data in various formats"
r.options = {
{"-bARG, --branch=ARG", "Select branch"},
{"-fARG, --format=ARG", "Select format (CSV, JSON)"},
{"-cARG, --columns=ARG",
"Comma-seperated list of columns. Possible values " ..
"(and abbreviations) are 'id', 'author' (a), " ..
"'added' (+), 'removed' (-), 'delta' (d), 'total' (t), " ..
"'files' (f), 'message' (m)." }
}
pepper.datetime.add_daterange_options(r)
return r
end
-- Returns the name of the given code
function codename(code)
if code == "id" then
return "Commit ID"
elseif code == "a" or code == "author" then
return "Author"
elseif code == "+" or code == "added" then
return "Lines added"
elseif code == "-" or code == "removed" then
return "Lines removed"
elseif code == "f" or code == "files" then
return "Changed Files"
elseif code == "t" or code == "total" then
return "Total lines"
elseif code == "d" or code == "delta" then
return "Line delta"
elseif code == "m" or code == "message" then
return "Message"
else
error("Unknown column code: " .. code)
end
end
-- Returns revision information given a field code
function info(r, code)
if code == "id" then
return r:id()
elseif code == "a" or code == "author" then
return r:author()
elseif code == "+" or code == "added" then
return r:diffstat():lines_added()
elseif code == "-" or code == "removed" then
return r:diffstat():lines_removed()
elseif code == "f" or code == "files" then
return r:diffstat():files()
elseif code == "t" or code == "total" then
return loc
elseif code == "d" or code == "delta" then
return r:diffstat():lines_added() - r:diffstat():lines_removed()
elseif code == "m" or code == "message" then
return r:message()
else
error("Unknown column code: " .. code)
end
end
-- Checks if a table contains a value
function contains(t, v)
for _,u in ipairs(t) do
if u == v then
return true
end
end
return false
end
-- Escape and quotes a string
function mytostring(v)
return tostring(v):gsub("[\\\"]", "\\%1"):gsub('\n', "\\n"):gsub("\t", "\\t"):gsub("\r", "\\r")
end
-- Sets up the data renderer
function setup_renderer(format)
local r = {}
if format == "csv" then
r.head = function (columns)
local header = "# Timestamp, "
for i,v in ipairs(columns) do
header = header .. codename(v) .. ", "
end
print(header:sub(0, #header-2))
end
r.tail = function () end
r.row = function (data, first)
local s = ""
for _,v in ipairs(data) do
if type(v) == "table" then v = table.concat(v, ":") end
if type(v) == "string" then v = '"' .. mytostring(v):gsub('[,]', "\\%1") .. '"' end
s = s .. v .. ","
end
print(s:sub(0, #s-1))
end
elseif format == "json" then
r.head = function (columns) r.bufs = {} end
r.tail = function () print("[" .. table.concat(r.bufs, ",") .. "]") end
r.row = function (data, first)
local s = "["
local f = true
for _,v in ipairs(data) do
if not f then s = s .. "," end
if type(v) == "table" then
local str = "["
for _,f in ipairs(v) do str = str .. '"' .. mytostring(f) .. "\"," end
v = str:sub(0, #str-1) .. "]"
elseif type(v) == "string" then v = '"' .. mytostring(v) .. '"' end
s = s .. v
f = false
end
table.insert(r.bufs, s .. "]")
end
else
return nil
end
return r
end
-- Main report function
function run(self)
-- Global counters
loc = 0
local columns = pepper.utils.split(self:getopt("c,columns", "a,d,t"), ",")
-- Gather data, but start at the beginning of the repository
-- to get a proper LOC count if needed
local repo = self:repository()
local branch = self:getopt("b,branch", repo:default_branch())
local datemin, datemax = pepper.datetime.date_range(self)
local itstart = datemin
if contains(columns, "t") or contains(columns, "total") then itstart = -1 end
local format = self:getopt("f,format", "csv"):lower()
local renderer = setup_renderer(format)
if not renderer then
error("Unknown format: " .. format)
end
renderer.head(columns)
local first = true
repo:iterator(branch, {start=itstart, stop=datemax}):map(
function (r)
loc = loc + r:diffstat():lines_added() - r:diffstat():lines_removed()
if r:date() >= datemin then
local data = {}
table.insert(data, r:date())
for i,v in ipairs(columns) do
table.insert(data, info(r, v))
end
renderer.row(data, first)
first = false
end
end
)
renderer.tail()
end
|