Commits

Anonymous committed 5d810c0

now develop supports the --user option fixes #58

  • Participants
  • Parent commits c0d980d
  • Branches 0.6-maintenance

Comments (0)

Files changed (3)

 0.6.7
 -----
 
+* Issue 58: Added --user support to the deveop command
 * Issue 11: Generated scripts now wrap their call to the script entry point
   in the standard "if name == 'main'"
 * Added the 'DONT_PATCH_SETUPTOOLS' environment variable, so virtualenv

File setuptools/command/develop.py

 from setuptools.command.easy_install import easy_install
-from distutils.util import convert_path
+from distutils.util import convert_path, subst_vars
 from pkg_resources import Distribution, PathMetadata, normalize_path
 from distutils import log
 from distutils.errors import *
 import sys, os, setuptools, glob
+from distutils.sysconfig import get_config_vars
+from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS
+
+if sys.version < "2.6":
+    USER_BASE = None
+    USER_SITE = None
+    HAS_USER_SITE = False
+else:
+    from site import USER_BASE
+    from site import USER_SITE
+    HAS_USER_SITE = True
 
 class develop(easy_install):
     """Set up package for development"""
 
     boolean_options = easy_install.boolean_options + ['uninstall']
 
+    if HAS_USER_SITE:
+        user_options.append(('user', None,
+                             "install in user site-package '%s'" % USER_SITE))
+        boolean_options.append('user')
+
     command_consumes_arguments = False  # override base
 
     def run(self):
         easy_install.initialize_options(self)
         self.setup_path = None
         self.always_copy_from = '.'   # always copy eggs installed in curdir
+        self.user = 0
+        self.install_purelib = None     # for pure module distributions
+        self.install_platlib = None     # non-pure (dists w/ extensions)
+        self.install_headers = None     # for C/C++ headers
+        self.install_lib = None         # set to either purelib or platlib
+        self.install_scripts = None
+        self.install_data = None
+        self.install_base = None
+        self.install_platbase = None
+        self.install_userbase = USER_BASE
+        self.install_usersite = USER_SITE
+
+    def select_scheme(self, name):
+        """Sets the install directories by applying the install schemes."""
+        # it's the caller's problem if they supply a bad name!
+        scheme = INSTALL_SCHEMES[name]
+        for key in SCHEME_KEYS:
+            attrname = 'install_' + key
+            if getattr(self, attrname) is None:
+                setattr(self, attrname, scheme[key])
+
+    def create_home_path(self):
+        """Create directories under ~."""
+        if not self.user:
+            return
+        home = convert_path(os.path.expanduser("~"))
+        for name, path in self.config_vars.iteritems():
+            if path.startswith(home) and not os.path.isdir(path):
+                self.debug_print("os.makedirs('%s', 0700)" % path)
+                os.makedirs(path, 0700)
+
+    def _expand_attrs(self, attrs):
+        for attr in attrs:
+            val = getattr(self, attr)
+            if val is not None:
+                if os.name == 'posix' or os.name == 'nt':
+                    val = os.path.expanduser(val)
+                val = subst_vars(val, self.config_vars)
+                setattr(self, attr, val)
+
+    def expand_basedirs(self):
+        """Calls `os.path.expanduser` on install_base, install_platbase and
+        root."""
+        self._expand_attrs(['install_base', 'install_platbase', 'root'])
+
+    def expand_dirs(self):
+        """Calls `os.path.expanduser` on install dirs."""
+        self._expand_attrs(['install_purelib', 'install_platlib',
+                            'install_lib', 'install_headers',
+                            'install_scripts', 'install_data',])
 
     def finalize_options(self):
         ei = self.get_finalized_command("egg_info")
             )
         self.args = [ei.egg_name]
         easy_install.finalize_options(self)
+
+        py_version = sys.version.split()[0]
+        prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix')
+        self.config_vars = {'dist_name': self.distribution.get_name(),
+                            'dist_version': self.distribution.get_version(),
+                            'dist_fullname': self.distribution.get_fullname(),
+                            'py_version': py_version,
+                            'py_version_short': py_version[0:3],
+                            'py_version_nodot': py_version[0] + py_version[2],
+                            'sys_prefix': prefix,
+                            'prefix': prefix,
+                            'sys_exec_prefix': exec_prefix,
+                            'exec_prefix': exec_prefix,
+                           }
+
+        if HAS_USER_SITE:
+            self.config_vars['userbase'] = self.install_userbase
+            self.config_vars['usersite'] = self.install_usersite
+
+        # fix the install_dir if "--user" was used
+        if self.user:
+            self.create_home_path()
+            if self.install_userbase is None:
+                raise DistutilsPlatformError(
+                    "User base directory is not specified")
+            self.install_base = self.install_platbase = self.install_userbase
+            if os.name == 'posix':
+                self.select_scheme("unix_user")
+            else:
+                self.select_scheme(os.name + "_user")
+
+        self.expand_basedirs()
+        self.expand_dirs()
+
+        if self.user and self.install_purelib:
+            self.install_dir = self.install_purelib
+            self.script_dir = self.install_scripts
+
         # pick up setup-dir .egg files only: no .egg-info
         self.package_index.scan(glob.glob('*.egg'))
 

File setuptools/tests/test_develop.py

+"""develop tests
+"""
+import sys
+import os, shutil, tempfile, unittest
+import tempfile
+import site
+from StringIO import StringIO
+
+from setuptools.command.develop import develop
+from setuptools.command import develop as develop_pkg
+from setuptools.dist import Distribution
+
+SETUP_PY = """\
+from setuptools import setup
+
+setup(name='foo')
+"""
+
+class TestDevelopTest(unittest.TestCase):
+
+    def setUp(self):
+        self.dir = tempfile.mkdtemp()
+        setup = os.path.join(self.dir, SETUP_PY)
+        f = open(setup, 'w')
+        f.write(SETUP_PY)
+        f.close()
+        self.old_cwd = os.getcwd()
+        os.chdir(self.dir)
+        if sys.version >= "2.6":
+            self.old_base = site.USER_BASE
+            site.USER_BASE = develop_pkg.USER_BASE = tempfile.mkdtemp()
+            self.old_site = site.USER_SITE
+            site.USER_SITE = develop_pkg.USER_SITE = tempfile.mkdtemp()
+
+    def tearDown(self):
+        os.chdir(self.old_cwd)
+        shutil.rmtree(self.dir)
+        if sys.version >= "2.6":
+            shutil.rmtree(site.USER_BASE)
+            shutil.rmtree(site.USER_SITE)
+            site.USER_BASE = self.old_base
+            site.USER_SITE = self.old_site
+
+    def test_develop(self):
+        if sys.version < "2.6":
+            return
+        dist = Distribution()
+        dist.script_name = 'setup.py'
+        cmd = develop(dist)
+        cmd.user = 1
+        cmd.ensure_finalized()
+        cmd.user = 1
+        old_stdout = sys.stdout
+        sys.stdout = StringIO()
+        try:
+            cmd.run()
+        finally:
+            sys.stdout = old_stdout
+
+        # let's see if we got our egg link at the right place
+        content = os.listdir(site.USER_SITE)
+        self.assertEquals(content, ['UNKNOWN.egg-link'])
+