mirror of https://github.com/pypa/pip
Remove the bundle functionality from pip
This commit is contained in:
parent
228da66ccc
commit
f79ca70c66
|
@ -3,6 +3,9 @@
|
|||
|
||||
* **BACKWARD INCOMPATIBLE** Dropped support for Python 3.1.
|
||||
|
||||
* **BACKWARD INCOMPATIBLE** Removed the bundle support which was deprecated in
|
||||
1.4. (:pull:`1806`)
|
||||
|
||||
* Removed the deprecated support for dependency links and the
|
||||
``--process-dependency-links`` flag that turned them on. For alternatives to
|
||||
dependency links please see http://www.pip-installer.org/en/latest/dependency_links.html
|
||||
|
|
|
@ -3,7 +3,6 @@ Package containing all pip commands
|
|||
"""
|
||||
|
||||
|
||||
from pip.commands.bundle import BundleCommand
|
||||
from pip.commands.completion import CompletionCommand
|
||||
from pip.commands.freeze import FreezeCommand
|
||||
from pip.commands.help import HelpCommand
|
||||
|
@ -18,7 +17,6 @@ from pip.commands.wheel import WheelCommand
|
|||
|
||||
|
||||
commands = {
|
||||
BundleCommand.name: BundleCommand,
|
||||
CompletionCommand.name: CompletionCommand,
|
||||
FreezeCommand.name: FreezeCommand,
|
||||
HelpCommand.name: HelpCommand,
|
||||
|
@ -43,7 +41,6 @@ commands_order = [
|
|||
WheelCommand,
|
||||
ZipCommand,
|
||||
UnzipCommand,
|
||||
BundleCommand,
|
||||
HelpCommand,
|
||||
]
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
from pip.locations import build_prefix, src_prefix
|
||||
from pip.util import display_path, backup_dir
|
||||
from pip.log import logger
|
||||
from pip.exceptions import InstallationError
|
||||
from pip.commands.install import InstallCommand
|
||||
|
||||
|
||||
class BundleCommand(InstallCommand):
|
||||
"""Create pybundles (archives containing multiple packages)."""
|
||||
name = 'bundle'
|
||||
usage = """
|
||||
%prog [options] <bundle name>.pybundle <package>..."""
|
||||
summary = 'DEPRECATED. Create pybundles.'
|
||||
bundle = True
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(BundleCommand, self).__init__(*args, **kw)
|
||||
# bundle uses different default source and build dirs
|
||||
build_opt = self.parser.get_option("--build")
|
||||
build_opt.default = backup_dir(build_prefix, '-bundle')
|
||||
src_opt = self.parser.get_option("--src")
|
||||
src_opt.default = backup_dir(src_prefix, '-bundle')
|
||||
self.parser.set_defaults(**{
|
||||
src_opt.dest: src_opt.default,
|
||||
build_opt.dest: build_opt.default,
|
||||
})
|
||||
|
||||
def run(self, options, args):
|
||||
|
||||
logger.deprecated(
|
||||
'1.6',
|
||||
"DEPRECATION: 'pip bundle' and support for installing from "
|
||||
"*.pybundle files is deprecated. "
|
||||
"See https://github.com/pypa/pip/pull/1046"
|
||||
)
|
||||
|
||||
if not args:
|
||||
raise InstallationError('You must give a bundle filename')
|
||||
# We have to get everything when creating a bundle:
|
||||
options.ignore_installed = True
|
||||
logger.notify(
|
||||
'Putting temporary build files in %s and source/develop files in '
|
||||
'%s' % (
|
||||
display_path(options.build_dir),
|
||||
display_path(options.src_dir)
|
||||
)
|
||||
)
|
||||
self.bundle_filename = args.pop(0)
|
||||
requirement_set = super(BundleCommand, self).run(options, args)
|
||||
return requirement_set
|
|
@ -36,7 +36,6 @@ class InstallCommand(Command):
|
|||
%prog [options] <archive url/path> ..."""
|
||||
|
||||
summary = 'Install packages.'
|
||||
bundle = False
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(InstallCommand, self).__init__(*args, **kw)
|
||||
|
@ -313,15 +312,11 @@ class InstallCommand(Command):
|
|||
|
||||
try:
|
||||
if not options.no_download:
|
||||
requirement_set.prepare_files(
|
||||
finder,
|
||||
force_root_egg_info=self.bundle,
|
||||
bundle=self.bundle,
|
||||
)
|
||||
requirement_set.prepare_files(finder)
|
||||
else:
|
||||
requirement_set.locate_files()
|
||||
|
||||
if not options.no_install and not self.bundle:
|
||||
if not options.no_install:
|
||||
requirement_set.install(
|
||||
install_options,
|
||||
global_options,
|
||||
|
@ -331,15 +326,12 @@ class InstallCommand(Command):
|
|||
requirement_set.successfully_installed])
|
||||
if installed:
|
||||
logger.notify('Successfully installed %s' % installed)
|
||||
elif not self.bundle:
|
||||
else:
|
||||
downloaded = ' '.join([
|
||||
req.name for req in requirement_set.successfully_downloaded
|
||||
])
|
||||
if downloaded:
|
||||
logger.notify('Successfully downloaded %s' % downloaded)
|
||||
elif self.bundle:
|
||||
requirement_set.create_bundle(self.bundle_filename)
|
||||
logger.notify('Created bundle in %s' % self.bundle_filename)
|
||||
except PreviousBuildDirError:
|
||||
options.no_clean = True
|
||||
raise
|
||||
|
@ -347,7 +339,7 @@ class InstallCommand(Command):
|
|||
# Clean up
|
||||
if ((not options.no_clean)
|
||||
and ((not options.no_install) or options.download_dir)):
|
||||
requirement_set.cleanup_files(bundle=self.bundle)
|
||||
requirement_set.cleanup_files()
|
||||
|
||||
if options.target_dir:
|
||||
if not os.path.exists(options.target_dir):
|
||||
|
|
|
@ -304,7 +304,7 @@ def path_to_url(path):
|
|||
def is_archive_file(name):
|
||||
"""Return True if `name` is a considered as an archive file."""
|
||||
archives = (
|
||||
'.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.pybundle', '.whl'
|
||||
'.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.whl'
|
||||
)
|
||||
ext = splitext(name)[1].lower()
|
||||
if ext in archives:
|
||||
|
|
|
@ -36,7 +36,7 @@ class InstallRequirement(object):
|
|||
|
||||
def __init__(self, req, comes_from, source_dir=None, editable=False,
|
||||
url=None, as_egg=False, update=True, prereleases=None,
|
||||
editable_options=None, from_bundle=False, pycompile=True):
|
||||
editable_options=None, pycompile=True):
|
||||
self.extras = ()
|
||||
if isinstance(req, string_types):
|
||||
req = pkg_resources.Requirement.parse(req)
|
||||
|
@ -60,7 +60,6 @@ class InstallRequirement(object):
|
|||
# conflicts with another installed distribution:
|
||||
self.conflicts_with = None
|
||||
self._temp_build_dir = None
|
||||
self._is_bundle = None
|
||||
# True if the editable should be updated:
|
||||
self.update = update
|
||||
# Set to True after successful installation
|
||||
|
@ -69,7 +68,6 @@ class InstallRequirement(object):
|
|||
self.uninstalled = None
|
||||
self.use_user_site = False
|
||||
self.target_dir = None
|
||||
self.from_bundle = from_bundle
|
||||
|
||||
self.pycompile = pycompile
|
||||
|
||||
|
@ -276,7 +274,7 @@ class InstallRequirement(object):
|
|||
|
||||
return setup_py
|
||||
|
||||
def run_egg_info(self, force_root_egg_info=False):
|
||||
def run_egg_info(self):
|
||||
assert self.source_dir
|
||||
if self.name:
|
||||
logger.notify(
|
||||
|
@ -310,7 +308,7 @@ class InstallRequirement(object):
|
|||
# We can't put the .egg-info files at the root, because then the
|
||||
# source code will be mistaken for an installed egg, causing
|
||||
# problems
|
||||
if self.editable or force_root_egg_info:
|
||||
if self.editable:
|
||||
egg_base_option = []
|
||||
else:
|
||||
egg_info_dir = os.path.join(self.source_dir, 'pip-egg-info')
|
||||
|
@ -816,7 +814,7 @@ exec(compile(
|
|||
def remove_temporary_source(self):
|
||||
"""Remove the source files from this requirement, if they are marked
|
||||
for deletion"""
|
||||
if self.is_bundle or os.path.exists(self.delete_marker_filename):
|
||||
if os.path.exists(self.delete_marker_filename):
|
||||
logger.info('Removing source in %s' % self.source_dir)
|
||||
if self.source_dir:
|
||||
rmtree(self.source_dir)
|
||||
|
@ -912,82 +910,6 @@ exec(compile(
|
|||
def is_wheel(self):
|
||||
return self.url and '.whl' in self.url
|
||||
|
||||
@property
|
||||
def is_bundle(self):
|
||||
if self._is_bundle is not None:
|
||||
return self._is_bundle
|
||||
base = self._temp_build_dir
|
||||
if not base:
|
||||
# FIXME: this doesn't seem right:
|
||||
return False
|
||||
self._is_bundle = (
|
||||
os.path.exists(os.path.join(base, 'pip-manifest.txt'))
|
||||
or os.path.exists(os.path.join(base, 'pyinstall-manifest.txt'))
|
||||
)
|
||||
return self._is_bundle
|
||||
|
||||
def bundle_requirements(self):
|
||||
for dest_dir in self._bundle_editable_dirs:
|
||||
package = os.path.basename(dest_dir)
|
||||
# FIXME: svnism:
|
||||
for vcs_backend in vcs.backends:
|
||||
url = rev = None
|
||||
vcs_bundle_file = os.path.join(
|
||||
dest_dir, vcs_backend.bundle_file)
|
||||
if os.path.exists(vcs_bundle_file):
|
||||
vc_type = vcs_backend.name
|
||||
fp = open(vcs_bundle_file)
|
||||
content = fp.read()
|
||||
fp.close()
|
||||
url, rev = vcs_backend().parse_vcs_bundle_file(content)
|
||||
break
|
||||
if url:
|
||||
url = '%s+%s@%s' % (vc_type, url, rev)
|
||||
else:
|
||||
url = None
|
||||
yield InstallRequirement(
|
||||
package, self, editable=True, url=url,
|
||||
update=False, source_dir=dest_dir, from_bundle=True)
|
||||
for dest_dir in self._bundle_build_dirs:
|
||||
package = os.path.basename(dest_dir)
|
||||
yield InstallRequirement(
|
||||
package,
|
||||
self,
|
||||
source_dir=dest_dir,
|
||||
from_bundle=True,
|
||||
)
|
||||
|
||||
def move_bundle_files(self, dest_build_dir, dest_src_dir):
|
||||
base = self._temp_build_dir
|
||||
assert base
|
||||
src_dir = os.path.join(base, 'src')
|
||||
build_dir = os.path.join(base, 'build')
|
||||
bundle_build_dirs = []
|
||||
bundle_editable_dirs = []
|
||||
for source_dir, dest_dir, dir_collection in [
|
||||
(src_dir, dest_src_dir, bundle_editable_dirs),
|
||||
(build_dir, dest_build_dir, bundle_build_dirs)]:
|
||||
if os.path.exists(source_dir):
|
||||
for dirname in os.listdir(source_dir):
|
||||
dest = os.path.join(dest_dir, dirname)
|
||||
dir_collection.append(dest)
|
||||
if os.path.exists(dest):
|
||||
logger.warn(
|
||||
'The directory %s (containing package %s) already '
|
||||
'exists; cannot move source from bundle %s' %
|
||||
(dest, dirname, self)
|
||||
)
|
||||
continue
|
||||
if not os.path.exists(dest_dir):
|
||||
logger.info('Creating directory %s' % dest_dir)
|
||||
os.makedirs(dest_dir)
|
||||
shutil.move(os.path.join(source_dir, dirname), dest)
|
||||
if not os.listdir(source_dir):
|
||||
os.rmdir(source_dir)
|
||||
self._temp_build_dir = None
|
||||
self._bundle_build_dirs = bundle_build_dirs
|
||||
self._bundle_editable_dirs = bundle_editable_dirs
|
||||
|
||||
def move_wheel_files(self, wheeldir, root=None):
|
||||
move_wheel_files(
|
||||
self.name, self.req, wheeldir,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
|
||||
from pip._vendor import pkg_resources
|
||||
from pip.backwardcompat import HTTPError
|
||||
|
@ -206,7 +205,7 @@ class RequirementSet(object):
|
|||
(req_to_install, req_to_install.source_dir)
|
||||
)
|
||||
|
||||
def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
|
||||
def prepare_files(self, finder):
|
||||
"""
|
||||
Prepare process. Create temp directories, download and/or unpack files.
|
||||
"""
|
||||
|
@ -280,7 +279,6 @@ class RequirementSet(object):
|
|||
# ################################ #
|
||||
|
||||
try:
|
||||
is_bundle = False
|
||||
is_wheel = False
|
||||
if req_to_install.editable:
|
||||
if req_to_install.source_dir is None:
|
||||
|
@ -311,14 +309,10 @@ class RequirementSet(object):
|
|||
unpack = True
|
||||
url = None
|
||||
|
||||
# In the case where the req comes from a bundle, we should
|
||||
# assume a build dir exists and move on
|
||||
if req_to_install.from_bundle:
|
||||
pass
|
||||
# If a checkout exists, it's unwise to keep going. version
|
||||
# inconsistencies are logged later, but do not fail the
|
||||
# installation.
|
||||
elif os.path.exists(os.path.join(location, 'setup.py')):
|
||||
if os.path.exists(os.path.join(location, 'setup.py')):
|
||||
raise PreviousBuildDirError(
|
||||
"pip can't proceed with requirements '%s' due to a"
|
||||
" pre-existing build directory (%s). This is "
|
||||
|
@ -372,17 +366,8 @@ class RequirementSet(object):
|
|||
else:
|
||||
unpack = False
|
||||
if unpack:
|
||||
is_bundle = req_to_install.is_bundle
|
||||
is_wheel = url and url.filename.endswith(wheel_ext)
|
||||
if is_bundle:
|
||||
req_to_install.move_bundle_files(
|
||||
self.build_dir,
|
||||
self.src_dir,
|
||||
)
|
||||
for subreq in req_to_install.bundle_requirements():
|
||||
reqs.append(subreq)
|
||||
self.add_requirement(subreq)
|
||||
elif self.is_download:
|
||||
if self.is_download:
|
||||
req_to_install.source_dir = location
|
||||
if not is_wheel:
|
||||
# FIXME:https://github.com/pypa/pip/issues/1112
|
||||
|
@ -395,19 +380,7 @@ class RequirementSet(object):
|
|||
else:
|
||||
req_to_install.source_dir = location
|
||||
req_to_install.run_egg_info()
|
||||
if force_root_egg_info:
|
||||
# We need to run this to make sure that the
|
||||
# .egg-info/ directory is created for packing
|
||||
# in the bundle
|
||||
req_to_install.run_egg_info(
|
||||
force_root_egg_info=True,
|
||||
)
|
||||
req_to_install.assert_source_matches_version()
|
||||
# @@ sketchy way of identifying packages not
|
||||
# grabbed from an index
|
||||
if bundle and req_to_install.url:
|
||||
self.copy_to_build_dir(req_to_install)
|
||||
install = False
|
||||
# req_to_install.req is only avail after unpack for URL
|
||||
# pkgs repeat check_if_exists to uninstall-on-upgrade
|
||||
# (#14)
|
||||
|
@ -454,7 +427,7 @@ class RequirementSet(object):
|
|||
self.add_requirement(subreq)
|
||||
|
||||
# sdists
|
||||
elif not is_bundle:
|
||||
else:
|
||||
if (req_to_install.extras):
|
||||
logger.notify(
|
||||
"Installing extra requirements: %r" %
|
||||
|
@ -486,24 +459,17 @@ class RequirementSet(object):
|
|||
self.add_requirement(req_to_install)
|
||||
|
||||
# cleanup tmp src
|
||||
if not is_bundle:
|
||||
if (
|
||||
self.is_download or
|
||||
req_to_install._temp_build_dir is not None
|
||||
):
|
||||
self.reqs_to_cleanup.append(req_to_install)
|
||||
if (self.is_download or
|
||||
req_to_install._temp_build_dir is not None):
|
||||
self.reqs_to_cleanup.append(req_to_install)
|
||||
|
||||
if install:
|
||||
self.successfully_downloaded.append(req_to_install)
|
||||
if (bundle
|
||||
and (
|
||||
req_to_install.url
|
||||
and req_to_install.url.startswith('file:///')
|
||||
)):
|
||||
self.copy_to_build_dir(req_to_install)
|
||||
|
||||
finally:
|
||||
logger.indent -= 2
|
||||
|
||||
def cleanup_files(self, bundle=False):
|
||||
def cleanup_files(self):
|
||||
"""Clean up files, remove builds."""
|
||||
logger.notify('Cleaning up...')
|
||||
logger.indent += 2
|
||||
|
@ -514,11 +480,6 @@ class RequirementSet(object):
|
|||
if self._pip_has_created_build_dir():
|
||||
remove_dir.append(self.build_dir)
|
||||
|
||||
# The source dir of a bundle can always be removed.
|
||||
# FIXME: not if it pre-existed the bundle!
|
||||
if bundle:
|
||||
remove_dir.append(self.src_dir)
|
||||
|
||||
for dir in remove_dir:
|
||||
if os.path.exists(dir):
|
||||
logger.info('Removing temporary dir %s...' % dir)
|
||||
|
@ -658,83 +619,3 @@ class RequirementSet(object):
|
|||
finally:
|
||||
logger.indent -= 2
|
||||
self.successfully_installed = to_install
|
||||
|
||||
def create_bundle(self, bundle_filename):
|
||||
# FIXME: can't decide which is better; zip is easier to read
|
||||
# random files from, but tar.bz2 is smaller and not as lame a
|
||||
# format.
|
||||
|
||||
# FIXME: this file should really include a manifest of the
|
||||
# packages, maybe some other metadata files. It would make
|
||||
# it easier to detect as well.
|
||||
zip = zipfile.ZipFile(bundle_filename, 'w', zipfile.ZIP_DEFLATED)
|
||||
vcs_dirs = []
|
||||
for dir, basename in (self.build_dir, 'build'), (self.src_dir, 'src'):
|
||||
dir = os.path.normcase(os.path.abspath(dir))
|
||||
for dirpath, dirnames, filenames in os.walk(dir):
|
||||
for backend in vcs.backends:
|
||||
vcs_backend = backend()
|
||||
vcs_url = vcs_rev = None
|
||||
if vcs_backend.dirname in dirnames:
|
||||
for vcs_dir in vcs_dirs:
|
||||
if dirpath.startswith(vcs_dir):
|
||||
# vcs bundle file already in parent directory
|
||||
break
|
||||
else:
|
||||
vcs_url, vcs_rev = vcs_backend.get_info(
|
||||
os.path.join(dir, dirpath))
|
||||
vcs_dirs.append(dirpath)
|
||||
vcs_bundle_file = vcs_backend.bundle_file
|
||||
vcs_guide = vcs_backend.guide % {'url': vcs_url,
|
||||
'rev': vcs_rev}
|
||||
dirnames.remove(vcs_backend.dirname)
|
||||
break
|
||||
if 'pip-egg-info' in dirnames:
|
||||
dirnames.remove('pip-egg-info')
|
||||
for dirname in dirnames:
|
||||
dirname = os.path.join(dirpath, dirname)
|
||||
name = self._clean_zip_name(dirname, dir)
|
||||
zip.writestr(basename + '/' + name + '/', '')
|
||||
for filename in filenames:
|
||||
if filename == PIP_DELETE_MARKER_FILENAME:
|
||||
continue
|
||||
filename = os.path.join(dirpath, filename)
|
||||
name = self._clean_zip_name(filename, dir)
|
||||
zip.write(filename, basename + '/' + name)
|
||||
if vcs_url:
|
||||
name = os.path.join(dirpath, vcs_bundle_file)
|
||||
name = self._clean_zip_name(name, dir)
|
||||
zip.writestr(basename + '/' + name, vcs_guide)
|
||||
|
||||
zip.writestr('pip-manifest.txt', self.bundle_requirements())
|
||||
zip.close()
|
||||
|
||||
BUNDLE_HEADER = '''\
|
||||
# This is a pip bundle file, that contains many source packages
|
||||
# that can be installed as a group. You can install this like:
|
||||
# pip this_file.zip
|
||||
# The rest of the file contains a list of all the packages included:
|
||||
'''
|
||||
|
||||
def bundle_requirements(self):
|
||||
parts = [self.BUNDLE_HEADER]
|
||||
for req in [req for req in self.requirements.values()
|
||||
if not req.comes_from]:
|
||||
parts.append('%s==%s\n' % (req.name, req.installed_version))
|
||||
parts.append(
|
||||
'# These packages were installed to satisfy the above '
|
||||
'requirements:\n'
|
||||
)
|
||||
for req in [req for req in self.requirements.values()
|
||||
if req.comes_from]:
|
||||
parts.append('%s==%s\n' % (req.name, req.installed_version))
|
||||
# FIXME: should we do something with self.unnamed_requirements?
|
||||
return ''.join(parts)
|
||||
|
||||
def _clean_zip_name(self, name, prefix):
|
||||
assert name.startswith(prefix + os.path.sep), (
|
||||
"name %r doesn't start with prefix %r" % (name, prefix)
|
||||
)
|
||||
name = name[len(prefix) + 1:]
|
||||
name = name.replace(os.path.sep, '/')
|
||||
return name
|
||||
|
|
|
@ -631,13 +631,12 @@ def unpack_file(filename, location, content_type, link):
|
|||
filename = os.path.realpath(filename)
|
||||
if (content_type == 'application/zip'
|
||||
or filename.endswith('.zip')
|
||||
or filename.endswith('.pybundle')
|
||||
or filename.endswith('.whl')
|
||||
or zipfile.is_zipfile(filename)):
|
||||
unzip_file(
|
||||
filename,
|
||||
location,
|
||||
flatten=not filename.endswith(('.pybundle', '.whl'))
|
||||
flatten=not filename.endswith('.whl')
|
||||
)
|
||||
elif (content_type == 'application/x-gzip'
|
||||
or tarfile.is_tarfile(filename)
|
||||
|
|
|
@ -153,14 +153,6 @@ class VersionControl(object):
|
|||
"""
|
||||
return (self.normalize_url(url1) == self.normalize_url(url2))
|
||||
|
||||
def parse_vcs_bundle_file(self, content):
|
||||
"""
|
||||
Takes the contents of the bundled text file that explains how to revert
|
||||
the stripped off version control data of the given package and returns
|
||||
the URL and revision of it.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def obtain(self, dest):
|
||||
"""
|
||||
Called when installing or updating an editable package, takes the
|
||||
|
|
|
@ -12,13 +12,10 @@ class Bazaar(VersionControl):
|
|||
name = 'bzr'
|
||||
dirname = '.bzr'
|
||||
repo_name = 'branch'
|
||||
bundle_file = 'bzr-branch.txt'
|
||||
schemes = (
|
||||
'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp',
|
||||
'bzr+lp',
|
||||
)
|
||||
guide = ('# This was a Bazaar branch; to make it a branch again run:\n'
|
||||
'bzr branch -r %(rev)s %(url)s .\n')
|
||||
|
||||
def __init__(self, url=None, *args, **kwargs):
|
||||
super(Bazaar, self).__init__(url, *args, **kwargs)
|
||||
|
@ -28,19 +25,6 @@ class Bazaar(VersionControl):
|
|||
urlparse.uses_fragment.extend(['lp'])
|
||||
urlparse.non_hierarchical.extend(['lp'])
|
||||
|
||||
def parse_vcs_bundle_file(self, content):
|
||||
url = rev = None
|
||||
for line in content.splitlines():
|
||||
if not line.strip() or line.strip().startswith('#'):
|
||||
continue
|
||||
match = re.search(r'^bzr\s*branch\s*-r\s*(\d*)', line)
|
||||
if match:
|
||||
rev = match.group(1).strip()
|
||||
url = line[match.end():].strip().split(None, 1)[0]
|
||||
if url and rev:
|
||||
return url, rev
|
||||
return None, None
|
||||
|
||||
def export(self, location):
|
||||
"""
|
||||
Export the Bazaar repository at the url to the destination location
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import tempfile
|
||||
import re
|
||||
import os.path
|
||||
|
||||
from pip.util import call_subprocess
|
||||
from pip.util import display_path, rmtree
|
||||
from pip.vcs import vcs, VersionControl
|
||||
from pip.log import logger
|
||||
from pip.backwardcompat import url2pathname, urlparse
|
||||
|
||||
urlsplit = urlparse.urlsplit
|
||||
urlunsplit = urlparse.urlunsplit
|
||||
|
||||
|
@ -17,10 +18,6 @@ class Git(VersionControl):
|
|||
schemes = (
|
||||
'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file',
|
||||
)
|
||||
bundle_file = 'git-clone.txt'
|
||||
guide = ('# This was a Git repo; to make it a repo again run:\n'
|
||||
'git init\ngit remote add origin %(url)s -f\ngit '
|
||||
'checkout %(rev)s\n')
|
||||
|
||||
def __init__(self, url=None, *args, **kwargs):
|
||||
|
||||
|
@ -42,24 +39,6 @@ class Git(VersionControl):
|
|||
|
||||
super(Git, self).__init__(url, *args, **kwargs)
|
||||
|
||||
def parse_vcs_bundle_file(self, content):
|
||||
url = rev = None
|
||||
for line in content.splitlines():
|
||||
if not line.strip() or line.strip().startswith('#'):
|
||||
continue
|
||||
url_match = re.search(
|
||||
r'git\s*remote\s*add\s*origin(.*)\s*-f',
|
||||
line,
|
||||
)
|
||||
if url_match:
|
||||
url = url_match.group(1).strip()
|
||||
rev_match = re.search(r'^git\s*checkout\s*-q\s*(.*)\s*', line)
|
||||
if rev_match:
|
||||
rev = rev_match.group(1).strip()
|
||||
if url and rev:
|
||||
return url, rev
|
||||
return None, None
|
||||
|
||||
def export(self, location):
|
||||
"""Export the Git repository at the url to the destination location"""
|
||||
temp_dir = tempfile.mkdtemp('-export', 'pip-')
|
||||
|
|
|
@ -15,24 +15,6 @@ class Mercurial(VersionControl):
|
|||
dirname = '.hg'
|
||||
repo_name = 'clone'
|
||||
schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http')
|
||||
bundle_file = 'hg-clone.txt'
|
||||
guide = ('# This was a Mercurial repo; to make it a repo again run:\n'
|
||||
'hg init\nhg pull %(url)s\nhg update -r %(rev)s\n')
|
||||
|
||||
def parse_vcs_bundle_file(self, content):
|
||||
url = rev = None
|
||||
for line in content.splitlines():
|
||||
if not line.strip() or line.strip().startswith('#'):
|
||||
continue
|
||||
url_match = re.search(r'hg\s*pull\s*(.*)\s*', line)
|
||||
if url_match:
|
||||
url = url_match.group(1).strip()
|
||||
rev_match = re.search(r'^hg\s*update\s*-r\s*(.*)\s*', line)
|
||||
if rev_match:
|
||||
rev = rev_match.group(1).strip()
|
||||
if url and rev:
|
||||
return url, rev
|
||||
return None, None
|
||||
|
||||
def export(self, location):
|
||||
"""Export the Hg repository at the url to the destination location"""
|
||||
|
|
|
@ -18,9 +18,6 @@ class Subversion(VersionControl):
|
|||
dirname = '.svn'
|
||||
repo_name = 'checkout'
|
||||
schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn')
|
||||
bundle_file = 'svn-checkout.txt'
|
||||
guide = ('# This was an svn checkout; to make it a checkout again run:\n'
|
||||
'svn checkout --force -r %(rev)s %(url)s .\n')
|
||||
|
||||
def get_info(self, location):
|
||||
"""Returns (url, revision), where both are strings"""
|
||||
|
@ -49,18 +46,6 @@ class Subversion(VersionControl):
|
|||
return url, None
|
||||
return url, match.group(1)
|
||||
|
||||
def parse_vcs_bundle_file(self, content):
|
||||
for line in content.splitlines():
|
||||
if not line.strip() or line.strip().startswith('#'):
|
||||
continue
|
||||
match = re.search(r'^-r\s*([^ ])?', line)
|
||||
if not match:
|
||||
return None, None
|
||||
rev = match.group(1)
|
||||
rest = line[match.end():].strip().split(None, 1)[0]
|
||||
return rest, rev
|
||||
return None, None
|
||||
|
||||
def export(self, location):
|
||||
"""Export the svn repository at the url to the destination location"""
|
||||
url, rev = self.get_url_rev()
|
||||
|
|
Binary file not shown.
|
@ -1,100 +0,0 @@
|
|||
import zipfile
|
||||
import textwrap
|
||||
from os.path import exists, join
|
||||
from pip.download import path_to_url
|
||||
from tests.lib.local_repos import local_checkout
|
||||
|
||||
|
||||
def test_create_bundle(script, tmpdir, data):
|
||||
"""
|
||||
Test making a bundle. We'll grab one package from the filesystem
|
||||
(the FSPkg dummy package), one from vcs (initools) and one from an
|
||||
index (pip itself).
|
||||
|
||||
"""
|
||||
fspkg = path_to_url(data.packages / 'FSPkg')
|
||||
script.pip('install', '-e', fspkg)
|
||||
pkg_lines = textwrap.dedent(
|
||||
'''
|
||||
-e %s
|
||||
-e %s#egg=initools-dev
|
||||
pip
|
||||
''' %
|
||||
(
|
||||
fspkg,
|
||||
local_checkout(
|
||||
'svn+http://svn.colorstudy.com/INITools/trunk',
|
||||
tmpdir.join("cache"),
|
||||
),
|
||||
),
|
||||
)
|
||||
script.scratch_path.join("bundle-req.txt").write(pkg_lines)
|
||||
# Create a bundle in env.scratch_path/ test.pybundle
|
||||
result = script.pip(
|
||||
'bundle', '--no-use-wheel', '-r',
|
||||
script.scratch_path / 'bundle-req.txt',
|
||||
script.scratch_path / 'test.pybundle',
|
||||
)
|
||||
bundle = result.files_after.get(join('scratch', 'test.pybundle'), None)
|
||||
assert bundle is not None
|
||||
|
||||
files = zipfile.ZipFile(bundle.full).namelist()
|
||||
assert 'src/FSPkg/' in files
|
||||
assert 'src/initools/' in files
|
||||
assert 'build/pip/' in files
|
||||
|
||||
|
||||
def test_cleanup_after_create_bundle(script, tmpdir, data):
|
||||
"""
|
||||
Test clean up after making a bundle. Make sure (build|src)-bundle/ dirs are
|
||||
removed but not src/.
|
||||
|
||||
"""
|
||||
# Install an editable to create a src/ dir.
|
||||
args = ['install']
|
||||
args.extend([
|
||||
'-e',
|
||||
'%s#egg=pip-test-package' %
|
||||
local_checkout(
|
||||
'git+http://github.com/pypa/pip-test-package.git',
|
||||
tmpdir.join("cache"),
|
||||
),
|
||||
])
|
||||
script.pip(*args)
|
||||
build = script.venv_path / "build"
|
||||
src = script.venv_path / "src"
|
||||
assert not exists(build), "build/ dir still exists: %s" % build
|
||||
assert exists(src), "expected src/ dir doesn't exist: %s" % src
|
||||
|
||||
# Make the bundle.
|
||||
fspkg = path_to_url(data.packages / 'FSPkg')
|
||||
pkg_lines = textwrap.dedent(
|
||||
'''
|
||||
-e %s
|
||||
-e %s#egg=initools-dev
|
||||
pip
|
||||
''' %
|
||||
(
|
||||
fspkg,
|
||||
local_checkout(
|
||||
'svn+http://svn.colorstudy.com/INITools/trunk',
|
||||
tmpdir.join("cache"),
|
||||
),
|
||||
),
|
||||
)
|
||||
script.scratch_path.join("bundle-req.txt").write(pkg_lines)
|
||||
script.pip(
|
||||
'bundle', '--no-use-wheel', '-r', 'bundle-req.txt', 'test.pybundle',
|
||||
)
|
||||
build_bundle = script.scratch_path / "build-bundle"
|
||||
src_bundle = script.scratch_path / "src-bundle"
|
||||
assert not exists(build_bundle), (
|
||||
"build-bundle/ dir still exists: %s" % build_bundle
|
||||
)
|
||||
assert not exists(src_bundle), "src-bundle/ dir still exists: %s" % (
|
||||
src_bundle
|
||||
)
|
||||
script.assert_no_temp()
|
||||
|
||||
# Make sure previously created src/ from editable still exists
|
||||
assert exists(src), "expected src dir doesn't exist: %s" % src
|
|
@ -1,10 +0,0 @@
|
|||
def test_install_pybundle(script, data):
|
||||
"""
|
||||
Test intalling a *.pybundle file
|
||||
"""
|
||||
result = script.pip_install_local(
|
||||
data.packages.join("simplebundle.pybundle"),
|
||||
expect_temp=True,
|
||||
)
|
||||
result.assert_installed('simple', editable=False)
|
||||
result.assert_installed('simple2', editable=False)
|
Loading…
Reference in New Issue