-
Notifications
You must be signed in to change notification settings - Fork 0
/
clearcase.py
121 lines (95 loc) · 4 KB
/
clearcase.py
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
import os, stat, os.path
import tempfile
import re
import util
import logging
# This is temporary stuff just for recording, set level to DEBUG to enable
logger = logging.getLogger('log.bgcc.file')
recorder = logging.getLogger('log.bgcc.clearcase')
# h = logging.FileHandler('ccrecorder.log', 'w')
# h.setFormatter(logging.Formatter('%(message)s'))
# h.setLevel(logging.INFO)
# recorder.addHandler(h)
def formatRecord(res, *args):
xx = '(%s, \'%s\'),' % (str(args), str(res))
return xx
class ClearcaseFacade(object):
def __init__(self, cc_dir, includes, branches):
self.cc_dir = cc_dir
self.includes = includes
self.branches = branches
def needUpdate(self):
'''
Checks whether an update would result in any changes to the clearcase
working files.
'''
(fd, tmpfile) = tempfile.mkstemp()
os.close(fd)
self._cc_exec(['update', '-print', '-ove', '-log', tmpfile])
ff = open(tmpfile, 'r')
buf = ff.read()
ff.close()
os.remove(tmpfile)
hits = re.findall('^Updated:', buf, re.M)
recorder.debug('%s', formatRecord(len(hits) > 0))
return len(hits) > 0
def fileVersionDictionary(self):
'''
Return a dictionary containing all versioned files in the clearcase view, with their corresponding branch/version.
'''
ls = ['ls', '-long', '-recurse', '-vob']
ls.extend(self.includes)
vob = self._cc_exec(ls)
vob = re.findall('^(version.*)', vob, re.M)
fileversions = map(lambda ss: re.match('version\s+([^\s]+)', ss).group(1).replace('\\','/'), vob)
vobdict = {}
for fv in fileversions:
obj = re.match('[\./]*(.+)@@(.+)', fv, re.M)
if not obj:
logger.error('No cc version format: %s', fv)
else:
vobdict[obj.group(1)] = obj.group(2)
recorder.debug('%s', formatRecord(vobdict))
return vobdict
def checkinHistoryReversed(self, since):
lsh = ['lsh', '-fmt', '%o%m\001%Nd\001%u\001%En\001%Vn\001%Nc\n', '-recurse', '-since', since]
lsh.extend(self.includes) ## To filter our folders specified in configuration
blob = self._cc_exec(lsh).replace('\\', '/') # clean up windows separator ugliness
ptrn = '^(checkin.+?\x01.+?\x01.+?\x01.+?\x01.+[%s]/\d+\x01.*)' % ','.join(self.branches)
filtered = re.findall(ptrn, blob, re.M)
filtered.reverse()
logger.debug(filtered)
recorder.debug('%s', formatRecord(filtered, since, self.includes))
return filtered
def copyVobFile(self, ccfile, dest):
if os.path.exists(dest):
os.remove(dest)
self._cc_exec(['get','-to', dest, ccfile])
os.chmod(dest, os.stat(dest).st_mode | stat.S_IWRITE)
recorder.debug('%s', formatRecord(None, ccfile, dest))
def undoCheckout(self, file):
self._cc_exec(['unco', '-rm', file])
def update(self):
self._cc_exec(['update', '-overwrite'])
def checkin(self, file, comment):
self._cc_exec(['ci', '-identical', '-c', comment, file])
def checkout(self, file):
self._cc_exec(['co', '-reserved', '-nc', file])
def addDirectory(self, dir):
self._cc_exec(['mkelem', '-nc', '-eltype', 'directory', dir])
def addFile(self, file):
self._cc_exec(['mkelem', '-nc', file])
def removeFile(self, file):
self._cc_exec(['rm', file])
def moveFile(self, src, dst):
self._cc_exec(['mv', '-nc', src, dst])
def catcs(self):
out = self._cc_exec(['catcs'])
# return re.match('include\s(.*)', out).group(1)
return out
def setcs(self, csfile):
print 'setting config spec to: %s' % csfile
self._cc_exec(['setcs', csfile])
print 'done'
def _cc_exec(self, cmd, **args):
return util.popen('cleartool', cmd, self.cc_dir, **args)