| 1 | #!/bin/sh |
|---|
| 2 | # -*- coding: utf-8 -*- |
|---|
| 3 | # |
|---|
| 4 | # Copyright (C) 2009-2013 Edgewall Software |
|---|
| 5 | # Copyright (C) 2009 Christian Boos <cboos@edgewall.org> |
|---|
| 6 | # All rights reserved. |
|---|
| 7 | # |
|---|
| 8 | # This software is licensed as described in the file COPYING, which |
|---|
| 9 | # you should have received as part of this distribution. The terms |
|---|
| 10 | # are also available at http://trac.edgewall.com/license.html. |
|---|
| 11 | # |
|---|
| 12 | # This software consists of voluntary contributions made by many |
|---|
| 13 | # individuals. For the exact contribution history, see the revision |
|---|
| 14 | # history and logs, available at http://trac.edgewall.org/. |
|---|
| 15 | # |
|---|
| 16 | # = trac-svn-hook = |
|---|
| 17 | # |
|---|
| 18 | # Purpose:: this script is meant to be called from the Subversion hooks |
|---|
| 19 | # for notifying Trac when changesets are added or modified. |
|---|
| 20 | # |
|---|
| 21 | # Scope:: The http://trac.edgewall.org/wiki/TracRepositoryAdmin page |
|---|
| 22 | # describes how to directly call the relevant trac-admin commands |
|---|
| 23 | # from the Subversion hooks. In most cases this should be enough, |
|---|
| 24 | # however this script should make troubleshooting easier and |
|---|
| 25 | # has support for notifying multiple Trac environments. |
|---|
| 26 | # |
|---|
| 27 | # Usage:: copy this script to some central place, for example in your |
|---|
| 28 | # TRAC_ENV or TRAC_PARENT_ENV folder |
|---|
| 29 | # **Be sure to read the Configuration Notes section below first** |
|---|
| 30 | # then fill in the variables listed below the Configuration section. |
|---|
| 31 | # |
|---|
| 32 | # For each Subversion repository $REPOS that has to be monitored by |
|---|
| 33 | # your Trac environment(s), you need to modify the hooks in order to |
|---|
| 34 | # call the present script: |
|---|
| 35 | # |
|---|
| 36 | # Add this to your `$REPOS/hooks/post-commit` script: |
|---|
| 37 | # |
|---|
| 38 | # /path/to/trac-svn-hook $REPOS $REV |
|---|
| 39 | # |
|---|
| 40 | # If you allow revision property editing in `$REPOS/hooks/pre-revprop-change`, |
|---|
| 41 | # then you can let Trac know about modified changesets by adding the following |
|---|
| 42 | # lines to the `$REPOS/hooks/post-revprop-change` script: |
|---|
| 43 | # |
|---|
| 44 | # if [ "$PROPNAME" = "svn:log" -o "$PROPNAME" = "svn:author" ]; then |
|---|
| 45 | # /path/to/trac-svn-hook $REPOS $REV $USER $PROPNAME |
|---|
| 46 | # fi |
|---|
| 47 | # |
|---|
| 48 | # See also http://svnbook.red-bean.com/en/1.5/svn.reposadmin.create.html#svn.reposadmin.create.hooks |
|---|
| 49 | # |
|---|
| 50 | # Platform:: Unix or Cygwin. |
|---|
| 51 | # |
|---|
| 52 | # On Windows, if you have Cygwin installed, you can also use this |
|---|
| 53 | # script instead of the `trac-svn-hook.cmd`. |
|---|
| 54 | # In your `post-commit.bat` and `post-revprop-change.bat` hooks, call |
|---|
| 55 | # this script using: |
|---|
| 56 | # |
|---|
| 57 | # bash /path/to/trac-svn-hook "%1" "%2" "%3" "%4" |
|---|
| 58 | # |
|---|
| 59 | # ----------------------------------------------------------------------------- |
|---|
| 60 | # |
|---|
| 61 | # == Configuration |
|---|
| 62 | # |
|---|
| 63 | # Uncomment and adapt to your local setup: |
|---|
| 64 | # |
|---|
| 65 | # export TRAC_ENV=/path/to/trac-env:/path/to/another/trac-env |
|---|
| 66 | # export PATH=/path/to/python/bin:$PATH |
|---|
| 67 | # export LD_LIBRARY_PATH=/path/to/python/lib:$LD_LIBRARY_PATH |
|---|
| 68 | # |
|---|
| 69 | # ----------------------------------------------------------------------------- |
|---|
| 70 | # |
|---|
| 71 | # == Configuration Notes |
|---|
| 72 | # |
|---|
| 73 | # As a preliminary remark, you should be aware that Subversion usually |
|---|
| 74 | # run the hooks in a very minimal environment. |
|---|
| 75 | # This is why we have to be very explicit about where to find things. |
|---|
| 76 | # |
|---|
| 77 | # According to http://subversion.apache.org/faq.html#hook-debugging, |
|---|
| 78 | # one useful method for getting the post-commit hook to work is to call |
|---|
| 79 | # the hook manually from a shell, as the user(s) which will end up running |
|---|
| 80 | # the hook (e.g. wwwrun, www-data, nobody). For example: |
|---|
| 81 | # |
|---|
| 82 | # env - $REPOS/hooks/post-commit $REPOS 1234 |
|---|
| 83 | # |
|---|
| 84 | # or: |
|---|
| 85 | # |
|---|
| 86 | # env - $REPOS/hooks/post-revprop-change $REPOS 1234 nobody svn:log |
|---|
| 87 | # |
|---|
| 88 | # |
|---|
| 89 | # The environment variables that have to be set in this script are |
|---|
| 90 | # TRAC_ENV, PATH and eventually LD_LIBRARY_PATH. |
|---|
| 91 | # |
|---|
| 92 | # TRAC_ENV:: the path(s) to the Trac environment(s) |
|---|
| 93 | # |
|---|
| 94 | # In case you need to maintain more than one environment in sync with |
|---|
| 95 | # the repository (using a different scope or not), simply specify more |
|---|
| 96 | # than one path, using the ":" path separator (or ";" if the script is |
|---|
| 97 | # used on Windows with Cygwin's bash - in this case also don't forget to |
|---|
| 98 | # enclose the list of paths in quotes, e.g. TRAC_ENV="path1;path2"). |
|---|
| 99 | # |
|---|
| 100 | # Note that if you have to maintain multiple repositories and multiple Trac |
|---|
| 101 | # environments, and you have some non-trivial mapping between repositories |
|---|
| 102 | # and Trac environments, then you can leave the TRAC_ENV setting out of |
|---|
| 103 | # this file and put it directly in your post-commit and post-revprop-change |
|---|
| 104 | # hooks, so that the changes to each repositories are notified to the |
|---|
| 105 | # appropriate environments (don't forget to export TRAC_ENV in this case). |
|---|
| 106 | # |
|---|
| 107 | # PATH:: the folder containing the trac-admin script |
|---|
| 108 | # |
|---|
| 109 | # This folder is typically the same as your Python installation bin/ folder. |
|---|
| 110 | # If this is /usr/bin, then you probably don't need to put it in the PATH. |
|---|
| 111 | # |
|---|
| 112 | # Note that if you're using a python program installed in a non-default |
|---|
| 113 | # location (such as /usr/local or a virtual environment), then you need |
|---|
| 114 | # to add it to the PATH as well. |
|---|
| 115 | # |
|---|
| 116 | # LD_LIBRARY_PATH:: folder(s) containing additional required libraries |
|---|
| 117 | # |
|---|
| 118 | # You may also need to setup the LD_LIBRARY_PATH accordingly. |
|---|
| 119 | # The same goes for any custom dependency, such as SQLite libraries or |
|---|
| 120 | # SVN libraries: make sure everything is reachable. |
|---|
| 121 | # For example, if you get errors like "global name 'sqlite' is not defined" |
|---|
| 122 | # or similar, then make sure the LD_LIBRARY_PATH contains the path to all |
|---|
| 123 | # the required libraries (libsqlite3.so in the above example). |
|---|
| 124 | # |
|---|
| 125 | # |
|---|
| 126 | # ----------------------------------------------------------------------------- |
|---|
| 127 | # |
|---|
| 128 | # == Examples |
|---|
| 129 | # |
|---|
| 130 | # === Minimal setup example === |
|---|
| 131 | # |
|---|
| 132 | # Python is installed in /usr/bin, Trac was easy_install'ed. |
|---|
| 133 | # |
|---|
| 134 | # {{{ |
|---|
| 135 | # export TRAC_ENV=/srv/trac/the_trac_env |
|---|
| 136 | # }}} |
|---|
| 137 | # |
|---|
| 138 | # |
|---|
| 139 | # === Virtualenv setup example === |
|---|
| 140 | # |
|---|
| 141 | # Here we're using a Trac installation set up using virtualenv |
|---|
| 142 | # (http://pypi.python.org/pypi/virtualenv). |
|---|
| 143 | # |
|---|
| 144 | # In this example, the virtualenv is located in |
|---|
| 145 | # /packages/trac/branches/trac-multirepos |
|---|
| 146 | # and is based off a custom Python installation (/opt/python-2.4.4). |
|---|
| 147 | # We're also using a custom SQLite build (/opt/sqlite-3.3.8). |
|---|
| 148 | # |
|---|
| 149 | # Note that virtualenv's activate script doesn't seem to care |
|---|
| 150 | # about LD_LIBRARY_PATH and the only other thing it does and that |
|---|
| 151 | # we need here is to set the PATH, we can as well do that ourselves: |
|---|
| 152 | # |
|---|
| 153 | # We also want to notify two Trac instances: |
|---|
| 154 | # |
|---|
| 155 | # {{{ |
|---|
| 156 | # export TRAC_ENV=/srv/trac/the_trac_env:/srv/trac/trac_other_trac_env |
|---|
| 157 | # export PATH=/packages/trac/branches/trac-multirepos/bin:$PATH |
|---|
| 158 | # export LD_LIBRARY_PATH=/opt/python-2.4.4/lib:/opt/sqlite-3.3.8/lib:$LD_LIBRARY_PATH |
|---|
| 159 | # }}} |
|---|
| 160 | # |
|---|
| 161 | # |
|---|
| 162 | # === Cygwin setup example === |
|---|
| 163 | # |
|---|
| 164 | # {{{ |
|---|
| 165 | # export TRAC_ENV=C:/Workspace/local/trac/devel |
|---|
| 166 | # export PYTHONPATH=C:/Workspace/src/trac/repos/multirepos |
|---|
| 167 | # export PATH=/C/Dev/Python261/Scripts:$PATH |
|---|
| 168 | # }}} |
|---|
| 169 | # |
|---|
| 170 | # ----------------------------------------------------------------------------- |
|---|
| 171 | # |
|---|
| 172 | # This is the script itself, you shouldn't need to modify this part. |
|---|
| 173 | |
|---|
| 174 | # -- Command line arguments (cf. usage) |
|---|
| 175 | |
|---|
| 176 | REPOS="$1" |
|---|
| 177 | REV="$2" |
|---|
| 178 | USER="$3" |
|---|
| 179 | PROPNAME="$4" |
|---|
| 180 | |
|---|
| 181 | # -- Foolproofing |
|---|
| 182 | |
|---|
| 183 | if [ -z "$REPOS" -o -z "$REV" ]; then |
|---|
| 184 | echo "Usage: $0 REPOS REV" |
|---|
| 185 | exit 2 |
|---|
| 186 | fi |
|---|
| 187 | |
|---|
| 188 | if ! python -V 2>/dev/null; then |
|---|
| 189 | echo "python is not in the PATH ($PATH), check PATH and LD_LIBRARY_PATH." |
|---|
| 190 | exit 2 |
|---|
| 191 | fi |
|---|
| 192 | |
|---|
| 193 | if [ -z "$TRAC_ENV" ]; then |
|---|
| 194 | echo "TRAC_ENV is not set." |
|---|
| 195 | exit 2 |
|---|
| 196 | fi |
|---|
| 197 | |
|---|
| 198 | # -- Feedback |
|---|
| 199 | |
|---|
| 200 | echo "----" |
|---|
| 201 | |
|---|
| 202 | if [ -z "$USER" -a -z "$PROPNAME" ]; then |
|---|
| 203 | EVENT="added" |
|---|
| 204 | echo "Changeset $REV was added in $REPOS" |
|---|
| 205 | else |
|---|
| 206 | EVENT="modified" |
|---|
| 207 | echo "Changeset $REV was modified by $USER in $REPOS" |
|---|
| 208 | fi |
|---|
| 209 | |
|---|
| 210 | # -- Call "trac-admin ... changeset ... $REPOS $REV" for each Trac environment |
|---|
| 211 | |
|---|
| 212 | ifs=$IFS |
|---|
| 213 | IFS=: |
|---|
| 214 | if [ -n "$BASH_VERSION" ]; then # we can use Bash syntax |
|---|
| 215 | if [[ ${BASH_VERSINFO[5]} = *cygwin ]]; then |
|---|
| 216 | IFS=";" |
|---|
| 217 | fi |
|---|
| 218 | fi |
|---|
| 219 | for env in $TRAC_ENV; do |
|---|
| 220 | if [ -r "$env/VERSION" ]; then |
|---|
| 221 | log=$env/log/svn-hooks-`basename $REPOS`.log |
|---|
| 222 | nohup sh <<EOF >> $log 2>&1 & |
|---|
| 223 | echo "Changeset $REV $EVENT" |
|---|
| 224 | trac-admin $env changeset $EVENT $REPOS $REV && \ |
|---|
| 225 | echo "OK" || echo "FAILED: see the Trac log" |
|---|
| 226 | EOF |
|---|
| 227 | else |
|---|
| 228 | echo "$env doesn't seem to be a Trac environment, skipping..." |
|---|
| 229 | fi |
|---|
| 230 | done |
|---|
| 231 | IFS=$ifs |
|---|
| 232 | |
|---|