#!/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=( virtualenv libapache2-mod-python )


######
# 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 Babel Trac \
			https://trac-hacks.org/svn/masterticketsplugin/tags/mastertickets-4.0.0/
	) >logs/init.log 2>&1
	run_popd
}

trac_site_delete() {
	run rm -rfv "$trac_root"
}

trac_site_datadir() { echo "$trac_root/data"; }


######
# 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() {
	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_new() {
	has_args 3 "$@"
	local host=$1
	local name=$2
	local desc=$3

	trac_project_exists "${@:0: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"

	run cd "$name"

	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
}


######
# 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_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_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"
}

# 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"
}


######
# 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 "$@"
}

View the Developer Guide Index

View the Reference Manual Index


Generated on Wed Jun 28 07:40:12 PDT 2017 by mcsh d14 v0.20.0.