I have finally managed to introduce Trac and Subversion (SVN) at work. For the first few months, only some projects were put into SVN and fewer were put into Trac. This was partly due to people not feeling the need, but more to do with people not knowing/understanding how to create these projects.
Since I was the one who setup and researched SVN and Trac, I was fairly comfortable setting up a new repository or new Trac project, however it was quite daunting for any body else to step in and do, and even more daunting for me to try and explain the process to people.
Now that 2010 (twenty ten?) is upon us, it was decided we would move all active projects (those that we are still supporting) into SVN and create Trac projects.
We have about 50 applications that are still being supported, so even split among 4, I didn’t really want to have to go through the process of creating repositories and Trac projects for all of this, so I started looking into a way of scripting this. Since I’ve really not done much scripting before, it took me slightly longer than planned, but 2 work days (work was snowed off for 3 days this week) later and the script is ‘done’, so I thought I’d share it here, and share the difficulties I had. Maybe someone will find this useful.
If you just want the script, it’s available here.
The first thing the script does is ask for input from the user, for the project name (we decided to insist that Trac project folder names and SVN repository names were kept the same). It was also decided that we’d use underscores to seperate words in a project name.
I’ll go through the script, picking out the ‘interesting’ or parts that I struggled with.
set /P project_name=[Enter Project Name]:
set nice_project_name=%project_name:_= %
set project_name=%project_name: =_%
The /P on the set command allows you to set a variable to a line of input from the user.
For Trac, I wanted the project name to have spaces in, as it was nicer, so
nice_project_name goes through the
project_name variable, and removes the underscores (_) and replace them with a single space.
Then it does almost the opposite, to allow the user to enter the ‘nice’ project name instead of with underscores, I make sure all spaces are replaced with underscores.
svnadmin create %svn%%project_name%
Setting up the SVN repository couldn’t really be any easier. (If you’re having trouble with this bit, make sure that the svn bin directory is setup in your windows PATH variable).
svnadmin create with the directory of the repository you want to create as the first argument and hey presto! a new repository.
Setting up Trac is almost as simple as setting up SVN was, the command you have to run is longer, and I had a bit of trouble with the project description as you’ll see in a minute.
call %trac-admin% %trac%%project_name% initenv "%nice_project_name%" sqlite:db/trac.db svn %svn%%project_name% --inherit=c:\trac_conf\trac.ini
If you’re using the
nice_project_name variable, you need to make sure it’s surrounded with speech marks, since you’ll get complaints if you have spaces in the project name.
By passing the repository location to Trac, it’ll nicely link the 2 together for you, so you can see your source code from within trac, and (as you’ll see later) be able to close tickets from commits.
The only added thing there of any interest, is the
--inherit=c:\trac_conf\trac.ini part, which allows us to use a single config file for trac. When given a file to inherit, Trac is smart enough to only include the parts that have changed in the project specific
I then needed (well, I didn’t need, but really wanted) to include the description of the project. I could find no way to do this nicely, so I had to ‘hack’ a solution together.
echo Project configuration file: %project_conf%
echo [project] >> %project_conf%
echo descr = %description% >> %project_conf%
This basically finds the project specific
trac.ini file and bolts the description part of it on to the end. It doesn’t check to see if the description is already there (it shouldn’t be) and it’s a complete hack that I am not at all proud of. However, after spending several hours searching for a ‘nice’ solution, I gave in and this works.
Another thing that developers where I work didn’t seem to quite grasp, was the base folder structure to use in SVN. At the top-level, we wanted 3 folders: trunk, branches and doc. A fairly standard layout, but we ended up with all kinds of things, so I put this into the script as well.
svn import c:\Repositories\.global\base %repoURL% -m "Create base folder structure."
This was another thing that took me longer than it should have done to figure out. I was trying to find a way to create a folder in the repository, without checking out first, I couldn’t. So the solution I settled on, was to create the folder structure somewhere on the server that was hosting svn, then just
import that folder into the repository, thus creating our top-level folder structure.
The next thing I wanted to do, was be able to close Trac tickets from an SVN commit comment, so it was time to set up a post-commit hook in SVN. These go in the hooks folder of your repositiory.
Since this was again a step I didn’t want other developers to be concerned with, I scripted the creation of these hooks too.
echo call "%%~dp0post-commit-run.bat" %%* ^> %%1/hooks/post-commit.log 2^>^&1 >> %svn_post_commit_hook%
Because I wanted to be able to log the output, the first file
post-commit.bat just calls the
post-commit-run.bat file and outputs it to the log file in the same directory.
echo Project configuration file: %svn_commit_hook%
echo @echo off >> %svn_commit_hook%
echo "rem |%1 and %2 come from the post-commit.bat that runs this. They are the repository and the revision number." >> %svn_commit_hook%
echo set APPFOLDER=%project_name% >> %svn_commit_hook%
echo call C:\Repositories\.hooks\post-commit-run.bat %%1 %%2 %%APPFOLDER%% >> %svn_commit_hook%
Since all of the repositories will do the same thing,
post-commit-run.bat just calls the global file, which looks something like this:
call C:\python25\python "c:\trac_conf\trac-post-commit-hook.py" -p "%TRAC_ENV%" -r "%REV%"
trac-post-commit-hook.py is the original found here on the Trac website.
If there’s an easier way to do any of this (especially the description bit of Trac) then please let me know.
I hope this post at least helps someone out, I had quite a lot of fun automating this, I might have to look into what else I can script to make my life easier.
I’ve put all the files (I think) needed for this to work (you will have to edit paths and such) into a zip file that you can download here.