Subversion and dependencies
I am trying to find a viable strategy to a following problem.
We have several web projects which are dependent on our framework. Everything is stored in our SVN and has its own project with all the necessary directory structure (trunk, tags, branches). In an example - we have projects webprj01 and webprj02 and we have a framework frm01. All of those have usual SVN project structure - trunk, tags, branches.
webprj01 and webprj01 are both dependent on frm01 and in real life frm01 is present as subdirectory of webprj01 and webprj02. To achieve this in SVN it is possible to set svn:external property and we can set frm01 to point to /frm01/trunk inside trunk of webprj01 and webprj02.
To do a real life coding we have to have all three projects checked out as a working copy and do the changes to particular codebase in it's own working copy. There is no way to publish changes from webprj01/frm01 to the SVN. The change needs to be done in frm01 working copy and transfered through SVN to webprj01/frm01 and webprj02/frm01 working copies.
This solution has a problem with dependencies while branching. I make a production branche from SVN /webprj01/trunk to /webprj01/branches/release-1.0.0. In two days while working on second project webprj02 and frm01 I am no longer able to have stable checkout as through svn:externals in branch release-1.0.0. directory frm01 already points to new changes of frm01/trunk.
Described is just a simplified version of the problem. In our real life situations the dependencies go sometimes five levels deep. I'd like to be able to obtain stable code from SVN at any time. In different words. When I branched/tagged webprj01 as release-1.0.0. I want to get stable code for that particular tag in a year from creation.
It is obvious, that described strategy using svn:externals does not do the work. What would be your experience with this situation? It is not necessary to use one checkout. Even using of build scripts or other solution would be of help here. I am looking for a long time solution to the issu开发者_StackOverflow社区e which would not depend heavily on human actions as we are prone to mistakes.
In the Java world, I would not try to solve this using only a version control system - I would instead use a dependency management tool like Maven + a version control system.
At the place where I work, we have a set-up which seems pretty common:
Any "framework" project lives in it's own directory structure (trunk, tags, branches) like you already seem to have. These are also managed using Maven and whenever something is checked in, a new version of the component (in most cases a JAR-file) is published to our local Maven repositry (which resides on a Nexus server).
Any project which needs to use the "framework" project will have a dependency towards a specific version of the framework project - Maven then automatically pulls this version from the Nexus server whenever the project is being built.
This enables us to release each project and framework component separately, but still keep track of the dependencies between them. We can even have multiple version of the framework components used by different projects without completely losing track of the dependencies.
So far this has worked pretty well for us - I can only see two drawbacks:
It takes a while to set-up, especially if you have not used Maven before.
There is some overhead when releasing each project, since you want to release each dependent component as well, to avoid having dependencies towards the "trunk" version of other components (i.e. the "SNAPSHOT" version in Maven terminology).
Erik is right, a dependency manager will help you out - may want to look into maven or ant/ivy.
Using svn:externals as a poor person's dependency manager is a hack and requires a lot of discipline - it's a PITA to figure out what version of a framework is included, and then some joker is going to set the external reference in a project to the trunk of the framework and you'll have a really rough time figuring out delta's between releases.
In the past I've had js,css & xsl common to many projects packaged as .tgz files and published to an ivy repo by simple ant scripts, then the projects have ant builds (and ivy.xml files) that resolve the dependencies and then package the whole thing. It worked but
Front end web devs struggled with source control, much less dependency management. It was really hard to get them to 'get it' enough to publish changes to a common module to a local repository and then build a project that depended on it to see their changes.
The extra step Erik mentioned, having to release multiple artifacts to get something ready for prod.
Cruddy legacy design meant most of the changes where actually in the common code, 1 in 10 releases of the deployable actually had changes in it's code... it was usually in the common code included.
seriously - svn:externals as a dependency management is going to get to be a headache. It's worth the investment. Having said that these guys had trouble with dependency management, they'd would be way less likely so sort the svn:externals on many branches you're having now.
If I had to do that stuff over again - I'd go maven.
精彩评论