Monday, April 27, 2009

Building Spring 3 working with Git

Until today, I've been keeping up on the Spring 3 development off the svn repository with svn. There is a great post by Chris Beams from SpringSource that provides adequate detail and is a great resource to read as a precursor to this post. In general, I'm moving all my development over to Git, and it was time to get Spring 3 inline. It was not without pain. For those who just want a quick reference, I will provide a quick step by step on how to achieve the end goal of setting up a git client to the spring 3 svn repository. Following that I will provide details for those who want a deeper understanding.

Quick Step-by-Step Spring 3 with Git
  1. In the directory you would like the spring project execute : "git svn clone --stdlayout https://src.springsource.org/svn/spring-framework"
  2. change directory to the newly created spring-framework directory
  3. copy forked script from github.com/kensipe named git-svn-clone-externals to the current directory; make executable and run.
  4. run "git svn show-ignore > .gitignore"
  5. run "git gc"
  6. from the current directory you'll need to create the following directories
  7. mkdir org.springframework.instrument/src/main/resources/
    mkdir org.springframework.instrument/src/main/resources/META-INF
    mkdir org.springframework.instrument.classloading/src/main/resources
    mkdir org.springframework.instrument.classloading/src/main/resources/META-INF
    mkdir org.springframework.asm/src
    mkdir org.springframework.asm/src/main
    mkdir org.springframework.asm/src/main/java
    mkdir org.springframework.core/src/main/resources
    mkdir org.springframework.core/src/main/resources/META-INF
    mkdir org.springframework.expression/src/main/resources
    mkdir org.springframework.expression/src/main/resources/META-INF
    mkdir org.springframework.web/src/main/resources
    mkdir org.springframework.web/src/main/resources/META-INF
    mkdir org.springframework.orm/src/main/resources
    mkdir org.springframework.orm/src/main/resources/META-INF
    mkdir org.springframework.context.support/src/main/resources
    mkdir org.springframework.context.support/src/main/resources/META-INF
    mkdir org.springframework.web.portlet/src/main/resources
    mkdir org.springframework.web.portlet/src/main/resources/META-INF
    mkdir org.springframework.test/src/main/resources
    mkdir org.springframework.test/src/main/resources/META-INF
    mkdir org.springframework.integration-tests/src/main
    mkdir org.springframework.integration-tests/src/main/java
    mkdir org.springframework.integration-tests/src/main/resources
    mkdir org.springframework.integration-tests/src/main/resources/META-INF
    mkdir org.springframework.instrument/src/test/java
    mkdir org.springframework.instrument.classloading/src/test/java
    mkdir org.springframework.asm/src/test
    mkdir org.springframework.asm/src/test/java
    mkdir org.springframework.aspects/src/test/java

  8. export ANT_OPTS="-XX:MaxPermSize=256m -Xmx1024m"
  9. change directory to "build-spring-framework" directory
  10. run "ant"
  11. wait 20 minutes :)
The background and detail
The first line is standard git-svn to get the repository. If you are new to Git, this will take a few minutes long then a standard svn checkout. It is copying all the changes throughout history to your local .git repo. Fortunately spring 3 is still young from a history standpoint.

svn external - The first issue
The first thing to note is that part of the build process for spring 3 is a project which is added to this svn project as an external, which led me to this post on why svn externals are evil :) evil or not we have to deal with them. This led to a post by Alieniloquent which has some good explanations, followed by what I eventually settled on, a post by Andre Pang, which includes a script he created, which I forked off github. Kudos to Andre!! The script he created (which I can see using again the future), provides a one execution solution to what Alieniloquent blogged. It is beautifully simple. The script provides the following:
  1. pulls down all the svn externals (spring 3 only has one)
  2. creates a symlink (mocking what svn would have done)
  3. adds the symlink and the .git_externals directory to the excludes file
If you wanted to check your svn externals for other projects use the following command: "git svn propget svn:externals ." in the root of the project directory.

The next step is to get all the svn ignores into the .gitignores file.

version control directory management - the next issue
The explanation behind this issue is that svn allows for and manages empty directories... git does not. git only manages content. There are a number of empty directories which the spring build files expects to be present for the build to succeed. This is based on a standardize build system and a lack of error handling in the build system. If I get some time, I'll send a patch to the springsource guys to fix this. At this time you will have to create all the directories listed.

jvm out of memory issues - the last issue
ant will run out of memory without these changes.... first you will run out of perm space, followed by heap. You may be able to get by with less; I didn't spend much time here. The standard defaults will fail.

Also if you need to update your master branch with git... "git svn rebase" will do the job!

I need to say thanks to those bloggers already noted and to fellow NFJS speaker Matthew McCollough.

1 comment:

Matthew McCullough said...

For empty directories in Git, the common solution is to create a .gitignore with nothing in it in the folders. But since this is coming from Subversion, the authors there could create some type of equivalent .something placeholders. Or, more robustly, as you said, just safety test the existence of the folders.