[Python-checkins] distutils2: merge

tarek.ziade python-checkins at python.org
Sun Jan 30 10:43:58 CET 2011


tarek.ziade pushed 1e23203b0675 to distutils2:

http://hg.python.org/distutils2/rev/1e23203b0675
changeset:   952:1e23203b0675
parent:      951:20b7b525914c
parent:      949:f31564d7ed76
user:        Alexis Metaireau <alexis at notmyidea.org>
date:        Sat Jan 29 18:07:41 2011 +0100
summary:
  merge

files:
  

diff --git a/distutils2/_backport/pkgutil.py b/distutils2/_backport/pkgutil.py
--- a/distutils2/_backport/pkgutil.py
+++ b/distutils2/_backport/pkgutil.py
@@ -1029,7 +1029,7 @@
         for dist in _yield_distributions(True, use_egg_info, paths):
             yield dist
     else:
-        _generate_cache(use_egg_info)
+        _generate_cache(use_egg_info, paths)
 
         for dist in _cache_path.itervalues():
             yield dist
@@ -1061,7 +1061,7 @@
             if dist.name == name:
                 return dist
     else:
-        _generate_cache(use_egg_info)
+        _generate_cache(use_egg_info, paths)
 
         if name in _cache_name:
             return _cache_name[name][0]
diff --git a/distutils2/install.py b/distutils2/install.py
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -1,15 +1,20 @@
 from tempfile import mkdtemp
 import shutil
 import os
+import sys
+import stat
 import errno
 import itertools
+import tempfile
 
 from distutils2 import logger
 from distutils2._backport.pkgutil import get_distributions
+from distutils2._backport.pkgutil import get_distribution
 from distutils2._backport.sysconfig import get_config_var
 from distutils2.depgraph import generate_graph
 from distutils2.index import wrapper
 from distutils2.index.errors import ProjectNotFound, ReleaseNotFound
+from distutils2.errors import DistutilsError
 from distutils2.version import get_version_predicate
 
 """Provides installations scripts.
@@ -310,10 +315,40 @@
             infos[key].extend(new_infos[key])
 
 
-def remove(project_name):
+def remove(project_name, paths=sys.path):
     """Removes a single project from the installation"""
-    pass
+    tmp = tempfile.mkdtemp(prefix=project_name+'-uninstall')
+    dist = get_distribution(project_name, paths=paths)
+    if dist is None:
+        raise DistutilsError('Distribution %s not found' % project_name)
+    files = dist.get_installed_files(local=True)
+    rmdirs = []
+    rmfiles = []
 
+    try:
+        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)
+                finally:
+                    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)
+    except OSError:
+        os.rmdir(tmp)
+
+    for file in rmfiles:
+        os.remove(file)
+
+    for dirname in rmdirs:
+        if not os.listdir(dirname):
+            if bool(os.stat(dirname).st_mode & stat.S_IWUSR):
+                os.rmdir(dirname)
 
 
 
diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py
--- a/distutils2/tests/support.py
+++ b/distutils2/tests/support.py
@@ -159,6 +159,21 @@
         dist = Distribution(attrs=kw)
         return project_dir, dist
 
+    def assertIsFile(self, *args):
+        path = os.path.join(*args)
+        dirname = os.path.dirname(path)
+        file = os.path.basename(path)
+        if os.path.isdir(dirname):
+            files = os.listdir(dirname)
+            msg = "%s not found in %s: %s" % (file, dirname, files)
+            assert os.path.isfile(path), msg
+        else:
+            raise AssertionError(
+                    '%s not found. %s does not exist' % (file, dirname))
+
+    def assertIsNotFile(self, *args):
+        path = os.path.join(*args)
+        assert not os.path.isfile(path), "%s exist" % path
 
 class EnvironGuard(object):
     """TestCase-compatible mixin to save and restore the environment."""
diff --git a/distutils2/tests/test_uninstall.py b/distutils2/tests/test_uninstall.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/test_uninstall.py
@@ -0,0 +1,93 @@
+"""Tests for the uninstall command."""
+import os
+import sys
+from StringIO import StringIO
+from distutils2._backport.pkgutil import disable_cache, enable_cache
+from distutils2.tests import unittest, support, run_unittest
+from distutils2.errors import DistutilsError
+from distutils2.install import remove
+
+SETUP_CFG = """
+[metadata]
+name = %(name)s
+version = %(version)s
+
+[files]
+packages =
+    %(name)s
+    %(name)s.sub
+"""
+
+class UninstallTestCase(support.TempdirManager,
+                     support.LoggingCatcher,
+                     unittest.TestCase):
+
+    def setUp(self):
+        super(UninstallTestCase, self).setUp()
+        self.addCleanup(setattr, sys, 'stdout', sys.stdout)
+        self.addCleanup(setattr, sys, 'stderr', sys.stderr)
+        self.addCleanup(os.chdir, os.getcwd())
+        self.addCleanup(enable_cache)
+        self.root_dir = self.mkdtemp()
+        disable_cache()
+
+    def run_setup(self, *args):
+        # run setup with args
+        #sys.stdout = StringIO()
+        sys.argv[:] = [''] + list(args)
+        old_sys = sys.argv[:]
+        try:
+            from distutils2.run import commands_main
+            dist = commands_main()
+        finally:
+            sys.argv[:] = old_sys
+        return dist
+
+    def get_path(self, dist, name):
+        from distutils2.command.install_dist import install_dist
+        cmd = install_dist(dist)
+        cmd.prefix = self.root_dir
+        cmd.finalize_options()
+        return getattr(cmd, 'install_'+name)
+
+    def make_dist(self, pkg_name='foo', **kw):
+        dirname = self.mkdtemp()
+        kw['name'] = pkg_name
+        if 'version' not in kw:
+            kw['version'] = '0.1'
+        self.write_file((dirname, 'setup.cfg'), SETUP_CFG % kw)
+        os.mkdir(os.path.join(dirname, pkg_name))
+        self.write_file((dirname, '__init__.py'), '#')
+        self.write_file((dirname, pkg_name+'_utils.py'), '#')
+        os.mkdir(os.path.join(dirname, pkg_name, 'sub'))
+        self.write_file((dirname, pkg_name, 'sub', '__init__.py'), '#')
+        self.write_file((dirname, pkg_name, 'sub', pkg_name+'_utils.py'), '#')
+        return dirname
+
+    def install_dist(self, pkg_name='foo', dirname=None, **kw):
+        if not dirname:
+            dirname = self.make_dist(pkg_name, **kw)
+        os.chdir(dirname)
+        dist = self.run_setup('install_dist', '--prefix='+self.root_dir)
+        install_lib = self.get_path(dist, 'purelib')
+        return dist, install_lib
+
+    def test_uninstall_unknow_distribution(self):
+        self.assertRaises(DistutilsError, remove, 'foo', paths=[self.root_dir])
+
+    def test_uninstall(self):
+        dist, install_lib = self.install_dist()
+        self.assertIsFile(install_lib, 'foo', 'sub', '__init__.py')
+        self.assertIsFile(install_lib, 'foo-0.1.dist-info', 'RECORD')
+        remove('foo', paths=[install_lib])
+        self.assertIsNotFile(install_lib, 'foo', 'sub', '__init__.py')
+        self.assertIsNotFile(install_lib, 'foo-0.1.dist-info', 'RECORD')
+
+
+
+
+def test_suite():
+    return unittest.makeSuite(UninstallTestCase)
+
+if __name__ == '__main__':
+    run_unittest(test_suite())

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


More information about the Python-checkins mailing list