#!/bin/rc
SITE_TITLE='Web mirror of shithub.us'
nl='
'
rfork ne
ramfs -m /tmp
cd $REPO_DIR
fn resolveref {
if(~ $gitref HEAD)
echo $gitref
if not if(test -d /mnt/git/branch/$gitref/tree)
echo branch/$gitref
if not if(test -d /mnt/git/object/$gitref/tree)
echo object/$gitref
if not {
status='bad ref'
}
}
fn htcat {
sed '
s/&/\&/g;
s/</\</g;
s/>/\>/g;
s/"/\"/g;
s/''/\'/g
' $*
}
fn redirect {
echo 'Status: 301 Moved Permanently'
echo 'Location: '$1
}
fn html_emit_start {
echo 'Content-type: text/html'
echo
echo '
<!DOCTYPE html>
<html>
<head>
<title>'$SITE_TITLE'</title>
<meta charset="UTF-8">
<style>
body {
background-color: #ffffea;
}
th {
text-align: left;
}
code > pre.code {
border: 2px solid #8888cc;
background-color: #eaffff;
width: max-content;
padding: 0 0.5em;
}
</style>
</head>'
}
fn html_emit_end {
echo '
</body>
</html>'
}
fn repo_index {
html_emit_start
echo '<h1> '$SITE_TITLE' - index </h1>'
dirs=`{walk -d -n2,2 | sort}
echo '
<table style="width: 100%">
<tr>
<th>Name</th>
<th>Last change</th>
</tr>'
for (d in $dirs) {
cd $REPO_DIR
if (test -d $d/.git) {
cd $d
git/fs
echo '
<tr>
<td><a href="/'$d'">'$d'</a></td>
<td>'
htcat /mnt/git/HEAD/msg | sed 1q
echo '
</td>
</tr>'
}
}
echo '</table>'
html_emit_end
}
fn readme {
echo '
<b>Description</b>
<code><pre class=code>'
htcat $1
echo '</pre></code>'
}
fn repo_view {
html_emit_start
gitref=HEAD
repo=`{echo $1 | sed 's,^/,,'}
echo '
<h1>'$repo'</h1>'
if (test -f $repo/README) {
readme $repo/README
}
if not if(test -f $repo/README.md) {
readme $repo/README.md
}
if not if(test -f $repo/.git/README) {
readme $repo/.git/README
}
echo '<b>Last 5 commits</b> (<a href="/'$repo'/shortlog">shortlog</a>)'
shortlog 5
echo '
<b>Files</b> (<a href="/'$repo'/browse">browse</a>)'
filepath=/
filetree
html_emit_end
}
fn filetree {
pwd=`{pwd}
cd $repo
git/fs
ref=`{resolveref $gitref}
if (! ref=`{resolveref $gitref}) {
`{resolveref $gitref}
echo '<b>'$status'</b>'
}
if not {
gitpath=/mnt/git/$ref/tree$filepath
if (test -d $gitpath) {
cd $gitpath
files=`$nl{ls -F | sed 's/\*//g'}
echo '<pre>'
for (f in $files) {
echo '<a href="/'$repo'/browse/'$gitref$filepath$f'">'$f'</a>'
}
echo '</pre>'
}
if not if (test -f $gitpath) {
echo '
<a href="/'$repo'/raw/'$gitref$filepath'">view raw</a>
<code><pre class="code">'
htcat $gitpath
echo '</pre></code>'
}
if not {
echo 'Sorry, could not find '$gitpath
}
}
cd $pwd
}
fn repo_browse {
html_emit_start
echo '<h2> Browsing '$repo' at commit '$gitref': '$filepath'</h2>'
filetree
html_emit_end
}
fn repo_raw {
echo
cd $repo
git/fs
ref=`{resolveref $gitref}
if (ref=`{resolveref $gitref}) {
cat /mnt/git/$ref/tree$filepath
}
}
fn shortlog {
commitcount=$1
pwd=`{pwd}
cd $repo
git/fs
if (! ref=`{resolveref $gitref}) {
`{resolveref $gitref}
echo '<b>'$status'</b>'
}
if not {
echo '
<table>
<tr>
<th>Date</th>
<th>Author</th>
<th>Short message</th>
<th>Commit hash</th>
</tr>'
commithash=`{cat /mnt/git/$ref/hash | sed 1q}
count=()
while (! ~ $#commithash 0 && ! ~ $#count $commitcount) {
count=($count 1)
message=`{htcat /mnt/git/object/$commithash/msg | sed 1q}
date=`{date -i `{mtime /mnt/git/object/$commithash/msg | awk '{print $1}'}}
author=`"{htcat /mnt/git/object/$commithash/author | awk '{print $1}'}
echo '
<tr>
<td>'$date'</td>
<td>'$author'</td>
<td>'$"message'</td>
<td><a href="/'$repo'/showcommit/'$commithash'">'$commithash'</a></td>
</tr>'
commithash=`{cat /mnt/git/object/$commithash/parent | sed 1q}
}
echo '</table>'
}
cd $pwd
}
fn repo_shortlog {
html_emit_start
echo '<b>Showing the last 100 commits</b>'
shortlog '100'
html_emit_end
}
fn show_commit {
html_emit_start
cd $repo
git/fs
gitref=$commithash
if (! ref=`{resolveref $gitref}) {
`{resolveref $gitref}
echo '<b>'$status'</b>'
html_emit_end
exit
}
oldcommit=`{cat /mnt/git/$ref/parent}
author=`''{htcat /mnt/git/$ref/author}
date=`''{date `{mtime /mnt/git/$ref/msg | awk '{print $1}'}}
msg=`''{htcat /mnt/git/$ref/msg}
echo '
<table>
<tr><td><b>Commit:</b></td><td>'$commithash' (<a href="/'$repo'/browse/'$commithash'/">browse</a>)</td></tr>'
if(~ $#oldcommit 0) {
echo '<tr><td><b>Parent:</b></td><td>No parent</td></tr>'
}
if not {
echo '<tr><td><b>Parent:</b></td><td><a href="/'$repo'/showcommit/'$oldcommit'">'$oldcommit'</a></td></tr>'
}
echo '<tr><td><b>Author:</b></td><td>'$author'</td></tr>
<tr><td><b>Date:</b></td><td>'$date'</td></tr>
<tr><td><b>Message:</b></td><td><pre>'$msg'</pre></td></tr>
<tr><td></td></tr>
</table>'
diff=`''{git/export $commithash |
sed 's,^--- ([^ ]*).*,--- \1,g' |
sed 's,^\+\+\+ ([^ ]*).*,+++ \1,g' |
awk '
BEGIN {
started=0
}
/^--- .*/ {
started = 1
}
/^+++/ {
}
{
if (started) {
print $0
}
}
' | htcat |
sed -e 's,^--- a/(.*),</pre></code><br>\n--- <a href="/'$repo'/browse/'$oldcommit'/\1">\1</a>,g' \
-e 's,^\+\+\+ b/(.*),+++ <a href="/'$repo'/browse/'$commithash'/\1">\1</a><code><pre class="code">,g' \
-e 's,^--- (/dev/null),</pre></code><br>\n--- \1,g' \
-e 's,^\+\+\+ (/dev/null),+++ \1<code><pre class="code">,g' |
ssam 's,^--- (.*)\n\+\+\+ (.*)$,\1 => \2,g'
}
echo '<pre><code><pre>'$diff'</pre></code></pre>'
html_emit_end
}
if (~ $location */browse) {
redirect $location/HEAD/
}
if not if (~ $location */browse/) {
redirect $locationHEAD
}
if not if (~ $location */shortlog) {
redirect $location/HEAD/
}
if not if (~ $location */shortlog/) {
redirect $locationHEAD
}
if (~ $location /) {
repo_index
}
if not if (~ $location */showcommit/*) {
parts=`{echo $location | sed 's,/(.*)/showcommit/([^/]*),\1 \2,'}
repo=$parts(1)
commithash=$parts(2)
show_commit
}
if not if (~ $location */browse/*/* ) {
parts=`{echo $location | sed 's,/(.*)/browse/([^/]*)(.*),\1 \2 \3,'}
repo=$parts(1)
gitref=$parts(2)
filepath=$parts(3)
repo_browse
}
if not if (~ $location */shortlog/*/* ) {
parts=`{echo $location | sed 's,/(.*)/shortlog/([^/]*)(.*),\1 \2 \3,'}
repo=$parts(1)
gitref=$parts(2)
filepath=$parts(3)
repo_shortlog
}
if not if (~ $location */raw/*/*) {
parts=`{echo $location | sed 's,/(.*)/raw/([^/]*)(.*),\1 \2 \3,'}
repo=$parts(1)
gitref=$parts(2)
filepath=$parts(3)
repo_raw
}
if not if (test -d $REPO_DIR$location/.git) {
repo_view $location
}
if not {
echo no match
}