views:

416

answers:

4

I have a set of applications that all rely on a cross-platform library (in-house development), and everything is stored in subversion. Now, this library is part of every app and as such a copy of it has to be in each app's working directory.

In order to be able to go back to any version of an app and have the correct version of the lib, one option would be to keep a copy of the lib in the project, however this is a nightmare to maintain.

More elegant seems to be to use subversion's externals definitions feature. However it seems to be necessary to use explicit revision numbers to make 100% sure that the correct revision is assigned (for example, if the trunk or a tag or a branch were specified without revision number, it seems you can't be 100% sure whether you will get EXACTLY the same revision as e.g. a year ago, as people can always commit on top of the trunk/branch/tag).

Now, this library is in constant development, as it is basically the heart of our multi-platform application. So maintaining the revisions in the svn:external prop will need constant updating. It is also common that devs will make changes to their local copy (bugfixes, new features) and then commit it. I am afraid now that if I set it up using revisions it will be harder to track down where exactly this commit is going (e.g. devs may lose track that the dep is on a branch; also when committing, it will be committed to the top of the trunk/branch, possibly skipping other commits by other devs).

Basically, it seems even with external definitions the devs working with that will still need to maintain a certain amount of constraint and control handling this (see e.g. this example on SO). Ideally they should be clever enough to do so, but (judging by myself) forgetting these small details is quite common and may cause a lot of headache later on.

So, what I am looking for is a really fool-proof solution (if there is one) to this problem of keeping this lib in sync with several projects in a way that I can go back in time and always get the correct versions together without having to constantly be on the watch.

+1  A: 

What may help is to restrict the write/commit access to the tags folder and than use tags in the svn:externals instead of revision numbers. (i.e. with svnperms)

So the users can't accidentally commit to wrong places but have to consciously choose the branch/trunk where the change belongs.

domruf
+1  A: 

Using svn:externals is fine (with revisions), but it sounds as if you need to use a build server (such as Hudson) which builds automatically when things are checked in. This will detect directly when developers make local changes and forget to update the externals.

JesperE
A: 

You can use Vendor Branches.

Davide Gualano
+2  A: 

The problem with your problem is that your library is not a library, at least not in a strict sense of the expression.

Your "library" is better described as a project that happens to be shared by the teams working on the different applications that rely on that core.

In this context, the biggest issue is not the subversion technique you may choose to use, but the way you organize your team in order to achieve a useful collaboration on that core component.

And the kind of problems that may arise are at least two. First, as the different applications may need different behaviors from your core, if they do not coordinate well, a perfectly valid commit from one team will break the other ones (continuous integration should help here).

But the second problem is harder to solve even with good inter-team communication, and it's related to the release management.

If the applications depending on this core are released at different points in time, you will have a hard time getting a stable core that is good enough for the release of one the apps while not halting the development of the rest.

My suggestion, have somebody dedicated to look after the core library. Use a branch of it in every project and let the applications developers to commit there while ensuring that they discuss the changes with everybody, specially the overseer of the lib.

And finally, make this library supervisor be in charge of coordinating the merges of the changes made by the different teams into the trunk of the library, thus generating stable, tested releases that will be used by the stable releases of your applications. And after every release of the core, spawn the next generation of branches into the rest of the projects.

It sounds like a lot of work compared with just defining an external and let everybody commit there. But actually, there is no point in hiding the fact that you must put some effort in keeping your core library coherent. If you don't do it upfront it will hunt you later.

Javier
You are right with the lib not really being a lib, but it was somewhat easier to explain (plus it doesn't really make a difference).
Steven
Yeah, I guess it is much easier to explain it that way. And I know it's a matter of semantics, but I think of libraries as more or less static artifacts, which is not the case here because the "lib" is in development state. Otherwise vendor branches would do.
Javier