Welcome, guest | Sign In | My Account | Store | Cart

Here is one example each of a pre-checkin and a post-checkin trigger, as well as a program that can register your triggers in ClearCase.

ClearCase is a software configuration management tool similar to CVS, but slightly more advanced and not free.

Python, 135 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# CommentPolicy.py - Pre Checkin Trigger 
import os, sys, re, tkMessageBox 
 
def checkComment(comment): 
    comment = comment.lower() 
    caseIds = re.findall(r'bug\d+|feat\d+',comment) 
    return caseIds 
 
def main(): 
    comment = os.environ.get('CLEARCASE_COMMENT','') 
    version = os.environ['CLEARCASE_XPN'] 
 
    error = 0 
    caseIds = checkComment(comment) 
    if not caseIds: 
        error = 1 
        tkMessageBox.showerror("Missing Case ID in check-in-comment", 
                               "Version:\n%s\n\nKommentar:\n%s" % 
                               (version, comment)) 
    sys.exit(error) 
 
# Remove # below to see what environment variables ClearCase sets. 
# 
#text = "\n".join( [" = ".join(x) for x in os.environ.items() 
#                   if x[0].startswith('CLEARCASE')]) 
#tkMessageBox.showinfo("Environment variable", text) 
     
if __name__ == '__main__':
    main()

####################################################################

# CommentPolicy2.py - Post Checkin Trigger 
import os, sys, re, tkMessageBox 
 
def checkComment(comment): 
    comment = comment.lower() 
    caseIds = re.findall(r'bug\d+|feat\d+',comment) 
    return caseIds 
 
def storeCheckInComment(caseIds, version, comment): 
    # In real life, this fuction would use ODBC, COM etc, not a dialog! 
    title = 'Store info in issue database' 
    message = ('Hello, can you store in the issue database\n'
               'that we got the following message:\n%s\n' 
               'when we checked in\n%s\n\n%s') % (" & ".join(caseIds), 
               version, comment) 
    if tkMessageBox.askyesno(title, message): 
        # Reply was yes
        return 0 
    else: 
        # Reply was no 
        return 1 
 
def main(): 
    comment = os.environ.get('CLEARCASE_COMMENT','') 
    version = os.environ['CLEARCASE_XPN'] 
 
    caseIds = checkComment(comment) 
    if not caseIds: 
        error = 1 
        tkMessageBox.showerror("Missing Case ID in check-in comment!!!", 
                               "Version:\n%s\n\nComment:\n%s" % 
                               (version, comment)) 
    else: 
        error = storeCheckInComment(caseIds, version, comment) 
        if error: 
            tkMessageBox.showerror("Error in issue database system!", 
                                   "Unable to store message:\n" 
                                   + comment) 
    sys.exit(error) 
 
if __name__ == '__main__':
    main()

####################################################################

# mktrig.py 
import os 
 
class Trigger: 
    def __init__(self, name, comment): 
        self.name = name 
        self.comment = comment 
 
    def run(self): 
        cmd = ('cleartool mktrtype %(type)s %(flags)s -c '
               '"%(comment)s" %(what)s %(name)s')
        args = {'type': self.type, 'flags': self.flags, 
                'comment' : self.comment, 
                'what': self.what, 'name': self.name} 
        print "Executing:" 
        print cmd % args 
        stdin, stdouterr = os.popen4(cmd % args) 
        stdin.close() 
        self.result = stdouterr.read() 
        stdouterr.close() 
 
class ElementTrigger(Trigger): 
    type = '-element' 
 
class TypeTrigger(Trigger): 
    type = '-type' 
 
class PreCITrigger(ElementTrigger): 
    flags = '-all -preop checkin' 
 
class PostCITrigger(ElementTrigger): 
    flags = '-all -postop checkin' 
 
class PythonExecMixIn: 
    def __init__(self, script): 
        self.what = '-exec "python %s"' % script 
 
class PythonPreCITrigger(PythonExecMixIn, PreCITrigger): 
    def __init__(self, name, comment, script): 
        Trigger.__init__(self, name, comment) 
        PythonExecMixIn.__init__(self, script) 
 
class PythonPostCITrigger(PythonExecMixIn, PostCITrigger): 
    def __init__(self, name, comment, script): 
        Trigger.__init__(self, name, comment) 
        PythonExecMixIn.__init__(self, script) 
 
trigger1 = PythonPreCITrigger('CommentPolicy', 
                    'Verify case id in check-in comment', 
                    '/path/to/CommentPolicy.py') 
trigger2 = PythonPostCITrigger('CommentPolicy2', 
                    'Report check-in to case handling system', 
                    '/path/to/CommentPolicy2.py') 
 
for trigger in [trigger1, trigger2]: 
    trigger.run() 
    print "Result:" 
    print trigger.result

The first program shows an example of a ClearCase pre-checkin trigger. Note that ClearCase sets up a number of environment variable whose names start with CLEARCASE. A non-zero exit code from sys.exit() will prevent the checkin from taking place. In this case we verify that the check-in comment contains a reference to a case id. We assume that the words "bug" or "feat" directly followed by at least one digit is a case id. We could also have checked against a database etc. A good thing to check pre checkin is that unit tests have been performed.

The second program is triggered after the checkin has been done. A use for this could be to register that fact for the noted case id in a database system. We don't do that here. Since the checkin has already been performed here, the exit code doesn't really matter.

The third program is a beginning of a program that would register all our python based triggers with the ClearCase system. As you can see, there are a number of different trigger types, but only the two trigger scripts above are actually registered.