Permalink
Browse files

Merge pull request #693 from hetmankp/develop

Added --root command line option to give functionality equivalent to distutils --root
  • Loading branch information...
2 parents 32f0be7 + 0b2a01b commit fad65326c8faac2b220b299a6c12f5ff8d362efd @pnasrat pnasrat committed Oct 29, 2012
Showing with 40 additions and 6 deletions.
  1. +1 −0 AUTHORS.txt
  2. +4 −0 docs/news.txt
  3. +8 −1 pip/commands/install.py
  4. +15 −5 pip/req.py
  5. +12 −0 tests/test_basic.py
View
@@ -48,6 +48,7 @@ Paul van der Linden
Peter Waller
Phil Whelan
Piet Delport
+Przemek Wrzos
Qiangning Hong
Rafael Caricio
Rene Dudfield
View
@@ -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)
------------------
@@ -172,6 +172,13 @@ def __init__(self):
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 @@ def run(self, options, args):
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
@@ -8,6 +8,7 @@
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 @@ def _clean_zip_name(self, name, prefix):
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 @@ def install(self, install_options, global_options=()):
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 @@ def install(self, install_options, global_options=()):
# 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 @@ def install(self, install_options, global_options=()):
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 @@ def unpack_url(self, link, location, only_download=False):
_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 @@ def install(self, install_options, global_options=()):
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
@@ -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

0 comments on commit fad6532

Please sign in to comment.