local git = require "git"
local scan = require "scan"
local lud = require "ludweb"
git.init()
local path = "/tmp/cogit"
local limit = 20
local groups = scan.scanrepos(path)
local function time_fmt(sig)
local s = os.date("%Y-%m-%d %H:%M:%S", sig.time_)
local offset = sig.offset
local sign
if offset < 0 then
offset = -offset
sign = "-"
else
sign = "+"
end
local hours = math.floor(offset / 60)
local mins = offset % 60
s = s .. (" (UTC%s%02d:%02d)"):format(sign, hours, mins)
return s
end
local function diff_cb(line_type, line)
line = lud.template.escape(line:sub(1, #line-1))
if line_type == " " then
line = ' <span class="diff_ctx">' .. line .. '</span>'
elseif line_type == "+" then
line = '+<span class="diff_add">' .. line .. '</span>'
elseif line_type == "-" then
line = '-<span class="diff_del">' .. line .. '</span>'
elseif line_type == "=" then
line = ' <span class="diff_nonl diff_ctx_nonl">' .. line .. '</span>'
elseif line_type == ">" then
line = ' <span class="diff_nonl diff_old_nonl">' .. line .. '</span>'
elseif line_type == "<" then
line = ' <span class="diff_nonl diff_new_nonl">' .. line .. '</span>'
elseif line_type == "F" then
line = '\n<span class="diff_file_hdr">' .. line .. '</span>'
elseif line_type == "H" then
line = '<span class="diff_hunk_hdr">' .. line .. '</span>'
elseif line_type == "B" then
line = '<span class="diff_bin">' .. line .. '</span>'
else
line = line_type .. line
end
return line .. "\n"
end
local routes = {
{"GET", "/?",
function (req)
local gnames = {}
for gname in pairs(groups) do
table.insert(gnames, gname)
end
return lud.template.render_file("view/home.html", {gnames=gnames})
end},
{"GET", "/group/([%w_-]+)",
function (req, gname)
local rnames = {}
for rname in pairs(groups[gname]) do
table.insert(rnames, rname)
end
return lud.template.render_file("view/group.html", {gname=gname, rnames=rnames})
end},
{"GET", "/group/([%w_-]+)/repo/([%w_-]+)",
function (req, gname, rname)
local repo = groups[gname][rname]
local bnames = repo:branches()
local tnames = repo:tags()
local env = {repo=repo, gname=gname, rname=rname, bnames=bnames, tnames=tnames}
return lud.template.render_file("view/repo.html", env)
end},
{"GET", "/group/([%w_-]+)/repo/([%w_-]+)/history/([%w_-]+)",
function (req, gname, rname, first)
local repo = groups[gname][rname]
local commit = repo:commit(first)
local prev = repo:find_prev(commit:id(), limit)
local env = {
gname=gname, rname=rname, bname=bname, commit=commit,
limit=limit, prev=prev, first=first,
}
return lud.template.render_file("view/history.html", env)
end},
{"GET", "/group/([%w_-]+)/repo/([%w_-]+)/commit/([%w_-]+)",
function (req, gname, rname, cid)
local repo = groups[gname][rname]
local commit = repo:commit(cid)
local prev = repo:find_prev(commit:id(), 1)
local sig = commit:signature()
local time_str = time_fmt(sig)
local diff = repo:diff(commit, diff_cb)
local env = {
gname=gname, rname=rname, bname=bname, commit=commit,
time_str=time_str, sig=sig, cid=cid, prev=prev, diff=diff,
}
return lud.template.render_file("view/commit.html", env)
end},
{"GET", "/group/([%w_-]+)/repo/([%w_-]+)/commit/([%w_-]+)/tree/(.*)",
function (req, gname, rname, cid, path)
local repo = groups[gname][rname]
local commit = repo:commit(cid)
local node = commit:tree_entry(path)
if node == nil then
return "File not found", 404, "Not found"
end
local parts = {}
for part in path:gmatch("[^/]+") do
table.insert(parts, part)
end
local env = {
gname=gname, rname=rname, cid=cid, path=path,
base=req.path, parts=parts, node=node,
}
if node.type_ == "dir" then
return lud.template.render_file("view/dir.html", env)
elseif node.type_ == "file" then
return lud.template.render_file("view/file.html", env)
end
end},
}
local app = lud.app.new_app(routes)
app:run(8080)
git.shutdown()