[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