summaryrefslogtreecommitdiff
path: root/localikiwikicreatesite
blob: c75d0d9ff181a7998327ab0e9b18d85cddd05ff4 (plain)
  1. #!/bin/sh
  2. #
  3. # /usr/local/bin/localikiwikicreatesite
  4. # Copyright 2008 Jonas Smedegaard <dr@jones.dk>
  5. #
  6. # $Id: localikiwikicreatesite,v 1.18 2008-06-03 11:20:16 jonas Exp $
  7. #
  8. # Initialize ikiwiki site
  9. #
  10. # Origin: http://ikiwiki.info/setup/
  11. #
  12. # TODO: Explicitly replace ~ with $HOME for shell use, and $ENV{'HOME'} for Perl
  13. # TODO: Quote variables everywhere
  14. # TODO: Implement --verbose and --quiet options (and fail if both are set)
  15. # TODO: Implement --force option
  16. # TODO: check for required helper commands (like make for originated sites)
  17. # TODO: when using origin, do these replacements on all setup files:
  18. # s/samplewiki/$project/
  19. # s/wiki\.example\.org/$host/
  20. # s/git\.example\.org/$srchost/
  21. # and when --wikiname, --adminemail and --user is implemented:
  22. # s/MyWiki/$wikiname/
  23. # s/me\@example\.org/$adminemail/
  24. # s/\bme\b/$user/
  25. # TODO: Print a final note on missing tasks:
  26. # * setup webserver
  27. # * setup Git server
  28. # * include Git hooks in main post-update hook of *_content Git
  29. # * enable Git post-update hooks of all Gits
  30. # * add git-daemon-export-ok file in all Gits
  31. # * write proper description in all Gits
  32. #
  33. set -e
  34. PRG=$(basename "$0")
  35. TEMP=$(getopt -s sh -o d:s:o:b:fh -l domain:,srcdomain:,origin:,branch:,force,help -n "$PRG" -- "$@")
  36. if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
  37. eval set -- "$TEMP"
  38. if [ -f /etc/local/ikiwiki.cfg ]; then
  39. . /etc/local/ikiwiki.cfg
  40. fi
  41. gitsrcuri="http://source.jones.dk"
  42. domain="${domain:-example.com}"
  43. srcdomain="$srcdomain"
  44. origin="$origin"
  45. branch="$branch"
  46. force="$force"
  47. showhelp() {
  48. cat <<EOF
  49. Usage: $PRG [opts...] PROJECT [HOST [SRCHOST]]
  50. Options:
  51. -d, --domain If HOST is a FQDN: Ignore the DOMAIN value.
  52. If HOST is a shortname: FQDN is HOST.DOMAIN.
  53. If HOST is omitted: FQDN is PROJECT.DOMAIN.
  54. (default: $domain)
  55. -s, --srcdomain If SRCHOST is a FQDN: Ignore the SRCDOMAIN value.
  56. If SRCHOST is a shortname: FQDN is HOST.SRCDOMAIN.
  57. If SRCHOST is omitted: FQDN is source.SRCDOMAIN.
  58. (default: ${srcdomain:-$domain without any leading www.})
  59. -o, --origin Clone Git repositories from origin as skeleton
  60. (default: ${origin:-do not clone.})
  61. -b, --branch Use this branch of cloned Git repository
  62. (default: ${branch:-Git default})
  63. -f, --force Update without asking for confirmation
  64. -h, --help This help text
  65. Examples:
  66. $PRG -d example.com wiki
  67. $PRG mysite www.example.com source.example.org
  68. $PRG -d example.com -o git://source.jones.dk/ikiwiki -b clean wiki
  69. EOF
  70. }
  71. exit1() {
  72. echo >&2 "Error: $1"
  73. echo >&2 "Exiting..."
  74. exit 1
  75. }
  76. ask() {
  77. echo -n "$1 (y/N)? "
  78. read response
  79. case "$response" in
  80. y|Y)
  81. :
  82. ;;
  83. *)
  84. return 1
  85. ;;
  86. esac
  87. return
  88. }
  89. git_setenv_work() {
  90. set -e
  91. targetdir="$1"
  92. shift
  93. export GIT_WORK_TREE="$targetdir"
  94. export GIT_DIR="$targetdir/.git"
  95. }
  96. git_unsetenv() {
  97. unset GIT_WORK_TREE
  98. unset GIT_DIR
  99. }
  100. git_init_pub() {
  101. repo="$DESTSRCDIR/$1.git"
  102. # export GIT_WORK_TREE="$repo"
  103. export GIT_DIR="$repo"
  104. mkdir -p $repo
  105. git --bare init --shared
  106. chmod +x $repo/hooks/post-update
  107. git_unsetenv
  108. }
  109. git_init_work() {
  110. set -e
  111. repo="$DESTSRCDIR/$1.git"
  112. targetdir="$2"
  113. shift 2
  114. git_setenv_work "$targetdir"
  115. git init
  116. for ignore in "$@"; do
  117. echo "$1" >> $targetdir/.gitignore
  118. done
  119. git add .
  120. git commit -m "initial commit"
  121. git remote add origin $repo
  122. git config branch.master.remote origin
  123. git config branch.master.merge refs/heads/master
  124. git push --all
  125. git_unsetenv
  126. }
  127. while true ; do
  128. case "$1" in
  129. -d|--domain) domain="$2"; shift 2;;
  130. -s|--srcdomain) srcdomain="$2"; shift 2;;
  131. -o|--origin) origin="$2"; shift 2;;
  132. -b|--branch) branch="$2"; shift 2;;
  133. -f|--force) force="1"; shift;;
  134. -h|--help) showhelp; exit 0;;
  135. --) shift; break;;
  136. *) exit1 "Internal error!";;
  137. esac
  138. done
  139. # Resolve FQDNs
  140. project="$1"
  141. [ -n "$project" ] || exit1 "Project name must be supplied!"
  142. host="$2"
  143. [ -n "$host" ] || host="$project"
  144. echo "$host" | grep -q '\.' || host="$host.$domain"
  145. srchost="$3"
  146. [ -n "$srchost" ] || srchost="source"
  147. if echo "$srchost" | grep -qv '\.'; then
  148. [ -n "$srcdomain" ] || srcdomain=$(echo "$host" | sed 's/^www\.//')
  149. srchost="$srchost.$srcdomain"
  150. fi
  151. SRCDIR=~/private_webdata/$project/content
  152. CFGDIR=~/private_webdata/$project
  153. DESTDIR=~/public_websites/$host
  154. DESTSRCDIR=~/public_websites/$srchost
  155. # Create parent if missing / remove if already existing
  156. # (eg. leave out SRCDIR if subdir of CFGDIR)
  157. mkdirchildlist="CFGDIR DESTDIR DESTSRCDIR"
  158. rmdirlist="CFGDIR DESTDIR DESTSRCDIR"
  159. mkdirchildfoundlist=''
  160. for item in $mkdirchildlist; do
  161. eval "childdir=\"\$$item\""
  162. parentdir="`dirname "$childdir"`"
  163. if [ ! -d "$parentdir" ]; then
  164. eval "mkdirchild_$item='(will create parent dir)'"
  165. mkdirchildfoundlist="$mkdirchildfoundlist $item"
  166. fi
  167. done
  168. rmdirfoundlist=''
  169. for item in $rmdirlist; do
  170. eval "dir=\"\$$item\""
  171. if [ -d "$dir" ]; then
  172. eval "rmdir_$item='(will replace existing!)'"
  173. rmdirfoundlist="$rmdirfoundlist $item"
  174. fi
  175. done
  176. if [ "$quiet" != 'yes' ]; then
  177. cat <<EOF
  178. You chose to make an iki site with the following settings:
  179. Project: $project
  180. Host: $host
  181. Sourcehost: $srchost
  182. The following directories will be added to your system:
  183. Project dir: $CFGDIR $rmdir_CFGDIR$mkdir_CFGDIR
  184. Content dir: $SRCDIR $rmdir_SRCDIR$mkdir_SRCDIR
  185. Central Git: $DESTSRCDIR $rmdir_DESTSRCDIR$mkdir_DESTSRCDIR
  186. Website dir: $DESTDIR $rmdir_DESTDIR$mkdir_DESTDIR
  187. EOF
  188. fi
  189. if [ -n "$mkdirchildfoundlist$rmdirfoundlist" ] || [ "$verbose" = 'yes' ]; then
  190. [ "$force" = 'yes' ] \
  191. || ask 'Continue' \
  192. || exit1 "User aborted (no changes made)"
  193. fi
  194. for item in $mkdirchildfoundlist; do
  195. eval "childdir=\"\$$item\""
  196. parentdir="`dirname "$childdir"`"
  197. if [ ! -d "$parentdir" ]; then
  198. mkdir -p "$parentdir"
  199. fi
  200. done
  201. for item in $rmdirfoundlist; do
  202. eval "dir=\"\$$item\""
  203. if [ -d "$dir" ]; then
  204. rm -rf "$dir"
  205. fi
  206. done
  207. ## Init public RCS repositories
  208. git_init_pub "$project"
  209. git_init_pub "${project}_content"
  210. ## Create initial basedir
  211. if [ -n "$origin" ]; then
  212. git clone $origin $CFGDIR
  213. git_setenv_work "$CFGDIR"
  214. if [ -n "$branch" ]; then
  215. git branch -f "$branch" "origin/$branch"
  216. git checkout "$branch"
  217. fi
  218. git config remote.origin.url "$DESTSRCDIR/$project.git"
  219. git push --all
  220. git_unsetenv
  221. else
  222. mkdir -p $CFGDIR
  223. cp /usr/share/doc/ikiwiki/html/ikiwiki.setup $CFGDIR
  224. fi
  225. ## Init working RCS repositories
  226. if [ -n "$origin" ]; then
  227. make -C $CFGDIR
  228. else
  229. git_init_work "$project" "$CFGDIR" "/content"
  230. fi
  231. ## Create initial content
  232. if ! [ -e $SRCDIR ]; then
  233. mkdir -p $SRCDIR
  234. cat <<'EOF' >$SRCDIR/index.mdwn
  235. Welcome to your new wiki.
  236. All wikis are supposed to have a <a href="../sandbox/">SandBox</a>,
  237. so this one does too.
  238. ----
  239. This wiki is powered by [ikiwiki](http://ikiwiki.info).
  240. EOF
  241. git_init_work "${project}_content" "$SRCDIR" "/.ikiwiki"
  242. fi
  243. ## Adjust backend to actual paths, and enable Git post-update wrapper
  244. # TODO: Rewrite as semi-generic functions:
  245. #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "srcdir" "$SRCDIR"
  246. #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "destdir" "$DESTDIR"
  247. #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "url" "$host"
  248. #perl_param_disable "$CFGDIR/ikiwiki.setup" "cgiurl"
  249. #perl_param_match_enable "$CFGDIR/ikiwiki.setup" "rcs" "git"
  250. #perl_section_match_enable_param_set "$CFGDIR/ikiwiki.setup" "git post-update wrapper" "wrapper" "$DESTSRCDIR/${project}_content.git/hooks/post-update-$project"
  251. #perl_section_match_enable_param_match_enable "$CFGDIR/ikiwiki.setup" "git post-update wrapper" "wrappermode" "06755"
  252. #shell_line_match_enable_appendlinebefore "$DESTSRCDIR/${project}_content.git/hooks/post-update" "^exec" "hooks/post-update-$project\n"
  253. perl -pi -e '
  254. s,^(\s*)#?(srcdir\s*=>\s*")[^"]*("\,\s*),$1$2'$SRCDIR'$3,;
  255. s,^(\s*)#?(destdir\s*=>\s*")[^"]*("\,\s*),$1$2'$DESTDIR'$3,;
  256. s,^(\s*)#?(url\s*=>\s*")[^"]*("\,\s*),$1$2http://'$host'$3,;
  257. s,^(\s*)#?(cgiurl\s*=>\s*")([^"]*)("\,\s*),$1#$2$3$4,;
  258. s,^(\s*)#?(rcs\s*=>\s*")(git)("\,\s*),$1$2$3$4,;
  259. ' $CFGDIR/ikiwiki.setup
  260. perl -0 -pi -e '
  261. s,#{([\s#]*The git post-update wrapper[^}]*\s*)#(\s*wrapper =>\s*")[^"]*("\,\s*[^}]*)#(\s*wrappermode =>[^}]*)#},{$1$2'$DESTSRCDIR/${project}_content.git/hooks/post-update-$project'$3$4},;
  262. ' $CFGDIR/ikiwiki.setup
  263. perl -0 -pi -e '
  264. s,\n(exec\s[^\n]*),\nhooks/post-update-'"$project"'\n\n$1,;
  265. ' $DESTSRCDIR/${project}_content.git/hooks/post-update
  266. git_setenv_work "$CFGDIR"
  267. git add ikiwiki.setup
  268. git commit -m "Adjust ikiwiki.setup to use actual paths, and add+enable Git post-update hooks"
  269. git_unsetenv
  270. ## Add Makefile for further customization
  271. if ! [ -e $CFGDIR/Makefile ]; then
  272. cat <<EOF >$CFGDIR/Makefile
  273. #underlays = basewiki smiley templates
  274. underlays = templates
  275. #locale = danish
  276. master = master
  277. #master = master-LOCALE
  278. all: \$(underlays)
  279. \$(underlays):
  280. mkdir \$@
  281. cd \$@ && git init
  282. cd \$@ && git remote add -f -t \$(master:LOCALE=\$(locale)) -m \$(master:LOCALE=\$(locale)) origin $gitsrcuri/${project}_\$@.git
  283. cd \$@ && git merge origin
  284. EOF
  285. git_setenv_work "$CFGDIR"
  286. git add Makefile
  287. git commit -m "Setup local paths"
  288. git_unsetenv
  289. fi
  290. if [ -n "$origin" ]; then
  291. make -C $CFGDIR install
  292. else
  293. ikiwiki --verbose $SRCDIR $DESTDIR --url=http://"$host" --setup $CFGDIR/ikiwiki.setup
  294. fi
  295. git_setenv_work "$CFGDIR"
  296. git push
  297. git_unsetenv