可以设置Trigger的ClearCase 操作
声明:在本文中描述的Trigger在实际应用中需要做修改,如果直接应用可能会产生不明后果,本文作者对此概不负责。
首先我们来看一下应用UCM模式的Trigger。UCM中Rational 已经提供一些基本的流程定制,可以简化我们创建分支、版本归并的许多操作,但是每个项目都是独一无二的,对于复杂的项目,UCM不能完全满足需要。所有UCM类型的操作基本对应同样Cleartool子命令,其中Deliver类、Rebase类及mkbl_complete操作是特例,这些操作不对应具体的cleartool子命令。针对UCM模式有以下几类ClearCase操作:
1. Deliver:将源流的修改提交到目标流;创建Trigger可以针对deliver_start,deliver_cancel,deliver_complete这三个操作;cleartool deliver子命令会引起这几个操作;Deliver包括Deliver from Stream与Deliver Baseline两种。在创建完Trigger后,需要将Trigger关联到目标流上,Trigger才能起作用。在创建针对Deliver操作的Trigger时只能设置Stream与Project进行约束。
2. Rebase:从源流获取最新的修改;其中包括rebase_start,rebase_cancel,rebase_complete这三个操作。与Deliver操作类似,在创建完Trigger后,需要将Trigger关联到目标流上,Trigger才能起作用。在创建针对Rebase操作的Trigger时只能设置Stream与Project进行约束。
3. Activity:其中包括mkactivity,chactivity,rmactivity,setactivity这四个操作。其中针对mkactivity的Trigger需要关联到要创建活动的流,其他三个操作的Trigger需要关联到要操作的活动。在创建针对Activity操作的Trigger时只能设置Stream与Project进行约束。
4. Stream:其中包括mkstream,chstream,rmstream这三个操作。其中针对mkstream的 Trigger需要被关联到要创建流的project,其他两个操作的Trigger需要关联到被操作的流。同时,在创建针对mkstream操作的Trigger只能设置Project进行约束,而对其他两个操作可以设置Stream与project约束条件。
5. Baseline:其中包括mkbl,mkbl_complete,chbl,rmbl这四个操作。mkbl_complete操作是一个特例,从cleartool mkbl子命令来看,针对的是Component,而mkbl_complete是对一个Stream上所有的Component打上baseline的操作,可以理解为在图形界面下,针对一个Stream执行Make Baselines。所以针对mkbl_complete 的Trigger必须关联到要执行Make Baselines的Stream上,其他三个操作都要被关联到与Baseline有关的Component上;针对mkbl与mkbl_complete操作,可以设置Stream、Component与Project约束条件,针对另两个操作只可以设置Component与Project 约束条件。另外针对mkbl,如果在环境变更中CLEARCASE-PROJECT与CLEARCSE_STREAM都没有被定义,则针对Component执行Import Label时也会触发Trigger。
6. Project:其中包括mkproject,chproject,rmproject这三个操作。其中针对mkproject操作的trigger需要关联到PVOB,并且不能设置约束条件,另两个条件则需要关联到被操作的Project上,并可以针对Project设置约束条件。
7. Component:其中包括mkcomp与rmcomp这两个操作。针对这两个操作的trigger需要被关联到PVOB,并且不能设置约束条件。
8. 其他:其中包括mkfolder,chfolder与rmfolder这三个操作。针对这些操作的的Trigger需要被关联要操作的Folder,并且可以设置project约束条件。
在前面根据需要定制Trigger一节,描述了我对Deliver操作的理解,这里我们仔细看一下,针对Deliver的操作我们可以定制哪些Trigger,需要注意这些Trigger都比较简单,是针对某一项非常明确的需求,在具体应用时要加以组合成为一个Trigger。
1. deliver_start:Stream的 Policy中有一些设置可以理解为已设置好的Trigger,deliver_start这个操作的事前触发的Trigger在检查完Project及Stream的Policy之后才会被触发,所以没有必要在这里设置Trigger检查源流是否有未Check in的配置项、是否执行了Rebase操作等,这些可以通过设置Stream的Policy来解决;针对deliver_start,可以设置以下Trigger:
a) 事前触发(preop)的Trigger,检查是否有Deliver的权限:Cleartool mktrtype –ucmobject c "Only Cuibz could execute deliver opeartion" -element -preop deliver_start -nusers cuibz -execunix "Perl -e /"exit -1;/"" -execwin "ccperl -e /"exit (-1);/"" deliver_check;之后我们可以将这个Trigger关联到相应的流上,需要注意的是Deliver及Rebase类型操作的Trigger要关联到要Deliver或Rebase的Stream上,即目标流,否则不会起作用;cleartool mktrigger deliver_check stream:test_Int@/Test_PVOB,这里你可以根据实际情况修改stream。如果目标流上只允许有deliver权限的人员进行Deliver操作,则可以不设置这个trigger,而是简单的锁定目标流,同时将有权限的操作人员加入Excluded中即可。
b) 事前触发的trigger,锁定目标流,这样可以避免针对同一个配置项进行多个Deliver同时操作导致的Merge及Check out的Reserved及Unreserved的问题(对一个配置项只能有一个Reserved 类型check out操作,其他都为Unreserved操作,在Reserved类型check out没有check in之前,其他Unreserved类型的check out操作不能check in);需要注意,如果认定了这个Trigger,则要有针对deliver_cancel及deliver_complete的事后触发的trigger,来对目标流及源流进行解锁。具体的Trigger如下:cleartool mktrtype –ucmobject –preop deliver_start –exec “cleartool lock –nusers %CLEARCASE_USER% stream:%CLEARCASE_STREAM%” -comment “Lock source stream except operater” deliver_lock_targetstream。其中lock命令的参数中-nusers %CLEARCASE_USER%的目的是在锁定目标Stream后,可以让deliver这个操作的发起用户不受影响,否则会无法执行deliver操作;%CLEARCASE_STREAM%是目标Stream,但是前面一定要加上stream:这个前缀,否则锁定时cleartool lock这个命令会无法识别,导致deliver操作被拒绝。
c) 事前触发的trigger,锁定源流,这样可以避免准备提交时,有用户check in不准备提交的版本;具体Trigger如下:cleartool mktrtype –ucmobject –preop deliver_start –exec “cleartool lock –nusers %CLEARCASE_USER% stream:%CLEARCASE_SRC_STREAM%” -comment “Lock target stream except operater” deliver_lock_sourcestream。%CLEARCASE_SRC_STREAM%是源Stream。你可以将这这个trigger与前一个trigger结合起来,同时锁定目标流与源流,具体trigger如下:cleartool mktrtype –ucmobject –preop deliver_start –exec “cleartool lock –nusers %CLEARCASE_USER% stream:%CLEARCASE_STREAM% stream:%CLEARCASE_SRC_STREAM%” -comment “Lock target and source stream except operater” deliver_lock_stream。
d) 事前触发的trigger,通过脚本对源流进行构建,以验证提交的源码的完整性,如果构建失败,则可以自动回滚deliver操作,并给出提示;这个trigger如果和下一个结合在一起可以支持在目标流上的Daliy Build工作。
e) 事后触发的trigger,对目标流进行构建,如果构建失败,则执行自动执行deliver –cancel回滚deliver操作;一般情况下建议和上一个trigger合并为一个trigger,先检测在源流修改是否可构建,再检测目标流上配置项经过merge后,是否可构建,这样可以支持在目标流上的Daliy Build工作。
f) 事后触发的trigger,对锁定的源流进行解锁。 Trigger如下:cleartool mktrtype -ucmobject –postop deliver_start –exec “cleartool unlock stream:%CLEARCASE_SRC_STREAM%” -comment “Unlock source stream” deliver_unlock_source_stream。
g) 事前触发的trigger,将deliver的发起人、源流、目标流、活动等信息发送邮件到相关人处。可以参见IBM Rational ClearCase随机帮助文档cc_proj.pdf。
h) 如果应用脚本等,还可以建议设置其他的trigger,如锁定源流上要提交的活动,或检查目标流上要进行归并的配置项是否处于check out状态等。
i) 检查目标流是是否有正在执行的Deliver操作。保证目标流上的Deliver是唯一的,这个脚 本在 IBM Rational ClearCase的随机帮助文档cc_proj.pdf中有,章节为Working in UCM -> Using Trigger to Enforce Development Policies -> Enforce Serial Deliver Operations,读者可以自行查看。
2. deliver_cancel:如果没有执行deliver_complete,则回滚deliver操作,针对这个clearcase操作,可以设置以下trigger:
a) 事前触发的trigger,检查权限,确保只有deliver操作发起者与配置管理人员才能进行回滚deliver操作,这样可以避免以下这种情况:一个deliver在进行中,其他人员由于尝试进行其他deliver导致回滚原deliver问题。
b) 事前触发的trigger,将deliver -cancel的消息发送到相关人员处。
c) 事后触发的trigger,对目标流、源流、活动等进行解锁,如果在deliver_start中设置了trigger对目标流、源流、活动等锁定,则回滚时一定要进行解锁。
d) 事后触发的Trigger:与事前触发的保证 Deliver操作唯一性的Trigger对应,同样参见IBM Rational CleaseCase的随机文档cc_proj.pdf。
3. Deliver_complete:将目标流上check out的配置项check in,并打上隐藏的delivered基线,针对这个clearcase操作,可以设置以下trigger:
a) 事前触发的trigger,检查权限,确保只有deliver操作发起者与配置管理人员才能进行执行deliver -complete操作。
b) 事后触发的trigger,对应deliver_start相应的trigger,如果在deliver_start的trigger中锁定了目标流、源流或活动,则在deliver_complete后进行解锁。
c) 事前触发的trigger,对目标流进行构建,如果构建失败,则提示进行回滚,一般情况下建议如果在deliver_start中设置事后触发的trigger检查对目标流进行构建检查,则不必在deliver_complete设置此trigger。
d) 事后触发的trigger,将目标流打上baseline。
e) 事后触发的trigger,发起对目标流上所有静态视 图的update操作。
f) 事后触发的trigger,发送邮件通知相关人员,deliver已经完成,构建工程师可以进行构建及版本发布,测试人员可以开始测试工作。
g) 事后触发的trigger,自动对各个相关的流执行rebase,这个trigger需要注意,一般情况下只rebase推荐基线,刚deliver的不一定是稳定的基线,所以不建议使用该trigger。
针对其他UCM类型操作的Trigger可以参考IBM Rational ClearCase随机帮助文档cc_proj.pdf。
接着我们来看一下针对配置项的ClearCase操作有哪些可以定义Trigger;需要注意,和针对UCM对象的ClearCase操作不同,针对配置项的ClearCase操作并不等同于cleartool的子命令。针对配置项的ClearCasse操作有以下几类:
1. Modify_ELEM:对配置项的修改,包括以下ClearCase操作
a) checkout:Check out命令一定会导致这个操作,clearimport、findmerge、mkelem、mkbranch 与relocate命令可能会发起checkout操作。针对checkout操作,我们可以设置Trigger,发送通知有checkout操作进行,尤其是针对clearimport、findmerge、mkelem、mkbranch 与relocate操作,因为这些命令如果导致checkout操作,大多数情况下是增加配置项或更改配置项的目录等,这种情况需要通知相关人员。也可以用Trigger进行权限控制等。如果是多个开发人员在一个开发流上进行开发,也可以设置一个事后触发的Trigger,将所有Reserved类型的Checkout改为Unreserved类型,以防止针对同一配置项多人Check out后,如果Reserved Check out没有执行Check in操作,其他Check out都不能执行check in操作;针对checkout的Trigger除了设置配置项类型与分支类型的约束条件。
b) chevent:为配置项关联的某个event修改注释,一般情况下只有chevent命令可以导致这个操作;针对这个操作,设置事前触发的Trigger只允许配置管理员执行可以防止对注释的错误修改。
c) reserve:将unserved类型的checkout操作改为reserved类型的checkout操作,一般情况下可以设置一个事前触发的Trigger,防止开发人员任意修改操作导致其他开发人员必须等待,不能执行check in操作的问题。
d) unreserve:将reserved类型的check out操作改为Unreserved类型的Check out操作;可以设置一个事前触发的Trigger,防止其他人修改check out类型,限制任意的check out操作,这个Trigger与reserve的Trigger是对立的;也可以设置一个事后触发的Trigger,邮件通知原check out操作人员,你的check out操作类型被修改了,其他人可以不等原操作者Check in就执行Check in操作了。
e) uncheckout:回滚Check out操作;可以设置事前触发的Trigger,检查权限,只允许Check out操作人与配置管理人员执行该操作。
2. MODIFY_DATA:包括以下ClearCase操作:
a) Check in操作:check in、mkelem与mkbranch一定会导致这个操作,clearimport与relocate可能会导致这个操作。可以设置事前触发的Trigger,检查权限;也可以设置事后触发的Trigger,更新静态视图,可以应用脚本检查注释是否符合要求等。
b) chtype:修改配置项的类型及各个Type,只有chtype会导致这个操作;可以设置事前触发的Trigger,检查权限。
c) lnname:将配置项链接到某个目录配置项,ln、ln –s、mkelem、mkdir与mv一定会导致这个操作,relocate可能会导致这个操作;可以设置事前触发的trigger检查权限。
d) lock:这里的lock只是针对配置项的lock,而不包括对Type及UCM Object;可以设置事前触发的trigger检查权限。
e) mkbranch:产生新的分支;mkbrach、mkelem一定会导致这个操作,checkout、clearimport与relocate可能会导致这个操作;可以设置事前触发的trigger检查权限。
f) mkelem:新建配置英;mkelem与mkdir一定会导致这个操作,clearimport与relocate可能会导致这个操作;可以设置事前触发的trigger检查权限。
g) mkslink:在目录配置项下建立另一个配置项的Symbolic Link;ln –s一定会导致这个操作,可以设置事前触发的trigger检查权限。可以设置事前触发的trigger检查权限。
h) protect:修改配置项的Owner、Group及权限;只有protect会导致这个操作;可以设置事前触发的trigger检查权限。
i) rmbranch:删除分支;只有rmbranch会导致这个操作;可以设置事前触发的trigger检查权限。
j) rmelem:完全的删除配置项;rmelem一定会导致这个操作,relocate可能会导致这个操作发生;再这里再一次介绍我认为最重要的Trigger,强烈建议所有的VOB都 要建立这个Trigger,禁止配置管理人员以外人员删除配置项:Cleartool mktrtype -c "Only Cuibz could execute rmelem" -element –all -preop rmelem -nusers cuibz -execunix "Perl -e /"exit -1;/"" -execwin "ccperl -e /"exit (-1);/"" rmelem_check。
k) rmname:从一个目录配置项内移走一个配置项;rmname、rmelem与mv一定会导致这个操作;可以设置事前触发的trigger检查权限。
l) rmver:删除配置项的某一个版本;rmver一定会导致这个操作,注意:checkvob –fix命令也可能会导致这个操作;同rmelem一样,建议一定要建立禁止配置管理人员以外人员删除版本的事前触发的trigger:Cleartool mktrtype -c "Only SCM could execute rmelem" -element –all -preop rmver -nusers cuibz -execunix "Perl -e /"exit -1;/"" -execwin "ccperl -e /"exit (-1);/"" rmver_check。
m) unlock:对配置项进行解锁;可以设置事前触发的trigger检查权限。
3. MODIFY_MD,有以下ClearCase操作:
a) chmaster:主要是针对Multisite ClearCase的,修改配置项的Mastership;
b) mkattr:将定义好的attribute关联到配置项;mkattr一定会导致这个操作,clearimport、mkhlink与relocate可能会导致这个操作发生;
c) mkhlink:将定义好的hyperlink关联到配置项;mkhlink一定会导致这个操作,clearimport、findmerge、merge与relocate可能会导致这个操作发生;
d) mklable:将定义好的label关联到配置项的某个版本;mklabel一定会导致这个操作,clearimport与relocate可能会导致这个操作发生;
e) mktrigger;将定义好的Trigger关联到配置项;mktrigger一定会导致这个操作,relocate可能会导致这个操作发生;
f) rmattr:取消配置项上关联的某个attribute;只有rmattr会导致这个操作;
g) rmhlink:取消配置项上关联的某个hyperlink;rmhlink与rmmerge一定会导致这个操作的发生;
h) rmlabel:取消配置项某个版本关联的label;只有rmlabel会导致这个操作的发生;
i) rmtrigger:取消配置项关联的某个Trigger;只有rmtrigger会导致这个操作的发生;
针对以上这些操作,可以设置Trigger检查权限。
最后是针对Type的操作,前文提到针对Type操作的Trigger设置不需要应用mktrigger,下面我们来看一下有哪些针对Type的操作可以设置Trigger:
1. chevent:修改Type对象事件的注释;
2. chmaster:主要是针对Multisite ClearCase的,修改Type对象的Mastership;
3. lock:锁定type对象;
4. mkattr:将已定义好的将定义好的attribute关联到Type对象;
5. mkhlink:将定义好的hyperlink关联到Type对象;
6. mktype:定义一个新的Type类型;
7. modtype:修改一个Type,mktype –replace可以导致这个操作;
8. mklable:将定义好的label关联到Type对象的某个版本;
9. mktrigger;将定义好的Trigger关联到Type对象;
10. rmattr:取消Type对象上关联的某个attribute;
11. rmhlink:取消Type对象上关联的某个hyperlink
12. rmtype:删除某一个Type类型;
13. rntype:修改某个Type的名称;rename可以导致这个操作的发生;
14. unlock:对某个type对象解锁;
针对以上这些操作,可以设置Trigger检查权限。
由于篇幅所限,对具体的Trigger这里没有具体描述,所有的Trigger都应进行本地化定义。
在本文的最后,我要真诚的感谢SCM论坛Rational ClearCase分论坛的朋友,在2005年2月我开始写这篇文档,由于各种原因中断,在他们鼓励下我重新完成了这篇文档。
本文参考了IBM Rational ClearCase的随机文档。本文的所有的例子都基于ClearCase 2003.06.15实现。