summaryrefslogtreecommitdiff
path: root/localikiwikicreatesite
blob: fbb2935ffcf56df775f79adff979d6af74d48993 (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 ignores GIT_DIR and GIT_WORKING_TREE
  217. ( cd "$CFGDIR" && git checkout "$branch" )
  218. fi
  219. git config remote.origin.url "$DESTSRCDIR/$project.git"
  220. git push --all
  221. git_unsetenv
  222. else
  223. mkdir -p $CFGDIR
  224. cp /usr/share/doc/ikiwiki/html/ikiwiki.setup $CFGDIR
  225. fi
  226. ## Init working RCS repositories
  227. if [ -n "$origin" ]; then
  228. make -C $CFGDIR
  229. else
  230. git_init_work "$project" "$CFGDIR" "/content"
  231. fi
  232. ## Create initial content
  233. if ! [ -e $SRCDIR ]; then
  234. mkdir -p $SRCDIR
  235. cat <<'EOF' >$SRCDIR/index.mdwn
  236. Welcome to your new wiki.
  237. All wikis are supposed to have a <a href="../sandbox/">SandBox</a>,
  238. so this one does too.
  239. ----
  240. This wiki is powered by [ikiwiki](http://ikiwiki.info).
  241. EOF
  242. git_init_work "${project}_content" "$SRCDIR" "/.ikiwiki"
  243. fi
  244. ## Adjust backend to actual paths, and enable Git post-update wrapper
  245. git_setenv_work "$CFGDIR"
  246. # TODO: Rewrite as semi-generic functions:
  247. #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "srcdir" "$SRCDIR"
  248. #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "destdir" "$DESTDIR"
  249. #perl_param_enable_set "$CFGDIR/ikiwiki.setup" "url" "$host"
  250. #perl_param_disable "$CFGDIR/ikiwiki.setup" "cgiurl"
  251. #perl_param_match_enable "$CFGDIR/ikiwiki.setup" "rcs" "git"
  252. #perl_section_match_enable_param_set "$CFGDIR/ikiwiki.setup" "git post-update wrapper" "wrapper" "$DESTSRCDIR/${project}_content.git/hooks/post-update-$project"
  253. #perl_section_match_enable_param_match_enable "$CFGDIR/ikiwiki.setup" "git post-update wrapper" "wrappermode" "06755"
  254. #shell_line_match_enable_appendlinebefore "$DESTSRCDIR/${project}_content.git/hooks/post-update" "^exec" "hooks/post-update-$project\n"
  255. for cfgfile in $CFGDIR/ikiwiki*.setup; do
  256. perl -pi -e "
  257. s,samplewiki,$project,g;
  258. s,wiki\.example\.org,$host,g;
  259. s,git\.example\.org,$srchost,g;
  260. s,^(\s*)#?(rcs\s*=>\s*')[^']*('\,\s*),\$1\$2git\$3,;
  261. s,^(\s*)#?(git_wrapper\s*=>),\$1\$2,;
  262. s,^(\s*)#?(git_wrappermode\s*=>),\$1\$2,;
  263. " "$cfgfile"
  264. git add "$(basename "$cfgfile")"
  265. done
  266. if [ -n "$origin" ]; then
  267. git commit -m "Adjust config files to use actual paths, and enable Git hooks."
  268. else
  269. perl -pi -e "
  270. s,^(\s*)#?(srcdir\s*=>\s*')[^']*('\,\s*),\$1\$2$SRCDIR\$3,;
  271. s,^(\s*)#?(destdir\s*=>\s*')[^']*('\,\s*),\$1\$2$DESTDIR\$3,;
  272. s,^(\s*)#?(url\s*=>\s*')[^']*('\,\s*),\$1\$2http://$host\$3,;
  273. s,^(\s*)#?(cgiurl\s*=>\s*')([^']*)('\,\s*),\$1#\$2\$3\$4,;
  274. s,^(\s*)#?(git_wrapper\s*=>\s*')([^']*)('\,\s*),\$1\$2$DESTSRCDIR/${project}_content.git/hooks/post-update-ikiwiki\$4,;
  275. " $CFGDIR/ikiwiki.setup
  276. git add ikiwiki.setup
  277. git commit -m "Add customized config file with Git hook enabled."
  278. fi
  279. git_unsetenv
  280. # Attach hooks to general post-update hook
  281. # FIXME: Attach localized before master configs, and admin before non-admin
  282. for hookfile in $DESTSRCDIR/${project}_content.git/hooks/post-update-*; do
  283. perl -0 -pi -e "
  284. s,\n(exec\s[^\n]*),\nhooks/$(basename "$hookfile")\n\n\$1,;
  285. " $DESTSRCDIR/${project}_content.git/hooks/post-update
  286. done
  287. ## Add Makefile for further customization
  288. if ! [ -e $CFGDIR/Makefile ]; then
  289. cat <<EOF >$CFGDIR/Makefile
  290. #underlays = basewiki smiley templates
  291. underlays = templates
  292. #locale = danish
  293. master = master
  294. #master = master-LOCALE
  295. all: \$(underlays)
  296. \$(underlays):
  297. mkdir \$@
  298. cd \$@ && git init
  299. cd \$@ && git remote add -f -t \$(master:LOCALE=\$(locale)) -m \$(master:LOCALE=\$(locale)) origin $gitsrcuri/${project}_\$@.git
  300. cd \$@ && git merge origin
  301. EOF
  302. git_setenv_work "$CFGDIR"
  303. git add Makefile
  304. git commit -m "Setup local paths"
  305. git_unsetenv
  306. fi
  307. if [ -n "$origin" ]; then
  308. make -C $CFGDIR install
  309. else
  310. ikiwiki --verbose $SRCDIR $DESTDIR --url=http://"$host" --setup $CFGDIR/ikiwiki.setup
  311. fi
  312. git_setenv_work "$CFGDIR"
  313. git push
  314. git_unsetenv