[Python-checkins] python/dist/src/Lib/plat-mac pimp.py,1.9,1.10

jackjansen@users.sourceforge.net jackjansen@users.sourceforge.net
Fri, 14 Feb 2003 06:12:04 -0800


Update of /cvsroot/python/python/dist/src/Lib/plat-mac
In directory sc8-pr-cvs1:/tmp/cvs-serv8973

Modified Files:
	pimp.py 
Log Message:
Factored out classes for handling source and binary distributions. Source
now means "distutils-based source", binary "bdist format archive". Also
fixed various lurking bugs.


Index: pimp.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/pimp.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** pimp.py	12 Feb 2003 16:37:00 -0000	1.9
--- pimp.py	14 Feb 2003 14:11:59 -0000	1.10
***************
*** 32,35 ****
--- 32,38 ----
  PIMP_VERSION="0.1"
  
+ # Flavors:
+ # source: setup-based package
+ # binary: tar (or other) archive created with setup.py bdist.
  DEFAULT_FLAVORORDER=['source', 'binary']
  DEFAULT_DOWNLOADDIR='/tmp'
***************
*** 39,47 ****
  
  ARCHIVE_FORMATS = [
! 	(".tar.Z", "zcat \"%s\" | tar xf -"),
! 	(".taz", "zcat \"%s\" | tar xf -"),
! 	(".tar.gz", "zcat \"%s\" | tar xf -"),
! 	(".tgz", "zcat \"%s\" | tar xf -"),
! 	(".tar.bz", "bzcat \"%s\" | tar xf -"),
  ]
  
--- 42,50 ----
  
  ARCHIVE_FORMATS = [
! 	(".tar.Z", "zcat \"%s\" | tar -xf -"),
! 	(".taz", "zcat \"%s\" | tar -xf -"),
! 	(".tar.gz", "zcat \"%s\" | tar -xf -"),
! 	(".tgz", "zcat \"%s\" | tar -xf -"),
! 	(".tar.bz", "bzcat \"%s\" | tar -xf -"),
  ]
  
***************
*** 133,136 ****
--- 136,144 ----
  		self._description = ""
  		
+ 	def close(self):
+ 		"""Clean up"""
+ 		self._packages = []
+ 		self.preferences = None
+ 		
  	def appendURL(self, url, included=0):
  		"""Append packages from the database with the given URL.
***************
*** 162,166 ****
  		
  		for p in packages:
! 			pkg = PimpPackage(self, dict(p))
  			self._packages.append(pkg)
  			
--- 170,181 ----
  		
  		for p in packages:
! 			p = dict(p)
! 			flavor = p.get('Flavor')
! 			if flavor == 'source':
! 				pkg = PimpPackage_source(self, p)
! 			elif flavor == 'binary':
! 				pkg = PimpPackage_binary(self, p)
! 			else:
! 				pkg = PimpPackage(self, dict(p))
  			self._packages.append(pkg)
  			
***************
*** 176,179 ****
--- 191,195 ----
  		for pkg in self._packages:
  			rv.append(pkg.fullname())
+ 		rv.sort()
  		return rv
  		
***************
*** 267,271 ****
  	def flavor(self): return self._dict['Flavor']
  	def description(self): return self._dict['Description']
! 	def homepage(self): return self._dict['Home-page']
  	def downloadURL(self): return self._dict['Download-URL']
  	
--- 283,287 ----
  	def flavor(self): return self._dict['Flavor']
  	def description(self): return self._dict['Description']
! 	def homepage(self): return self._dict.get('Home-page')
  	def downloadURL(self): return self._dict['Download-URL']
  	
***************
*** 343,347 ****
  		if not self._dict.get('Download-URL'):
  			return [(None, "This package needs to be installed manually")]
! 		if not self._dict['Prerequisites']:
  			return []
  		for item in self._dict['Prerequisites']:
--- 359,363 ----
  		if not self._dict.get('Download-URL'):
  			return [(None, "This package needs to be installed manually")]
! 		if not self._dict.get('Prerequisites'):
  			return []
  		for item in self._dict['Prerequisites']:
***************
*** 382,386 ****
  		return rv
  		
! 	def downloadSinglePackage(self, output=None):
  		"""Download a single package, if needed.
  		
