| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # Interactively decide what to distribute | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # The exclude file signals files to always exclude, | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | # The pattern file lines are of the form | 
					
						
							|  |  |  | # *.c | 
					
						
							|  |  |  | # This excludes all files ending in .c. | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # The include file signals files and directories to include. | 
					
						
							|  |  |  | # Records are of the form | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | # ('Tools:bgen:AE:AppleEvents.py', 'Lib:MacToolbox:AppleEvents.py') | 
					
						
							|  |  |  | # This includes the specified file, putting it in the given place, or | 
					
						
							|  |  |  | # ('Tools:bgen:AE:AppleEvents.py', None) | 
					
						
							|  |  |  | # This excludes the specified file. | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | # | 
					
						
							|  |  |  | from MkDistr_ui import * | 
					
						
							|  |  |  | import fnmatch | 
					
						
							|  |  |  | import regex | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import macfs | 
					
						
							|  |  |  | import macostools | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | DEBUG=0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | SyntaxError='Include/exclude file syntax error' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Matcher: | 
					
						
							|  |  |  | 	"""Include/exclude database, common code""" | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 	def __init__(self, filename): | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		self.filename = filename | 
					
						
							|  |  |  | 		self.rawdata = [] | 
					
						
							|  |  |  | 		self.parse(filename) | 
					
						
							|  |  |  | 		self.rawdata.sort() | 
					
						
							|  |  |  | 		self.rebuild() | 
					
						
							|  |  |  | 		self.modified = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def parse(self, dbfile): | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			fp = open(dbfile) | 
					
						
							|  |  |  | 		except IOError: | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		data = fp.readlines() | 
					
						
							|  |  |  | 		fp.close() | 
					
						
							|  |  |  | 		for d in data: | 
					
						
							|  |  |  | 			d = d[:-1] | 
					
						
							|  |  |  | 			if not d or d[0] == '#': continue | 
					
						
							|  |  |  | 			pat = self.parseline(d) | 
					
						
							|  |  |  | 			self.rawdata.append(pat) | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 	def save(self): | 
					
						
							|  |  |  | 		fp = open(self.filename, 'w') | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 		self.savedata(fp, self.rawdata) | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		self.modified = 0 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	def add(self, value): | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 		if len(value) == 1: | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 			value = value + ('',) | 
					
						
							|  |  |  | 		self.rawdata.append(value) | 
					
						
							|  |  |  | 		self.rebuild1(value) | 
					
						
							|  |  |  | 		self.modified = 1 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def delete(self, value): | 
					
						
							|  |  |  | 		key = value | 
					
						
							|  |  |  | 		for i in range(len(self.rawdata)): | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 			if self.rawdata[i][0] == key: | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 				del self.rawdata[i] | 
					
						
							|  |  |  | 				self.unrebuild1(i, key) | 
					
						
							|  |  |  | 				self.modified = 1 | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 		print 'Not found!', key | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 	def getall(self): | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 		return map(lambda x: x[0], self.rawdata) | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	def get(self, value): | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 		for src, dst in self.rawdata: | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 			if src == value: | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 				return src, dst | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		print 'Not found!', value | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 	def is_modified(self): | 
					
						
							|  |  |  | 		return self.modified | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | class IncMatcher(Matcher): | 
					
						
							|  |  |  | 	"""Include filename database and matching engine""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def rebuild(self): | 
					
						
							|  |  |  | 		self.idict = {} | 
					
						
							|  |  |  | 		self.edict = {} | 
					
						
							|  |  |  | 		for v in self.rawdata: | 
					
						
							|  |  |  | 			self.rebuild1(v) | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 	def parseline(self, line): | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			data = eval(line) | 
					
						
							|  |  |  | 		except: | 
					
						
							|  |  |  | 			raise SyntaxError, line | 
					
						
							|  |  |  | 		if type(data) <> type(()) or len(data) not in (1,2): | 
					
						
							|  |  |  | 			raise SyntaxError, line | 
					
						
							|  |  |  | 		if len(data) == 1: | 
					
						
							|  |  |  | 			data = data + ('',) | 
					
						
							|  |  |  | 		return data | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def savedata(self, fp, data): | 
					
						
							|  |  |  | 		for d in self.rawdata: | 
					
						
							|  |  |  | 			fp.write(`d`+'\n') | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def rebuild1(self, (src, dst)): | 
					
						
							|  |  |  | 		if dst == '': | 
					
						
							|  |  |  | 			dst = src | 
					
						
							|  |  |  | 		if dst == None: | 
					
						
							|  |  |  | 			self.edict[src] = None | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		else: | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 			self.idict[src] = dst | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 	def unrebuild1(self, num, src): | 
					
						
							|  |  |  | 		if self.idict.has_key(src): | 
					
						
							|  |  |  | 			del self.idict[src] | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			del self.edict[src] | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def match(self, patharg): | 
					
						
							|  |  |  | 		removed = [] | 
					
						
							|  |  |  | 		# First check the include directory | 
					
						
							|  |  |  | 		path = patharg | 
					
						
							|  |  |  | 		while 1: | 
					
						
							|  |  |  | 			if self.idict.has_key(path): | 
					
						
							|  |  |  | 				# We know of this path (or initial piece of path) | 
					
						
							|  |  |  | 				dstpath = self.idict[path] | 
					
						
							|  |  |  | 				# We do want it distributed. Tack on the tail. | 
					
						
							|  |  |  | 				while removed: | 
					
						
							|  |  |  | 					dstpath = os.path.join(dstpath, removed[0]) | 
					
						
							|  |  |  | 					removed = removed[1:] | 
					
						
							|  |  |  | 				# Finally, if the resultant string ends in a separator | 
					
						
							|  |  |  | 				# tack on our input filename | 
					
						
							|  |  |  | 				if dstpath[-1] == os.sep: | 
					
						
							|  |  |  | 					dir, file = os.path.split(path) | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 					dstpath = os.path.join(dstpath, file) | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 				if DEBUG: | 
					
						
							|  |  |  | 					print 'include', patharg, dstpath | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 				return dstpath | 
					
						
							|  |  |  | 			path, lastcomp = os.path.split(path) | 
					
						
							|  |  |  | 			if not path: | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			removed[0:0] = [lastcomp] | 
					
						
							|  |  |  | 		# Next check the exclude directory | 
					
						
							|  |  |  | 		path = patharg | 
					
						
							|  |  |  | 		while 1: | 
					
						
							|  |  |  | 			if self.edict.has_key(path): | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 				if DEBUG: | 
					
						
							|  |  |  | 					print 'exclude', patharg, path | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 				return '' | 
					
						
							|  |  |  | 			path, lastcomp = os.path.split(path) | 
					
						
							|  |  |  | 			if not path: | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			removed[0:0] = [lastcomp] | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 		if DEBUG: | 
					
						
							|  |  |  | 			print 'nomatch', patharg | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		return None | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	def checksourcetree(self): | 
					
						
							|  |  |  | 		rv = [] | 
					
						
							|  |  |  | 		for name in self.idict.keys(): | 
					
						
							|  |  |  | 			if not os.path.exists(name): | 
					
						
							|  |  |  | 				rv.append(name) | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | class ExcMatcher(Matcher): | 
					
						
							|  |  |  | 	"""Exclude pattern database and matching engine""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def rebuild(self): | 
					
						
							|  |  |  | 		self.relist = [] | 
					
						
							|  |  |  | 		for v in self.rawdata: | 
					
						
							|  |  |  | 			self.rebuild1(v) | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 	def parseline(self, data): | 
					
						
							|  |  |  | 		return (data, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def savedata(self, fp, data): | 
					
						
							|  |  |  | 		for d in self.rawdata: | 
					
						
							|  |  |  | 			fp.write(d[0]+'\n')		 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def rebuild1(self, (src, dst)): | 
					
						
							|  |  |  | 		pat = fnmatch.translate(src) | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 		if DEBUG: | 
					
						
							|  |  |  | 			print 'PATTERN', `src`, 'REGEX', `pat` | 
					
						
							| 
									
										
										
										
											1996-08-28 14:18:58 +00:00
										 |  |  | 		self.relist.append(regex.compile(pat)) | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 	def unrebuild1(self, num, src): | 
					
						
							|  |  |  | 		del self.relist[num] | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def match(self, path): | 
					
						
							|  |  |  | 		comps = os.path.split(path) | 
					
						
							|  |  |  | 		file = comps[-1] | 
					
						
							|  |  |  | 		for pat in self.relist: | 
					
						
							|  |  |  | 			if pat and pat.match(file) == len(file): | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 				if DEBUG: | 
					
						
							|  |  |  | 					print 'excmatch', file, pat | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 				return 1 | 
					
						
							|  |  |  | 		return 0		 | 
					
						
							|  |  |  | 		  | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | class Main: | 
					
						
							|  |  |  | 	"""The main program glueing it all together""" | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def __init__(self): | 
					
						
							|  |  |  | 		InitUI() | 
					
						
							| 
									
										
										
										
											2000-05-05 23:07:43 +00:00
										 |  |  | 		os.chdir(sys.prefix) | 
					
						
							| 
									
										
										
										
											1996-10-23 15:52:56 +00:00
										 |  |  | 		if not os.path.isdir(':Mac:Distributions'): | 
					
						
							|  |  |  | 			os.mkdir(':Mac:Distributions') | 
					
						
							| 
									
										
										
										
											2000-05-05 23:07:43 +00:00
										 |  |  | 		self.typedist = GetType() | 
					
						
							|  |  |  | 		self.inc = IncMatcher(':Mac:Distributions:%s.include'%self.typedist) | 
					
						
							|  |  |  | 		self.exc = ExcMatcher(':Mac:Distributions:%s.exclude'%self.typedist) | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		self.ui = MkDistrUI(self) | 
					
						
							|  |  |  | 		self.ui.mainloop() | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def check(self): | 
					
						
							|  |  |  | 		return self.checkdir(':', 1) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def checkdir(self, path, istop): | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 		if DEBUG: | 
					
						
							|  |  |  | 			print 'checkdir', path | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		files = os.listdir(path) | 
					
						
							|  |  |  | 		rv = [] | 
					
						
							|  |  |  | 		todo = [] | 
					
						
							|  |  |  | 		for f in files: | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 			if DEBUG: | 
					
						
							|  |  |  | 				print 'checkfile', f | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 			if self.exc.match(f): | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 				if DEBUG: | 
					
						
							|  |  |  | 					print 'exclude match', f | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 				continue | 
					
						
							|  |  |  | 			fullname = os.path.join(path, f) | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 			if DEBUG: | 
					
						
							|  |  |  | 				print 'checkpath', fullname | 
					
						
							|  |  |  | 			matchvalue = self.inc.match(fullname) | 
					
						
							|  |  |  | 			if matchvalue == None: | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 				if os.path.isdir(fullname): | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 					if DEBUG: | 
					
						
							|  |  |  | 						print 'do dir', fullname | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 					todo.append(fullname) | 
					
						
							|  |  |  | 				else: | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 					if DEBUG: | 
					
						
							|  |  |  | 						print 'include', fullname | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 					rv.append(fullname) | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 			elif DEBUG: | 
					
						
							|  |  |  | 				print 'badmatch', matchvalue | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		for d in todo: | 
					
						
							| 
									
										
										
										
											1997-05-23 15:41:15 +00:00
										 |  |  | 			if len(rv) > 500: | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 				if istop: | 
					
						
							|  |  |  | 					rv.append('... and more ...') | 
					
						
							|  |  |  | 				return rv | 
					
						
							|  |  |  | 			rv = rv + self.checkdir(d, 0) | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2000-05-05 23:07:43 +00:00
										 |  |  | 	def run(self): | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		missing = self.inc.checksourcetree() | 
					
						
							|  |  |  | 		if missing: | 
					
						
							|  |  |  | 			print '==== Missing source files ====' | 
					
						
							|  |  |  | 			for i in missing: | 
					
						
							|  |  |  | 				print i | 
					
						
							|  |  |  | 			print '==== Fix and retry ====' | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2000-05-05 23:07:43 +00:00
										 |  |  | 		destprefix = os.path.join(sys.prefix, ':Mac:Distributions:vise') | 
					
						
							|  |  |  | 		destprefix = os.path.join(destprefix, '%s Distribution'%self.typedist) | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		if not self.rundir(':', destprefix, 0): | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		self.rundir(':', destprefix, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def rundir(self, path, destprefix, doit): | 
					
						
							|  |  |  | 		files = os.listdir(path) | 
					
						
							|  |  |  | 		todo = [] | 
					
						
							|  |  |  | 		rv = 1 | 
					
						
							|  |  |  | 		for f in files: | 
					
						
							|  |  |  | 			if self.exc.match(f): | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			fullname = os.path.join(path, f) | 
					
						
							|  |  |  | 			if os.path.isdir(fullname): | 
					
						
							|  |  |  | 				todo.append(fullname) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				dest = self.inc.match(fullname) | 
					
						
							|  |  |  | 				if dest == None: | 
					
						
							|  |  |  | 					print 'Not yet resolved:', fullname | 
					
						
							|  |  |  | 					rv = 0 | 
					
						
							|  |  |  | 				if dest: | 
					
						
							|  |  |  | 					if doit: | 
					
						
							|  |  |  | 						print 'COPY ', fullname | 
					
						
							|  |  |  | 						print '  -> ', os.path.join(destprefix, dest) | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 						try: | 
					
						
							|  |  |  | 							macostools.copy(fullname, os.path.join(destprefix, dest), 1) | 
					
						
							|  |  |  | 						except: #DBG | 
					
						
							| 
									
										
										
										
											1998-04-27 15:12:13 +00:00
										 |  |  | 							print 'cwd', os.getcwd() #DBG | 
					
						
							| 
									
										
										
										
											1998-02-20 16:08:19 +00:00
										 |  |  | 							print 'fsspec', macfs.FSSpec(fullname) #DBG | 
					
						
							| 
									
										
										
										
											1998-04-27 15:12:13 +00:00
										 |  |  | 							raise | 
					
						
							| 
									
										
										
										
											1995-08-31 13:50:16 +00:00
										 |  |  | 		for d in todo: | 
					
						
							|  |  |  | 			if not self.rundir(d, destprefix, doit): | 
					
						
							|  |  |  | 				rv = 0 | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def save(self): | 
					
						
							|  |  |  | 		self.inc.save() | 
					
						
							|  |  |  | 		self.exc.save() | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def is_modified(self): | 
					
						
							|  |  |  | 		return self.inc.is_modified() or self.exc.is_modified() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  | 	Main() | 
					
						
							|  |  |  | 	 |