tags:

views:

745

answers:

1

We are migrating a fairly large codebase from VSS to Clearcase w\ UCM and are considering organizing our source into one or more components within a single project. What best practices\potential pitfalls should we keep in mind?

The source is organized into layers (data layer, business layer, GUI layer). The team is fairly small, developers tend to own a certain layer of the codebase and we anticipate a fair amount of branching due to parallel development efforts.

+1  A: 

Single most dangerous pitfall:

Once a component is defined, you cannot move an element outside of this component (you can copy it and re-create it elsewhere, but you will loose its history)

Single most useful best-practice:

Understand well the nature of an UCM component: it is about coherency.
A component is a set of file which:

  • evolves as a single unit,
  • is labeled (baselined) as a whole,
  • is branched as a whole.

If you can make evolutions without touching another group of files, chances are you have two components.

Example of components:

  • an application (or a autonomous part of an application)
  • a technical library
  • a packaged set of file (for release)

The one document that should guide you to define components is the Applicative Architecture (which takes the business and functional specifications and project them onto applications which will then be specified at the technical level and implemented).

When all those components are defined, you have two approaches to manage them:

  • system approach (every components is writable in a UCM project): useful for starting a project, but cumbersome with legacy project: you do not need to put a baseline on each and every components simply because 3 files has changed in one of those components.

  • component approach: one or two writable components, the rest is there only as non-modifiable component. This is a scalable approach, allowing you to define one project per-component to develop, with a "fixed configuration" (i.e. "the other baselines", representing fixed states of the non-modifiable components you need to have in order to compile the modifiable one. You can change at any time this configuration, that is you can rebase the foundation baselines of the non-modifiable component whenever you want).

You can define as many Projects and Streams you want, allowing you to easily visualize the merge workflow.

Remember: a Stream represents a development effort.
Do not call a Stream after a resource (like VonC_stream), but after a task or set of tasks to do in that Stream (as in APP_LCH_R32_Dev: Development for 32th release of my App Launcher)


Note: UCM is just some meta-data on top of ClearCase: even if a group of file is defined as a UCM component, nothing prevents you to still making classic non-UCM branches, checkouts or checkins (in non-UCM views).


Is there a danger in creating too many fine grained components or having too many dependencies between components?

Yes, that is why Applicative Architecture is important. Again, once a component is defined, you cannot move elements between those components.

Another details to know about components is their layout:

myVob
  myComponent1
  myComponent2
  myComponent3

A root component is always at the first level below a Vob.
You also can define a component as a all Vob but I would not recommend it (adding a Vob put stress on your Vob server. Adding a directory within an existing Vob cost nothing)

That means if you define some technical libraries as components, you cannot go as:

myLibs
  Apache
    ant
    xalan
    xerces

but will have to do:

myLibs
  apapche_ant
  apache_xalan
  apache_xerces


Final warning: dependency (the true mark of a configuration management system)

One of the main advantage of UCM (or so I thought at the time -- 2003 --) is dependency.
If A depends on B, and I put A in my project, it will automatically include B in the same project.

Magic.

But it is broken.

  • First, never do root-based dependency (a root-based component is a set of file). It will break at the first overlap:

    A1
      B1
    B2

Here you need B2 to go on building A, but A starts from A1 based on B1: B2 overrides B1. As soon as you put a baseline on A (A2), it is over. You will not be able to change B anymore. A parasite baseline (called A2!?) will have been put on the (non-modifiable!) component B because of the overlap.

  • Always include your dependencies in a rootless component
    ADep1
      A1
      BDep1
        B1
    BDep2
        B2

Here you have rootless components ADep and BDep (a rootless component is a special component which aggregates other rootless or root-based components)
You still have an override, but this time between rootless components.
That will still make a parasite baseline (on BDep, called A2), but at least you will be able to rebase BDep2 into other baselines later (BDep3, BDep4...)

More on this Incoherences and Inconsistencies of ClearCase UCM, with Rational counter-arguments here (and just after that their post, proof that their arguments are not very good to say the least).

Read also How to Leverage Clearcase’s features

VonC
Is there a danger in creating too many fine grained components or having too many dependencies between components?
zac