Often in the course of developing a project it is desirable to use code from a third party. The main benefit, of course, is being able to add functionality without developing that functionality from scratch. Some third-party projects we have used in the past include FCKEditor (now CKEditor), the Yahoo! User Interface library, and, more recently, the CakePHP framework.
When our code is maintained in a subversion repository there are two options for including third-party code: externals and vendor branches.
For third-party code that will require little modification an externals property definition is preferred. Subversion externals are pointers to subversion sources outside the current path (either within the current repository or that are stored in entirely different repositories). Whenever a copy of our own project is checked out from the repository the third-party code is also checked out. One benefit of this approach is that a local copy of the third-party code does not have to be maintained. If an update to third-party code is available you only need to update the externals reference to the third-party repository.
For example, we want to add an externals definition for FCKEditor to our project. For the sake of this example we’ll use the 2.6.4-tagged version of FCKEditor and we’ll link this to the /includes/fckeditor path of our project. The steps are as follows:
- Ensure that /includes/fckeditor does not exist;
- From the root of the working copy of the project run the following command:
svn propset svn:externals 'fckeditor http://svn.fckeditor.net/FCKeditor/tags/2.6.4' includes
- Update the local working copy of the project
That’s all there is to it.
When using externals I recommend that we only point to stable (tagged) versions of third-party projects. By pointing to a stable version we can test for bugs and for compatibility between our code and the third-party code prior to implementing updates on our own systems.
Vendor branches are locally-maintained copies of third-party code. Vendor branches are treated much like any project developed in-house. Using vendor branches is less desirable mainly due to the extra work required to update the code in the repository when significant additions and deletions have been made by the third-party. However, it is advisable to use a vendor branch when third-party code will require significant modification in order to be useful in own project.
To set up a vendor branch, first create a new project in the subversion repository as described in the post Using Subversion for Application Development and Deployment. Note that it is standard to place vendor branches in a subdirectory of the “/vendor” directory of the repository. Once this is done we can tag stable versions and create branches just as we do with any other project in the repository. To add the vendor branch to another project within our repository I would recommend using an externals link much as we would for any third-party code. This should ease maintenance as the code is updated.
When third-party code is updated there are two methods you can use to update the vendor branch. The first method is best used when there are only a few files added to or removed from the third-party code. In this situation you can manually update a working copy of the trunk with the new release and commit the modifications. Any in-house changes to the code will have to be re-created (either by editing the code again or merging with an older branch).
When a significant number of file changes have been made to the third-party code it’s easiest to use svn_load_dirs.pl. This file will perform all the operations of adding, removing, and updating the files in the repository. And with the -t option you can automatically create a tagged (stable) version. For example, to update a vendor branch of the Yahoo! UI Library to version 2.6.0 you would issue the following command:
svn_load_dirs.pl -t tags/2.6.0 svn+ssh://svnrepo/vendor/yui trunk /src/yui-2_6_0
There are four parts to this command:
-t tags/2.6.0: creates a tagged version of the imported code
svn+ssh://svnrepo/vendor/yui: the location of the vendor branch
trunk: the subdirectory of the vendor branch where the updated code should be imported
/src/yui-2_6_0: the path to the updated YUI library code downloaded from the YUI site
Once you’ve executed this command you would continue with modification of the vendor branch just as you would if you had updated it manually.
Working with both externals and vendor branches should ease the process of integrating third-party code. For more detailed information on these topics see the documentation from the SVN book.