[evla-sw-discuss] code organization

Brian Truitt btruitt at nrao.edu
Wed Oct 25 17:07:10 EDT 2006


(This is long, I apologize in advance.)

I like maven's suggested directory layout for the individual projects 
and it being the default for maven 2, it'll be the easiest to use "out 
of the box" (for new projects that aren't having to convert from maven 
1). I'm much more interested in the repository layout at the higher 
level though: where in the repository are the projects?

I don't know how many of us have worked with subversion before, but I 
have so I'll go ahead and throw some meat on the grill as it were.

Subversion isn't a really a source code versioning thing like cvs. 
Really, it's just a versioned file system. ANYTHING can go into that 
file system pretty much. Commits to the repository are atomic and the 
repository has a single, repository-wide version. Individual files are 
not versioned separately.

Furthermore, it has no explicit concept of tags and branches. To tag a 
release, for instance, one would COPY your project into a directory in 
the repository that is designated as the place to store tags (usually 
called "tags"). Similarly for branches. In contrast, you would use some 
cvs command to tag a release and that release would simply reference 
specific versions of every file in the repository (or subdirectory in 
the repository or whatever).

An implication here is that a subversion "tag" can be modified at any 
time because it's not a tag really, just a copy stored someplace else in 
the repository.

Copied sections of the repository get their own revision history from 
that point in time forward and can be merged back together later with 
the original.

In any case, an example repository layout that is pretty common is as 
follows:

repository_root/
	projectFoo/
		tags/
		branches/
		trunk/
	projectBar/
		tags/
		branches/
		trunk/


In our case, we'd store a maven2 project for projectFoo under 
projectFoo/trunk/ which may look like:

projectFoo/
   trunk/
     src/main/java/
     test/main/java/
     pom.xml

(With an emphasis on the TEST directory. unit tests are your friend.)

under the tags directory you might find things like:
projectFoo/tags/
   v0.1/
     /* copy of "projectFoo/trunk" here */

For a person working on projectFoo, they would check it out in this manner:

svn checkout file:///home/asg/svnroot/projectFoo/trunk projectFoo

This would check out the "trunk" of your project into a new directory 
called "projectFoo". Now, you can ignore the fact that you have the tags 
and branches subdirectories until you need to create a tag or branch.

I like this layout fairly well, but it has its caveats. The 1st is that 
the whole repository has a single version number. So, if a person 
working on projectBar commits some new work, the repository version goes 
up one, including the version number of projectFoo.

The 2nd caveat is that this structure can be a little more annoying to 
use if you're actively developing 2 projects. It would be nice to simply 
check out the parent directory of both projects, but in this scheme 
you'd be checking out each project's tags and branches directory as well 
and there'd be an extra directory (trunk) in between you and what you 
actually want. It's a little cumbersome. You can make 2 separate 
checkouts and put them in the same (local) directory to get around that, 
but you'd be running svn commands in 2 different working copies to 
commit changes or whatever.

The 3rd caveat is our structure is a little more complicated, but I'm 
not sure it'll be an issue. What we have is:

repository_root/
   NRAO/
     EVLA/
       COMMONS/
     E2E/
       COMMONS/
       PST/
       USERDB/

etc. Each of those leaf nodes in the tree above would have tags, 
branches, and trunk subdirectories if we followed the scheme described 
above. However, since we're just dealing with a versioned filesystem, 
there's no obligation to put the tags and branches directories under 
each project individually. We could possibly make a structure like:

repository_root/
   tags/
     NRAO/
       EVLA/
       E2E/
         USERDB/
           v0.1/
             /* copy of "USERDB/" here */
   NRAO/
     E2E/
       USERDB/

And similarly for branches (hopefully we won't have any branches really, 
but you can look here for some examples of what branches may be useful 
for: 
http://svn.collab.net/repos/svn/trunk/doc/user/svn-best-practices.html).

Moving the tags and branches up means we don't have a use for the 
"trunk" directory either, so we can omit that as well.

I think pushing the tags directory up would give Maven a good handle on 
where to look for official releases of our various projects so our maven 
jar file repository can have jars (or wars) for v0.1 of the USERDB or 
whatever (as opposed to just nightly v1.0-SNAPSHOT's of everything).

There's more to be haggled about (like what goes under the various 
COMMONS directories; I'd like to see multiple artifacts produced from 
E2E/COMMONS at least. Dave and I have a lot of stuff to put in there.) 
I've ranted for longer than most people will read I think, so I'm done. 
I can try to answer any questions like: "How would you do X in 
subversion?". Feel free to e-mail me.



More information about the evla-sw-discuss mailing list