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