1 |
arta |
1.1 |
#!/home/jsoc/bin/linux_x86_64/activepython |
2 |
arta |
1.7 |
|
3 |
|
|
# Run like this: |
4 |
|
|
# CM/tagRelease.py -t /home/jsoc/cvs/Development/waystation/JSOC_9.4.1_beta -v 9.41 |
5 |
|
|
# |
6 |
|
|
# -t is a HEAD check-out of the CVS tree; the file jsoc_version.h will be edited, and the tree will then be tagged with the release version specified in the `-v` argument |
7 |
|
|
# -v is a version string with a single '.' |
8 |
arta |
1.1 |
import sys, getopt |
9 |
|
|
import re |
10 |
|
|
import os |
11 |
|
|
import shutil |
12 |
|
|
from subprocess import call |
13 |
|
|
|
14 |
|
|
# Return values |
15 |
|
|
kRetSuccess = 0 |
16 |
|
|
kRetArgs = 1 |
17 |
|
|
kRetOS = 2 |
18 |
|
|
kRetRegexp = 3 |
19 |
|
|
|
20 |
|
|
# Constants |
21 |
|
|
kTagCmd = '/home/jsoc/dlsource.pl -o tag' |
22 |
|
|
kUntagCmd = '/home/jsoc/dlsource.pl -o untag' |
23 |
|
|
kTmpFile = '/tmp/.versfile.tmp' |
24 |
arta |
1.4 |
kVersFile = 'base/jsoc_version.h' |
25 |
arta |
1.1 |
|
26 |
|
|
# Classes |
27 |
|
|
|
28 |
arta |
1.7 |
# This class changes the current working directory, and restores the original working directory when |
29 |
arta |
1.1 |
# the context is left. |
30 |
|
|
class Chdir: |
31 |
|
|
"""Context manager for changing the current working directory""" |
32 |
|
|
def __init__(self, newPath): |
33 |
|
|
self.newPath = os.path.realpath(newPath) |
34 |
arta |
1.7 |
|
35 |
arta |
1.1 |
def __enter__(self): |
36 |
|
|
self.savedPath = os.path.realpath(os.getcwd()) |
37 |
|
|
os.chdir(self.newPath) |
38 |
|
|
cdir = os.path.realpath(os.getcwd()) |
39 |
|
|
if cdir == self.newPath: |
40 |
|
|
return 0 |
41 |
|
|
else: |
42 |
|
|
return 1 |
43 |
arta |
1.7 |
|
44 |
arta |
1.1 |
def __exit__(self, etype, value, traceback): |
45 |
|
|
os.chdir(self.savedPath) |
46 |
|
|
cdir = os.path.realpath(os.getcwd()) |
47 |
|
|
if cdir == self.savedPath: |
48 |
|
|
return 0 |
49 |
|
|
else: |
50 |
|
|
return 1 |
51 |
|
|
|
52 |
|
|
# Read arguments |
53 |
|
|
def GetArgs(args): |
54 |
|
|
rv = kRetSuccess |
55 |
|
|
optD = {} |
56 |
|
|
|
57 |
|
|
# tag by defuault |
58 |
|
|
optD['untag'] = 0 |
59 |
arta |
1.7 |
|
60 |
arta |
1.1 |
try: |
61 |
|
|
opts, remainder = getopt.getopt(args,"ht:uv:",["tree=", "version="]) |
62 |
|
|
except getopt.GetoptError: |
63 |
|
|
print('Usage:') |
64 |
|
|
print('tagRelease.py [-hu] -t <CVS tree with jsoc_version.h> -v <version string>') |
65 |
|
|
rv = kRetArgs |
66 |
|
|
|
67 |
|
|
if rv == kRetSuccess: |
68 |
|
|
for opt, arg in opts: |
69 |
|
|
if opt == '-h': |
70 |
|
|
print('tagRelease.py [-hu] -t <CVS tree with jsoc_version.h> -v <version string>') |
71 |
arta |
1.6 |
exit(0) |
72 |
arta |
1.1 |
elif opt in ("-t", "--tree"): |
73 |
|
|
regexp = re.compile(r"(\S+)/?") |
74 |
|
|
matchobj = regexp.match(arg) |
75 |
|
|
if matchobj is None: |
76 |
|
|
rv = kRetArgs |
77 |
|
|
else: |
78 |
|
|
optD['tree'] = matchobj.group(1) |
79 |
|
|
elif opt == '-u': |
80 |
|
|
optD['untag'] = 1 |
81 |
|
|
elif opt in ("-v", "--version"): |
82 |
|
|
regexp = re.compile(r"\d+(\.\d+)?") |
83 |
|
|
ret = regexp.match(arg) |
84 |
|
|
if ret is None: |
85 |
|
|
print('Invalid version string ' + arg) |
86 |
|
|
rv = kRetArgs |
87 |
|
|
optD['version'] = arg |
88 |
|
|
else: |
89 |
|
|
optD[opt] = arg |
90 |
arta |
1.6 |
|
91 |
|
|
if not rv == kRetSuccess: |
92 |
|
|
return {} |
93 |
|
|
|
94 |
arta |
1.1 |
return optD |
95 |
|
|
|
96 |
|
|
# Create version strings for jsoc_version.h and CVS, returns a tuple |
97 |
arta |
1.7 |
# containing either the two release strings (e.g., ("V8R1", "(801)", "8-1")), |
98 |
arta |
1.1 |
# or the two development strings (e.g., ("V8R1X", "(-801)", "8-1")). The |
99 |
arta |
1.7 |
# third member of the tuple is always "8-1". Which |
100 |
arta |
1.1 |
# tuple is returned is controlled by the 'dev' argument |
101 |
|
|
def CreateVersString(versin, dev): |
102 |
|
|
regexp = re.compile(r"(\d+)\.(\d+)") |
103 |
|
|
matchobj = regexp.match(versin) |
104 |
arta |
1.7 |
|
105 |
arta |
1.1 |
if not(matchobj is None): |
106 |
|
|
try: |
107 |
|
|
maj = matchobj.group(1) |
108 |
|
|
min = matchobj.group(2) |
109 |
|
|
except IndexError: |
110 |
|
|
print('Invalid regexp group number.') |
111 |
|
|
return None |
112 |
arta |
1.7 |
|
113 |
arta |
1.1 |
tagstring = maj + "-" + min |
114 |
arta |
1.7 |
|
115 |
arta |
1.1 |
if dev == 0: |
116 |
|
|
return ("V" + maj + "R" + min, "(" + maj + "{0:02d}".format(int(min)) + ")", tagstring) |
117 |
|
|
else: |
118 |
|
|
return ("V" + maj + "R" + min + "X", "(-" + maj + "{0:02d}".format(int(min)) + ")", tagstring) |
119 |
|
|
else: |
120 |
|
|
return None |
121 |
|
|
|
122 |
|
|
def EditVersionFile(versfile, verstuple): |
123 |
|
|
rv = kRetSuccess |
124 |
arta |
1.7 |
|
125 |
arta |
1.1 |
try: |
126 |
arta |
1.7 |
with open(versfile, 'r') as fin, open(kTmpFile, 'w') as fout: |
127 |
arta |
1.1 |
regexp1 = re.compile(r"#define\s+jsoc_version\s+\"\w+\"") |
128 |
|
|
regexp2 = re.compile(r"#define\s+jsoc_vers_num\s+\(\-?\d+\)") |
129 |
arta |
1.7 |
|
130 |
arta |
1.1 |
for line in fin: |
131 |
|
|
matchobj1 = regexp1.match(line) |
132 |
|
|
matchobj2 = regexp2.match(line) |
133 |
|
|
if not (matchobj1 is None): |
134 |
|
|
fbuf = "#define jsoc_version \"" + verstuple[0] + "\"\n" |
135 |
|
|
fout.write(fbuf) |
136 |
|
|
elif not (matchobj2 is None): |
137 |
|
|
fbuf = "#define jsoc_vers_num " + verstuple[1] + "\n" |
138 |
|
|
fout.write(fbuf) |
139 |
|
|
else: |
140 |
|
|
# Simply copy input to output |
141 |
|
|
fout.write(line) |
142 |
|
|
except OSError: |
143 |
|
|
print('Unable to read or write input or output file.') |
144 |
|
|
rv = kRetOS |
145 |
|
|
except re.error: |
146 |
|
|
print('Bad regular expression string.') |
147 |
|
|
rv = kRetRegexp |
148 |
|
|
|
149 |
|
|
if rv == kRetSuccess: |
150 |
|
|
# Rename tmp file |
151 |
|
|
try: |
152 |
|
|
shutil.move(kTmpFile, versfile) |
153 |
|
|
except OSError: |
154 |
|
|
print('Unable to rename file ', kTmpFile, 'to ', versfile) |
155 |
|
|
rv = kRetOS |
156 |
|
|
|
157 |
|
|
return rv |
158 |
|
|
|
159 |
|
|
|
160 |
|
|
rv = kRetSuccess |
161 |
|
|
optD = {} |
162 |
|
|
tree = '' |
163 |
|
|
version = '' |
164 |
|
|
untag = 0 |
165 |
|
|
cmd = '' |
166 |
|
|
ret = 0 |
167 |
|
|
|
168 |
|
|
if __name__ == "__main__": |
169 |
|
|
optD = GetArgs(sys.argv[1:]) |
170 |
arta |
1.7 |
|
171 |
arta |
1.1 |
if not(optD is None): |
172 |
|
|
if not(optD['version'] is None) and not(optD['untag'] is None): |
173 |
arta |
1.4 |
regexp = re.compile(r"(.+)/\s*$") |
174 |
|
|
matchobj = regexp.match(optD['tree']) |
175 |
|
|
if not (matchobj is None): |
176 |
|
|
tree = matchobj.group(1) |
177 |
|
|
else: |
178 |
|
|
tree = optD['tree'] |
179 |
arta |
1.7 |
|
180 |
|
|
# `tree` is used for editing jsoc_version.h only; the file in this tree is edited (twice - once for the release tag and once for the development tag) and then checked in; |
181 |
|
|
# `tree` should be a HEAD version CVS tree; the file is edited with the release-tag content, committed, tagged with the release tag, edited with the dev tag, and then checked in; |
182 |
arta |
1.1 |
version = optD['version'] |
183 |
|
|
untag = optD['untag'] |
184 |
arta |
1.4 |
versfile = tree + '/' + kVersFile |
185 |
arta |
1.1 |
verstuple = CreateVersString(version, 0) |
186 |
arta |
1.7 |
|
187 |
arta |
1.1 |
if verstuple is None: |
188 |
|
|
print('Invalid version string ' + version) |
189 |
|
|
rv = kRetArgs |
190 |
|
|
|
191 |
|
|
if rv == kRetSuccess: |
192 |
|
|
# Edit jsoc_version.h - set the release version of the version numbers. |
193 |
|
|
rv = EditVersionFile(versfile, verstuple) |
194 |
arta |
1.7 |
|
195 |
arta |
1.1 |
if rv == kRetSuccess: |
196 |
|
|
# Commit jsoc_version.h back to CVS |
197 |
|
|
try: |
198 |
|
|
with Chdir(tree) as ret: |
199 |
|
|
if ret == 0: |
200 |
arta |
1.4 |
cmd = 'cvs commit -m "Set the release versions of the version macros for the ' + version + ' release." ' + kVersFile |
201 |
arta |
1.1 |
ret = call(cmd, shell=True) |
202 |
|
|
else: |
203 |
|
|
print('Unable to cd to ' + tree + '.') |
204 |
|
|
rv = kRetOS |
205 |
|
|
except OSError: |
206 |
|
|
print('Unable to cd to ' + tree + '.') |
207 |
|
|
rv = kRetOS |
208 |
|
|
except ValueError: |
209 |
|
|
print('Unable to run cvs cmd: ' + cmd + '.') |
210 |
|
|
rv = kRetOS |
211 |
arta |
1.7 |
|
212 |
arta |
1.2 |
if not(ret == 0): |
213 |
|
|
print('cvs command ' + cmd + ' ran improperly.') |
214 |
|
|
rv = kRetOS |
215 |
arta |
1.1 |
|
216 |
|
|
if rv == kRetSuccess: |
217 |
arta |
1.3 |
print('Successfully edited ' + versfile + '; set release version.') |
218 |
arta |
1.1 |
# Create the tags |
219 |
|
|
try: |
220 |
arta |
1.7 |
# untag existing tags (if they exist); if the tag does not exist, then no error is returned; calling dlsource.pl is a bit inefficient since each time a new CVS tree is downloaded; dlsource.pl downloads the HEAD tree into a temp dir before untagging; |
221 |
|
|
|
222 |
arta |
1.1 |
# Full DRMS-release tags |
223 |
|
|
cmd = '/home/jsoc/dlsource.pl -o untag -f sdp -t Ver_' + verstuple[2] |
224 |
|
|
ret = call(cmd, shell=True) |
225 |
|
|
if not(ret == 0): |
226 |
|
|
print('ERROR: Unable to delete tag Ver_' + verstuple[2]) |
227 |
|
|
rv = kRetOS |
228 |
|
|
if rv == kRetSuccess: |
229 |
|
|
cmd = '/home/jsoc/dlsource.pl -o untag -f sdp -t Ver_LATEST' |
230 |
|
|
ret = call(cmd, shell=True) |
231 |
|
|
if not(ret == 0): |
232 |
|
|
print('ERROR: Unable to delete tag Ver_LATEST') |
233 |
|
|
rv = kRetOS |
234 |
arta |
1.7 |
|
235 |
arta |
1.1 |
# NetDRMS-release tags |
236 |
|
|
if rv == kRetSuccess: |
237 |
|
|
cmd = '/home/jsoc/dlsource.pl -o untag -f net -t NetDRMS_Ver_' + verstuple[2] |
238 |
|
|
ret = call(cmd, shell=True) |
239 |
|
|
if not(ret == 0): |
240 |
|
|
print('ERROR: Unable to delete tag NetDRMS_Ver_' + verstuple[2]) |
241 |
|
|
rv = kRetOS |
242 |
|
|
if rv == kRetSuccess: |
243 |
arta |
1.5 |
cmd = '/home/jsoc/dlsource.pl -o untag -f net -t NetDRMS_Ver_LATEST' |
244 |
arta |
1.1 |
ret = call(cmd, shell=True) |
245 |
|
|
if not(ret == 0): |
246 |
arta |
1.5 |
print('ERROR: Unable to delete tag NetDRMS_Ver_LATEST') |
247 |
arta |
1.1 |
rv = kRetOS |
248 |
arta |
1.7 |
|
249 |
arta |
1.1 |
# Create new tags |
250 |
arta |
1.7 |
# dlsource.pl downloads the HEAD tree into a temp dir before tagging |
251 |
arta |
1.1 |
|
252 |
|
|
# Full DRMS-release tags |
253 |
|
|
if rv == kRetSuccess: |
254 |
|
|
cmd = '/home/jsoc/dlsource.pl -o tag -f sdp -t Ver_' + verstuple[2] |
255 |
|
|
ret = call(cmd, shell=True) |
256 |
|
|
if not(ret == 0): |
257 |
|
|
print('ERROR: Unable to create tag Ver_' + verstuple[2]) |
258 |
|
|
rv = kRetOS |
259 |
|
|
if rv == kRetSuccess: |
260 |
|
|
cmd = '/home/jsoc/dlsource.pl -o tag -f sdp -t Ver_LATEST' |
261 |
|
|
ret = call(cmd, shell=True) |
262 |
|
|
if not(ret == 0): |
263 |
|
|
print('ERROR: Unable to create tag Ver_LATEST') |
264 |
|
|
rv = kRetOS |
265 |
|
|
|
266 |
|
|
# NetDRMS-release tags |
267 |
|
|
if rv == kRetSuccess: |
268 |
|
|
cmd = '/home/jsoc/dlsource.pl -o tag -f net -t NetDRMS_Ver_' + verstuple[2] |
269 |
|
|
ret = call(cmd, shell=True) |
270 |
|
|
if not(ret == 0): |
271 |
|
|
print('ERROR: Unable to create tag NetDRMS_Ver_' + verstuple[2]) |
272 |
|
|
rv = kRetOS |
273 |
|
|
if rv == kRetSuccess: |
274 |
arta |
1.5 |
cmd = '/home/jsoc/dlsource.pl -o tag -f net -t NetDRMS_Ver_LATEST' |
275 |
arta |
1.1 |
ret = call(cmd, shell=True) |
276 |
|
|
if not(ret == 0): |
277 |
arta |
1.5 |
print('ERROR: Unable to create tag NetDRMS_Ver_LATEST') |
278 |
arta |
1.1 |
rv = kRetOS |
279 |
|
|
except ValueError: |
280 |
|
|
print('Unable to run cvs cmd: ' + cmd + '.') |
281 |
|
|
rv = kRetOS |
282 |
|
|
|
283 |
|
|
if rv == kRetSuccess: |
284 |
arta |
1.3 |
print('Successfully created DRMS and NetDRMS release CVS tags.') |
285 |
arta |
1.1 |
# Edit jsoc_version.h - set the development version of the version number. |
286 |
|
|
verstuple = CreateVersString(version, 1) |
287 |
|
|
|
288 |
|
|
if verstuple is None: |
289 |
|
|
print('Invalid version string ' + version) |
290 |
|
|
rv = kRetArgs |
291 |
|
|
|
292 |
|
|
if rv == kRetSuccess: |
293 |
|
|
# Edit jsoc_version.h - set the development version of the version numbers. |
294 |
|
|
rv = EditVersionFile(versfile, verstuple) |
295 |
arta |
1.7 |
|
296 |
arta |
1.1 |
if rv == kRetSuccess: |
297 |
|
|
# Commit jsoc_version.h back to CVS |
298 |
|
|
try: |
299 |
|
|
with Chdir(tree) as ret: |
300 |
|
|
if ret == 0: |
301 |
arta |
1.4 |
cmd = 'cvs commit -m "Set the development version of the version macros for the ' + version + ' release." ' + kVersFile |
302 |
arta |
1.1 |
ret = call(cmd, shell=True) |
303 |
|
|
else: |
304 |
|
|
rv = kRetOS |
305 |
|
|
except OSError: |
306 |
|
|
print('Unable to cd to ' + tree + '.') |
307 |
|
|
rv = kRetOS |
308 |
|
|
except ValueError: |
309 |
|
|
print('Unable to run cvs cmd: ' + cmd + '.') |
310 |
|
|
rv = kRetOS |
311 |
|
|
|
312 |
|
|
if not(ret == 0): |
313 |
arta |
1.2 |
print('cvs command ' + cmd + ' ran improperly.') |
314 |
arta |
1.1 |
rv = kRetOS |
315 |
|
|
|
316 |
arta |
1.3 |
if rv == kRetSuccess: |
317 |
|
|
print('Successfully edited ' + versfile + '; set development version.') |
318 |
arta |
1.1 |
else: |
319 |
|
|
print('Invalid arguments.') |
320 |
|
|
rv = kRetArgs |
321 |
|
|
else: |
322 |
|
|
print('Invalid arguments.') |
323 |
|
|
rv = kRetArgs |
324 |
|
|
|
325 |
|
|
exit(rv) |