shithub: gitonline

ref: e93d21841d3274e262e745f0f8ebcce7d298e28a
dir: /gitonline.rc/

View raw version
#!/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/</\&lt;/g;
		s/>/\&gt;/g;
		s/"/\&quot;/g;
		s/''/\&#39;/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: 1px solid black;
		background-color: #eaffff;
	}
		</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>Description</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 .git/description
		echo '
		</td>
		<td>'
		htcat /mnt/git/HEAD/msg | sed 1q
		echo '
		</td>
	</tr>'
		}
	}
	echo '</table>'
	html_emit_end
}

fn readme {
	echo '
	<b>Description</b>
	<pre>'
	htcat $1
	echo '</pre>'
}

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
}