5 Commits
0.10 ... 0.11

Author SHA1 Message Date
Alberto Bertogli
6f5f3c4aa5 Add a post-receive hook
This patch adds a post-receive hook that can be used to trigger a git-arr
update when there is a push to a repository.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>
2013-03-12 22:09:25 +00:00
Alberto Bertogli
c72278c97c Allow calling the executable from any directory
When the tool is invoked like /path/to/git-arr, it currently fails because
both the serving of static files and bottle templates assume they're on the
current working directory.

This patch fixes that by computing the directories based on the executable
location.

Note this is assuming the static directory and the templates live next to the
executable, which will not always be the case, and eventually it should be
configurable; but it's ok for the time being.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>
2013-03-10 00:55:56 +00:00
Alberto Bertogli
18e8599bfa Use "cloneurl" as a default for git_url
This patch makes git_url have the same default as gitweb.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>
2013-03-09 23:23:52 +00:00
Alberto Bertogli
c303c30755 Fix the "--only" option
This patch fixes the --only option, and makes it avoid generating the
top-level index so we don't get a broken one with only the specified
repositories.

The intention is that this option is used in hooks to update the views after a
commit or push.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>
2013-03-09 23:23:52 +00:00
Alberto Bertogli
9ec2bde5c4 Only guess the lexer if the file starts with "#!"
The lexer guesser based on content is often wrong; to minimize the chances of
that happening, we only use it on files that start with "#!", for which it
usually has smarter rules.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>
2012-11-27 02:57:31 +00:00
5 changed files with 111 additions and 17 deletions

39
git-arr
View File

@@ -5,6 +5,7 @@ git-arr: A git web html generator.
from __future__ import print_function
import sys
import os
import math
import optparse
@@ -20,6 +21,18 @@ import git
import utils
# Tell bottle where to find the views.
# Note this assumes they live next to the executable, and that is not a good
# assumption; but it's good enough for now.
bottle.TEMPLATE_PATH.insert(
0, os.path.abspath(os.path.dirname(sys.argv[0])) + '/views/')
# The path to our static files.
# Note this assumes they live next to the executable, and that is not a good
# assumption; but it's good enough for now.
static_path = os.path.abspath(os.path.dirname(sys.argv[0])) + '/static/'
# The list of repositories is a global variable for convenience. It will be
# populated by load_config().
repos = {}
@@ -41,7 +54,7 @@ def load_config(path):
'web_url': '',
'web_url_file': 'web_url',
'git_url': '',
'git_url_file': 'git_url',
'git_url_file': 'cloneurl',
}
config = configparser.SafeConfigParser(defaults)
@@ -240,14 +253,14 @@ def blob(repo, bname, fname, dirname = ''):
@bottle.route('/static/<path:path>')
def static(path):
return bottle.static_file(path, root = './static/')
return bottle.static_file(path, root = static_path)
#
# Static HTML generation
#
def generate(output):
def generate(output, skip_index = False):
"""Generate static html to the output directory."""
def write_to(path, func_or_str, args = (), mtime = None):
path = output + '/' + path
@@ -323,14 +336,15 @@ def generate(output):
(str(r.name), str(bn), oname.raw),
tree, (r, bn, oname.url), mtime)
write_to('index.html', index())
if not skip_index:
write_to('index.html', index())
# We can't call static() because it relies on HTTP headers.
read_f = lambda f: open(f).read()
write_to('static/git-arr.css', read_f, ['static/git-arr.css'],
os.stat('static/git-arr.css').st_mtime)
write_to('static/syntax.css', read_f, ['static/syntax.css'],
os.stat('static/syntax.css').st_mtime)
write_to('static/git-arr.css', read_f, [static_path + '/git-arr.css'],
os.stat(static_path + '/git-arr.css').st_mtime)
write_to('static/syntax.css', read_f, [static_path + '/syntax.css'],
os.stat(static_path + '/syntax.css').st_mtime)
for r in sorted(repos.values(), key = lambda r: r.name):
write_to('r/%s/index.html' % r.name, summary(r))
@@ -384,6 +398,7 @@ def main():
parser.add_option('-o', '--output', metavar = 'DIR',
help = 'output directory (for generate)')
parser.add_option('', '--only', metavar = 'REPO', action = 'append',
default = [],
help = 'generate/serve only this repository')
opts, args = parser.parse_args()
@@ -400,15 +415,17 @@ def main():
parser.error('Must specify an action (serve|generate)')
if opts.only:
global repos
repos = [ r for r in repos if r.name in opts.only ]
for rname in list(repos.keys()):
if rname not in opts.only:
del repos[rname]
if args[0] == 'serve':
bottle.run(host = 'localhost', port = 8008, reloader = True)
elif args[0] == 'generate':
if not opts.output:
parser.error('Must specify --output')
generate(output = opts.output)
generate(output = opts.output,
skip_index = len(opts.only) > 0)
else:
parser.error('Unknown action %s' % args[0])

