#!/bin/bash
# trac.in - Trac support
set -e
lib_load 'sys/tool/virtualenv'
######
# Settings
net_tool_trac_config_init() {
lib_setting_vars trac_host trac_root trac_admin
lib_setting_vars --null trac_group
lib_setting_vars -ro trac_owner trac_db
lib_setting_vars -ro trac_wsgi_script
lib_setting_arrays -ro trac_site_dirs
trac_site_dirs=( conf eggs logs data wsgi )
}
net_tool_trac_config_check() {
export PYTHON_EGG_CACHE="$trac_root/eggs"
trac_wsgi_script="${trac_wsgi_script:-$trac_root/wsgi/trac.wsgi}"
}
######
# Native dependencies
# FIXME: need wsgi deps
trac_server_packages=( libapache2-mod-python libldap2-dev libsasl2-dev )
# $trac_python_packages[] - List of Python packages to run Trac
trac_python_packages=(
Babel
Trac
TracMasterTickets
python-ldap
https://trac-hacks.org/svn/ldapplugin/0.12
)
######
# Admin
trac_admin() {
ve_activate "$trac_root"
run trac-admin $(pwd) "$@"
}
######
# Site
is_site_owner() { [ "$USER" = "$trac_owner" ]; }
is_site_dir() { test -d "${1:-.}/wsgi"; }
trac_site_wsgi() {
has_args 2 "$@"
echo "$trac_root/wsgi/$1-$2.py"
}
trac_site_init() {
# create and change to site directory
[ -d "$trac_root" ] || run_mkdir "$trac_root"
run_pushd "$trac_root"
run_mkdir "${trac_site_dirs[@]}"
# create/update virtual machine
(
ve_create "$trac_root"
ve_activate "$trac_root"
ve_install "${trac_python_packages[@]}"
) 2>&1 | tee logs/init.log
run_popd
}
trac_site_delete() {
run rm -rfv "$trac_root"
}
trac_site_datadir() { echo "$trac_root/data"; }
######
# Project Groups
trac_project_groups() { file_readdir "$(trac_site_datadir)"; }
trac_project_groupdir() { has_args 1 "$@"; echo "$(trac_site_datadir)/$1"; }
trac_project_group_projects() { file_readdir "$(trac_project_groupdir "$@")"; }
######
# Projects
# trac_project_dir() - Prints name of project directory for given host
# ($1) and project name ($2).
trac_project_dir() {
has_args 2 "$@"
echo "$(trac_site_datadir)/$1/$2"
}
# trac_project_run() - Run a command in the given project directory.
# $1 - Project group
# $2 - Project name
trac_project_run() {
min_args 3 "$@"
local dir
dir=$(trac_project_dir "$1" "$2")
shift 2
run_in_dir "$dir" "$@"
}
# trac_project_exists() - Checks whether a project eixsts
# $1 - Project group
# $2 - Project name
trac_project_exists() {
has_args 2 "$@"
local dir
dir=$(trac_project_dir "$@")
[ -f "$dir/VERSION" ]
}
# trac_project_config_file() - Prints project configuration file name
# $1 - Project group
# $2 - Project name
trac_project_config_file() {
local dir
dir=$(trac_project_dir "$@")
echo "$dir/conf/trac.ini"
}
# trac_project_log_file() - Prints project log file name
# $1 - Project group
# $2 - Project name
# $3 - Log name (default: ``trac.log``)
trac_project_log_file() {
min_max_args 2 3 "$@"
local dir
dir=$(trac_project_dir "$1" "$2")
local file=${3:-trac.log}
echo "$dir/log/$file"
}
trac_project_new() {
has_args 3 "$@"
local host=$1
local name=$2
local desc=$3
! trac_project_exists "$1" "$2" || error "$host/$name: project exists"
app_echo "$host/$name: creating project directory"
local pdir
pdir="$(trac_site_datadir)/$host/$name"
run_mkdir "$pdir"
run_pushd "$pdir"
app_echo "$host/$name: running trac-admin to create project"
local log
log=$(cmd_tempfile)
trac_admin initenv "$desc" "$trac_db" 2>&1 | tee "$log"
run mv "$log" log/init.log
run_popd
}
trac_project_delete() {
has_args 2 "$@"
local host=$1
local name=$2
trac_project_disable "$@"
local dir
dir=$(trac_project_dir "$@")
run rm -rf "$dir"
}
trac_project_enable() {
has_args 2 "$@"
local host=$1
local name=$2
local wsgi
wsgi=$(trac_site_wsgi "$@")
if [ -L "$wsgi" ]; then
warn "$host/$name: project already enabled"
else
run ln -s "$trac_wsgi_script" "$wsgi"
info "$host/$name: project enabled"
fi
}
trac_project_disable() {
has_args 2 "$@"
local host=$1
local name=$2
local wsgi
wsgi=$(trac_site_wsgi "$@")
if [ -L "$wsgi" ]; then
run rm "$wsgi"
info "$host/$name: project disabled"
else
warn "$host/$name: project was not enabled"
fi
}
######
# Permissions
# trac_project_perm_add() - Grants permissions to a user ($3) for the
# given group ($1) project ($2).
trac_project_perm_add() {
local pgroup=$1
local pname=$2
local puser=$3
shift 3
trac_project_run "$pgroup" "$pname" \
for_each "trac_admin permission add $puser" "$@"
}
######
# Repositories
# trac_repos_dir() - Prints path to a Trac-hosted repository.
# $1 - Group name
# $2 - Project name
# $3 - Repository name
trac_repos_dir() {
min_max_args 2 3 "$@"
local tgroup=$1
local tproj=$2
local trepo=$3
local pdir
pdir=$(trac_project_dir "$1" "$2")
local ppath
[ -z "$3" ] || ppath="/$3.git"
echo "$pdir/repos$ppath"
}
# trac_repo_exists() - Returns success if a repository exists for a project
# $1 - Group name
# $2 - Project name
# $3 - Repository name
trac_repo_exists() { [ -d "$(trac_repos_dir "$@")" ]; }
# trac_repo_clone() - Clones a repository from a URL into a project
# $1 - Group name
# $2 - Project name
# $3 - Repository name
# $4 - Repository URL
trac_repo_clone() {
has_args 4 "$@"
local rpath
rpath=$(trac_repos_dir "$1" "$2" "$3")
[ ! -d "$rpath" ] || error "$rpath: repository exists"
lib_load 'sys/tool/git'
git_clone --bare "$4" "$rpath"
}
# trac_repo_update() - Updates a repository for a project
# $1 - Group name
# $2 - Project name
# $3 - Repository name
trac_repo_update() {
has_args 3 "$@"
local rpath
rpath=$(trac_repos_dir "$1" "$2" "$3")
[ -d "$rpath" ] || error "$rpath: repository does not exists"
lib_load 'sys/tool/git'
run_in_dir "$rpath" git_fetch
trac_repo_sync "$@"
}
# trac_repo_delete() - Deletes a repository from a project
# $1 - Group name
# $2 - Project name
# $3 - Repository name
trac_repo_delete() {
has_args 3 "$@"
local rdir
rdir=$(trac_repos_dir "$@")
run rm -rf "$rdir"
}
# trac_repo_sync() - Deletes a repository from a project
# $1 - Group name
# $2 - Project name
# $3 - Repository name
trac_repo_sync() {
has_args 3 "$@"
trac_project_run "$1" "$2" trac_admin repository resync "$3"
}
# trac_repo_hook_init() - Creates a Git repository hook file, taking
# input from `stdin`.
# $1 - Group name
# $2 - Project name
# $3 - Repository name
# $4 - Hook name
trac_repo_hook_init() {
has_args 4 "$@"
local rdir
rdir=$(trac_repos_dir "$1" "$2")
local hookfile="$rdir/$3.git/hooks/$4"
cat >"$hookfile"
run chmod a+x "$hookfile"
}
# trac_repo_post_commit() - Runs the post-commit hook to update Trac.
# input from `stdin`.
# $1 - Group name
# $2 - Project name
# $3 - Repository name
# $4 - Revision
trac_repo_post_commit() {
has_args 4 "$@"
trac_project_run "$1" "$2" trac_admin changeset added "$3" "$4"
}
# trac_repo_post_receive() - Runs the post-receive hook to update Trac.
# input from `stdin`.
# $1 - Group name
# $2 - Project name
# $3 - Repository name
trac_repo_post_receive() {
has_args 3 "$@"
local oldrev newrev refname
while read oldrev newrev refname; do
if [ "$oldrev" = 0000000000000000000000000000000000000000 ]; then
git rev-list --reverse "$newrev" --
else
git rev-list --reverse "$newrev" "^$oldrev" --
fi | xargs trac_repo_post_commit "$@"
done
}
######
# CLI
trac_dispatch() {
is_site_owner || error "must be run by site owner ($trac_owner)"
is_site_dir || error "must be run in the trac site directory"
ve_activate
cmd_dispatch "$@"
}
Generated on Tue Jul 4 17:00:55 PDT 2017 by mcsh d14 v0.21.0.