#!/bin/bash
# net/tool/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 -ro trac_owner trac_group 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_group=${trac_group:-$trac_owner}
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
https://trac-hacks.org/svn/accountmanagerplugin/trunk
https://trac-hacks.org/svn/usermanagerplugin/1.2
python-ldap
https://trac-hacks.org/svn/ldapacctmngrplugin/trunk/ldapacctmngrplugin
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() {
local ddir
ddir=$(trac_site_datadir)
file_readdir "$ddir"
}
trac_project_groupdir() { has_args 1 "$@"; echo "$(trac_site_datadir)/$1"; }
# for_each_trac_group() - Calls a function ($@) with each project
# group in the current Trac site.
for_each_trac_group() {
min_args 1 "$@"
local -a groups
groups=( $(trac_project_groups) )
for_each "$*" "${groups[@]}"
}
######
# Projects
trac_projects() {
local gdir
gdir=$(trac_project_groupdir "$@")
file_readdir "$gdir"
}
# for_each_trac_project() - Calls a function ($@) with each project
# in the given project group ($1).
for_each_trac_project() {
min_args 2 "$@"
local group=$1
shift
local -a projects
projects=( $(trac_projects "$group") )
for_each "$*" "${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 pdir
pdir=$(trac_project_dir "$1" "$2")
local ppath
[ -z "$3" ] || ppath="/$3.git"
echo "$pdir/repos$ppath"
}
# trac_project_repos() - Prints list of repositories
trac_project_repos() {
local rdir
rdir=$(trac_repos_dir "$@")
[ -d "$rdir" ] || return 0
file_readdir "$rdir" |sed -e 's,\.git,,'
}
# for_each_trac_repo() - Calls a function ($@) with each repository
# in the given group ($1) project ($2).
for_each_trac_repo() {
min_args 3 "$@"
local group=$1
local project=$2
shift 2
local -a repos
repos=( $(trac_project_repos "$group" "$project") )
for_each "$*" "${repos[@]}"
}
# trac_project_run() - Run a command in the given project directory.
# $1 - Group name
# $2 - Project name
# $3 - Repository name
# $@ - Command to run
trac_repo_run() {
min_args 4 "$@"
local dir
dir=$(trac_repos_dir "$1" "$2" "$3")
shift 3
[ -d "$dir" ] || error "$dir: repository does not exist"
run_in_dir "$dir" "$@"
}
# 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 "$@"
lib_load 'sys/tool/git'
trac_repo_run "$@" 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() - Synchronizes the specified project repository
# $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" "$3")
local hookfile="$rdir/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
}
######
# Cron support
# trac_cron_run() - Runs all periodic Trac tasks
trac_cron_run() {
for_each_trac_group trac_cron_group_run
}
trac_cron_group_run() {
for_each_trac_project "$1" trac_cron_project_run "$1"
}
trac_cron_project_run() {
for_each_trac_repo "$1" "$2" trac_cron_repo_run "$1" "$2"
}
trac_cron_repo_run() {
trac_repo_update "$1" "$2" "$3"
}
######
# Command Support
# trac_dispatch() - Dispatches tool command after activating virtual
# environment for the site.
# $@ - Command and arguments to dispatch
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 Fri Jul 28 14:35:53 PDT 2017 by mcsh d14 v0.23.0.