--- 398,402 ----
  		return rv
  		
! 	def downloadPackageOnly(self, output=None):
  		"""Download a single package, if needed.
  		
***************
*** 423,427 ****
  		return checksum == self._dict['MD5Sum']
  			
! 	def unpackSinglePackage(self, output=None):
  		"""Unpack a downloaded package archive."""
  		
--- 439,443 ----
  		return checksum == self._dict['MD5Sum']
  			
! 	def unpackPackageOnly(self, output=None):
  		"""Unpack a downloaded package archive."""
  		
***************
*** 434,443 ****
  		basename = filename[:-len(ext)]
  		cmd = cmd % self.archiveFilename
- 		self._buildDirname = os.path.join(self._db.preferences.buildDir, basename)
  		if self._cmd(output, self._db.preferences.buildDir, cmd):
  			return "unpack command failed"
! 		setupname = os.path.join(self._buildDirname, "setup.py")
! 		if not os.path.exists(setupname) and not NO_EXECUTE:
! 			return "no setup.py found after unpack of archive"
  			
  	def installSinglePackage(self, output=None):
--- 450,459 ----
  		basename = filename[:-len(ext)]
  		cmd = cmd % self.archiveFilename
  		if self._cmd(output, self._db.preferences.buildDir, cmd):
  			return "unpack command failed"
! 			
! 	def installPackageOnly(self, output=None):
! 		"""Default install method, to be overridden by subclasses"""
! 		return "Cannot automatically install package %s" % self.fullname()
  			
  	def installSinglePackage(self, output=None):
***************
*** 449,485 ****
  		if not self._dict['Download-URL']:
  			return "%s: This package needs to be installed manually" % _fmtpackagename(self)
! 		msg = self.downloadSinglePackage(output)
  		if msg:
  			return "download %s: %s" % (self.fullname(), msg)
  			
! 		msg = self.unpackSinglePackage(output)
  		if msg:
  			return "unpack %s: %s" % (self.fullname(), msg)
  			
! 		if self._dict.has_key('Pre-install-command'):
! 			if self._cmd(output, self._buildDirname, self._dict['Pre-install-command']):
! 				return "pre-install %s: running \"%s\" failed" % \
! 					(self.fullname(), self._dict['Pre-install-command'])
! 					
! 		old_contents = os.listdir(self._db.preferences.installDir)
! 		installcmd = self._dict.get('Install-command')
! 		if not installcmd:
! 			installcmd = '"%s" setup.py install' % sys.executable
! 		if self._cmd(output, self._buildDirname, installcmd):
! 			return "install %s: running \"%s\" failed" % self.fullname()
! 		
! 		new_contents = os.listdir(self._db.preferences.installDir)
! 		self._interpretPthFiles(old_contents, new_contents)
  		
! 		if self._dict.has_key('Post-install-command'):
! 			if self._cmd(output, self._buildDirname, self._dict['Post-install-command']):
! 				return "post-install %s: running \"%s\" failed" % \
! 					(self.fullname(), self._dict['Post-install-command'])
! 		return None
  		
! 	def _interpretPthFiles(self, old_contents, new_contents):
! 		"""Evaluate any new .pth files that have appeared after installing"""
  		for fn in new_contents:
! 			if fn in old_contents:
  				continue
  			if fn[-4:] != '.pth':
--- 465,489 ----
  		if not self._dict['Download-URL']:
  			return "%s: This package needs to be installed manually" % _fmtpackagename(self)
! 		msg = self.downloadPackageOnly(output)
  		if msg:
  			return "download %s: %s" % (self.fullname(), msg)
  			
! 		msg = self.unpackPackageOnly(output)
  		if msg:
  			return "unpack %s: %s" % (self.fullname(), msg)
  			
! 		return self.installPackageOnly(output)
  		
! 	def beforeInstall(self):
! 		"""Bookkeeping before installation: remember what we have in site-packages"""
! 		self._old_contents = os.listdir(self._db.preferences.installDir)
  		
! 	def afterInstall(self):
! 		"""Bookkeeping after installation: interpret any new .pth files that have
! 		appeared"""
! 				
! 		new_contents = os.listdir(self._db.preferences.installDir)
  		for fn in new_contents:
! 			if fn in self._old_contents:
  				continue
  			if fn[-4:] != '.pth':
***************
*** 501,507 ****
  				line = os.path.realpath(line)
  				if not line in sys.path:
! 					sys.path.append(line)
! 				
  
  class PimpInstaller:
  	"""Installer engine: computes dependencies and installs
