Merge pull request #693 from hetmankp/develop

Added --root command line option to give functionality equivalent to distutils --root
This commit is contained in:
Paul Nasrat 2012-10-29 09:58:18 -07:00
commit fad65326c8
5 changed files with 40 additions and 6 deletions

View File

@ -48,6 +48,7 @@ Paul van der Linden
Peter Waller
Phil Whelan
Piet Delport
Przemek Wrzos
Qiangning Hong
Rafael Caricio
Rene Dudfield

View File

@ -27,6 +27,10 @@ develop (unreleased)
* Added "pip show" command to get information about an installed
package. Fixes #131. Thanks Kelsey Hightower and Rafael Caricio.
* Added `--root` option for "pip install" to specify root directory. Behaves
like the same option in distutils but also plays nice with pip's egg-info.
(Issue #253)
1.2.1 (2012-09-06)
------------------

View File

@ -172,6 +172,13 @@ class InstallCommand(Command):
action='store_true',
help="Install as self contained egg file, like easy_install does.")
self.parser.add_option(
'--root',
dest='root_path',
metavar='DIR',
default=None,
help="Install everything relative to this alternate root directory")
def _build_package_finder(self, options, index_urls):
"""
Create a package finder appropriate to this install command.
@ -258,7 +265,7 @@ class InstallCommand(Command):
requirement_set.locate_files()
if not options.no_install and not self.bundle:
requirement_set.install(install_options, global_options)
requirement_set.install(install_options, global_options, root=options.root_path)
installed = ' '.join([req.name for req in
requirement_set.successfully_installed])
if installed:

View File

@ -8,6 +8,7 @@ import shutil
import tempfile
import zipfile
from distutils.util import change_root
from pip.locations import bin_py, running_under_virtualenv
from pip.exceptions import (InstallationError, UninstallationError,
BestVersionAlreadyInstalled,
@ -557,7 +558,7 @@ exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
name = name.replace(os.path.sep, '/')
return name
def install(self, install_options, global_options=()):
def install(self, install_options, global_options=(), root=None):
if self.editable:
self.install_editable(install_options, global_options)
return
@ -576,6 +577,9 @@ exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
if not self.as_egg:
install_args += ['--single-version-externally-managed']
if root is not None:
install_args += ['--root', root]
if running_under_virtualenv():
## FIXME: I'm not sure if this is a reasonable location; probably not
## but we can't put it in the default location, as that is a virtualenv symlink that isn't writable
@ -598,11 +602,17 @@ exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
# so we unable to save the installed-files.txt
return
def prepend_root(path):
if root is None or not os.path.isabs(path):
return path
else:
return change_root(root, path)
f = open(record_filename)
for line in f:
line = line.strip()
if line.endswith('.egg-info'):
egg_info_dir = line
egg_info_dir = prepend_root(line)
break
else:
logger.warn('Could not find .egg-info directory in install record for %s' % self)
@ -616,7 +626,7 @@ exec(compile(open(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
filename = line.strip()
if os.path.isdir(filename):
filename += os.path.sep
new_lines.append(make_path_relative(filename, egg_info_dir))
new_lines.append(make_path_relative(prepend_root(filename), egg_info_dir))
f.close()
f = open(os.path.join(egg_info_dir, 'installed-files.txt'), 'w')
f.write('\n'.join(new_lines)+'\n')
@ -1151,7 +1161,7 @@ class RequirementSet(object):
_write_delete_marker_message(os.path.join(location, PIP_DELETE_MARKER_FILENAME))
return retval
def install(self, install_options, global_options=()):
def install(self, install_options, global_options=(), *args, **kwargs):
"""Install everything in this set (after having downloaded and unpacked the packages)"""
to_install = [r for r in self.requirements.values()
if not r.satisfied_by]
@ -1170,7 +1180,7 @@ class RequirementSet(object):
finally:
logger.indent -= 2
try:
requirement.install(install_options, global_options)
requirement.install(install_options, global_options, *args, **kwargs)
except:
# if install did not succeed, rollback previous uninstall
if requirement.conflicts_with and not requirement.install_succeeded:

View File

@ -491,6 +491,18 @@ def test_install_package_with_target():
assert Path('scratch')/'target'/'initools' in result.files_created, str(result)
def test_install_package_with_root():
"""
Test installing a package using pip install --root
"""
env = reset_env()
root_dir = env.scratch_path/'root'
result = run_pip('install', '--root', root_dir, '--install-option=--home=',
'--install-option=--install-lib=/lib/python', "initools==0.1")
assert Path('scratch')/'root'/'lib'/'python'/'initools' in result.files_created, str(result)
def test_find_command_folder_in_path():
"""
If a folder named e.g. 'git' is in PATH, and find_command is looking for