Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Currently working on multiple projects that need to share internal libraries. The internal libraries are updated continually. Currently only 1 project needs to be stable but soon we will need to have both projects stable at any given time.

What is the best way to SVN internal libraries?

Currently we are using the 'just another folder' like so...

trunk\project1
trunk\project2
trunk\libs

It causes a major headache when a shared library is updated for project1 and project2 is now dead until the parts that use the library are updated.

So after doing some research on SVN externals I thought of this...

trunk\project1\libs (external to trunk\libs @ some revision)
trunk\project2\libs (external to trunk\libs @ different revision)
trunk\libs\

I'm a little worried about how externals work with commits and not making library commits so complicated that I am the only one capable of doing it (mostly worried about branches with externals as we use them extensively).

On top of that we have multiple programming languages within each project some of which don't support per-project library directories (at least not easily) so we would need to check out on a per project basis instead of checking out the trunk.

There is also the 'vendor' style branching of libraries but it has the same problem as above where the library would have to be a sub folder of each project and is maybe a little to complicated for how little projects we have.

Any insight would be nice. I've spent quite a bit of time reading the Subversion book and feeling like I'm getting no where.

share|improve this question
1  
Looks like you're talking about libraries in code form, there's no way you could use your libraries in binary (either static or dynamic) form during development ? –  Matthieu Feb 22 '11 at 20:27
    
Python is one of the primary languages and I think we really need to be able to edit the libraries during development. I usually work on both adding functionality to the library as well as the changes the new functionality requires at the same time - but that could just be because I don't want to break the current code. –  user18012 Feb 22 '11 at 20:31
1  
It is usually a trade-off between constant edition capacity and stability across multiple projects. I'm curious about the answers, as I've always ended up using versionned binaries (or worse, branches when not able to have compiled modules) for stability. –  Matthieu Feb 22 '11 at 20:35

3 Answers 3

up vote 2 down vote accepted

When dealing with multiple projects, I usually switch common libraries code from directly editable to versionned binaries. This way, I can have releases of this libraries, and it let me choose between updating or not updating the projects that depend on it. You generally don't want to force an update on a project if you can avoid it, and breaking a build is certainly the worst way to force an update. Stability comes to the price of relatively quick edition. But at the end of the day the time you loose managing your library is far less than the time and energy you would loose handling unhappy programmers with their builds broken.

This method implies that the common code is relatively stable, and that's where unit testing and even TDD really pays. It's possible to debate about their Return On Investment in small projects, but in my opinion, they really worth it when you're dealing with code that is used across multiple projects, because you cannot just go around and compile/test every project that use it.

Regarding SVN, If you go the binary way, each library should become a distinct project, and each release implies a label, and optionally a branch if maintenance is preferable to update. Avoid the monster library that rule them all. You would have to update it every time there's a minor change, making it impossible for projects to follow the versions. That's where it takes a bit of architecture, to organize your libraries, if they have dependencies on each others.

As for the binaries, some people upload them in SVN, some people use scripts to download them from a network repository. It really depends on the binaries size, the update frequences, your network architecture, and your personnal preferences.

That's my experience with this specific issue, but I mainly worked in C/C++ and .Net, so there might be other ways to combine editability and stability that I'm not aware of :)

share|improve this answer
    
I think you have a pretty good point. I guess my question was a little subjective and does expose the issue that we need to better consider the libraries as libraries instead of working with them along side project 1 then saying '@#$ we broke project2'. I think I will try to use SVN externals @ rev for this since we can't really compile the Python parts without rewriting a lot of code and see how it works out. –  user18012 Feb 24 '11 at 17:27

In practice, this is less of a problem than it at first appears.

The basic principle is this: If you make a change to a library, it is your responsibility to ensure that all products and systems that are impacted by your change are modified to accomodate that change.

It is easy enough to identify components that use a library, and your regression tests should catch anything that you miss.

Comprehensive testing gives you the peace of mind to make changes quickly and with confidence.

Go with what you already have. It is the right thing to do.

trunk/developmentAutomation
trunk/libs/library1
trunk/libs/library2
trunk/productLines/productLine1/product1a
trunk/productLines/productLine1/product1b
trunk/productLines/productLine2/product2a
trunk/customers/customer1/bespokeProject1a
trunk/customers/customer1/bespokeProject1b
trunk/customers/customer2/bespokeProject2a
share|improve this answer

The original proposal of using SVN externals is a good one, since this is pretty much exactly the problem that the externals feature was meant to solve.

trunk\project1\libs (external to trunk\libs @ some revision)
trunk\project2\libs (external to trunk\libs @ different revision)
trunk\libs\

The main advantage of this arrangement is that it decouples project1 and project2 from changes to the library. The act of committing a change to trunk\libs does not by itself affect anyone working on either project1 and project2 (since they continue to refer to earlier versions of trunk\lib). Only when project1 or project2 are ready to deal with updates to trunk\lib will they commit a change to their repository updating the external reference to point to a more recent version of trunk\libs (and likely also including corresponding changes in their code that is affected by the library changes).

The key point is that project1 deciding to use a newer version of trunk\lib doesn't affect project2 (or vice-versa).

If you make trunk\lib a shared folder in a single repository, then commits to it will be normally affect both project1 and project2 whenever they update their working copies unless you work on branches to keep updates to the trunk from having immediate effect (but then you have to deal with merging changes you do want).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.