Rational ClearCase ベスト10トリガー

第3回 「統合トリガー(前編)」

Comments

統合トリガー

異なるクラスのトリガーである統合トリガーを使用すると、基盤となるオペレーティング・システムの他の側面や、ソフトウェア開発環境で使用している他のツールとClearCaseを連携することができます。以下のトリガーで、オペレーティング・システムおよび他の障害追跡システムと連携します。

8.バグ / 機能番号属性トリガー

UCM (Unified Change Management)は、ClearCaseを介し、主としてアクティビティー指向のソフトウェア構成管理で使用されるプロセスを実装します。

たとえば、変更理由を説明するため、プロジェクト成果物に施した各変更とアクティビティーを関連付けるとします。

通常のClearCaseをシミュレートして、clearpromptを使用すれば、チェックイン時にアクティビティー(バグや機能参照など)の入力を促すメッセージを、ユーザーに対して簡単に表示できます。

さらに、バグ / 機能番号に関する情報を属性に保存することもできます。

この概念を最小限に実装したものを以下に示します。

トリガーのインストール / トリガー・スクリプト】

最初に、バグ/機能番を保存する新規文字列属性を定義する必要があります。
cleartool mkattype -c "Attribute to store bug/feature 
number" BUGNUM
以下のように表示されるはずです。
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
トリガーの作成コマンド:
cleartool mktrtype -c "Trigger to store bug/feature number"
 -element -all -postop checkin -execwin "ccperl 
\\mw-ddiebolt\triggers\put_bug_num.bat" BUG_NUMBER
トリガー・スクリプト:
@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		= $ENV{CLEARCASE_XPN};

$outfile		= "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

【使用法】 エレメントのチェックイン中、次のようなダイアログ・メッセージが表示されます。

図1:参照情報を入力します。
参照情報を入力します
参照情報を入力します

その後、チェックインしたファイルのバージョン・ツリーを表示すると、次のように表示されます。

図2:先のダイアログで入力した文字列がバグ名として表示されます。
先のダイアログで入力した文字列がバグ名として表示されます
先のダイアログで入力した文字列がバグ名として表示されます

9. RCS 代替キーワード

\\\\\[David Weintraubに感謝します。\\\\\]

ソフトウェア構成管理システムからのバージョン番号や履歴、他の情報をソース・ファイルに直接追加するよう要求されることはよくあります。

RCS SCM システムのユーザーは、チェックイン/チェックアウト中の、ソース・ファイル・キーワードの入力操作に慣れています。

チェックイン時のトリガーで、このClearCaseの動作をシミュレートできます。

【トリガーのインストール / トリガー・スクリプト】

スクリプトのインストール:
cleartool mktrtype -c "RCS Keyword substitution in a 
source file" -element -all -preop checkin -eltype text_file 
-execwin "ccperl \\mw-ddiebolt\triggers\keyword_subst.perl" 
-execunix "Perl /net/titeuf/triggers/keyword_subst.perl" 
KEYWORD_SUBST
keyword_subst.perl スクリプト:
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\\\\\];
   $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
#
#   ####Quite Simple, if you find the RCS Keyword 
#       in the file
#   ####Simply sub?stitute 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 各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} 
					 \$/;
                    $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 = "";
for各$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;
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;

【使用法】 インストールしたトリガーを使用するには、すべてのソース・ファイル(たとえば、“text_file”タイプの全エレメント)に、以下のキーワードを入力します。

$Author:$
$Date:$
$Header:$
$Id:$
$Name:$
$Source:$
$Log:$

例(代替後):

 /* 
 ===========================================================
 /*
 /*
 /*
 /*     This is an example of RCS keyword substitution
 /*
 /*
 /* $Author: ddiebolt $
 /*
 /* $Date: 1999-07-16 15:16:02 GMT $
 /*
 /* $Header: @(#) \app_VOB\lolo.c@@\main\37  
 /* 1999-07-16 15:16:02 GMT  ddiebolt $
 /*
 /* $Id: @(#) lolo.c@@\main\37  
 /* 1999-07-16 15:16:02 GMT  
 /*
 /* ddiebolt $
 /*
 /* $Name: lolo.c $
 /*
 /* $Revision: \main\37 $
 /*
 /* $Source: \app_VOB\lolo.c $
 /*
 /* $Log: lolo.c $
 /*  \main\37 1999-07-16 15:16:02 GMT ddiebolt
 /*     This is a test
 /*  
 /*  \main\36 1999-07-16 15:14:14 GMT ddiebolt
 /*  \main\35 1999-07-16 15:13:17 GMT ddiebolt
 /*  \main\34 1999-07-16 15:11:58 GMT ddiebolt
 /*  \main\30 1999-07-16 14:55:00 GMT ddiebolt
 /*
 /*
 /*
 /* ===================================================== */

第4回 最終回 「統合トリガー(後編)・まとめ」


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Rational
ArticleID=312349
ArticleTitle=Rational ClearCase ベスト10トリガー
publish-date=10032006