views:

67

answers:

4

I am the lead developer on a project whose continuing mission is the implementation, expansion, and maintenance of our highly trafficked site's content management system. The CMS is neither an in-house solution nor an open-source project - it is an expensive product purchased from a vendor. Unfortunately, it's a very... shall we say... enterprisey product.

To make a long back-story short, the product in its delivered state simply did not meet the company's technical requirements. The vendor designated a portion of the codebase that we could modify freely to implement our business requirements without changing the core product and losing the ability to upgrade to new versions easily; however, due to the nature of core product's codebase (very tight coupling, no DI, singletons everywhere, lots of "magic"), there was simply no way to implement our requirements (and fix their bugs) without "voiding our warranty", so to speak, and hacking away at the core application.

So, essentially:

  1. We can't make this product work the way we need it to work without hacking away at the core system.
  2. We can't hack away at the core system without compromising our ability to seamlessly upgrade to new versions of the vendor's product.
  3. We are stuck with the product and cannot abandon upgradability.
  4. GOTO 1

We cannot possibly be the only team that has faced this dilemma... what are some strategies you have used in the past to modify third party code to suit your needs while still being able to upgrade to their new versions as time goes on?

What I've done thus far is the following:

  1. Create unit tests (when possible - and its often not possible without an impractical amount of refactoring) for the behavior that has changed.
  2. Do as much of the modification in designated "customer area" of the codebase as possible, when possible.
  3. Created an SVN vendor branch of the initial, unmodified application to be used to merge in the new versions.

Vendor branches will only guarantee that we will know which changes to apply, but they won't help us at all with the nightmare of conflicts we're likely to encounter.

What else, if anything, can we do now to ease the pain later?

+2  A: 

Take this with a grain of salt. This is just what I would do, in the ideal situation, where I had full political impunity to do whatever the hell I wanted:

  1. Switch immediately from SVN to GIT
  2. set up a branch named CLEAN which is the original code, unmodified.
  3. set up a branch named PATCH which is your modified code.
  4. when you go to upgrade, switch to CLEAN, clobber the old version with the new version.
  5. switch to branch PATCH, diff to check for conflicts, and merge CLEAN into PATCH.
  6. Demand noisily that they fix the bugs in their product which you have spent so much money on. Send them patches. Be absolutely friendly and polite, but persistent.

switching version control systems might seem like a minor thing, but branching and merging is so much easier with git than with svn, that the time investment spent in switching will be recouped very quickly by the time you save otherwise spent on scanning line by line through conflict files, and remembering obscure merge commands. I wouldn't dream of taking on such a problem with SVN, the thought gives me heart palpitations.

Breton
+1; however, I don't see why this couldn't be done in SVN as well. I've used both (albeit SVN more extensively), and I've found it equally easy to branch and merge with both of them (and equally difficult when there are conflicts).
Mike
I find that revelation utterly shocking and surprising. You sir, must have the memory and patience of a turtle.
Breton
I'm going to assume that's a compliment. :)
Mike
+2  A: 

In the bad old days of mainframes, this was a common situation. The OS had to be hacked to match site requirements. But the OS vendor never issued patches, only released a whole new OS which had to be diffed to redo the local site patches.

To my knowledge, there was never a better solution. Computer centers had staff dedicated to patching the OS after a release came out.

All I can suggest is that you don't upgrade unless there is something desperately needed in a release. Even then, managing each vendor revision into its own source code repository would go a long way to identifying which modules you've patched and need changing. A patch from the deltas you generate can be mostly automated for new releases.

wallyk
+1  A: 

This might be overkill, but you could keep each "feature" you add in a seperate branch too. You make sure each branch (+dependent branches) works on its own. Everyone once in a while you merge them all together to see that they work together too and that's how you "build".

This way, when an upgrade comes you have a series of smaller more controlled merges to do where you know each branch should work on it own (+ dependencies). You also have this kind of dependency tree where you add in more lower level features first and work your way up etc. Maybe.

o---o------ Vendor Base V  -------o
     \                          
      o--- V + Feature A ---o---o---o
       \
        o--- V + Feature B ---o---o---o
                               \
                                o--- V + B + Feature C ---o

Well, yeah. It was just really an idea about breaking down the process into smaller parts. This way it would be easier to work several people concurrently on an upgrade too--everyone has their own "features" to test and, yeah, I duno, it just feels like it would make sense and be easier.

I believe this should be ok to do with most DCVS out there (Git, Mercurial, Bazaar). Actually I think most of them encourage such schemes. Svn is probably not really cut out for it.(?)

(But you know, of course: Secretly build your own CMS too and switch to that later :)

0scar
+1  A: 

Keep track of costs. At some point you might be able to make a decent pitch to management that switching to an alternate CMS is actually a cost-cutting measure. You definitely want to be thinking about how you can migrate out of this situation, even if it is only for a subset of your site.

Joeri Sebrechts