[Python-checkins] distutils2: hooked the remove code - tests w/ data tree coming up

tarek.ziade python-checkins at python.org
Sun Jan 30 17:12:25 CET 2011


tarek.ziade pushed 76c83ee98558 to distutils2:

http://hg.python.org/distutils2/rev/76c83ee98558
changeset:   982:76c83ee98558
user:        Tarek Ziade <tarek at ziade.org>
date:        Sun Jan 30 17:09:46 2011 +0100
summary:
  hooked the remove code - tests w/ data tree coming up

files:
  distutils2/_backport/pkgutil.py
  distutils2/install.py
  distutils2/run.py

diff --git a/distutils2/_backport/pkgutil.py b/distutils2/_backport/pkgutil.py
--- a/distutils2/_backport/pkgutil.py
+++ b/distutils2/_backport/pkgutil.py
@@ -7,6 +7,13 @@
 import warnings
 from csv import reader as csv_reader
 from types import ModuleType
+from stat import ST_SIZE
+
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import md5
+
 from distutils2.errors import DistutilsError
 from distutils2.metadata import DistributionMetadata
 from distutils2.version import suggest_normalized_version, VersionPredicate
@@ -969,6 +976,33 @@
         return '%s-%s at %s' % (self.name, self.metadata.version, self.path)
 
     def get_installed_files(self, local=False):
+
+        def _md5(path):
+            f = open(path)
+            try:
+                content = f.read()
+            finally:
+                f.close()
+            return md5(content).hexdigest()
+
+        def _size(path):
+            return os.stat(path)[ST_SIZE]
+
+        path = self.path
+        if local:
+            path = path.replace('/', os.sep)
+
+        # XXX What about scripts and data files ?
+        if os.path.isfile(path):
+            return [(path, _md5(path), _size(path))]
+        else:
+            files = []
+            for root, dir, files_ in os.walk(path):
+                for item in files_:
+                    item = os.path.join(root, item)
+                    files.append((item, _md5(item), _size(item)))
+            return files
+
         return []
 
     def uses(self, path):
diff --git a/distutils2/install.py b/distutils2/install.py
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -334,37 +334,64 @@
 
 def remove(project_name, paths=sys.path):
     """Removes a single project from the installation"""
-    dist = get_distribution(project_name, paths=paths)
+    dist = get_distribution(project_name, use_egg_info=True, paths=paths)
     if dist is None:
-        raise DistutilsError('Distribution %s not found' % project_name)
+        raise DistutilsError('Distribution "%s" not found' % project_name)
     files = dist.get_installed_files(local=True)
     rmdirs = []
     rmfiles = []
     tmp = tempfile.mkdtemp(prefix=project_name + '-uninstall')
     try:
-        for file, md5, size in files:
-            if os.path.isfile(file):
-                dirname, filename = os.path.split(file)
+        for file_, md5, size in files:
+            if os.path.isfile(file_):
+                dirname, filename = os.path.split(file_)
                 tmpfile = os.path.join(tmp, filename)
                 try:
-                    os.rename(file, tmpfile)
+                    os.rename(file_, tmpfile)
                 finally:
-                    if not os.path.isfile(file):
-                        os.rename(tmpfile, file)
-                if file not in rmfiles:
-                    rmfiles.append(file)
+                    if not os.path.isfile(file_):
+                        os.rename(tmpfile, file_)
+                if file_ not in rmfiles:
+                    rmfiles.append(file_)
                 if dirname not in rmdirs:
                     rmdirs.append(dirname)
     finally:
         shutil.rmtree(tmp)
 
-    for file in rmfiles:
-        os.remove(file)
+    logger.info('Removing %r...' % project_name)
 
+    file_count = 0
+    for file_ in rmfiles:
+        os.remove(file_)
+        file_count +=1
+
+    dir_count = 0
     for dirname in rmdirs:
-        if not os.listdir(dirname):
-            if bool(os.stat(dirname).st_mode & stat.S_IWUSR):
-                os.rmdir(dirname)
+        if not os.path.exists(dirname):
+            # could
+            continue
+
+        files_count = 0
+        for root, dir, files in os.walk(dirname):
+            files_count += len(files)
+
+        if files_count > 0:
+            # XXX Warning
+            continue
+
+        # empty dirs with only empty dirs
+        if bool(os.stat(dirname).st_mode & stat.S_IWUSR):
+            # XXX Add a callable in shutil.rmtree to count
+            # the number of deleted elements
+            shutil.rmtree(dirname)
+            dir_count += 1
+
+    # removing the top path
+    # XXX count it ?
+    shutil.rmtree(dist.path)
+
+    logger.info('Success ! Removed %d files and %d dirs' % \
+            (file_count, dir_count))
 
 
 def install(project):
diff --git a/distutils2/run.py b/distutils2/run.py
--- a/distutils2/run.py
+++ b/distutils2/run.py
@@ -11,7 +11,7 @@
 from distutils2 import __version__
 from distutils2._backport.pkgutil import get_distributions, get_distribution
 from distutils2.depgraph import generate_graph
-from distutils2.install import install
+from distutils2.install import install, remove
 
 # This is a barebones help message generated displayed when the user
 # runs the setup script with no arguments at all.  More useful help
@@ -225,6 +225,10 @@
         install(options.install)
         return 0
 
+    if options.remove is not None:
+        remove(options.remove)
+        return 0
+
     if len(args) == 0:
         parser.print_help()
         return 0

--
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list