- #!/bin/sh
- #
- # /usr/local/bin/localikiwikicreatesite
- # Copyright 2008 Jonas Smedegaard <dr@jones.dk>
- #
- # $Id: localikiwikicreatesite,v 1.18 2008-06-03 11:20:16 jonas Exp $
- #
- # Initialize ikiwiki site
- #
- # Origin: http://ikiwiki.info/setup/
- #
- # TODO: Explicitly replace ~ with $HOME for shell use, and $ENV{'HOME'} for Perl
- # TODO: Quote variables everywhere
- # TODO: Implement --verbose and --quiet options (and fail if both are set)
- # TODO: Implement --force option
- # TODO: check for required helper commands (like make for originated sites)
- # TODO: when using origin, do these replacements on all setup files:
- # s/samplewiki/$project/
- # s/wiki\.example\.org/$host/
- # s/git\.example\.org/$srchost/
- # and when --wikiname, --adminemail and --user is implemented:
- # s/MyWiki/$wikiname/
- # s/me\@example\.org/$adminemail/
- # s/\bme\b/$user/
- # TODO: Print a final note on missing tasks:
- # * setup webserver
- # * setup Git server
- # * include Git hooks in main post-update hook of *_content Git
- # * enable Git post-update hooks of all Gits
- # * add git-daemon-export-ok file in all Gits
- # * write proper description in all Gits
- #
- set -e
- PRG=$(basename "$0")
- TEMP=$(getopt -s sh -o d:s:o:b:fh -l domain:,srcdomain:,origin:,branch:,force,help -n "$PRG" -- "$@")
- if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
- eval set -- "$TEMP"
- if [ -f /etc/local/ikiwiki.cfg ]; then
- . /etc/local/ikiwiki.cfg
- fi
- gitsrcuri="http://source.jones.dk"
- domain="${domain:-example.com}"
- srcdomain="$srcdomain"
- origin="$origin"
- branch="$branch"
- force="$force"
- showhelp() {
- cat <<EOF
- Usage: $PRG [opts...] PROJECT [HOST [SRCHOST]]
- Options:
- -d, --domain If HOST is a FQDN: Ignore the DOMAIN value.
- If HOST is a shortname: FQDN is HOST.DOMAIN.
- If HOST is omitted: FQDN is PROJECT.DOMAIN.
- (default: $domain)
- -s, --srcdomain If SRCHOST is a FQDN: Ignore the SRCDOMAIN value.
- If SRCHOST is a shortname: FQDN is HOST.SRCDOMAIN.
- If SRCHOST is omitted: FQDN is source.SRCDOMAIN.
- (default: ${srcdomain:-$domain without any leading www.})
- -o, --origin Clone Git repositories from origin as skeleton
- (default: ${origin:-do not clone.})
- -b, --branch Use this branch of cloned Git repository
- (default: ${branch:-Git default})
- -f, --force Update without asking for confirmation
- -h, --help This help text
- Examples:
- $PRG -d example.com wiki
- $PRG mysite www.example.com source.example.org
- $PRG -d example.com -o git://source.jones.dk/ikiwiki -b clean wiki
- EOF
- }
- exit1() {
- echo >&2 "Error: $1"
- echo >&2 "Exiting..."
- exit 1
- }
- ask() {
- echo -n "$1 (y/N)? "
- read response
- case "$response" in
- y|Y)
- :
- ;;
- *)
- return 1
- ;;
- esac
- return
- }
- git_setenv_work() {
- set -e
- targetdir="$1"
- shift
- export GIT_WORK_TREE="$targetdir"
- export GIT_DIR="$targetdir/.git"
- }
- git_unsetenv() {
- unset GIT_WORK_TREE
- unset GIT_DIR
- }
- git_init_pub() {
- repo="$DESTSRCDIR/$1.git"
- # export GIT_WORK_TREE="$repo"
- export GIT_DIR="$repo"
- mkdir -p $repo
- git --bare init --shared
- chmod +x $repo/hooks/post-update
- git_unsetenv
- }
- git_init_work() {
- set -e
- repo="$DESTSRCDIR/$1.git"
- targetdir="$2"
- shift 2
- git_setenv_work "$targetdir"
- git init
- for ignore in "$@"; do
- echo "$1" >> $targetdir/.gitignore
- done
- git add .
- git commit -m "initial commit"
- git remote add origin $repo
- git config branch.master.remote origin
- git config branch.master.merge refs/heads/master
- git push --all
- git_unsetenv
- }
- while true ; do
- case "$1" in
- -d|--domain) domain="$2"; shift 2;;
- -s|--srcdomain) srcdomain="$2"; shift 2;;
- -o|--origin) origin="$2"; shift 2;;
- -b|--branch) branch="$2"; shift 2;;
- -f|--force) force="1"; shift;;
- -h|--help) showhelp; exit 0;;
- --) shift; break;;
- *) exit1 "Internal error!";;
- esac
- done
- # Resolve FQDNs
- project="$1"
- [ -n "$project" ] || exit1 "Project name must be supplied!"
- host="$2"
- [ -n "$host" ] || host="$project"
- echo "$host" | grep -q '\.' || host="$host.$domain"
- srchost="$3"
- [ -n "$srchost" ] || srchost="source"
- if echo "$srchost" | grep -qv '\.'; then
- [ -n "$srcdomain" ] || srcdomain=$(echo "$host" | sed 's/^www\.//')
- srchost="$srchost.$srcdomain"
- fi
- SRCDIR=~/private_webdata/$project/content
- CFGDIR=~/private_webdata/$project
- DESTDIR=~/public_websites/$host
- DESTSRCDIR=~/public_websites/$srchost
- # Create parent if missing / remove if already existing
- # (eg. leave out SRCDIR if subdir of CFGDIR)
- mkdirchildlist="CFGDIR DESTDIR DESTSRCDIR"
- rmdirlist="CFGDIR DESTDIR DESTSRCDIR"
- mkdirchildfoundlist=''
- for item in $mkdirchildlist; do
- eval "childdir=\"\$$item\""
- parentdir="`dirname "$childdir"`"
- if [ ! -d "$parentdir" ]; then
- eval "mkdirchild_$item='(will create parent dir)'"
- mkdirchildfoundlist="$mkdirchildfoundlist $item"
- fi
- done
- rmdirfoundlist=''
- for item in $rmdirlist; do
- eval "dir=\"\$$item\""
- if [ -d "$dir" ]; then
- eval "rmdir_$item='(will replace existing!)'"
- rmdirfoundlist="$rmdirfoundlist $item"
- fi
- done
- if [ "$quiet" != 'yes' ]; then
- cat <<EOF
- You chose to make an iki site with the following settings:
- Project: $project
- Host: $host
- Sourcehost: $srchost
- The following directories will be added to your system:
- Project dir: $CFGDIR $rmdir_CFGDIR$mkdir_CFGDIR
- Content dir: $SRCDIR $rmdir_SRCDIR$mkdir_SRCDIR
- Central Git: $DESTSRCDIR $rmdir_DESTSRCDIR$mkdir_DESTSRCDIR
- Website dir: $DESTDIR $rmdir_DESTDIR$mkdir_DESTDIR
-
- EOF
- fi
- if [ -n "$mkdirchildfoundlist$rmdirfoundlist" ] || [ "$verbose" = 'yes' ]; then
- [ "$force" = 'yes' ] \
- || ask 'Continue' \
- || exit1 "User aborted (no changes made)"
- fi
- for item in $mkdirchildfoundlist; do
- eval "childdir=\"\$$item\""
- parentdir="`dirname "$childdir"`"
- if [ ! -d "$parentdir" ]; then
- mkdir -p "$parentdir"
- fi
- done
- for item in $rmdirfoundlist; do
- eval "dir=\"\$$item\""
- if [ -d "$dir" ]; then
- rm -rf "$dir"
- fi
- done
- ## Init public RCS repositories
- git_init_pub "$project"
- git_init_pub "${project}_content"
- ## Create initial basedir
- if [ -n "$origin" ]; then
- git clone $origin $CFGDIR
- git_setenv_work "$CFGDIR"
- if [ -n "$branch" ]; then
- git branch -f "$branch" "origin/$branch"
- # git checkout ignores GIT_DIR and GIT_WORKING_TREE
- ( cd "$CFGDIR" && git checkout "$branch" )
- fi
- git config remote.origin.url "$DESTSRCDIR/$project.git"
- git push --all
- git_unsetenv
- else
- mkdir -p $CFGDIR
- cp /usr/share/doc/ikiwiki/html/ikiwiki.setup $CFGDIR
- fi
- ## Init working RCS repositories
- if [ -n "$origin" ]; then
- make -C $CFGDIR
- else
- git_init_work "$project" "$CFGDIR" "/content"
- fi
- ## Create initial content
- if ! [ -e $SRCDIR ]; then
- mkdir -p $SRCDIR
- cat <<'EOF' >$SRCDIR/index.mdwn
- Welcome to your new wiki.
- All wikis are supposed to have a <a href="../sandbox/">SandBox</a>,
- so this one does too.
- ----
- This wiki is powered by [ikiwiki](http://ikiwiki.info).
- EOF
- git_init_work "${project}_content" "$SRCDIR" "/.ikiwiki"
- fi
- ## Adjust backend to actual paths, and enable Git post-update wrapper
- git_setenv_work "$CFGDIR"
- # TODO: Rewrite as semi-generic functions:
- #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "srcdir" "$SRCDIR"
- #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "destdir" "$DESTDIR"
- #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "url" "$host"
- #perl_param_disable "$CFGDIR/ikiwiki.setup" "cgiurl"
- #perl_param_match_enable "$CFGDIR/ikiwiki.setup" "rcs" "git"
- #perl_section_match_enable_param_set "$CFGDIR/ikiwiki.setup" "git post-update wrapper" "wrapper" "$DESTSRCDIR/${project}_content.git/hooks/post-update-$project"
- #perl_section_match_enable_param_match_enable "$CFGDIR/ikiwiki.setup" "git post-update wrapper" "wrappermode" "06755"
- #shell_line_match_enable_appendlinebefore "$DESTSRCDIR/${project}_content.git/hooks/post-update" "^exec" "hooks/post-update-$project\n"
- for cfgfile in $CFGDIR/ikiwiki*.setup; do
- perl -pi -e "
- s,samplewiki,$project,g;
- s,wiki\.example\.org,$host,g;
- s,git\.example\.org,$srchost,g;
- s,^(\s*)#?(rcs\s*=>\s*')[^']*('\,\s*),\$1\$2git\$3,;
- s,^(\s*)#?(git_wrapper\s*=>),\$1\$2,;
- s,^(\s*)#?(git_wrappermode\s*=>),\$1\$2,;
- " "$cfgfile"
- git add "$(basename "$cfgfile")"
- done
- if [ -n "$origin" ]; then
- git commit -m "Adjust config files to use actual paths, and enable Git hooks."
- else
- perl -pi -e "
- s,^(\s*)#?(srcdir\s*=>\s*')[^']*('\,\s*),\$1\$2$SRCDIR\$3,;
- s,^(\s*)#?(destdir\s*=>\s*')[^']*('\,\s*),\$1\$2$DESTDIR\$3,;
- s,^(\s*)#?(url\s*=>\s*')[^']*('\,\s*),\$1\$2http://$host\$3,;
- s,^(\s*)#?(cgiurl\s*=>\s*')([^']*)('\,\s*),\$1#\$2\$3\$4,;
- s,^(\s*)#?(git_wrapper\s*=>\s*')([^']*)('\,\s*),\$1\$2$DESTSRCDIR/${project}_content.git/hooks/post-update-ikiwiki\$4,;
- " $CFGDIR/ikiwiki.setup
- git add ikiwiki.setup
- git commit -m "Add customized config file with Git hook enabled."
- fi
- git_unsetenv
- # Attach hooks to general post-update hook
- # FIXME: Attach localized before master configs, and admin before non-admin
- for hookfile in $DESTSRCDIR/${project}_content.git/hooks/post-update-*; do
- perl -0 -pi -e "
- s,\n(exec\s[^\n]*),\nhooks/$(basename "$hookfile")\n\n\$1,;
- " $DESTSRCDIR/${project}_content.git/hooks/post-update
- done
- ## Add Makefile for further customization
- if ! [ -e $CFGDIR/Makefile ]; then
- cat <<EOF >$CFGDIR/Makefile
- #underlays = basewiki smiley templates
- underlays = templates
- #locale = danish
- master = master
- #master = master-LOCALE
- all: \$(underlays)
- \$(underlays):
- mkdir \$@
- cd \$@ && git init
- cd \$@ && git remote add -f -t \$(master:LOCALE=\$(locale)) -m \$(master:LOCALE=\$(locale)) origin $gitsrcuri/${project}_\$@.git
- cd \$@ && git merge origin
- EOF
- git_setenv_work "$CFGDIR"
- git add Makefile
- git commit -m "Setup local paths"
- git_unsetenv
- fi
- if [ -n "$origin" ]; then
- make -C $CFGDIR install
- else
- ikiwiki --verbose $SRCDIR $DESTDIR --url=http://"$host" --setup $CFGDIR/ikiwiki.setup
- fi
- git_setenv_work "$CFGDIR"
- git push
- git_unsetenv
|