| 
									
										
										
										
											1995-04-27 18:07:07 +00:00
										 |  |  | #! /usr/local/bin/python | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | """Remote CVS -- command line interface""" | 
					
						
							| 
									
										
										
										
											1995-04-27 18:07:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | # XXX To do: | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1995-06-23 22:33:57 +00:00
										 |  |  | # Bugs: | 
					
						
							|  |  |  | # - if the remote file is deleted, "rcvs update" will fail | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | # Functionality: | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | # - cvs log | 
					
						
							|  |  |  | # - cvs rm | 
					
						
							| 
									
										
										
										
											1995-06-23 22:33:57 +00:00
										 |  |  | # - descend into directories (alraedy done for update) | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | # - conflict resolution | 
					
						
							|  |  |  | # - other relevant commands? | 
					
						
							|  |  |  | # - branches | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # - Finesses: | 
					
						
							|  |  |  | # - retain file mode's x bits | 
					
						
							|  |  |  | # - complain when "nothing known about filename" | 
					
						
							|  |  |  | # - edit log message the way CVS lets you edit it | 
					
						
							|  |  |  | # - cvs diff -rREVA -rREVB | 
					
						
							|  |  |  | # - send mail the way CVS sends it | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Performance: | 
					
						
							|  |  |  | # - cache remote checksums (for every revision ever seen!) | 
					
						
							|  |  |  | # - translate symbolic revisions to numeric revisions | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Reliability: | 
					
						
							|  |  |  | # - remote locking | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Security: | 
					
						
							|  |  |  | # - Authenticated RPC? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | from cvslib import CVS, File | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | import md5 | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import string | 
					
						
							|  |  |  | import sys | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | from cmdfw import CommandFrameWork | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | DEF_LOCAL = 1				# Default -l | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | class MyFile(File): | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 	def action(self): | 
					
						
							|  |  |  | 		"""Return a code indicating the update status of this file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		The possible return values are: | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		'=' -- everything's fine | 
					
						
							|  |  |  | 		'0' -- file doesn't exist anywhere | 
					
						
							|  |  |  | 		'?' -- exists locally only | 
					
						
							|  |  |  | 		'A' -- new locally | 
					
						
							|  |  |  | 		'R' -- deleted locally | 
					
						
							|  |  |  | 		'U' -- changed remotely, no changes locally | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 		       (includes new remotely or deleted remotely) | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		'M' -- changed locally, no changes remotely | 
					
						
							|  |  |  | 		'C' -- conflict: changed locally as well as remotely | 
					
						
							|  |  |  | 		       (includes cases where the file has been added | 
					
						
							|  |  |  | 		       or removed locally and remotely) | 
					
						
							| 
									
										
										
										
											1995-04-28 15:33:03 +00:00
										 |  |  | 		'D' -- deleted remotely | 
					
						
							|  |  |  | 		'N' -- new remotely | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 		'r' -- get rid of entry | 
					
						
							|  |  |  | 		'c' -- create entry | 
					
						
							|  |  |  | 		'u' -- update entry | 
					
						
							| 
									
										
										
										
											1995-05-01 20:22:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		(and probably others :-) | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		"""
 | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		if not self.lseen: | 
					
						
							|  |  |  | 			self.getlocal() | 
					
						
							|  |  |  | 		if not self.rseen: | 
					
						
							|  |  |  | 			self.getremote() | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		if not self.eseen: | 
					
						
							| 
									
										
										
										
											1995-05-01 20:22:01 +00:00
										 |  |  | 			if not self.lsum: | 
					
						
							|  |  |  | 				if not self.rsum: return '0' # Never heard of | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 				else: | 
					
						
							|  |  |  | 					return 'N' # New remotely | 
					
						
							| 
									
										
										
										
											1995-05-01 20:22:01 +00:00
										 |  |  | 			else: # self.lsum | 
					
						
							|  |  |  | 				if not self.rsum: return '?' # Local only | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 				# Local and remote, but no entry | 
					
						
							|  |  |  | 				if self.lsum == self.rsum: | 
					
						
							|  |  |  | 					return 'c' # Restore entry only | 
					
						
							|  |  |  | 				else: return 'C' # Real conflict | 
					
						
							|  |  |  | 		else: # self.eseen | 
					
						
							| 
									
										
										
										
											1995-05-01 20:22:01 +00:00
										 |  |  | 			if not self.lsum: | 
					
						
							|  |  |  | 				if self.edeleted: | 
					
						
							|  |  |  | 					if self.rsum: return 'R' # Removed | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 					else: return 'r' # Get rid of entry | 
					
						
							| 
									
										
										
										
											1995-05-01 20:22:01 +00:00
										 |  |  | 				else: # not self.edeleted | 
					
						
							|  |  |  | 					if self.rsum: | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 						print "warning:", | 
					
						
							|  |  |  | 						print self.file, | 
					
						
							|  |  |  | 						print "was lost" | 
					
						
							|  |  |  | 						return 'U' | 
					
						
							|  |  |  | 					else: return 'r' # Get rid of entry | 
					
						
							| 
									
										
										
										
											1995-05-01 20:22:01 +00:00
										 |  |  | 			else: # self.lsum | 
					
						
							|  |  |  | 				if not self.rsum: | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 					if self.enew: return 'A' # New locally | 
					
						
							|  |  |  | 					else: return 'D' # Deleted remotely | 
					
						
							| 
									
										
										
										
											1995-05-01 20:22:01 +00:00
										 |  |  | 				else: # self.rsum | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 					if self.enew: | 
					
						
							|  |  |  | 						if self.lsum == self.rsum: | 
					
						
							|  |  |  | 							return 'u' | 
					
						
							|  |  |  | 						else: | 
					
						
							|  |  |  | 							return 'C' | 
					
						
							|  |  |  | 					if self.lsum == self.esum: | 
					
						
							|  |  |  | 						if self.esum == self.rsum: | 
					
						
							|  |  |  | 							return '=' | 
					
						
							|  |  |  | 						else: | 
					
						
							|  |  |  | 							return 'U' | 
					
						
							|  |  |  | 					elif self.esum == self.rsum: | 
					
						
							|  |  |  | 						return 'M' | 
					
						
							|  |  |  | 					elif self.lsum == self.rsum: | 
					
						
							|  |  |  | 						return 'u' | 
					
						
							|  |  |  | 					else: | 
					
						
							|  |  |  | 						return 'C' | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def update(self): | 
					
						
							|  |  |  | 		code = self.action() | 
					
						
							| 
									
										
										
										
											1995-04-28 21:48:16 +00:00
										 |  |  | 		if code == '=': return | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		print code, self.file | 
					
						
							| 
									
										
										
										
											1995-04-28 15:33:03 +00:00
										 |  |  | 		if code in ('U', 'N'): | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 			self.get() | 
					
						
							|  |  |  | 		elif code == 'C': | 
					
						
							|  |  |  | 			print "%s: conflict resolution not yet implemented" % \ | 
					
						
							|  |  |  | 			      self.file | 
					
						
							| 
									
										
										
										
											1995-04-28 15:33:03 +00:00
										 |  |  | 		elif code == 'D': | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 			remove(self.file) | 
					
						
							| 
									
										
										
										
											1995-04-28 15:33:03 +00:00
										 |  |  | 			self.eseen = 0 | 
					
						
							|  |  |  | 		elif code == 'r': | 
					
						
							|  |  |  | 			self.eseen = 0 | 
					
						
							|  |  |  | 		elif code in ('c', 'u'): | 
					
						
							| 
									
										
										
										
											1995-04-28 15:37:22 +00:00
										 |  |  | 			self.eseen = 1 | 
					
						
							| 
									
										
										
										
											1995-04-28 15:33:03 +00:00
										 |  |  | 			self.erev = self.rrev | 
					
						
							|  |  |  | 			self.enew = 0 | 
					
						
							|  |  |  | 			self.edeleted = 0 | 
					
						
							|  |  |  | 			self.esum = self.rsum | 
					
						
							|  |  |  | 			self.emtime, self.ectime = os.stat(self.file)[-2:] | 
					
						
							| 
									
										
										
										
											1995-04-28 15:37:22 +00:00
										 |  |  | 			self.extra = '' | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def commit(self, message = ""): | 
					
						
							|  |  |  | 		code = self.action() | 
					
						
							|  |  |  | 		if code in ('A', 'M'): | 
					
						
							|  |  |  | 			self.put(message) | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 			return 1 | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		elif code == 'R': | 
					
						
							|  |  |  | 			print "%s: committing removes not yet implemented" % \ | 
					
						
							|  |  |  | 			      self.file | 
					
						
							|  |  |  | 		elif code == 'C': | 
					
						
							|  |  |  | 			print "%s: conflict resolution not yet implemented" % \ | 
					
						
							|  |  |  | 			      self.file | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 	def diff(self, opts = []): | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		self.action()		# To update lseen, rseen | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 		flags = '' | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		rev = self.rrev | 
					
						
							|  |  |  | 		# XXX should support two rev options too! | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 		for o, a in opts: | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 			if o == '-r': | 
					
						
							|  |  |  | 				rev = a | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				flags = flags + ' ' + o + a | 
					
						
							|  |  |  | 		if rev == self.rrev and self.lsum == self.rsum: | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 		flags = flags[1:] | 
					
						
							|  |  |  | 		fn = self.file | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		data = self.proxy.get((fn, rev)) | 
					
						
							|  |  |  | 		sum = md5.new(data).digest() | 
					
						
							|  |  |  | 		if self.lsum == sum: | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		import tempfile | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 		tfn = tempfile.mktemp() | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			tf = open(tfn, 'w') | 
					
						
							|  |  |  | 			tf.write(data) | 
					
						
							|  |  |  | 			tf.close() | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 			print 'diff %s -r%s %s' % (flags, rev, fn) | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 			sts = os.system('diff %s %s %s' % (flags, tfn, fn)) | 
					
						
							|  |  |  | 			if sts: | 
					
						
							|  |  |  | 				print '='*70 | 
					
						
							|  |  |  | 		finally: | 
					
						
							|  |  |  | 			remove(tfn) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 	def commitcheck(self): | 
					
						
							|  |  |  | 		return self.action() != 'C' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def put(self, message = ""): | 
					
						
							| 
									
										
										
										
											1995-04-28 15:41:51 +00:00
										 |  |  | 		print "Checking in", self.file, "..." | 
					
						
							|  |  |  | 		data = open(self.file).read() | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | 		if not self.enew: | 
					
						
							|  |  |  | 			self.proxy.lock(self.file) | 
					
						
							| 
									
										
										
										
											1995-04-28 15:41:51 +00:00
										 |  |  | 		messages = self.proxy.put(self.file, data, message) | 
					
						
							|  |  |  | 		if messages: | 
					
						
							|  |  |  | 			print messages | 
					
						
							| 
									
										
										
										
											1995-04-28 21:48:16 +00:00
										 |  |  | 		self.setentry(self.proxy.head(self.file), self.lsum) | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	def get(self): | 
					
						
							|  |  |  | 		data = self.proxy.get(self.file) | 
					
						
							|  |  |  | 		f = open(self.file, 'w') | 
					
						
							|  |  |  | 		f.write(data) | 
					
						
							|  |  |  | 		f.close() | 
					
						
							| 
									
										
										
										
											1995-04-28 21:48:16 +00:00
										 |  |  | 		self.setentry(self.rrev, self.rsum) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 	def log(self, otherflags): | 
					
						
							|  |  |  | 		print self.proxy.log(self.file, otherflags) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | 	def add(self): | 
					
						
							|  |  |  | 		self.eseen = 0		# While we're hacking... | 
					
						
							|  |  |  | 		self.esum = self.lsum | 
					
						
							|  |  |  | 		self.emtime, self.ectime = 0, 0 | 
					
						
							|  |  |  | 		self.erev = '' | 
					
						
							|  |  |  | 		self.enew = 1 | 
					
						
							|  |  |  | 		self.edeleted = 0 | 
					
						
							|  |  |  | 		self.eseen = 1		# Done | 
					
						
							|  |  |  | 		self.extra = '' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-28 21:48:16 +00:00
										 |  |  | 	def setentry(self, erev, esum): | 
					
						
							|  |  |  | 		self.eseen = 0		# While we're hacking... | 
					
						
							|  |  |  | 		self.esum = esum | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		self.emtime, self.ectime = os.stat(self.file)[-2:] | 
					
						
							| 
									
										
										
										
											1995-04-28 21:48:16 +00:00
										 |  |  | 		self.erev = erev | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 		self.enew = 0 | 
					
						
							|  |  |  | 		self.edeleted = 0 | 
					
						
							| 
									
										
										
										
											1995-04-28 21:48:16 +00:00
										 |  |  | 		self.eseen = 1		# Done | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		self.extra = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SENDMAIL = "/usr/lib/sendmail -t" | 
					
						
							|  |  |  | MAILFORM = """To: %s
 | 
					
						
							|  |  |  | Subject: CVS changes: %s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ...Message from rcvs... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Committed files: | 
					
						
							|  |  |  | 	%s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Log message: | 
					
						
							|  |  |  | 	%s | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 18:07:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | class RCVS(CVS): | 
					
						
							| 
									
										
										
										
											1995-04-27 18:07:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 	FileClass = MyFile | 
					
						
							| 
									
										
										
										
											1995-04-27 18:07:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 	def __init__(self): | 
					
						
							|  |  |  | 		CVS.__init__(self) | 
					
						
							| 
									
										
										
										
											1995-04-27 18:07:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 	def update(self, files): | 
					
						
							|  |  |  | 		for e in self.whichentries(files, 1): | 
					
						
							|  |  |  | 			e.update() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def commit(self, files, message = ""): | 
					
						
							|  |  |  | 		list = self.whichentries(files) | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		if not list: return | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		ok = 1 | 
					
						
							|  |  |  | 		for e in list: | 
					
						
							|  |  |  | 			if not e.commitcheck(): | 
					
						
							|  |  |  | 				ok = 0 | 
					
						
							|  |  |  | 		if not ok: | 
					
						
							|  |  |  | 			print "correct above errors first" | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		if not message: | 
					
						
							|  |  |  | 			message = raw_input("One-liner: ") | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | 		committed = [] | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		for e in list: | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 			if e.commit(message): | 
					
						
							|  |  |  | 				committed.append(e.file) | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | 		self.mailinfo(committed, message) | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def mailinfo(self, files, message = ""): | 
					
						
							|  |  |  | 		towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX | 
					
						
							|  |  |  | 		mailtext = MAILFORM % (towhom, string.join(files), | 
					
						
							|  |  |  | 					string.join(files), message) | 
					
						
							|  |  |  | 		print '-'*70 | 
					
						
							|  |  |  | 		print mailtext | 
					
						
							|  |  |  | 		print '-'*70 | 
					
						
							|  |  |  | 		ok = raw_input("OK to mail to %s? " % towhom) | 
					
						
							|  |  |  | 		if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'): | 
					
						
							|  |  |  | 			p = os.popen(SENDMAIL, "w") | 
					
						
							|  |  |  | 			p.write(mailtext) | 
					
						
							|  |  |  | 			sts = p.close() | 
					
						
							|  |  |  | 			if sts: | 
					
						
							|  |  |  | 				print "Sendmail exit status %s" % str(sts) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				print "Mail sent." | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			print "No mail sent." | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def report(self, files): | 
					
						
							|  |  |  | 		for e in self.whichentries(files): | 
					
						
							|  |  |  | 			e.report() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def diff(self, files, opts): | 
					
						
							|  |  |  | 		for e in self.whichentries(files): | 
					
						
							|  |  |  | 			e.diff(opts) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | 	def add(self, files): | 
					
						
							|  |  |  | 		if not files: | 
					
						
							|  |  |  | 			raise RuntimeError, "'cvs add' needs at least one file" | 
					
						
							|  |  |  | 		list = [] | 
					
						
							|  |  |  | 		for e in self.whichentries(files, 1): | 
					
						
							|  |  |  | 			e.add() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def rm(self, files): | 
					
						
							|  |  |  | 		if not files: | 
					
						
							|  |  |  | 			raise RuntimeError, "'cvs rm' needs at least one file" | 
					
						
							|  |  |  | 		raise RuntimeError, "'cvs rm' not yet imlemented" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 	def log(self, files, opts): | 
					
						
							|  |  |  | 		flags = '' | 
					
						
							|  |  |  | 		for o, a in opts: | 
					
						
							|  |  |  | 			flags = flags + ' ' + o + a | 
					
						
							|  |  |  | 		for e in self.whichentries(files): | 
					
						
							|  |  |  | 			e.log(flags) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 	def whichentries(self, files, localfilestoo = 0): | 
					
						
							|  |  |  | 		if files: | 
					
						
							|  |  |  | 			list = [] | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 			for file in files: | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 				if self.entries.has_key(file): | 
					
						
							|  |  |  | 					e = self.entries[file] | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					e = self.FileClass(file) | 
					
						
							|  |  |  | 					self.entries[file] = e | 
					
						
							|  |  |  | 				list.append(e) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			list = self.entries.values() | 
					
						
							|  |  |  | 			for file in self.proxy.listfiles(): | 
					
						
							|  |  |  | 				if self.entries.has_key(file): | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				e = self.FileClass(file) | 
					
						
							|  |  |  | 				self.entries[file] = e | 
					
						
							|  |  |  | 				list.append(e) | 
					
						
							|  |  |  | 			if localfilestoo: | 
					
						
							|  |  |  | 				for file in os.listdir(os.curdir): | 
					
						
							|  |  |  | 					if not self.entries.has_key(file) \ | 
					
						
							|  |  |  | 					   and not self.ignored(file): | 
					
						
							|  |  |  | 						e = self.FileClass(file) | 
					
						
							|  |  |  | 						self.entries[file] = e | 
					
						
							|  |  |  | 						list.append(e) | 
					
						
							|  |  |  | 			list.sort() | 
					
						
							|  |  |  | 		if self.proxy: | 
					
						
							|  |  |  | 			for e in list: | 
					
						
							|  |  |  | 				if e.proxy is None: | 
					
						
							|  |  |  | 					e.proxy = self.proxy | 
					
						
							|  |  |  | 		return list | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class rcvs(CommandFrameWork): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-23 22:33:57 +00:00
										 |  |  | 	GlobalFlags = 'd:h:p:qvL' | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 	UsageMessage = \ | 
					
						
							| 
									
										
										
										
											1995-04-28 19:24:50 +00:00
										 |  |  | "usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]" | 
					
						
							|  |  |  | 	PostUsageMessage = \ | 
					
						
							|  |  |  | 		"If no subcommand is given, the status of all files is listed" | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def __init__(self): | 
					
						
							|  |  |  | 		"""Constructor.""" | 
					
						
							|  |  |  | 		CommandFrameWork.__init__(self) | 
					
						
							|  |  |  | 		self.proxy = None | 
					
						
							|  |  |  | 		self.cvs = RCVS() | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	def close(self): | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		if self.proxy: | 
					
						
							|  |  |  | 			self.proxy._close() | 
					
						
							|  |  |  | 		self.proxy = None | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def recurse(self): | 
					
						
							|  |  |  | 		self.close() | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		names = os.listdir(os.curdir) | 
					
						
							|  |  |  | 		for name in names: | 
					
						
							|  |  |  | 			if name == os.curdir or name == os.pardir: | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			if name == "CVS": | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			if not os.path.isdir(name): | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			if os.path.islink(name): | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			print "--- entering subdirectory", name, "---" | 
					
						
							|  |  |  | 			os.chdir(name) | 
					
						
							|  |  |  | 			try: | 
					
						
							|  |  |  | 				if os.path.isdir("CVS"): | 
					
						
							|  |  |  | 					self.__class__().run() | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					self.recurse() | 
					
						
							|  |  |  | 			finally: | 
					
						
							|  |  |  | 				os.chdir(os.pardir) | 
					
						
							|  |  |  | 				print "--- left subdirectory", name, "---" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 	def options(self, opts): | 
					
						
							|  |  |  | 		self.opts = opts | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def ready(self): | 
					
						
							|  |  |  | 		import rcsclient | 
					
						
							|  |  |  | 		self.proxy = rcsclient.openrcsclient(self.opts) | 
					
						
							|  |  |  | 		self.cvs.setproxy(self.proxy) | 
					
						
							|  |  |  | 		self.cvs.getentries() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def default(self): | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		self.cvs.report([]) | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | 	def do_report(self, opts, files): | 
					
						
							|  |  |  | 		self.cvs.report(files) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 23:33:43 +00:00
										 |  |  | 	def do_update(self, opts, files): | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		"""update [-l] [-R] [file] ...""" | 
					
						
							|  |  |  | 		local = DEF_LOCAL | 
					
						
							|  |  |  | 		for o, a in opts: | 
					
						
							|  |  |  | 			if o == '-l': local = 1 | 
					
						
							|  |  |  | 			if o == '-R': local = 0 | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		self.cvs.update(files) | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 		self.cvs.putentries() | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 		if not local and not files: | 
					
						
							|  |  |  | 			self.recurse() | 
					
						
							|  |  |  | 	flags_update = '-lR' | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 	do_up = do_update | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 	flags_up = flags_update | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 	def do_commit(self, opts, files): | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		"""commit [-m message] [file] ...""" | 
					
						
							|  |  |  | 		message = "" | 
					
						
							|  |  |  | 		for o, a in opts: | 
					
						
							|  |  |  | 			if o == '-m': message = a | 
					
						
							|  |  |  | 		self.cvs.commit(files, message) | 
					
						
							| 
									
										
										
										
											1995-04-28 15:26:37 +00:00
										 |  |  | 		self.cvs.putentries() | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 	flags_commit = 'm:' | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 	do_com = do_commit | 
					
						
							|  |  |  | 	flags_com = flags_commit | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def do_diff(self, opts, files): | 
					
						
							|  |  |  | 		"""diff [difflags] [file] ...""" | 
					
						
							| 
									
										
										
										
											1995-05-01 20:06:44 +00:00
										 |  |  | 		self.cvs.diff(files, opts) | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 	flags_diff = 'cbitwcefhnlr:sD:S:' | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 	do_dif = do_diff | 
					
						
							| 
									
										
										
										
											1995-06-21 01:02:06 +00:00
										 |  |  | 	flags_dif = flags_diff | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-18 18:34:34 +00:00
										 |  |  | 	def do_add(self, opts, files): | 
					
						
							|  |  |  | 		"""add file ...""" | 
					
						
							|  |  |  | 		if not files: | 
					
						
							|  |  |  | 			print "'rcvs add' requires at least one file" | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		self.cvs.add(files) | 
					
						
							|  |  |  | 		self.cvs.putentries() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def do_remove(self, opts, files): | 
					
						
							|  |  |  | 		"""remove file ...""" | 
					
						
							|  |  |  | 		if not files: | 
					
						
							|  |  |  | 			print "'rcvs remove' requires at least one file" | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		self.cvs.remove(files) | 
					
						
							|  |  |  | 		self.cvs.putentries() | 
					
						
							|  |  |  | 	do_rm = do_remove | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 	def do_log(self, opts, files): | 
					
						
							|  |  |  | 		"""log [rlog-options] [file] ...""" | 
					
						
							|  |  |  | 		self.cvs.log(files, opts) | 
					
						
							|  |  |  | 	flags_log = 'bhLNRtd:s:V:' | 
					
						
							| 
									
										
										
										
											1995-04-28 17:56:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def remove(fn): | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		os.unlink(fn) | 
					
						
							|  |  |  | 	except os.error: | 
					
						
							|  |  |  | 		pass | 
					
						
							| 
									
										
										
										
											1995-04-28 14:32:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-27 21:28:53 +00:00
										 |  |  | def main(): | 
					
						
							| 
									
										
										
										
											1995-10-07 19:47:26 +00:00
										 |  |  | 	r = rcvs() | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		r.run() | 
					
						
							|  |  |  | 	finally: | 
					
						
							|  |  |  | 		r.close() | 
					
						
							| 
									
										
										
										
											1995-04-27 18:07:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											1995-04-27 21:28:53 +00:00
										 |  |  | 	main() |