14
hooks/README Normal file
View File

@@ -0,0 +1,14 @@
You can use the post-receive hook to automatically generate the repository
view after a push.
To do so, configure in your target repository the following options:
$ git config hooks.git-arr-config /path/to/site.conf
$ git config hooks.git-arr-output /var/www/git/
# Only if the git-arr executable is not on your $PATH.
$ git config hooks.git-arr-path /path/to/git-arr
Then copy the post-receive file to the "hooks" directory in your repository.

58
hooks/post-receive Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/sh
#
# git-arr post-receive hook
#
# This is a script intended to be used as a post-receive hook, which updates
# its git-arr view.
#
# You should place it /path/to/your/repository.git/hooks/.
# Config
# --------
#
# hooks.git-arr-config
# The git-arr configuration file to use. Mandatory.
# Example: /srv/git-arr/site.conf
#
# hooks.git-arr-output
# Directory for the generated output. Mandatory.
# Example: /srv/www/git/
#
# hooks.git-arr-path
# The path to the git-arr executable. Optional, defaults to "git-arr".
#
# hooks.git-arr-repo-name
# The git-arr repository name. Optional, defaults to the path name.
git_arr_config="$(git config --path hooks.git-arr-config)"
git_arr_output="$(git config --path hooks.git-arr-output)"
git_arr_path="$(git config --path hooks.git-arr-path 2> /dev/null)"
git_arr_repo_name="$(git config hooks.git-arr-repo-name 2> /dev/null)"
if [ -z "$git_arr_config" -o -z "$git_arr_output" ]; then
echo "Error: missing config options."
echo "Both hooks.git-arr-config and hooks.git-arr-output must be set."
exit 1
fi
if [ -z "$git_arr_path" ]; then
git_arr_path=git-arr
fi
if [ -z "$git_arr_repo_name" ]; then
PARENT_DIR=$(cd $(dirname "$0")/..; echo "$PWD")
git_arr_repo_name=$(basename "$PARENT_DIR")
fi
echo "Running git-arr"
$git_arr_path --config "$git_arr_config" generate \
--output "$git_arr_output" \
--only "$git_arr_repo_name" > /dev/null
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "Error running git-arr"
exit $RESULT
fi

View File

@@ -38,8 +38,8 @@ path = /srv/git/repo/
# File name to get the git URLs from (optional).
# If git_url is not set, attempt to get its value from this file.
# Default: "git_url"
#git_url_file = git_url
# Default: "cloneurl" (same as gitweb).
#git_url_file = cloneurl
# Do we look for repositories within this path? (optional).
# This option enables a recursive, 1 level search for repositories within the

View File

@@ -52,10 +52,15 @@ def colorize_blob(fname, s):
try:
lexer = lexers.guess_lexer_for_filename(fname, s, encoding = 'utf-8')
except lexers.ClassNotFound:
try:
lexer = lexers.guess_lexer(s[:200], encoding = 'utf-8')
except lexers.ClassNotFound:
lexer = lexers.TextLexer(encoding = 'utf-8')
# Only try to guess lexers if the file starts with a shebang,
# otherwise it's likely a text file and guess_lexer() is prone to
# make mistakes with those.
lexer = lexers.TextLexer(encoding = 'utf-8')
if s.startswith('#!'):
try:
lexer = lexers.guess_lexer(s[:80], encoding = 'utf-8')
except lexers.ClassNotFound:
pass
formatter = HtmlFormatter(encoding = 'utf-8',
cssclass = 'source_code',