Commit b14e668b authored by Tarek Ziade's avatar Tarek Ziade

merge dance

--HG--
branch : distribute
extra : rebase_source : eab2d364ab56ec8a8c794715379c20162cea1734
parents 53b099f9 4b756caf
......@@ -13,6 +13,8 @@ CHANGES
* Issue 121: Fixed --help install command trying to actually install.
* Issue 112: Added an os.makedirs so that Tarek's solution will work.
* Issue 133: Added --no-find-links to easy_install
* Added easy_install --user
* Issue 100: Fixed develop --user not taking '.' in PYTHONPATH into account
------
0.6.10
......
......@@ -144,6 +144,10 @@ and Viewing Source Packages`_ below for more info.)::
easy_install --editable --build-directory ~/projects SQLObject
**Example 7**. (New in 0.6.11) Install a distribution within your home dir::
easy_install --user SQLAlchemy
Easy Install accepts URLs, filenames, PyPI package names (i.e., ``distutils``
"distribution" names), and package+version specifiers. In each case, it will
attempt to locate the latest available version that meets your criteria.
......@@ -716,6 +720,10 @@ Command-Line Options
versions of a package, but do not want to reset the version that will be
run by scripts that are already installed.
``--user`` (New in 0.6.11)
Use the the user-site-packages as specified in :pep:`370`
instead of the global site-packages.
``--always-copy, -a`` (New in 0.5a4)
Copy all needed distributions to the installation directory, even if they
are already present in a directory on sys.path. In older versions of
......
......@@ -19,7 +19,8 @@ __all__ = [
# a distribution with the same version.
#
# The distribute_setup script for instance, will check if this
# attribute is present to decide wether to reinstall the package
# attribute is present to decide whether to reinstall the package
# or not.
_distribute = True
bootstrap_install_from = None
......
......@@ -2,19 +2,8 @@ from setuptools.command.easy_install import easy_install
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
from distutils.errors import DistutilsError, DistutilsOptionError
import os, setuptools, glob
class develop(easy_install):
"""Set up package for development"""
......@@ -28,11 +17,6 @@ class develop(easy_install):
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):
......@@ -49,56 +33,8 @@ class develop(easy_install):
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")
......@@ -110,44 +46,11 @@ class develop(easy_install):
self.args = [ei.egg_name]
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
easy_install.finalize_options(self)
self.expand_basedirs()
self.expand_dirs()
# pick up setup-dir .egg files only: no .egg-info
self.package_index.scan(glob.glob('*.egg'))
......
......@@ -7,21 +7,30 @@ A tool for doing automatic download/extract/build of distutils-based Python
packages. For detailed documentation, see the accompanying EasyInstall.txt
file, or visit the `EasyInstall home page`__.
__ http://peak.telecommunity.com/DevCenter/EasyInstall
__ http://packages.python.org/distribute/easy_install.html
"""
import sys, os, os.path, zipimport, shutil, tempfile, zipfile, re, stat, random
import sys, os.path, zipimport, shutil, tempfile, zipfile, re, stat, random
from glob import glob
from setuptools import Command
from setuptools.sandbox import run_setup
from distutils import log, dir_util
from distutils.sysconfig import get_python_lib
from distutils.util import convert_path, subst_vars
from distutils.sysconfig import get_python_lib, get_config_vars
from distutils.errors import DistutilsArgError, DistutilsOptionError, \
DistutilsError
DistutilsError, DistutilsPlatformError
from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS
from setuptools.archive_util import unpack_archive
from setuptools.package_index import PackageIndex, parse_bdist_wininst
from setuptools.package_index import PackageIndex
from setuptools.package_index import URL_SCHEME
from setuptools.command import bdist_egg, egg_info
from pkg_resources import *
from pkg_resources import yield_lines, normalize_path, resource_string, \
ensure_directory, get_distribution, find_distributions, \
Environment, Requirement, Distribution, \
PathMetadata, EggMetadata, WorkingSet, \
DistributionNotFound, VersionConflict, \
DEVELOP_DIST
sys_executable = os.path.normpath(sys.executable)
__all__ = [
......@@ -29,6 +38,9 @@ __all__ = [
'main', 'get_exe_prefixes',
]
import site
HAS_USER_SITE = not sys.version < "2.6"
def samefile(p1,p2):
if hasattr(os.path,'samefile') and (
os.path.exists(p1) and os.path.exists(p2)
......@@ -99,10 +111,18 @@ class easy_install(Command):
'delete-conflicting', 'ignore-conflicts-at-my-risk', 'editable',
'no-deps', 'local-snapshots-ok', 'version'
]
if HAS_USER_SITE:
user_options.append(('user', None,
"install in user site-package '%s'" % site.USER_SITE))
boolean_options.append('user')
negative_opt = {'always-unzip': 'zip-ok'}
create_index = PackageIndex
def initialize_options(self):
self.user = 0
self.zip_ok = self.local_snapshots_ok = None
self.install_dir = self.script_dir = self.exclude_scripts = None
self.index_url = None
......@@ -114,6 +134,16 @@ class easy_install(Command):
self.editable = self.no_deps = self.allow_hosts = None
self.root = self.prefix = self.no_report = None
self.version = None
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 = site.USER_BASE
self.install_usersite = site.USER_SITE
self.no_find_links = None
# Options not specifiable via command line
......@@ -150,6 +180,41 @@ class easy_install(Command):
print 'distribute %s' % get_distribution('distribute').version
sys.exit()
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
#XXX: duplicate of the code in the setup command
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()
self._expand('install_dir','script_dir','build_directory','site_dirs')
# If a non-default installation directory was specified, default the
# script directory to match it.
......@@ -169,6 +234,10 @@ class easy_install(Command):
self.set_undefined_options('install_scripts',
('install_dir', 'script_dir')
)
if self.user and self.install_purelib:
self.install_dir = self.install_purelib
self.script_dir = self.install_scripts
# default --record from the install command
self.set_undefined_options('install', ('record', 'record'))
normpath = map(normalize_path, sys.path)
......@@ -235,6 +304,27 @@ class easy_install(Command):
self.outputs = []
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 run(self):
if self.verbose != self.distribution.verbose:
log.set_verbosity(self.verbose)
......@@ -278,6 +368,7 @@ class easy_install(Command):
def check_site_dir(self):
"""Verify that self.install_dir is .pth-capable dir, if needed"""
print 'install_dir', self.install_dir
instdir = normalize_path(self.install_dir)
pth_file = os.path.join(instdir,'easy-install.pth')
......@@ -349,7 +440,7 @@ variable.
For information on other options, you may wish to consult the
documentation at:
http://peak.telecommunity.com/EasyInstall.html
http://packages.python.org/distribute/easy_install.html
Please make the appropriate changes for your system and try again.
"""
......@@ -520,6 +611,15 @@ Please make the appropriate changes for your system and try again.
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])
......@@ -1084,7 +1184,7 @@ Here are some of your options for correcting the problem:
* You can set up the installation directory to support ".pth" files by
using one of the approaches described here:
http://peak.telecommunity.com/EasyInstall.html#custom-installation-locations
http://packages.python.org/distribute/easy_install.html#custom-installation-locations
Please make the appropriate changes for your system and try again.""" % (
self.install_dir, os.environ.get('PYTHONPATH','')
......@@ -1138,7 +1238,15 @@ Please make the appropriate changes for your system and try again.""" % (
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)
......@@ -1429,8 +1537,12 @@ class PthDistributions(Environment):
def add(self,dist):
"""Add `dist` to the distribution map"""
if dist.location not in self.paths and dist.location not in self.sitedirs:
self.paths.append(dist.location); self.dirty = True
if (dist.location not in self.paths and (
dist.location not in self.sitedirs or
dist.location == os.getcwd() #account for '.' being in PYTHONPATH
)):
self.paths.append(dist.location)
self.dirty = True
Environment.add(self,dist)
def remove(self,dist):
......
......@@ -7,7 +7,7 @@ import site
from StringIO import StringIO
from setuptools.command.develop import develop
from setuptools.command import develop as develop_pkg
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
SETUP_PY = """\
......@@ -18,7 +18,7 @@ setup(name='foo')
class TestDevelopTest(unittest.TestCase):
def setUp(self):
def setUp(self):
self.dir = tempfile.mkdtemp()
setup = os.path.join(self.dir, 'setup.py')
f = open(setup, 'w')
......@@ -28,11 +28,11 @@ class TestDevelopTest(unittest.TestCase):
os.chdir(self.dir)
if sys.version >= "2.6":
self.old_base = site.USER_BASE
site.USER_BASE = develop_pkg.USER_BASE = tempfile.mkdtemp()
site.USER_BASE = tempfile.mkdtemp()
self.old_site = site.USER_SITE
site.USER_SITE = develop_pkg.USER_SITE = tempfile.mkdtemp()
site.USER_SITE = tempfile.mkdtemp()
def tearDown(self):
def tearDown(self):
os.chdir(self.old_cwd)
shutil.rmtree(self.dir)
if sys.version >= "2.6":
......@@ -49,6 +49,7 @@ class TestDevelopTest(unittest.TestCase):
cmd = develop(dist)
cmd.user = 1
cmd.ensure_finalized()
cmd.install_dir = site.USER_SITE
cmd.user = 1
old_stdout = sys.stdout
sys.stdout = StringIO()
......
......@@ -2,8 +2,13 @@
"""
import sys
import os, shutil, tempfile, unittest
import site
from StringIO import StringIO
from setuptools.command.easy_install import easy_install, get_script_args, main
from setuptools.command.easy_install import PthDistributions
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
from pkg_resources import Distribution as PRDistribution
class FakeDist(object):
def get_entry_map(self, group):
......@@ -115,3 +120,69 @@ class TestEasyInstallTest(unittest.TestCase):
self.assertEquals(keys, ['link1', 'link2'])
class TestPTHFileWriter(unittest.TestCase):
def test_add_from_cwd_site_sets_dirty(self):
'''a pth file manager should set dirty
if a distribution is in site but also the cwd
'''
pth = PthDistributions('does-not_exist', [os.getcwd()])
self.assertFalse(pth.dirty)
pth.add(PRDistribution(os.getcwd()))
self.assertTrue(pth.dirty)
def test_add_from_site_is_ignored(self):
pth = PthDistributions('does-not_exist', ['/test/location/does-not-have-to-exist'])
self.assertFalse(pth.dirty)
pth.add(PRDistribution('/test/location/does-not-have-to-exist'))
self.assertFalse(pth.dirty)
class TestUserInstallTest(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 = tempfile.mkdtemp()
self.old_site = site.USER_SITE
site.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_install(self):
#XXX: replace with something meaningfull
return
if sys.version < "2.6":
return
dist = Distribution()
dist.script_name = 'setup.py'
cmd = easy_install(dist)
cmd.user = 1
cmd.args = ['py']
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)
content.sort()
self.assertEquals(content, ['UNKNOWN.egg-link', 'easy-install.pth'])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment