file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.

htm

ClearCase: The Ten Best Triggers
By Daniel Diebolt
q q q

q

Introduction Usage The 10 Best Triggers r Preventive Triggers 1. Rmelem trigger Trigger installation / Trigger script Usage r Post-Operation Triggers 2. Check comment trigger Trigger installation / Trigger script Usage 3. Remove empty branch Trigger installation / Trigger script Usage 4. Change owner trigger Trigger installation / Trigger script Usage 5. Execute bit set Trigger installation / Trigger script Usage 6. Choose coffee + net send Trigger installation / Trigger script Usage r Pre-Operation Triggers 7. Label naming convention Trigger installation / Trigger script Usage r Integration Triggers 8. Bug / feature number attribute trigger Trigger installation / Trigger script Usage 9. RCS Keyword substitution Trigger installation / Trigger script Usage 10. Sticky bit Trigger installation / Trigger script Usage Problems not solved Conclusion

Introduction
Rational ClearCase is a Software Configuration Management tool that benefits both small and large software development teams.
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (1 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

The complexity of the tool, and the fact that individual developers use it in different ways, can make the life of a Software Configuration Manager quite difficult. Over the last few years I've performed many implementations and presentations with ClearCase. I've observed that even though every project is unique, and each organization has its own approach to solving problems, the same questions about ClearCase usage always come up. Since I didn't want to reinvent the wheel for every project, I collected some of the most useful triggers that I've used during implementations. I made these as generic as possible to increase their applicability across projects. The practice has helped me immensely: I now have a collection of triggers that I can easily use to answer recurring questions about ClearCase usage. This document describes the 10 most useful triggers, which should help make the daily work of a Software Configuration Manager less complicated.

Usage
A word of caution: All the triggers described in this document are delivered "as is." There is no official support offered by Rational Software for these scripts and triggers. Also, as described in the ClearCase manual, triggers are always launched on the client computer, using the identity of the user who initiated the ClearCase command. All my triggers were developed in one of three languages: either directly as shell / batch, in Perl, or using the ClearCase API (CAL). I am not a Perl expert, and you will immediately see that my Perl language knowledge is limited, but hopefully these scripts are easy to understand. Nor am I a Visual Basic expert, and after looking over my VB programs you may get the feeling that they could be rewritten in a more optimized way. In any case, feel free to contact me with either your comments or suggestions for improvements that you would like to see in these scripts.

The 10 Best Triggers
Here's a list of the 10 best triggers for use with ClearCase, compiled from my daily work as a Rational consultant. To use these triggers, you must be the VOB owner, and reside in the VOB upon which you wish to perform the command. Associated with each trigger, you'll find a command to attach it to a VOB. Trigger scripts should be saved in a central, shared directory, such as NFS share for UNIX or SMB share for Windows. The best central place to put ClearCase triggers and scripts is actually the VOB storage share. If that's not available to you, you probably don't have access to the VOBs, and so you probably don't need triggers. In large organizations, ClearCase triggers and scripts can also be put under version control, and then accessed using a path such as:

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (2 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm
q q

/view/administration_view/VOB/trigger_VOB/directory (UNIX) \\view\administration_view\trigger_VOB\directory (Windows)

Nevertheless, you must have an administration_view available on each client computer. For example, all the triggers that follow, were stored in:
q q

/net/titeuf/triggers/ (UNIX) \\mw-ddiebolt\triggers\ (Windows)

Preventive Triggers
ClearCase contains some very powerful commands, and you may want to limit access to them in a particular ClearCase installation. The following trigger shows how to prevent some project users from initiating a specific ClearCase command.

1. Rmelem trigger
The cleartool rmelem command is one of the most powerful commands in ClearCase because it removes a complete element from version control. This command destroys information irretrievably. Using it carelessly may compromise your organization's ability to support previous releases. Since this command can be so destructive, the cleartool rmname command should be used in its place in almost all cases. It's probably pretty clear why this is one of the first commands on which I like to put a trigger. Trigger installation / Trigger script Here is the trigger definition: cleartool mktrtype -c "Trigger to avoid rmelem command" -element -all -preop rmelem execwin "ccperl -e \"exit 1\"" -execunix "Perl -e \"exit 1\"" NO_RMELEM The trigger script is pretty straightforward: it simply invokes the ClearCase embedded Perl interpreter and exits with a status of false, so the ClearCase command rmelem cannot be executed. Usage When a user tries to execute the rmelem command, the following message appears: Z:\rdn>cleartool rmelem test.txt CAUTION! This will destroy the element, all its branches and versions, including all data, meta-data and history, and will remove the element from all directory versions that now contain it. Once you destroy the element, there will be no way to restore it to its current state. If you want to preserve the element, but remove references to it from future directory versions, use the "rmname" command. Element "test.txt" has 1 branches, 4 versions, and is entered in 1 directory versions.
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (3 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

Destroy element? [no] yes cleartool: Warning: Trigger "NO_RMELEM" has refused to let rmelem proceed. cleartool: Error: Unable to remove element "test.txt". Z:\rdn> Post-Operation Triggers Post triggers perform an action after a ClearCase operation, to ensure that the action occurs in conjunction with the operation. For instance, you may want an e-mail notification sent after check-in or check-out. Following is a list of triggers that perform common post-operation actions.

2. Check comment trigger
[Many thanks to Rob Platt for the nice error message.] Developers don't usually add comments when checking in or checking out a file: they can be quite lazy about this and, thus, prefer just to hit return instead of inserting an adequate comment explaining why they are making changes to the project artifacts. Encouraging this good habit by verifying that a comment has been entered in a ClearCase operation is quite easy: ClearCase has a trigger environment variable, CLEARCASE_COMMENT, which contains the comment string. Trigger installation / Trigger script This is the command to install the trigger script: cleartool mktrtype -c "Trigger to check comment" -element -all -postop checkin execwin "ccperl \\mw-ddiebolt\triggers\check_comment.bat" -execunix "Perl /net/titeuf/triggers/check_comment.pl" CHECK_COMMENT And here the trigger script: @rem = ' PERL for Windows NT -- ccperl must be in search path @echo off ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; $CLEARCASE_COMMENT $CLEARCASE_FILE1 $CLEARCASE_FILE2 = $ENV{CLEARCASE_COMMENT}; = $ENV{CLEARCASE_PN}; = $ENV{CLEARCASE_XPN};

if ( $CLEARCASE_COMMENT eq "" ) { $text = "Caution : We kindly ask you to put comments in the future..."; $status = system("clearprompt proceed -prompt \"$text\" -prefer_gui"); } __END__
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (4 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

:endofperl In the script, we check if comments were added. If not, we invoke "clearprompt," which displays a nice message to the user. Usage During any check-in without comments, the following prompt will appear:

Figure 1: hey, at least we're asking kindly diagram.

3. Remove empty branch
Developers tend to have complex configuration specifications with a lot of branches. They tend to check out files just in case they need to modify them, and then after consideration they decide to reverse the checkout. This results in elements with branches that are empty, that is, they only contain version 0. Empty branches cause neither problems nor performance issues, but it is neater to remove them. Here is a trigger that can remove the unnecessary empty branch on the fly. Trigger installation / Trigger script Installation of the trigger: cleartool mktrtype -c "Automatically remove empty branch" -element -all -postop uncheckout -execwin "ccperl \\mw-ddiebolt\triggers\test_empty_branch.bat" REMOVE_EMPTY_BRANCH Trigger script: @rem= 'PERL for Windows NT -- ccperl must be in search path @echo off ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; ########################################### # Begin of Perl section use strict;
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (5 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

my my my my my

$idstring = $ENV{CLEARCASE_ID_STR}; $element = $ENV{CLEARCASE_XPN}; $count = 0; $nidstring = $idstring; $string;

#printf "\n Trigger is fired $idstring...\n"; $nidstring =~ s/\\0/XXXXXXXXXX/g; $count = ($nidstring =~ tr/X//); #printf ("\n $nidstring Count : $count \n"); if ($count == 10) { # printf "\n Only version 0 \n"; $nidstring = $idstring; $nidstring =~ s/\\main\\0/XXXXXXXXXX/g; $count = ($nidstring =~ tr/X//); # printf ("\n $nidstring Count : $count \n"); if ($count != 10) { $element =~ s/\\0//g; $string = "cleartool rmbranch -force $element"; system($string); #printf "\n ToDo : $string \n"; } else { # We cannot delete branch main !!! } } else { # There is not only version 0 !!! } # End of Perl section __END__ :endofperl The script automatically removes the branch when there is only a version 0 on it. Caution: If you have put a label on version 0, or on the checked-out version where you undo the checkout, the branch will still be deleted. Usage Here is an example of usage: Z:\rdn>cleartool mkbranch test_branch test.txt Creation comments for "test.txt@@\main\test_branch":

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (6 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

. Created branch "test_branch" from "test.txt" version "\main\1". cleartool: Warning: Version checked out ("\main\test_branch\0") is different from version selected by view before checkout ("\main\1 "). Checked out "test.txt" from version "\main\test_branch\0". Z:\rdn>cleartool unco test.txt Save private copy of "test.txt"? [yes] no Removed branch "Z:\rdn\test.txt@@\main\test_branch". Checkout cancelled for "test.txt".

4. Change owner trigger
[Many thanks to SwissLife / Urs Winkenbach, who told me about this very good trigger.] The person who puts a file under version control is usually its owner. This element owner has special permission over it. He can remove the element, remove the version, and so on. It is a better practice if all the elements belong to the same owner — the VOB owner. Since the VOB owner is usually the ClearCase Administrator, this also results in normal users being restricted from a lot of permissions to which they perhaps don't need access. Trigger installation / Trigger script Script to create the trigger: cleartool mktrtype -c "Trigger to change element ownership" -element -all -postop mkelem -execwin "ccperl \\mw-ddiebolt\triggers\change_owner.bat" CHANGE_OWNER Trigger script: @rem= 'PERL for Windows NT -- ccperl must be in search path @echo off ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; $COMPUTERNAME $VOB $filename = $ENV{COMPUTERNAME}; = $ENV{CLEARCASE_VOB_PN}; = $ENV{CLEARCASE_PN};

$owner = `cleartool describe -long VOB:$VOB | findstr owner | findstr \/v ownership`; $owner =~ s/owner //g; $owner =~ s/ //g; chop $owner; if (!($owner eq "")) { $status = system("cleartool protect -chown $owner \"$filename\"");

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (7 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

exit $status; } fi # End of Perl section __END__ :endofperl Usage When a new file is put under version control (either over the GUI or over the command line) with a cleartool mkelem command, this script automatically sets the owner as the VOB owner.

5. Execute bit set
[Many thanks to Daniel Mencnarowski] Elements under version control in ClearCase have bits permission, in the POSIX form. For example, each file has a set of permissions in the form rwxrwxrwx for the user, group, and others. Therefore the "execute" bit, a special bit, needs to be set if you want to be able to run the element. In Windows, this means that .exe, .com, .bat, .dll, and .cmd elements need to have this execute bit set. A trigger, over mkelem, can easily be set to perform this task. Trigger installation / Trigger script This is the command to install the trigger: cleartool mktrtype -c "Put execute bits for elements" -element -all -postop mkelem execwin "ccperl \\mw-ddiebolt\triggers\executebit.bat" EXECUTEBIT And this is the script: @rem= 'PERL for Windows NT -- ccperl must be in search path @echo off ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; ########################################### # Begin of Perl section $file = $ENV{CLEARCASE_PN}; $lowerfile = lc($file); #printf("executebit.bat : $lowerfile...\n"); if (($lowerfile =~ /.exe$/) || ($lowerfile =~ /.com$/) || # Executable # COM files

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (8 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

($lowerfile =~ /.cmd$/) || ($lowerfile =~ /.bat$/) || ($lowerfile =~ /.dll$/)) { #

# Old dos CMD files # Batch files # Dll's need the bit also

printf("Putting execute bits...\n"); $status = system("cleartool protect -chmod +x \"$file\"");

} # End of Perl section __END__ :endofperl Usage The trigger is fired after new elements are created, and it changes the protection only if the element has an .exe, .com, .cmd, .bat, or .dll extension. Here is an example: Z:\rdn>cleartool mkelem test.bat Creation comments for "test.bat": This is a test . Changed protection on "\rdn\.\test.bat". Created element "test.bat" (type "text_file"). Checked out "test.bat" from version "\main\0". Z:\rdn>cleartool des test.bat@@ file element "test.bat@@" created 03-juil.-02.10:53:29 by ddiebolt.staff@mw-ddiebolt "This is a test" element type: text_file Protection: User : SWITZERLAND\ddiebolt : r-x Group: SWITZERLAND\staff : r-x Other: : r-x source pool: sdft cleartext pool: cdft Z:\rdn>

6. Choose coffee + net send
It was quite late one Wednesday evening and, after a day of implementing and describing ClearCase, we were all feeling tired. As a joke, someone came to me and asked if ClearCase could also make coffee. I answered that yes, something like that could be done — when checking out a file, ClearCase can send a message to the secretary, asking for a coffee delivery. Trigger installation / Trigger script Command to create the trigger:
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (9 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

cleartool mktrtype -c "Get some coffee trigger" -element -all -postop checkout execwin "ccperl \\mw-ddiebolt\triggers\netsend.bat" COFFEE Trigger script: @rem= 'PERL for Windows NT -- ccperl must be in search path @echo off ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; ########################################### # Begin of Perl section # # Configuration Variables # #use strict; if ($ENV{TEMP}) { $TDIR=$ENV{TEMP}; } else { $TDIR="c:${S}temp"; } $S $JUNK $coffee_choosed $LIST_COMPUTER $CLEARCASE_XPN $CLEARCASE_USER $CLEARCASE_COMMENT = "\\"; = $TDIR . $S . "junk"; = "c:".$S."temp".$S."coffee_choosed"; = "\\\\mw-ddiebolt\\triggers\\list_computers.txt"; = $ENV{CLEARCASE_XPN}; = $ENV{CLEARCASE_USER}; = $ENV{CLEARCASE_COMMENT};

$status = system("clearprompt list -outfile $coffee_choosed -items \"dark coffee\",\"tea\",\"chocolate\" -prompt \"Choose a coffee\" -prefer_gui"); if ($status != 0) { exit $status; } $coffee = `cmd /c type $coffee_choosed`;
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (10 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

chop $coffee; $status = `del $coffee_choosed`; $MESSAGE = "$CLEARCASE_USER : The $CLEARCASE_XPN file was checked out. Please bring $coffee !!!"; open(COMPUTER,$LIST_COMPUTER); while ($computer=<COMPUTER>) { chop $computer; printf("Echo Processing computer : $computer \n"); $command="net send $computer \" $MESSAGE \" > NUL 2> NUL"; $status = system($command); } close(COMPUTER); # End of Perl section __END__ :endofperl Example of a list_computer.txt: mw-ddiebolt Usage During file checkout, you get the following message:

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (11 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

Figure 2: The menu diagram. After choosing your favorite beverage, your secretary will be sent the following message:

Figure 3: Just make sure you define an address other than mine when using this

Pre-Operation Triggers
Sometimes, we want to enforce a particular convention or style of usage for ClearCase. To do this we place a trigger that occurs before an operation, to make sure that all ClearCase users follow this convention. The following example makes sure that the names of newly created labels adhere to a particular convention.

7. Label naming convention
[Many thanks to Schindler Lift, Beat Arnold, who gave me these good ideas.]
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (12 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

After a few months of using ClearCase and Software Configuration Management, you tend to get a lot of labels in the VOB database. The naming consistency, of course, is not always the best. Many times I've seen variations of the same "conceptual" label: REL1, RELEASE_1, or REL_1.0. A trigger to check label-naming convention is always a good idea: you force people to follow the same guidelines, and you also control the labeling of the project more efficiently. Trigger installation / Trigger script This is the command to install the trigger: cleartool mktrtype -c "Trigger to check label naming" -type -preop mktype -lbtype all -execwin "ccperl \\mw-ddiebolt\triggers\test_label_name.bat" -execunix "Perl /net/titeuf/triggers/test_label_name.pl" CHECK_LABEL_NAME And this is the script: @rem= 'PERL for Windows NT -- ccperl must be in search path @echo off ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; ########################################### # Begin of Perl section # # Configuration Variables # my $USERPREFIX = 'USER'; my $BUGPREFIX = 'BUG'; my $RELPREFIX = 'REL'; ####################################### # # function definition # sub checkUserName { my $user = shift(@_); my $currentUser = uc($ENV{CLEARCASE_USER}); if ($user !~ m/^($currentUser)/) { `clearprompt proceed -mask proceed -type error -prompt \"Can't create label f exit 1; } exit 0; }
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (13 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

#################################################### # # main section # { my $label = $ENV{CLEARCASE_LBTYPE}; my my my my my $prefix; $KAno; $project; $version; $stream;

# check, if label is in uppercase format if ($label ne uc($label)) { `clearprompt proceed -mask proceed -type error -prompt \"CCFS: Label not in u exit 1; } # decompose label if ($label =~ m/^($USERPREFIX)_(.*)_(.*)$/) { &checkUserName($2); } elsif ($label =~ m/^($BUGPREFIX)_(.*)$/) { exit 0; } elsif ($label =~ m/^($RELPREFIX)_(.*)$/) { exit 0; } { # no valid prefix found `clearprompt proceed -mask proceed -type error -prompt \"No valid Label speci exit 1; } } # End of Perl section __END__ :endofperl In the script, we verify that the label is correctly named: in uppercase format, and beginning with either USER, BUG, or REL.

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (14 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

Usage Using this trigger, only the following forms can be created:
q q q

USER_<userlogin>_<something> REL_<something> BUG_<something>

If the new label does not follow the naming convention, then the following error message is displayed:

Figure 4: Now you have a gentle reminder to follow naming conventions

Integration Triggers
Another class of triggers, integration triggers, allows ClearCase to be integrated with other aspects of the underlying operating system, or with other tools that may be used in your software development environment. The following triggers integrate with the operating system and with other defect tracking systems.

8. Bug / feature number attribute trigger
UCM (Unified Change Management) implements a process over ClearCase that is mainly used in activity-oriented Software Configuration Management. For example, you are asked to associate an activity with each change you perform on the project artifacts, to help describe why the change was performed. Simulating that in normal ClearCase — prompting the user to input an activity (like a bug or a feature reference) at each checkin — isn't difficult with clearprompt. Furthermore, you can store the information about the bug/feature number in an attribute. Following is a minimal implementation of this concept. Trigger installation / Trigger script You first need to define a new string attribute to store the bug/feature number. cleartool mkattype -c "Attribute to store bug/feature number" BUGNUM It should then look like:
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (15 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

Z:\rdn>cleartool des attype:BUGNUM attribute type "BUGNUM" created 09-juil.-02.14:22:34 by ddiebolt.staff@mw-ddiebolt "Attribute to store bug/feature number" owner: SWITZERLAND\ddiebolt group: SWITZERLAND\staff scope: this VOB (ordinary type) value type: string Command to create the trigger: cleartool mktrtype -c "Trigger to store bug/feature number" -element -all -postop checkin -execwin "ccperl \\mw-ddiebolt\triggers\put_bug_num.bat" BUG_NUMBER Trigger script: @rem = ' PERL for Windows NT -- ccperl must be in search path @echo off ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; $CLEARCASE_FILE $outfile = $ENV{CLEARCASE_XPN}; = "c:\\bug_num.txt";

$text = "What is the bug / feature number reference ?"; $status = system("clearprompt text -outfile $outfile -prompt \"$text\" -prefer_gui"); $bug_num = `cmd /c type $outfile`; printf("\n Put bug num $bug_num on $CLEARCASE_FILE \n"); if ($status != 0) { exit $status } else { system("cmd /c del $outfile"); $status = system("cleartool mkattr -replace BUGNUM \"\\\"$bug_num\"\\\" $CLEARCASE_FILE "); exit $status; } __END__ :endofperl Usage
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (16 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

During element checkin, you see the following dialog message:

Figure 5: Here, you are prompted to enter reference information If you then display the version tree of the checked-in file, you get:

Figure 6: Note the naming of the bug

9. RCS Keyword substitution
[Many thanks to David Weintraub.] Adding the version number, the history, and other information from the Software Configuration Management system directly to the source file is a common request. Users of RCS SCM systems are used to being able to input the source file keywords during checkin/checkout. A trigger at checkin can simulate this behavior in ClearCase.

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (17 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

Trigger installation / Trigger script Installation of the script: cleartool mktrtype -c "RCS Keyword substitution in a source file" -element -all preop checkin -eltype text_file -execwin "ccperl \\mwddiebolt\triggers\keyword_subst.perl" -execunix "Perl /net/titeuf/triggers/keyword_subst.perl" KEYWORD_SUBST The keyword_subst.perl script: package CCASETriggers::keyword_subst; sub run { ######################################################################## # PURPOSE: CLEAR CASE CHECKIN TRIGGER # # original version programmed by: David Weintraub # Date: February 4, 1997 # Description: This program uses the RCS strings and fills them # in. Certain strings can be marked as "required" # and checks will fail if they aren't found in the file. # ######################################################################## # REQUIRE STRINGS # # A little backwards, but simple. If the value of the following is # zero, the RCS string is required, and a checkin won't procede if # not found. # $require{"Author"} = 1; #Name of User who Checked in Program $require{"Date"} = 1; #Date & Time (GMT) $require{"Header"} = 1; #$directory/$CLEARCASE_XPN Date Author $require{"Id"} = 1; #$CLEARCASE_XPN Date Author $require{"Name"} = 1; #Program's Name $require{"Revision"} = 1; #branch/revision $require{"Source"} = 1; #$CLEARCASE_XPN $require{"Log"} = 1; #This is where Checkin Comments go! my $logLength = @_\\\\[0\\\\]; #Minmum size required for comments. $logLength = 0 unless ($logLength); #just in case it's not defined ######################################################################## # CONSTANTS # $VOB="$ENV{'CLEARCASE_VOB_PN'}"; $unix=($VOB =~ /^\/+.*/); $Source = $Name = $CC_PN = "$ENV{CLEARCASE_PN}"; $Revision = "$ENV{CLEARCASE_ID_STR}"; $Log = $ENV{'CLEARCASE_COMMENT'}; $Author = $author = "$ENV{CLEARCASE_USER}"; $userName = "$Author"; if ($unix) { $userName = (getpwnam("$Author"))\\\\[6\\\\];
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (18 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

$Author = "$userName ($Author)"; $Name =~ s+.*/++; #Remove Directory Information } else { # remove Drive and View information; $view = "$ENV{CLEARCASE_VIEW_TAG}"; $Source =~ s/^\w://; $Source =~ s/^.*\\($view)\\/\\/; $Name = $Source ; $Name =~ s+.*\\++; } ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time); $year = $year + 1900; # not a Y2K bug, but functionality of fct. gmtime $mon = $mon + 1; # range of month:0..11 $Date = sprintf ("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d GMT", $year, $mon, $mday, $hour, $min, $sec); $Header = "${Source}\@\@$Revision ${Date} ${author}"; $Id = "${Name}\@\@${Revision} ${Date} ${author}"; $whatID="@(#)"; $tmp = $ENV{TMP}; $tmp = $ENV{TEMP} unless ($tmp); $tmp = "/tmp" unless ($tmp); $workFile = "$tmp\\ct.ci.$$"; ######################################################################## # First: CHECK COMMENT LENGTH (just in case the trigger check_comment # might be the second one called) # if (length($Log) < $logLength) { $message = "Your Checkin Comment must be at least $logLength character"; $message .= " long. \nRedo the Checkin with a longer comment!!!\n"; die("$message"); } ######################################################################## # CHECK IF IDENTICAL VERSION OF FILE # #chop ($diff = `cleartool diff -pre -ser "$CC_PN"`); #die("'$Name' is identical to it's predecessor. Use uncheckout instead...\n") # if ( $diff eq "Files are identical"); ######################################################################## # OPEN WORK FILE AND SOURCE FILE # open("SOURCE", "$CC_PN") || &error("Could not open Source File $CC_PN for reading"); open("WORKFILE", ">$workFile") || &error("Could not open Work File $workFile for writing"); ######################################################################## # LOOP THROUGH FILE AND FIND WHAT STRINGS # while (<SOURCE>) { $LogLineState = 0; #Needed for below #
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (19 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

# # # #

####Quite Simple, if you find the RCS Keyword in the file ####Simply substitute in the new value. Then you can write ####this line back to the work file. SWITCH: { /\$Author:?.*\$/ && do { s/\$Author:?.*\$/\$Author: $Author \$/; $require{"Author"} = 1; last SWITCH; }; /\$Date:?.*\$/ && do { s/\$Date:?.*\$/\$Date: $Date \$/; $require{"Date"} = 1; last SWITCH; }; /\$Header:?.*\$/ && do { s/\$Header:?.*\$/\$Header: $whatID $Header \$/; $require{"Header"} = 1; last SWITCH; }; /\$Id:?.*\$/ && do { s/\$Id:?.*\$/\$Id: $whatID $Id \$/; $require{"Id"} = 1; last SWITCH; }; /\$Name:?.*\$/ && do { s/\$Name:?.*\$/\$Name: $Name \$/; $require{"Name"} = 1; last SWITCH; }; /\$Revision:?.*\$/ && do { s/\$Revision:?.*\$/\$Revision: $Revision \$/; $require{"Revision"} = 1; last SWITCH; }; /\$Source:?.*\$/ && do { s/\$Source:?.*\$/\$Source: $Source \$/; $require{"Source"} = 1; last SWITCH; };

# # # # # # # #

####Write Comments ####A Tad Trickier. Comments in ClearCase can be multiple lines. ####Like RCS, I assume that everything before the $Log$ is needed ####for each comment line too. This is my LogLinePrefix. ####Once this file is written back, I fill in the checkin comments ####in the following lines.

/\$Log:?.*\$/ && do { $LogLineState = 1; s/^(.*)\$Log:?.*\$/${1}\$Log: ${Name} \$/;

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (20 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

$LogLinePrefix = $1; $require{"Log"} = 1; }; } print WORKFILE; if($LogLineState) { # # # # # # # ####Add Checkin Comments to under Log Line ####Under the $Log$ Line, I put the file version and the WIP ####value if there is one (for DDTs Integration). I then ####peel off one line at a time of the comments and add them to ####the workfile. print WORKFILE "$LogLinePrefix $Revision $Date $Author\n"; if ($Log) { $LogLine = "$Log"; # necessary for double \r in comments from the # CC comment window, might be removed later $LogLine =~ s/\r//g; $LogLine =~ s/^(\\\\[^\n\\\\]*)/${LogLinePrefix} ${1}/; $LogLine =~ s/\n(\\\\[^\n\\\\]*)/\n${LogLinePrefix} ${1}/g; print WORKFILE "$LogLine\n"; } } } ######################################################################## # CLOSE FILES # close WORKFILE; close SOURCE; ######################################################################## # CHECK TO SEE IF ALL REQUIRED FIELDS ARE FOUND # $requireFlag = 1; #Assume everything is okay $message = ""; foreach $RCSkeyword (keys(%require)) { if ($require{"$RCSkeyword"} == 0) { $requireFlag = 0; #Missing a Required Keyword! $message .= "RCS Keyword <$RCSkeyword> is required but not found\n"; } } if ($requireFlag == 0) { $message .= "\nRequired RCS Keywords are missing from file <$Name>.\n"; $message .= "Reedit this file and insert the missing RCS Keywords\n"; &error("$message"); } ######################################################################## # COPY FILE TO LOCATION # # I'd love just to use the "mv" command, but Windoze NT is a pain. # I'll have to do the whole thing manually;

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (21 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

open (WORKFILE, "$workFile") || &error ("Could not open Work File $workFile for reading"); open (SOURCE, ">$CC_PN") || &error ("Could not open Source File $CC_PN for writing"); while(<WORKFILE>) { print SOURCE; } close(WORKFILE); close(SOURCEFILE); unlink($workFile); return 0 } ######################################################################## # SUBROUTINE ERROR # sub error { close(WORKFILE); unlink($workFile); my ($message) = @_; die ($message."\nUnable to continue checkin ...\n"); } # run(); 1; Usage When the trigger is installed, you can use it by entering the following keywords in all source files (For example, all elements of type "text_file"). $Author:$ $Date:$ $Header:$ $Id:$ $Name:$ $Source:$ $Log:$ Example (after substitution): /* ==================================================================== /* /* /* /* This is an example of RCS keyword substitution /* /* /* $Author: ddiebolt $ /* /* $Date: 1999-07-16 15:16:02 GMT $

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (22 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*

$Header: @(#) \app_VOB\lolo.c@@\main\37 $Id: @(#) lolo.c@@\main\37 $Name: lolo.c $ $Revision: \main\37 $ $Source: \app_VOB\lolo.c $

1999-07-16 15:16:02 GMT ddiebolt $

ddiebolt $

1999-07-16 15:16:02 GMT

$Log: lolo.c $ \main\37 1999-07-16 15:16:02 GMT ddiebolt This is a test \main\36 \main\35 \main\34 \main\30 1999-07-16 1999-07-16 1999-07-16 1999-07-16 15:14:14 15:13:17 15:11:58 14:55:00 GMT GMT GMT GMT ddiebolt ddiebolt ddiebolt ddiebolt

=========================================================== */

10. Sticky bit
When you point the sticky bit to the group for a directory on UNIX (or at least on Solaris), all files created inside get the same group and directory as the primary group. I've had requests for the same feature in ClearCase. Since ClearCase also has the sticky bit option, I expected the same output as UNIX. Unfortunately, that's not the case. I needed to write some triggers to simulate that. Since you can require a group assignment while creating a new directory, I decided to approach the problem a bit earlier in the process. Here is my solution. Trigger installation / Trigger script Trigger installation: cleartool mktrtype -c "Sticky bit behaviour for directories" -element -all -postop mkelem -execwin "ccperl \\mw-ddiebolt\triggers\stickybit.bat" STICKYBIT Trigger script: @rem= 'PERL for Windows NT -- ccperl must be in search path @echo off

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (23 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

ccperl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; ########################################### # Begin of Perl section # # Fixed variable # $COMPUTERNAME $S $group_choosed = $ENV{COMPUTERNAME}; = "\\"; = "c:".$S."temp".$S."group_choosed";

# # Configuration Variables # $VOB $dir $filename $element_type = = = = $ENV{CLEARCASE_VOB_PN}; $ENV{CLEARCASE_PN}; $ENV{CLEARCASE_PN}; $ENV{CLEARCASE_ELTYPE};

#printf("stickybit.bat : $VOB $dir $filename $element_type \n"); if ($element_type eq "directory") { $list_group = `cleartool describe -long VOB:$VOB | findstr group`; $list_group =~ s/Additional groups:\n//g; $list_group =~ s/group //g; $list_group =~ s/ //g; $list_group =~ s/\n/,/g; $status = system("clearprompt list -outfile $group_choosed -items $list_group -prompt \"Choose a group\" -prefer_gui"); if ($status != 0) { exit $status; } $group = `cmd /c type $group_choosed`; chop $group; $status = `del $group_choosed`; # printf("cleartool protect -chgrp $group $dir\n"); if (!($group eq "")) { $status = system("cleartool protect -chgrp $group \"$dir\"\n"); } exit $status; }

else
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (24 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

{ $group = `cleartool describe -fmt \"%Gu\" .`; # printf("cleartool protect -chgrp \"$group\" $filename\n"); $status = system("cleartool protect -chgrp \"$group\" \"$filename\"\n"); exit $status; } fi # End of Perl section __END__ :endofperl Usage When a new directory element is created, the following dialog box appears:

Figure 7: Now groups can be assigned automatically You then must choose a group on the VOB group list, so you can protect the new directory with this group. If you choose "Abort" or do not select any group, then the primary group will be set as the default (or your CLEARCASE_PRIMARY_GROUP setting). When a new element is created, it will automatically be assigned a directory group.
file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (25 of 26) [4/6/2004 12:11:37 PM]

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm

Problems not solved The trigger script has the following problems:
q q q q

It only works and is tested on Windows. It is using findstr, which should be replaced by grep on UNIX. Group names cannot contain any spaces. Users need to be in the group chosen

Conclusion
With these 10 triggers, we are able to extend the flexibility and control a Software Configuration Manager should have over:
q q q

Handling permissions Handling naming / process conventions Special user requests such as automatic notification, publication, and so on

file:///C|/Documents%20and%20Settings/avaughan/Desktop/getstart/HTML/10triggers.htm (26 of 26) [4/6/2004 12:11:37 PM]

Master your semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master your semester with Scribd & The New York Times

Cancel anytime.