[Python-checkins] distutils2: first implementation of the remove() method
tarek.ziade
python-checkins at python.org
Sun Jan 30 10:43:58 CET 2011
tarek.ziade pushed b119d089a91b to distutils2:
http://hg.python.org/distutils2/rev/b119d089a91b
changeset: 947:b119d089a91b
user: Gael Pasgrimaud <gael at gawel.org>
date: Sat Jan 29 17:25:43 2011 +0100
summary:
first implementation of the remove() method
files:
distutils2/install.py
distutils2/tests/support.py
distutils2/tests/test_uninstall.py
diff --git a/distutils2/install.py b/distutils2/install.py
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -2,10 +2,14 @@
import logging
import shutil
import os
+import sys
+import stat
import errno
import itertools
+import tempfile
from distutils2._backport.pkgutil import get_distributions
+from distutils2._backport.pkgutil import get_distribution
from distutils2.depgraph import generate_graph
from distutils2.index import wrapper
from distutils2.index.errors import ProjectNotFound, ReleaseNotFound
@@ -208,10 +212,38 @@
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)
+ 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
@@ -167,6 +167,9 @@
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,86 @@
+"""Tests for the uninstall command."""
+import os
+import sys
+from StringIO import StringIO
+from distutils2.tests import unittest, support, run_unittest
+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.root_dir = self.mkdtemp()
+
+ 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(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