2

My company is transitioning from Visual Source Safe to Subversion; our pipeline management tools rely on the existence of the 'shadow folder' that VSS provides in order to move code from version control out to the various test environments. Note: we use an interpreted language and translate our source code into object code -- currently, both source and object code are under version control (specifically for the needs of the pipeline management machinery).

As an iterative step, I am trying to mimic the shadow folder feature with a bit of flair in that I'm looking to kick off translation upon commit, so that we need not store both source and object code in Subversion. Note: I had to hack the process from performing a clean 'build' of everything to just translate the affected files during the commit, though, because it otherwise took too long to be a realtime commit operation (in the future I expect we will drop this process in favor of something a little less interactive, e.g. hourly builds or whatnot).

All of this backstory is simply to ask the question: how does the ${user.dir} property get setup?

This is my post-commit hook batch file (everything is done on Windows):

SET REPO=%1
SET REV=%2

FOR %%* IN (%REPO%) DO SET REPONAME=%%~n*

SET BUILDROOT=E:\builds
IF NOT EXIST %BUILDROOT% ( MKDIR %BUILDROOT% )
SET BUILDDIR=%BUILDROOT%\%REPONAME%
IF NOT EXIST %BUILDDIR% ( MKDIR %BUILDDIR% )
CD %BUILDDIR%

ECHO %CD%
ECHO %BUILDDIR%

C:\apache-ant-1.8.3\bin\ant -f C:\dev\shadow\build.xml -DWorkingDir=%BUILDDIR%\!build_work_dir -DSvnRepoUrl=file:///%REPO% -DFromRevision=%REV% > %BUILDDIR%\!last_build_result.txt 2>&1

the last line is the actual Ant call; you can see that I'm redirecting the output to a file, which lives in the %BUILDDIR%, or E:\builds\. This file gets created as expected, which indicates to me that %BUILDDIR% was correctly setup and thus the:

CD %BUILDDIR%

line should have executed. I understand that SVN kicks off the post-commit hook with an empty environment, but I would expect that changing the directory within it should preserve the state once kicking off Ant.

Later, in my Ant script, I setup my ${build.dir} property thusly:

<property name="build.dir" value="${user.dir}\.build.${build.time}" />
<!-- delete the build.dir, just in case we attempt a new build within the same minute...
     TODO: we may need to account for concurrent builds; does SVN single-thread commits? -->
<delete dir="${build.dir}" />
<mkdir dir="${build.dir}" />

If %REPONAME% (in the batch file) was DEMO, I expected the current working directory to be: E:\builds\DEMO and thus ${build.dir} should be something like: E:\builds\DEMO.build.20120622.1127, but it is: C:\dev\shadow.build.20120622.1127, instead.

As I understand it, Ant is simply pulling in the System.Properties from Java for things like ${user.dir} -- ${user.dir} is described as User's current working directory. Clearly, based on my experimentation, something is getting crossed between the initial setup within the batch file and the invocation of Java with regards to the working directory.

Does Ant change the working directory to the build file's location? I did not find any documentation to suggest it does, but it's possible I simply overlooked something. I have %ANT_HOME% defined, but given Subversion's 'empty environment', it wouldn't be loaded...perhaps that has an effect? I will need to investigate, but was hoping somebody might simply know how this works.

Edit (2012-06-22-16:38):

I tried setting up %ANT_HOME%, %JAVA_HOME% and %JAVA_CMD%, but to no avail.

rguilbault
  • 553
  • 1
  • 5
  • 17

1 Answers1

1

There's no working directory when you do a commit on the server where the various hooks execute. That makes it impossible to do what you want via hooks.

I suggest you take a look at Jenkins. Jenkins is a continuous integration server, and can run your Ant scripts after each commit. Jenkins does the checkouts and updates necessary for a working directory and can do this after every commit. Because Jenkins has a working directory, it can run your ant programs without problems.

Plus, since Jenkins is executed after the commit finishes, your commit is not waiting around which gives your developers enough time to build up a seething hatred of you. For example, if it took 20 seconds for your hook script to execute, the developers would have to wait around that full 20 seconds before they can continue.

Jenkins also allows you to store your built objects inside of Jenkins, so they don't have to be stored in your Subversion repository. This means it's easy to find the correct release because it's in Jenkins where it's easy to find. It keeps your Subversion repository from growing way too fast.

So, take a look at Jenkins as a solution for what you want to do.

David W.
  • 105,218
  • 39
  • 216
  • 337
  • thanks for the advice -- long term, this is what I'm looking to do (still trying to wrap my head around how it can all work out in our environment). as noted above, my post-commit hook, while not desirable, is the best I can do as a stop-gap solution until we're ready for the next transition (which will likely involve adopting a new ALM system). – rguilbault Jun 25 '12 at 14:16
  • btw, ${user.dir} (which is supposed to be the current working directory) *does* exist, it's just not setup to the directory I changed to within the .bat file -- it's as if Ant has some default behavior that changes the working directory to the location of the build file (but only when invoked from the commit hook, when I run it from a command shell, it behaves as desired). there has got to be some missing environment variable that is causing the behavior, but I'm not sure. I suppose it doesn't matter -- I added a command-line property for the build directory and all is solved. – rguilbault Jun 25 '12 at 14:25