shithub: shithub

ref: 95d87ae1d14c74b85c1247d03ad3fc71e61c0d8b
dir: /shithub/

View raw version
#!/bin/rc -e

cd $1
shift

rfork ne
nl='
'

fn htcat {
	sed '
		s/&/\&/g;
		s/</\&lt;/g;
		s/>/\&gt;/g;
		s/"/\&quot;/g;
		s/''/\&#39;/g
	' $*
}

fn resolveref {
	if(~ $refname HEAD)
		echo $refname
	if not if(test -d /mnt/git/branch/$refname/tree)
		echo branch/$refname
	if not if(test -d /mnt/git/object/$refname/tree)
		echo object/$refname
	if not
		status='bad ref'
}

fn repons {
	mntgen
	mntgen /mnt/mnt
	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 {
	phash=$1

	message=`{htcat /mnt/git/object/$phash/msg | sed 1q}
	date=`{date -t `{mtime /mnt/git/object/$phash/msg | awk '{print $1}'}}
	author=`"{htcat /mnt/git/object/$phash/author | awk '{print $1}'}
	shorthash=`{echo $phash | awk '{print substr($0, 0, 8)}'}
	echo '	<div id="commit">
		<a href=/git/'$gituser/$repo/$phash'/commit.html>'$shorthash'</a>
		 – '$author' – '$"date'
		<pre>'$"message'</pre>
		</div>'
}

fn shortlog {
	ref=$1
	commitcount=$2

	d=`{pwd}
	commithash=`{cat /mnt/git/$ref/hash | sed 1q}
	count=()
	while (! ~ $#commithash 0 && ! ~ $#count $commitcount) {
		count=($count 1)
		formatcommit $commithash
		echo '<br/>'
		commithash=`{cat /mnt/git/object/$commithash/parent | sed 1q}
	}
	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 prelude {
	echo '
	<!DOCTYPE html>
	<html>
	
	<head>
		<style type="text/css">
			body{
				padding: 3em;
				margin: auto;
				min-width: 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>
	 	<link rel="alternate" type="application/rss+xml" href="feed.rss" title="rss">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1">
		<title>Shithub: '$"1'</title>
	</head>
	<body>
	'
}

fn user_prelude {
	puser=$1
	prepo=$2
	phash=$3

	prelude $prepo
	echo '	<h1><a href="/git/repos.html">Git</a>: 
		<a href="/git/'$puser/$prepo/$phash'/info.html">'$prepo'</a></h1>
		<div id="linkbar">
		<a href="/git/'$puser/$prepo/$phash'/info.html">Info</a>
		&nbsp;•&nbsp;
		<a href="/git/'$puser/$prepo/$phash'/files.html">Files</a>
		&nbsp;•&nbsp;
		<a href="/git/'$puser/$prepo/$phash'/log.html">Log</a>
		</div>'
}

switch($1){
case 'list'
	rfork m
	prelude Repolist
	echo '	<h1>Repos</h1>'
	udir=()
	for(repo in `$nl{ls */}){
		ndir=`{basename -d $repo}
		if(! ~ $udir $ndir)
			echo '</dl>'
		if(! ~ $udir $ndir){
			echo '<h3>'$ndir'</h3>'
			echo '<dl>'
			udir=$ndir
		}
		if(test -e $repo/.git/webpublish){
			echo '<dt><a href="/git/'$repo'/HEAD/info.html">'$repo'</a></dt>'
			echo '<dd>'
			if(test -f $repo/.git/desc)
				htcat $repo/.git/desc
			if not if(test -f $repo/.git/description)
				htcat $repo/.git/description
			if not
				echo 'probably some code'
			echo '</dd>'
		}
	}

case 'tar'
	gituser=$2
	repo=$3
	refname=$4

	repons $gituser $repo
	if(! ref=`{resolveref $refname}){
		echo '<b>invalid ref '$refname'</b>'
		exit
	}
	bind /mnt/git/$ref/tree /mnt/$repo
	cd /mnt
	tar cz $repo

case 'info'
	gituser=$2
	repo=$3
	refname=$4

	repons $gituser $repo
	repodir=/mnt/$repo/.git
	if(! ref=`{resolveref $refname}){
		echo '<b>invalid ref '$refname'</b>'
		exit
	}

	if(test -f /mnt/git/$ref/hash)
		hash=`{cat /mnt/git/$ref/hash}
	if not
		hash=$ref

	user_prelude $gituser $repo $hash		
	echo '	<h3>Clone</h3>
		<div>
		<b>clone:</b> git://shithub.us/'$gituser/$repo' gits://shithub.us/'$gituser/$repo'<br>
		<b>push:</b> hjgit://shithub.us/'$gituser/$repo'<br>'
	if(test -f $repodir/contact)
		echo '	<b>patches to: </b>'^`$nl{cat $repodir/contact}^'<br>'
	echo '	</div>'
	

	if(test -f /mnt/git/object/$hash/msg){
		echo '	<h3>Last commit</h3>'
		formatcommit $hash
	}

	echo '	<h3>About</h3>
		<pre id="desc">'
	if(test -f $repodir/README)
		htcat $repodir/README
	if not if(test -f README)
		htcat README
	if not if (test -f README.md)
		htcat README.md
	if not if(test -f $repodir/desc)
		htcat $repodir/desc
	if not if(test -f $repodir/description)
		htcat $repodir/description
	if not
		echo 'this repo has no description'
	echo '
		</pre>
		</body>
		</html>
	'

case 'files'
	gituser=$2
	repo=$3
	refname=$4

	repons $gituser $repo
	repodir=/mnt/$repo/.git
	if(! ref=`{resolveref $refname}){
		echo '<b>invalid ref '$refname'</b>'
		exit
	}

	if(test -f /mnt/git/$ref/hash)
		hash=`{cat /mnt/git/$ref/hash}
	if not
		hash=$ref

	user_prelude $gituser $repo $hash

	if(! test -d /mnt/git/$ref/tree){
		echo '	<p>No code pushed</p>
			</body>
			</html>
		'
		exit
	}

	cd /mnt/git/$ref/tree

	echo '	<p>
		<b>ref:</b> <a href="'/git/$gituser/$repo/$hash/files.html'">'$hash'</a><br/>
		<b>tar:</b> <a href="'/git/$gituser/$repo/$hash/snap.tar.gz'">snap.tar.gz</a><br/></p>'

	echo '<p><div id="code">'
	for(f in `$nl{ls}){
		url=`$nl{echo -n $f/f.html | urlencode}
		fname=`$nl{echo -n $f | htcat}
		echo -n '<a href="'$url'">'$fname
		if (test -d $f) echo '/'
		echo '</a><br/>'
	}		
	echo '	</div>
		</p>
		</body>
		</html>'

case 'view'
	gituser=$2
	repo=$3
	refname=$4
	file=$5

	repons $gituser $repo
	if(! ref=`{resolveref $refname}){
		echo '<b>invalid ref '$refname'</b>'
		exit
	}
	cd /mnt/git/$ref/tree
	if(~ $file '')
		file='.'
	hash=`{cat /mnt/git/$ref/hash}

	user_prelude $gituser $repo $hash

	echo '	<p>
		<b>ref:</b> <a href="'/git/$gituser/$repo/$hash/files.html'">'$hash'</a><br/>
		</p>'
	if(test -f $file){
		echo '	<a href="'/git/$gituser/$repo/$hash/$file'/raw">View raw version</a>'
		type=`{file -m $file}
		switch($type){
		case text/*
			echo '	<pre id="code">'
			htcat $file
			echo '	</pre>'
		case image/*
			echo '	<br/><div><img src="'/git/$gituser/$repo/$hash/$file'/raw" /></div>'
		case *
			echo '	<p>Binary file not displayed</p>'
		}
	}
	if not if(test -d $file){
		cd $file
		echo '	<div id="code">'
		for(f in `$nl{ls}){
			url=`$nl{echo -n $f/f.html | urlencode}
			fname=`$nl{echo -n $f | htcat}
			echo '<a href="'$url'">'$fname'</a><br/>'
		}
		echo '	</div>'
	}
	echo '	</body>
		</html>'

case 'viewraw'
	gituser=$2
	repo=$3
	refname=$4
	file=$5

	repons $gituser $repo
	if(! ref=`{resolveref $refname}){
		echo 'invalid ref '$refname''
		exit
	}
	cd /mnt/git/$ref/tree
	cat $file

case 'log'
	gituser=$2
	repo=$3
	refname=$4

	repons $gituser $repo
	repodir=/mnt/$repo/.git
	if(! ref=`{resolveref $refname}){
		echo '<b>invalid ref '$refname'</b>'
		exit
	}

	if(test -f /mnt/git/$ref/hash)
		hash=`{cat /mnt/git/$ref/hash}
	if not
		hash=$ref

	user_prelude $gituser $repo $hash

	if(! test -d /mnt/git/$ref/tree){
		echo '	<p>No commits yet.</p>
			</body>
			</html>
		'
		exit
	}
	cd /mnt/git/$ref/tree
	echo '	<p>'
	shortlog $ref 100
	echo '	</p>'
	if(! ~ $"commithash '')
		echo '<a href="/git/'$gituser/$repo/$commithash'/log.html">Next</a>'
	echo '	</body>
		</html>'

case 'show'
	gituser=$2
	repo=$3
	refname=$4

	repons $gituser $repo
	repodir=/mnt/$repo/.git
	if(! ref=`{resolveref $refname}){
		echo '<b>invalid ref '$refname'</b>'
		exit
	}

	user_prelude $gituser $repo $refname

	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 '	<p>
		<a href="/git/'$gituser/$repo/$refname'/patch">Download patch</a><br/>
		</p>
		<p>
		<b>ref:</b> <a href="/git/'$gituser/$repo/$refname'/files.html">'$refname'</a><br/>'
	if(! ~ $#oldcommit 0) {
		echo '<b>parent:</b> <a href="/git/'$gituser/$repo/$oldcommit'/files.html">'$oldcommit'</a><br/>'
	}
	echo '	<b>author:</b> '$author'<br/>
		<b>date:</b> '$date'
		<pre id="commit">'$msg'</pre><br/>
		</p>'
	cd /mnt/$repo
	echo '	<div id="diff">'
	git/export $refname | htcat | difftohtml
	echo '	</div>
		</body>
		</html>'

case 'patch'
	gituser=$2
	repo=$3
	hash=$4

	repons $gituser $repo
	cd /mnt/$repo
	git/export $hash

}