views:

663

answers:

2

We are starting a new SOA project with a lot of shared .net assemblies. The code for these assemblies will be stored in SVN.

In development phase, we would like to be able to code these assemblies as an entire solution with as little SVN 'friction' as possible.

When the project enters more of a maintenance mode, the assemblies will be maintained on an individual level.

Without making Branching, Tagging, and Automated Builds a maintenance nightmare, what's the best way to organize these libraries in SVN that also works well with the VS 2008 IDE?

Do you setup Trunk/Branches/Tags at each library level and try to spaghetti it all together somehow at compile time, or is it better to keep it all as one big project with code replicated here and there for simplicity? Is there a solution using externs?

A: 

What we did with shared assemblies during development phase (in a project which had loads of these), is that we put them on a network share (N Drive) type of a place, and every developer referenced them from there.

Our build process would always update this share with the latest versions. This way the actual assemblies never had to be kept in source control. Only the code.

Vaibhav
Thanks for the quick response, but I'm referring to storing the projects assemblies. I cleaned up the question a bit. So if I have a TierA solution that changes Assembly1 and Assembly2 source and I have TierB solution that changes Assembly2 and Assembly3 source, whats a good way to organize SVN?
JKueck
+6  A: 

What we did at our company was to set up a tools repository, and then a project repository. The tools repository is a Subversion repository, organized as follows:

/svn/tools/
   vendor1/
     too11/
       1.0/
       1.1/
       latest = a copy of vendor1/tool1/1.1
     tool2/
       1.0/
       1.5/
       latest = a copy of vendor1/tool2/1.5
   vendor2/
     foo/
       1.0.0/
       1.1.0/
       1.2.0/
       latest = a copy of vendor2/foo/1.2.0

Every time we get a new version of a tool from a vendor, it is added under its vendor, name, and version number, and the 'latest' tag is updated.

[Clarification: this is NOT a typical source respository -- it's intended to store specific versions of 'installed' images. Thus /svn/tools/nunit/nunit2/2.4 would be the top of a directory tree containing the results of installing NUnit 2.4 to a directory and importing it into the tools repository. Source and examples may be present, but the primary focus is on executables and libraries that are necessary to use the tool. If we needed to modify a vendor tool, we'd do that in a separate repository, and release the result to this repository.]

One of the vendors is my company, and has a separate section for each tool, assembly, whatever that we release internally.


The projects repository is a standard Subversion repository, with trunks, tags, and branches as you normally expect. Any given project will look like:

/svn/
  branches/
  tags/
  trunk/
    foo/
      source/
      tools/
      publish/
      foo-build.xml (for NAnt)
      foo.build (for MSBuild)

The tools directory has a Subversion svn:externals property set, that links in the appropriate version (either a specific version or 'latest') of each tool or assembly that is needed by that project. When the 'foo' project is built by CruiseControl.NET, the publish task will populate the 'publish' directory as the 'foo' assembly is intended to be deployed, and then executes the following subversion commands:

svn import publish /svn/tools/vendor2/foo/1.2.3
svn delete /svn/tools/vendor2/foo/latest
svn copy /svn/tools/vendor2/foo/1.2.3 /svn/tools/vendor2/foo/latest

Developers work on their projects as normal, and let the build automation take care of the details. A normal subversion update will pull the latest versions of external tools as well as as project updates.

If you've got a lot of tool interdependency, you can configure CruiseControl.NET (by hand) to trigger builds for subordinate projects when their dependencies change, but we haven't needed to go that far yet.

Note: All of the Subversion repository paths have been shortened for clarity. We actually use Apache+SVN, and two separate servers, but you should adapt this as you see fit.

Craig Trader
That looks like a really good and clean way - +1 from me
Michael Stum
Thanks. I put a lot of thought (and research) into it before I implemented it.
Craig Trader
Good overall answer! Questions:1. How do you keep historical snapshots if SVN:Externals points to 'latest' and not a tag/revision #?2. How do you branch your vendor source? Perhaps it would be better to reorganize as '/tool1/trunk/', '/tool1/tags/REL-1.2.3/' and '/tool1/branches/BUG-blah/'?
JKueck
(1) The svn:externals property is versioned. If you point to a specific version, and change it as necessary, that solves your problem. We typically use the 'latest' tag for build and test tools and libraries, things that aren't shipped as part of the product.(2) Edited for clarification.
Craig Trader
Thanks for the clarification. It's really the internal source code libraries AND the resulting shared binary files that I'm trying to organize. My apologies if my question was not clear.
JKueck
Well, I hope this answers your question. If it does, please accept it as the answer.
Craig Trader