1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | """ This script (rcvs) executes cvs on a remote cvs client. |
---|
4 | Useful when cvs access is only allowed from one particular host. |
---|
5 | |
---|
6 | Definitions |
---|
7 | CVS server: host where CVS repository resides |
---|
8 | CVS client: host from which access to CVS server is allowed |
---|
9 | local host: host that must access CVS repository through CVS client |
---|
10 | |
---|
11 | |
---|
12 | Assumptions: |
---|
13 | |
---|
14 | 1:CVS client can be reached from local host without passwords |
---|
15 | using ssh and rsync |
---|
16 | |
---|
17 | 2:Usernames on CVS client and CVS server are the same |
---|
18 | |
---|
19 | 3:Details about CVS Host are supplied at the top of this script |
---|
20 | |
---|
21 | 4:CVSROOT environment variable point to CVS client so that username and CVS client |
---|
22 | can be inferred automatically |
---|
23 | |
---|
24 | 5:Each user has a directory called sandpit in their home directory on the CVS client |
---|
25 | |
---|
26 | 6:CVS client has a UNIX/Linux file structure |
---|
27 | |
---|
28 | 7:That user has performed a CVS login once from CVS client to CVS host |
---|
29 | |
---|
30 | |
---|
31 | Modus operandi: |
---|
32 | |
---|
33 | The rcvs script will do updates, add and commit plus download (unique to rcvs) |
---|
34 | Commands such as tag, remove etc mus be done on cvs client. |
---|
35 | |
---|
36 | |
---|
37 | Examples: |
---|
38 | |
---|
39 | |
---|
40 | rcvs checkout repository (checkout and download repository from cvs client) |
---|
41 | |
---|
42 | rcvs add [files...] (add named files to repository) |
---|
43 | |
---|
44 | rcvs update [files...] (update named files from cvs server) |
---|
45 | |
---|
46 | rcvs com -m "msg" [files...] (Commit changes with log message) |
---|
47 | |
---|
48 | rcvs log [files...] (List log history for files) |
---|
49 | |
---|
50 | rcvs download repository (download repository from cvs client) |
---|
51 | |
---|
52 | |
---|
53 | If files are omitted command will work on all files in repository. |
---|
54 | |
---|
55 | SSH Setup |
---|
56 | To get cgywin ssh working, wothout using passwords; |
---|
57 | 1) Set the environment variable |
---|
58 | CYGWIN = smbntsec |
---|
59 | 2) In windows explorer/permissions/security, make sure the private key has |
---|
60 | only 1 user |
---|
61 | |
---|
62 | Copyright 2004 |
---|
63 | Ole Nielsen and Duncan Gray |
---|
64 | Geoscience Australia |
---|
65 | """ |
---|
66 | |
---|
67 | #Details about CVS Host |
---|
68 | protocol = 'pserver' |
---|
69 | cvs_host = 'cuttlefish.anu.edu.au' |
---|
70 | cvs_dir = '/home/cvs' |
---|
71 | |
---|
72 | |
---|
73 | rsep = '/' #Separator on cvs client |
---|
74 | from os import sep #Separator on local machine |
---|
75 | |
---|
76 | import sys, os |
---|
77 | |
---|
78 | #Get Username and cvs client - assumed to be the same on cvs host and remote cvs client |
---|
79 | |
---|
80 | s = os.getenv('CVSROOT') |
---|
81 | username = '' |
---|
82 | cvs_client = '' |
---|
83 | if len(s) > 0: |
---|
84 | atsign = s.index('@') |
---|
85 | |
---|
86 | #Username |
---|
87 | i = atsign-1 |
---|
88 | while i > 0 and s[i] != ':': |
---|
89 | username = s[i] + username |
---|
90 | i -= 1 |
---|
91 | |
---|
92 | #CVS client |
---|
93 | i = atsign+1 |
---|
94 | while i < len(s) and s[i] != ':': |
---|
95 | cvs_client += s[i] |
---|
96 | i += 1 |
---|
97 | |
---|
98 | if len(username) == 0: |
---|
99 | msg = 'Could not infer user name from environment variable CVSROOT (%s)' %s |
---|
100 | raise Exception(msg) |
---|
101 | |
---|
102 | if len(cvs_client) == 0: |
---|
103 | msg = 'Could not infer CVS client from environment variable CVSROOT (%s)' %s |
---|
104 | raise Exception(msg) |
---|
105 | |
---|
106 | |
---|
107 | #CVSROOT = ':pserver:%s@cuttlefish.anu.edu.au:/home/cvs' %username |
---|
108 | CVSROOT = ':%s:%s@%s:%s' %(protocol, username, cvs_host, cvs_dir) |
---|
109 | |
---|
110 | |
---|
111 | #specify location of remote repositories (assuming UNIX separators) |
---|
112 | sandpit = '~' + rsep + 'sandpit' |
---|
113 | |
---|
114 | |
---|
115 | def run(cmd): |
---|
116 | import os |
---|
117 | print cmd |
---|
118 | os.system(cmd) |
---|
119 | |
---|
120 | |
---|
121 | def upload(dir): |
---|
122 | files=get_cvsfiles() |
---|
123 | #s = 'rsync --cvs-exclude -qavz %s %s@%s:%s'\ |
---|
124 | s = 'rsync -qavz %s %s@%s:%s' %(files, username, cvs_client, sandpit + rsep + dir) |
---|
125 | print '---------- UPLOADING -------------' |
---|
126 | run(s) |
---|
127 | |
---|
128 | |
---|
129 | def download(dir): |
---|
130 | import os |
---|
131 | |
---|
132 | s = 'rsync -qavz %s@%s:%s' %(username, cvs_client, sandpit) +\ |
---|
133 | rsep + dir + rsep + '* .' |
---|
134 | print '---------- DOWNLOADING -------------' |
---|
135 | run(s) |
---|
136 | |
---|
137 | |
---|
138 | def cvscmd(dir, cmd, args): |
---|
139 | x = '' |
---|
140 | for arg in args: |
---|
141 | x += str(arg) + ' ' |
---|
142 | |
---|
143 | s = 'ssh -X %s@%s "cd %s; cvs %s %s"' %(username, cvs_client, |
---|
144 | sandpit + rsep + dir, |
---|
145 | cmd, x) |
---|
146 | print '---------- CVS OUTPUT -------------' |
---|
147 | run(s) |
---|
148 | |
---|
149 | |
---|
150 | |
---|
151 | #FIXME: Not done yet and maybe it shouldn't |
---|
152 | def get_cvsfiles(): |
---|
153 | """Get files that are registered under CVS |
---|
154 | """ |
---|
155 | import os |
---|
156 | |
---|
157 | #Get name of local repository |
---|
158 | localdir = os.getcwd() |
---|
159 | |
---|
160 | if not 'CVS' in os.listdir(localdir): |
---|
161 | raise Exception('No CVS directory in current directory') |
---|
162 | |
---|
163 | FN = localdir + sep + 'CVS' + sep + 'Entries' |
---|
164 | try: |
---|
165 | fid = open(FN) |
---|
166 | except: |
---|
167 | msg = 'Could not open %s' %FN |
---|
168 | raise Exception(msg) |
---|
169 | else: |
---|
170 | files = '' |
---|
171 | for entry in fid.readlines(): |
---|
172 | #print entry |
---|
173 | pass |
---|
174 | |
---|
175 | |
---|
176 | return '*' |
---|
177 | |
---|
178 | |
---|
179 | def get_repository(): |
---|
180 | """Get name of CVS repository from CVS directory |
---|
181 | """ |
---|
182 | import os |
---|
183 | |
---|
184 | #Get name of local repository |
---|
185 | localdir = os.getcwd() |
---|
186 | |
---|
187 | if not 'CVS' in os.listdir(localdir): |
---|
188 | raise Exception('No CVS directory in current directory') |
---|
189 | |
---|
190 | |
---|
191 | FN = localdir + sep + 'CVS' + sep + 'Repository' |
---|
192 | try: |
---|
193 | fid = open(FN) |
---|
194 | except: |
---|
195 | msg = 'Could not open %s' %FN |
---|
196 | raise Exception(msg) |
---|
197 | else: |
---|
198 | repository = fid.readlines()[0].strip() |
---|
199 | |
---|
200 | |
---|
201 | #Get actual name of local repository |
---|
202 | local = os.path.split(localdir)[1] |
---|
203 | |
---|
204 | #if local != repository: |
---|
205 | # msg = 'Local directory (%s) and ' %local |
---|
206 | # msg += 'CVS repository (%s) must have the same name' %repository |
---|
207 | # raise Exception(msg) |
---|
208 | |
---|
209 | return repository |
---|
210 | |
---|
211 | |
---|
212 | if len(sys.argv) > 1: |
---|
213 | arg = sys.argv[1] |
---|
214 | |
---|
215 | if arg.find('upd') == 0: |
---|
216 | dir = get_repository() |
---|
217 | upload(dir) |
---|
218 | cvscmd(dir, 'update', sys.argv[2:]) |
---|
219 | download(dir) |
---|
220 | |
---|
221 | |
---|
222 | if arg.find('com') == 0 or arg.find('ci') == 0: |
---|
223 | dir = get_repository() |
---|
224 | upload(dir) |
---|
225 | |
---|
226 | args = sys.argv[2:] |
---|
227 | |
---|
228 | try: |
---|
229 | i = args.index('-m') |
---|
230 | except: |
---|
231 | comment = 'None' |
---|
232 | remaining_args = args |
---|
233 | else: |
---|
234 | #We have a text argument for the log file |
---|
235 | comment = '%s' %(args[i+1]) |
---|
236 | if len(comment) == 0: |
---|
237 | comment = 'None' |
---|
238 | remaining_args = args[:i]+args[i+2:] |
---|
239 | |
---|
240 | command = 'commit -m """%s"""' %comment |
---|
241 | #cvscmd(dir, 'update', remaining_args) |
---|
242 | cvscmd(dir, command, remaining_args) |
---|
243 | download(dir) |
---|
244 | |
---|
245 | |
---|
246 | if arg.find('add') == 0: |
---|
247 | dir = get_repository() |
---|
248 | upload(dir) |
---|
249 | cvscmd(dir, 'add', sys.argv[2:]) |
---|
250 | download(dir) |
---|
251 | |
---|
252 | |
---|
253 | if arg.find('log') == 0: |
---|
254 | dir = get_repository() |
---|
255 | upload(dir) |
---|
256 | cvscmd(dir, 'log', sys.argv[2:]) |
---|
257 | |
---|
258 | if arg.find('diff') == 0: |
---|
259 | dir = get_repository() |
---|
260 | upload(dir) |
---|
261 | cvscmd(dir, 'diff', sys.argv[2:]) |
---|
262 | |
---|
263 | if arg.find('annotate') == 0: |
---|
264 | dir = get_repository() |
---|
265 | upload(dir) |
---|
266 | cvscmd(dir, 'annotate', sys.argv[2:]) |
---|
267 | |
---|
268 | |
---|
269 | |
---|
270 | #FIXME: Maybe Obsolete |
---|
271 | if arg.find('down') == 0: |
---|
272 | import os |
---|
273 | if len(sys.argv) == 3: |
---|
274 | arg = sys.argv[2] |
---|
275 | |
---|
276 | os.mkdir(arg) #Create local copy of repository |
---|
277 | os.chdir(arg) |
---|
278 | download(arg) |
---|
279 | |
---|
280 | |
---|
281 | if arg.find('co') == 0 or arg.find('checkout') == 0: |
---|
282 | import os |
---|
283 | if len(sys.argv) == 3: |
---|
284 | arg = sys.argv[2] |
---|
285 | |
---|
286 | #Create local copy of repository |
---|
287 | try: |
---|
288 | os.mkdir(arg) |
---|
289 | except OSError: |
---|
290 | pass |
---|
291 | #msg = 'Could not create directory %s' %arg |
---|
292 | #raise Exception(msg) |
---|
293 | |
---|
294 | os.chdir(arg) |
---|
295 | |
---|
296 | #Check out from CVS host |
---|
297 | s = 'ssh -X %s@%s "cd %s;cvs -d %s checkout %s"'\ |
---|
298 | %(username, cvs_client, sandpit, CVSROOT, arg) |
---|
299 | print '---------- CVS OUTPUT -------------' |
---|
300 | run(s) |
---|
301 | |
---|
302 | #Download from CVS client |
---|
303 | download(arg) |
---|
304 | |
---|
305 | else: |
---|
306 | print 'Usage' |
---|
307 | print ''' |
---|
308 | rcvs checkout repository (checkout repository from cvs client) |
---|
309 | |
---|
310 | rcvs add [files...] (add named files to repository) |
---|
311 | |
---|
312 | rcvs update [files...] (update named files from cvs server) |
---|
313 | |
---|
314 | rcvs com -m "msg" [files...] (Commit changes with log message) |
---|
315 | |
---|
316 | rcvs log [files...] (List log history for files) |
---|
317 | |
---|
318 | rcvs diff [files...] (List diffs for files) |
---|
319 | |
---|
320 | rcvs annotate [files...] (List files with cvs annotations) |
---|
321 | |
---|
322 | rcvs download repository (download repository from cvs client)''' |
---|
323 | |
---|