[Distutils] Generic uninstall command
M.-A. Lemburg
mal@lemburg.com
Fri Feb 16 11:50:03 2001
Here is a different uninstall command which works by checking
.get_outputs(). Rene already hinted towards this idea -- I found
it while looking at the install.py source code (there's even a
flag to write a list of these files somewhere...).
This command should work with all install commands which adhere to
the .get_outputs() logic, meaning that this API should return
a list of absolute filenames of all files which the command wrote
to the file system.
The directory removal is a bit flaky, but works great on systems
which do not allow the removal of directories which aren't empty.
Unfortunately, the .get_outputs() method does not support adding
directories to the list (at least the code using that method
doesn't), so there doesn't seem to be a more elegant way...
#
# Uninstall command
#
class mx_uninstall(Command):
description = "uninstall the package"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
# Execute build
self.announce('determining installation files')
savevalue = self.distribution.dry_run
self.distribution.dry_run = 0
self.run_command('build')
# Execute install in dry-run mode
self.distribution.dry_run = 1
self.run_command('install')
self.distribution.dry_run = savevalue
build = self.get_finalized_command('build')
install = self.get_finalized_command('install')
# Remove all installed files
self.announce("removing files")
dirs = {}
filenames = install.get_outputs()
for filename in filenames:
if not os.path.isabs(filename):
raise DistutilsError,\
'filename "%s" from .get_output() not absolute' % \
filename
if os.path.isfile(filename):
self.announce("removing '%s'" % filename)
if not self.dry_run:
try:
os.remove(filename)
except OSError, details:
self.warn("Could not remove file: %s" % details)
dir = os.path.split(filename)[0]
if not dirs.has_key(dir):
dirs[dir] = 1
if os.path.splitext(filename)[1] == '.py':
# Try to remove .pyc and .pyo files also
try:
os.remove(filename + 'c')
except OSError:
pass
try:
os.remove(filename + 'o')
except OSError:
pass
elif os.path.isdir(filename):
if not dirs.has_key(dir):
dirs[filename] = 1
else:
self.announce("skipping removal of '%s' (not found)" %
filename)
# Remove the installation directories
self.announce("removing directories")
dirs = dirs.keys()
dirs.sort(); dirs.reverse() # sort descending
for dir in dirs:
self.announce("removing directory '%s'" % dir)
if not self.dry_run:
try:
os.rmdir(dir)
except OSError, details:
self.warn("could not remove directory: %s" % details)
--
Marc-Andre Lemburg
______________________________________________________________________
Company: http://www.egenix.com/
Consulting: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/