. /sys/lib/shithub/config.rc nl='' fn http_response { ct = 'text/html' if(! ~ $1 '') ct=$1 echo 'HTTP/1.1 200' echo 'Content-Type: '^$ct if(! ~ $2 '') echo 'Content-Disposition: attachment; filename="'^$2^'"' echo ''} fn htcat { sed ' s/&/\&/g; s/</\</g; s/>/\>/g; s/"/\"/g; s/''/\'/g ' $*} fn resolveref { if(~ $refname HEAD) echo $refname if not if(test -d $gitfs/branch/$refname/tree) echo branch/$refname if not if(test -d $gitfs/object/$refname/tree) echo object/$refname if not status='bad ref'} fn repons { mntgen mntgen /mnt/mnt gitfs=/mnt/$repo/.git/fs ramfs -m /mnt/tmp bind /bin /mnt/bin bind /rc /mnt/rc bind /sys /mnt/sys bind -c /env /mnt/env bind /dev /mnt/dev bind $1/$2 /mnt/$repo bind /mnt / cd /mnt/$repo git/fs mntgen /mnt/scratch rfork m} fn formatcommit { puser=$1 prepo=$2 phash=$3 message=`{htcat $gitfs/object/$phash/msg | sed 1q} date=`{date -f 'YYYY/MM/DD hh:mm' `{mtime $gitfs/object/$phash/msg | awk '{print $1}'}} author=`"{htcat $gitfs/object/$phash/author | awk '{print $1}'} shorthash=`{echo $phash | awk '{print substr($0, 0, 8)}'} if (test -f $gitfs/object/$phash/committer) committer=`"{htcat $gitfs/object/$phash/committer | awk '{print $1}'} echo ' <div id="commit"> <a href=/'$puser/$prepo/commit/$phash'>'$shorthash'</a> – '$author' authored' if (! ~ $#committer 0 && ! ~ $committer $author) echo ' and '^$committer^' committed' echo ' on '$"date' <pre>'$"message'</pre> </div>'} fn shortlog { puser=$1 prepo=$2 pref=$3 pcount=$4 d=`{pwd} commithash=`{cat $gitfs/$pref/hash | sed 1q} count=() while (! ~ $#commithash 0 && ! ~ $#count $pcount) { count=($count 1) formatcommit $puser $prepo $commithash echo '<br/>' commithash=`{cat $gitfs/object/$commithash/parent | sed 1q} } if(! ~ $"commithash '') echo '<a href="/'$puser/$prepo/log/$commithash'">Next</a>' cd $d} fn difftohtml { awk ' function printpre(id, text) { printf "<pre id='%s'>%s</pre>", id, text } BEGIN { started = 0; diff = 0; } /^---$/ { diff = 1; next } /^diff .*$/ && diff && !started { started = 1; next } /^\+\+\+ .*$/ && started { printpre("files", $0); next } /^--- .*$/ && started { printpre("files", $0); next } /^@@ .*$/ && started { printpre("sep", $0); next } /^\+.*$/ && started { printpre("add", $0); next } /^-.*$/ && started { printpre("del", $0); next } started { printpre("ctx", $0); next } '} fn breadcrumb { awk ' function breadcrumb(baseurl, repo, p) { printf "» <a href='%s'>%s</a>\n", baseurl, repo; n = split(p, a, "/"); q = ""; for (i = 2; i <= n; i++) { q = sprintf("%s/%s", q, a[i]); printf " / "; if (i == n) printf "%s\n", a[i]; else printf "<a href='%s%s'>%s</a>\n", baseurl, q, a[i]; } } { breadcrumb($1, $2, $3); } '} fn prelude { puser=$1 prepo=$2 echo ' <!DOCTYPE html> <html> <head> <style type="text/css"> body{ padding: 3em; margin: auto; min-width: min(95vw, 50em); width: min-content; font-family: sans-serif; tab-space: 8; } h1{ font-size: 1.5em; color: #4c4c99; } h2{ font-size: 1.3em; color: #4c4c99; } h3{ font-size: 1em; color: #4c4c99; } #code{ background: #ffffea; border: 1px solid #99994c; overflow: auto; padding: 4px; } #commit{ font-family: sans-serif; background: #eeeeee; border: 1px solid #cccccc; padding: 4px; } #diff{ font-family: monospace; border: 2px solid #efefef; } #diff #files{ background: #efefef; margin: 0em; } #diff #sep{ background: #eaffff; margin: 0em; } #diff #add{ background: #e6ffed; margin: 0em; } #diff #del{ background: #ffeef0; margin: 0em; } #diff #ctx{ margin: 0em; } </style>' if(! ~ $puser '') echo '<link rel="alternate" type="application/rss+xml" href="/git/'$puser/$prepo'/HEAD/feed.rss" title="rss">' echo ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>'$title': '$"prepo'</title> </head> <body> '} fn user_prelude { puser=$1 prepo=$2 phash=$3 prelude $puser $prepo echo ' <h1><a href="/">'$title'</a>: <a href="/'$puser/$prepo'/">'$prepo'</a></h1> <div id="linkbar"> <a href="/'$puser/$prepo'/">Info</a> • <a href="/'$puser/$prepo'/browse/'$phash'/">Files</a> • <a href="/'$puser/$prepo'/log/'$phash'/">Log</a> </div>'}
. /sys/lib/shithub/config.rc
nl='
'
fn http_response {
ct = 'text/html'
if(! ~ $1 '') ct=$1
echo 'HTTP/1.1 200'
echo 'Content-Type: '^$ct
if(! ~ $2 '') echo 'Content-Disposition: attachment; filename="'^$2^'"'
echo ''
}
fn htcat {
sed '
s/&/\&/g;
s/</\</g;
s/>/\>/g;
s/"/\"/g;
s/''/\'/g
' $*
}
fn resolveref {
if(~ $refname HEAD)
echo $refname
if not if(test -d $gitfs/branch/$refname/tree)
echo branch/$refname
if not if(test -d $gitfs/object/$refname/tree)
echo object/$refname
if not
status='bad ref'
}
fn repons {
mntgen
mntgen /mnt/mnt
gitfs=/mnt/$repo/.git/fs
ramfs -m /mnt/tmp
bind /bin /mnt/bin
bind /rc /mnt/rc
bind /sys /mnt/sys
bind -c /env /mnt/env
bind /dev /mnt/dev
bind $1/$2 /mnt/$repo
bind /mnt /
cd /mnt/$repo
git/fs
mntgen /mnt/scratch
rfork m
}
fn formatcommit {
puser=$1
prepo=$2
phash=$3
message=`{htcat $gitfs/object/$phash/msg | sed 1q}
date=`{date -f 'YYYY/MM/DD hh:mm' `{mtime $gitfs/object/$phash/msg | awk '{print $1}'}}
author=`"{htcat $gitfs/object/$phash/author | awk '{print $1}'}
shorthash=`{echo $phash | awk '{print substr($0, 0, 8)}'}
if (test -f $gitfs/object/$phash/committer) committer=`"{htcat $gitfs/object/$phash/committer | awk '{print $1}'}
echo ' <div id="commit">
<a href=/'$puser/$prepo/commit/$phash'>'$shorthash'</a>
– '$author' authored'
if (! ~ $#committer 0 && ! ~ $committer $author) echo ' and '^$committer^' committed'
echo ' on '$"date'
<pre>'$"message'</pre>
</div>'
}
fn shortlog {
puser=$1
prepo=$2
pref=$3
pcount=$4
d=`{pwd}
commithash=`{cat $gitfs/$pref/hash | sed 1q}
count=()
while (! ~ $#commithash 0 && ! ~ $#count $pcount) {
count=($count 1)
formatcommit $puser $prepo $commithash
echo '<br/>'
commithash=`{cat $gitfs/object/$commithash/parent | sed 1q}
}
if(! ~ $"commithash '')
echo '<a href="/'$puser/$prepo/log/$commithash'">Next</a>'
cd $d
}
fn difftohtml {
awk '
function printpre(id, text) { printf "<pre id='%s'>%s</pre>", id, text }
BEGIN { started = 0; diff = 0; }
/^---$/ { diff = 1; next }
/^diff .*$/ && diff && !started { started = 1; next }
/^\+\+\+ .*$/ && started { printpre("files", $0); next }
/^--- .*$/ && started { printpre("files", $0); next }
/^@@ .*$/ && started { printpre("sep", $0); next }
/^\+.*$/ && started { printpre("add", $0); next }
/^-.*$/ && started { printpre("del", $0); next }
started { printpre("ctx", $0); next }
'
}
fn breadcrumb {
awk '
function breadcrumb(baseurl, repo, p) {
printf "» <a href='%s'>%s</a>\n", baseurl, repo;
n = split(p, a, "/");
q = "";
for (i = 2; i <= n; i++) {
q = sprintf("%s/%s", q, a[i]);
printf " / ";
if (i == n)
printf "%s\n", a[i];
else
printf "<a href='%s%s'>%s</a>\n", baseurl, q, a[i];
}
}
{ breadcrumb($1, $2, $3); }
'
}
fn prelude {
puser=$1
prepo=$2
echo '
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body{
padding: 3em;
margin: auto;
min-width: min(95vw, 50em);
width: min-content;
font-family: sans-serif;
tab-space: 8;
}
h1{
font-size: 1.5em;
color: #4c4c99;
}
h2{
font-size: 1.3em;
color: #4c4c99;
}
h3{
font-size: 1em;
color: #4c4c99;
}
#code{
background: #ffffea;
border: 1px solid #99994c;
overflow: auto;
padding: 4px;
}
#commit{
font-family: sans-serif;
background: #eeeeee;
border: 1px solid #cccccc;
padding: 4px;
}
#diff{
font-family: monospace;
border: 2px solid #efefef;
}
#diff #files{
background: #efefef;
margin: 0em;
}
#diff #sep{
background: #eaffff;
margin: 0em;
}
#diff #add{
background: #e6ffed;
margin: 0em;
}
#diff #del{
background: #ffeef0;
margin: 0em;
}
#diff #ctx{
margin: 0em;
}
</style>'
if(! ~ $puser '')
echo '<link rel="alternate" type="application/rss+xml" href="/git/'$puser/$prepo'/HEAD/feed.rss" title="rss">'
echo ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>'$title': '$"prepo'</title>
</head>
<body>
'
}
fn user_prelude {
puser=$1
prepo=$2
phash=$3
prelude $puser $prepo
echo ' <h1><a href="/">'$title'</a>:
<a href="/'$puser/$prepo'/">'$prepo'</a></h1>
<div id="linkbar">
<a href="/'$puser/$prepo'/">Info</a>
•
<a href="/'$puser/$prepo'/browse/'$phash'/">Files</a>
•
<a href="/'$puser/$prepo'/log/'$phash'/">Log</a>
</div>'
}