--- 505,593 ----
  				line = os.path.realpath(line)
  				if not line in sys.path:
! 					sys.path.append(line)			
  
+ class PimpPackage_binary(PimpPackage):
+ 
+ 	def unpackPackageOnly(self, output=None):
+ 		"""We don't unpack binary packages until installing"""
+ 		pass
+ 			
+ 	def installPackageOnly(self, output=None):
+ 		"""Install a single source package.
+ 		
+ 		If output is given it should be a file-like object and it
+ 		will receive a log of what happened."""
+ 					
+ 		msgs = []
+ 		if self._dict.has_key('Pre-install-command'):
+ 			msg.append("%s: Pre-install-command ignored" % self.fullname())
+ 		if self._dict.has_key('Install-command'):
+ 			msgs.append("%s: Install-command ignored" % self.fullname())
+ 		if self._dict.has_key('Post-install-command'):
+ 			msgs.append("%s: Post-install-command ignored" % self.fullname())
+ 					
+ 		self.beforeInstall()
+ 
+ 		# Install by unpacking
+ 		filename = os.path.split(self.archiveFilename)[1]
+ 		for ext, cmd in ARCHIVE_FORMATS:
+ 			if filename[-len(ext):] == ext:
+ 				break
+ 		else:
+ 			return "unknown extension for archive file: %s" % filename
+ 		
+ 		# Modify where the files are extracted
+ 		prefixmod = '-C /'
+ 		cmd = cmd % self.archiveFilename
+ 		if self._cmd(output, self._db.preferences.buildDir, cmd, prefixmod):
+ 			return "unpack command failed"
+ 		
+ 		self.afterInstall()
+ 		
+ 		if self._dict.has_key('Post-install-command'):
+ 			if self._cmd(output, self._buildDirname, self._dict['Post-install-command']):
+ 				return "post-install %s: running \"%s\" failed" % \
+ 					(self.fullname(), self._dict['Post-install-command'])
+ 		return None
+ 		
+ 	
+ class PimpPackage_source(PimpPackage):
+ 
+ 	def unpackPackageOnly(self, output=None):
+ 		"""Unpack a source package and check that setup.py exists"""
+ 		PimpPackage.unpackPackageOnly(self, output)
+ 		# Test that a setup script has been create
+ 		self._buildDirname = os.path.join(self._db.preferences.buildDir, basename)
+ 		setupname = os.path.join(self._buildDirname, "setup.py")
+ 		if not os.path.exists(setupname) and not NO_EXECUTE:
+ 			return "no setup.py found after unpack of archive"
+ 
+ 	def installPackageOnly(self, output=None):
+ 		"""Install a single source package.
+ 		
+ 		If output is given it should be a file-like object and it
+ 		will receive a log of what happened."""
+ 					
+ 		if self._dict.has_key('Pre-install-command'):
+ 			if self._cmd(output, self._buildDirname, self._dict['Pre-install-command']):
+ 				return "pre-install %s: running \"%s\" failed" % \
+ 					(self.fullname(), self._dict['Pre-install-command'])
+ 					
+ 		self.beforeInstall()
+ 		installcmd = self._dict.get('Install-command')
+ 		if not installcmd:
+ 			installcmd = '"%s" setup.py install' % sys.executable
+ 		if self._cmd(output, self._buildDirname, installcmd):
+ 			return "install %s: running \"%s\" failed" % self.fullname()
+ 		
+ 		self.afterInstall()
+ 		
+ 		if self._dict.has_key('Post-install-command'):
+ 			if self._cmd(output, self._buildDirname, self._dict['Post-install-command']):
+ 				return "post-install %s: running \"%s\" failed" % \
+ 					(self.fullname(), self._dict['Post-install-command'])
+ 		return None
+ 		
+ 	
  class PimpInstaller:
  	"""Installer engine: computes dependencies and installs