From e2cc2530fc6d54ebc975c01a4ff887ce12f0a736 Mon Sep 17 00:00:00 2001 From: Pavel Aharoni Date: Wed, 29 Mar 2017 13:35:45 +0300 Subject: [SDC-6] sdc-distribution-client 1707 rebasing Change-Id: I322a05fd79beb6ba4fee4d32afffecf531b86e98 Signed-off-by: Pavel Aharoni --- .../Lib/site-packages/pip/commands/__init__.py | 88 +++++ .../Lib/site-packages/pip/commands/bundle.py | 50 +++ .../Lib/site-packages/pip/commands/completion.py | 61 ++++ .../Lib/site-packages/pip/commands/freeze.py | 133 +++++++ .../Lib/site-packages/pip/commands/help.py | 33 ++ .../Lib/site-packages/pip/commands/install.py | 362 ++++++++++++++++++ .../Lib/site-packages/pip/commands/list.py | 183 ++++++++++ .../Lib/site-packages/pip/commands/search.py | 146 ++++++++ .../Lib/site-packages/pip/commands/show.py | 87 +++++ .../Lib/site-packages/pip/commands/uninstall.py | 64 ++++ .../Lib/site-packages/pip/commands/unzip.py | 7 + .../Lib/site-packages/pip/commands/wheel.py | 213 +++++++++++ .../Lib/site-packages/pip/commands/zip.py | 404 +++++++++++++++++++++ 13 files changed, 1831 insertions(+) create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/__init__.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/bundle.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/completion.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/freeze.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/help.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/install.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/list.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/search.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/show.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/uninstall.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/unzip.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/wheel.py create mode 100644 jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/zip.py (limited to 'jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands') diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/__init__.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/__init__.py new file mode 100644 index 0000000..e0702d2 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/__init__.py @@ -0,0 +1,88 @@ +""" +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 +from pip.commands.list import ListCommand +from pip.commands.search import SearchCommand +from pip.commands.show import ShowCommand +from pip.commands.install import InstallCommand +from pip.commands.uninstall import UninstallCommand +from pip.commands.unzip import UnzipCommand +from pip.commands.zip import ZipCommand +from pip.commands.wheel import WheelCommand + + +commands = { + BundleCommand.name: BundleCommand, + CompletionCommand.name: CompletionCommand, + FreezeCommand.name: FreezeCommand, + HelpCommand.name: HelpCommand, + SearchCommand.name: SearchCommand, + ShowCommand.name: ShowCommand, + InstallCommand.name: InstallCommand, + UninstallCommand.name: UninstallCommand, + UnzipCommand.name: UnzipCommand, + ZipCommand.name: ZipCommand, + ListCommand.name: ListCommand, + WheelCommand.name: WheelCommand, +} + + +commands_order = [ + InstallCommand, + UninstallCommand, + FreezeCommand, + ListCommand, + ShowCommand, + SearchCommand, + WheelCommand, + ZipCommand, + UnzipCommand, + BundleCommand, + HelpCommand, +] + + +def get_summaries(ignore_hidden=True, ordered=True): + """Yields sorted (command name, command summary) tuples.""" + + if ordered: + cmditems = _sort_commands(commands, commands_order) + else: + cmditems = commands.items() + + for name, command_class in cmditems: + if ignore_hidden and command_class.hidden: + continue + + yield (name, command_class.summary) + + +def get_similar_commands(name): + """Command name auto-correct.""" + from difflib import get_close_matches + + close_commands = get_close_matches(name, commands.keys()) + + if close_commands: + guess = close_commands[0] + else: + guess = False + + return guess + + +def _sort_commands(cmddict, order): + def keyfn(key): + try: + return order.index(key[1]) + except ValueError: + # unordered items should come last + return 0xff + + return sorted(cmddict.items(), key=keyfn) diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/bundle.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/bundle.py new file mode 100644 index 0000000..52b4f19 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/bundle.py @@ -0,0 +1,50 @@ +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] .pybundle ...""" + 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 diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/completion.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/completion.py new file mode 100644 index 0000000..a3fa2fb --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/completion.py @@ -0,0 +1,61 @@ +import sys +from pip.basecommand import Command + +BASE_COMPLETION = """ +# pip %(shell)s completion start%(script)s# pip %(shell)s completion end +""" + +COMPLETION_SCRIPTS = { + 'bash': """ +_pip_completion() +{ + COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + PIP_AUTO_COMPLETE=1 $1 ) ) +} +complete -o default -F _pip_completion pip +""", 'zsh': """ +function _pip_completion { + local words cword + read -Ac words + read -cn cword + reply=( $( COMP_WORDS="$words[*]" \\ + COMP_CWORD=$(( cword-1 )) \\ + PIP_AUTO_COMPLETE=1 $words[1] ) ) +} +compctl -K _pip_completion pip +"""} + + +class CompletionCommand(Command): + """A helper command to be used for command completion.""" + name = 'completion' + summary = 'A helper command to be used for command completion' + hidden = True + + def __init__(self, *args, **kw): + super(CompletionCommand, self).__init__(*args, **kw) + self.parser.add_option( + '--bash', '-b', + action='store_const', + const='bash', + dest='shell', + help='Emit completion code for bash') + self.parser.add_option( + '--zsh', '-z', + action='store_const', + const='zsh', + dest='shell', + help='Emit completion code for zsh') + + def run(self, options, args): + """Prints the completion code of the given shell""" + shells = COMPLETION_SCRIPTS.keys() + shell_options = ['--' + shell for shell in sorted(shells)] + if options.shell in shells: + script = COMPLETION_SCRIPTS.get(options.shell, '') + print(BASE_COMPLETION % {'script': script, 'shell': options.shell}) + else: + sys.stderr.write( + 'ERROR: You must pass %s\n' % ' or '.join(shell_options) + ) diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/freeze.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/freeze.py new file mode 100644 index 0000000..2d5b10d --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/freeze.py @@ -0,0 +1,133 @@ +import re +import sys +import pip + +from pip.backwardcompat import stdlib_pkgs +from pip.req import InstallRequirement +from pip.log import logger +from pip.basecommand import Command +from pip.util import get_installed_distributions + +# packages to exclude from freeze output +freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute'] + + +class FreezeCommand(Command): + """ + Output installed packages in requirements format. + + packages are listed in a case-insensitive sorted order. + """ + name = 'freeze' + usage = """ + %prog [options]""" + summary = 'Output installed packages in requirements format.' + + def __init__(self, *args, **kw): + super(FreezeCommand, self).__init__(*args, **kw) + + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirement', + action='store', + default=None, + metavar='file', + help="Use the order in the given requirements file and its " + "comments when generating output.") + self.cmd_opts.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the ' + 'output.') + self.cmd_opts.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv that has global access, do not output ' + 'globally-installed packages.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def setup_logging(self): + logger.move_stdout_to_stderr() + + def run(self, options, args): + requirement = options.requirement + find_links = options.find_links or [] + local_only = options.local + # FIXME: Obviously this should be settable: + find_tags = False + skip_match = None + + skip_regex = options.skip_requirements_regex + if skip_regex: + skip_match = re.compile(skip_regex) + + f = sys.stdout + + for link in find_links: + f.write('-f %s\n' % link) + installations = {} + for dist in get_installed_distributions(local_only=local_only, + skip=freeze_excludes): + req = pip.FrozenRequirement.from_dist(dist, find_tags=find_tags) + installations[req.name] = req + if requirement: + req_f = open(requirement) + for line in req_f: + if not line.strip() or line.strip().startswith('#'): + f.write(line) + continue + if skip_match and skip_match.search(line): + f.write(line) + continue + elif line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + line_req = InstallRequirement.from_editable( + line, + default_vcs=options.default_vcs + ) + elif (line.startswith('-r') + or line.startswith('--requirement') + or line.startswith('-Z') + or line.startswith('--always-unzip') + or line.startswith('-f') + or line.startswith('-i') + or line.startswith('--extra-index-url') + or line.startswith('--find-links') + or line.startswith('--index-url')): + f.write(line) + continue + else: + line_req = InstallRequirement.from_line(line) + if not line_req.name: + logger.notify( + "Skipping line because it's not clear what it would " + "install: %s" % line.strip() + ) + logger.notify( + " (add #egg=PackageName to the URL to avoid" + " this warning)" + ) + continue + if line_req.name not in installations: + logger.warn( + "Requirement file contains %s, but that package is not" + " installed" % line.strip() + ) + continue + f.write(str(installations[line_req.name])) + del installations[line_req.name] + f.write( + '## The following requirements were added by pip --freeze:\n' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + f.write(str(installation)) diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/help.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/help.py new file mode 100644 index 0000000..2253387 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/help.py @@ -0,0 +1,33 @@ +from pip.basecommand import Command, SUCCESS +from pip.exceptions import CommandError + + +class HelpCommand(Command): + """Show help for commands""" + name = 'help' + usage = """ + %prog """ + summary = 'Show help for commands.' + + def run(self, options, args): + from pip.commands import commands, get_similar_commands + + try: + # 'pip help' with no args is handled by pip.__init__.parseopt() + cmd_name = args[0] # the command we need help for + except IndexError: + return SUCCESS + + if cmd_name not in commands: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + command = commands[cmd_name]() + command.parser.print_help() + + return SUCCESS diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/install.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/install.py new file mode 100644 index 0000000..850a6ff --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/install.py @@ -0,0 +1,362 @@ +import os +import tempfile +import shutil + +from pip.req import InstallRequirement, RequirementSet, parse_requirements +from pip.log import logger +from pip.locations import (src_prefix, virtualenv_no_global, distutils_scheme, + build_prefix) +from pip.basecommand import Command +from pip.index import PackageFinder +from pip.exceptions import ( + InstallationError, CommandError, PreviousBuildDirError, +) +from pip import cmdoptions + + +class InstallCommand(Command): + """ + Install packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports installing from "requirements files", which provide + an easy way to specify a whole environment to be installed. + """ + name = 'install' + + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Install packages.' + bundle = False + + def __init__(self, *args, **kw): + super(InstallCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='path/url', + help=('Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.'), + ) + + cmd_opts.add_option(cmdoptions.requirements.make()) + cmd_opts.add_option(cmdoptions.build_dir.make()) + + cmd_opts.add_option( + '-t', '--target', + dest='target_dir', + metavar='dir', + default=None, + help='Install packages into .') + + cmd_opts.add_option( + '-d', '--download', '--download-dir', '--download-directory', + dest='download_dir', + metavar='dir', + default=None, + help=("Download packages into instead of installing them, " + "regardless of what's already installed."), + ) + + cmd_opts.add_option(cmdoptions.download_cache.make()) + + cmd_opts.add_option( + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + metavar='dir', + default=src_prefix, + help='Directory to check out editable projects into. ' + 'The default in a virtualenv is "/src". ' + 'The default for global installs is "/src".') + + cmd_opts.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all packages to the newest available version. ' + 'This process is recursive regardless of whether a dependency' + ' is already satisfied.' + ) + + cmd_opts.add_option( + '--force-reinstall', + dest='force_reinstall', + action='store_true', + help='When upgrading, reinstall all packages even if they are ' + 'already up-to-date.') + + cmd_opts.add_option( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages (reinstalling instead).') + + cmd_opts.add_option(cmdoptions.no_deps.make()) + + cmd_opts.add_option( + '--no-install', + dest='no_install', + action='store_true', + help="DEPRECATED. Download and unpack all packages, but don't " + "actually install them." + ) + + cmd_opts.add_option( + '--no-download', + dest='no_download', + action="store_true", + help="DEPRECATED. Don't download any packages, just install the " + "ones already downloaded (completes an install run with " + "--no-install).") + + cmd_opts.add_option(cmdoptions.install_options.make()) + cmd_opts.add_option(cmdoptions.global_options.make()) + + cmd_opts.add_option( + '--user', + dest='use_user_site', + action='store_true', + help='Install using the user scheme.') + + cmd_opts.add_option( + '--egg', + dest='as_egg', + action='store_true', + help="Install packages as eggs, not 'flat', like pip normally " + "does. This option is not about installing *from* eggs. " + "(WARNING: Because this option overrides pip's normal install" + " logic, requirements files may not behave as expected.)") + + cmd_opts.add_option( + '--root', + dest='root_path', + metavar='dir', + default=None, + help="Install everything relative to this alternate root " + "directory.") + + cmd_opts.add_option( + "--compile", + action="store_true", + dest="compile", + default=True, + help="Compile py files to pyc", + ) + + cmd_opts.add_option( + "--no-compile", + action="store_false", + dest="compile", + help="Do not compile py files to pyc", + ) + + cmd_opts.add_option(cmdoptions.use_wheel.make()) + cmd_opts.add_option(cmdoptions.no_use_wheel.make()) + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help="Include pre-release and development versions. By default, " + "pip only finds stable versions.") + + cmd_opts.add_option(cmdoptions.no_clean.make()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def _build_package_finder(self, options, index_urls, session): + """ + Create a package finder appropriate to this install command. + This method is meant to be overridden by subclasses, not + called directly. + """ + return PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + use_wheel=options.use_wheel, + allow_external=options.allow_external, + allow_unverified=options.allow_unverified, + allow_all_external=options.allow_all_external, + allow_all_prereleases=options.pre, + session=session, + ) + + def run(self, options, args): + + if ( + options.no_install or + options.no_download or + (options.build_dir != build_prefix) or + options.no_clean + ): + logger.deprecated( + '1.7', + 'DEPRECATION: --no-install, --no-download, --build, ' + 'and --no-clean are deprecated. See ' + 'https://github.com/pypa/pip/issues/906.', + ) + + if options.download_dir: + options.no_install = True + options.ignore_installed = True + options.build_dir = os.path.abspath(options.build_dir) + options.src_dir = os.path.abspath(options.src_dir) + install_options = options.install_options or [] + if options.use_user_site: + if virtualenv_no_global(): + raise InstallationError( + "Can not perform a '--user' install. User site-packages " + "are not visible in this virtualenv." + ) + install_options.append('--user') + + temp_target_dir = None + if options.target_dir: + options.ignore_installed = True + temp_target_dir = tempfile.mkdtemp() + options.target_dir = os.path.abspath(options.target_dir) + if (os.path.exists(options.target_dir) + and not os.path.isdir(options.target_dir)): + raise CommandError( + "Target path exists but is not a directory, will not " + "continue." + ) + install_options.append('--home=' + temp_target_dir) + + global_options = options.global_options or [] + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.notify('Ignoring indexes: %s' % ','.join(index_urls)) + index_urls = [] + + if options.use_mirrors: + logger.deprecated( + "1.7", + "--use-mirrors has been deprecated and will be removed" + " in the future. Explicit uses of --index-url and/or " + "--extra-index-url is suggested." + ) + + if options.mirrors: + logger.deprecated( + "1.7", + "--mirrors has been deprecated and will be removed in " + " the future. Explicit uses of --index-url and/or " + "--extra-index-url is suggested." + ) + index_urls += options.mirrors + + session = self._build_session(options) + + finder = self._build_package_finder(options, index_urls, session) + + requirement_set = RequirementSet( + build_dir=options.build_dir, + src_dir=options.src_dir, + download_dir=options.download_dir, + download_cache=options.download_cache, + upgrade=options.upgrade, + as_egg=options.as_egg, + ignore_installed=options.ignore_installed, + ignore_dependencies=options.ignore_dependencies, + force_reinstall=options.force_reinstall, + use_user_site=options.use_user_site, + target_dir=temp_target_dir, + session=session, + pycompile=options.compile, + ) + for name in args: + requirement_set.add_requirement( + InstallRequirement.from_line(name, None)) + for name in options.editables: + requirement_set.add_requirement( + InstallRequirement.from_editable( + name, + default_vcs=options.default_vcs + ) + ) + for filename in options.requirements: + for req in parse_requirements( + filename, finder=finder, options=options, session=session): + requirement_set.add_requirement(req) + if not requirement_set.has_requirements: + opts = {'name': self.name} + if options.find_links: + msg = ('You must give at least one requirement to %(name)s ' + '(maybe you meant "pip %(name)s %(links)s"?)' % + dict(opts, links=' '.join(options.find_links))) + else: + msg = ('You must give at least one requirement ' + 'to %(name)s (see "pip help %(name)s")' % opts) + logger.warn(msg) + return + + try: + if not options.no_download: + requirement_set.prepare_files( + finder, + force_root_egg_info=self.bundle, + bundle=self.bundle, + ) + else: + requirement_set.locate_files() + + if not options.no_install and not self.bundle: + requirement_set.install( + install_options, + global_options, + root=options.root_path, + ) + installed = ' '.join([req.name for req in + requirement_set.successfully_installed]) + if installed: + logger.notify('Successfully installed %s' % installed) + elif not self.bundle: + 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 + finally: + # Clean up + if ((not options.no_clean) + and ((not options.no_install) or options.download_dir)): + requirement_set.cleanup_files(bundle=self.bundle) + + if options.target_dir: + if not os.path.exists(options.target_dir): + os.makedirs(options.target_dir) + lib_dir = distutils_scheme('', home=temp_target_dir)['purelib'] + for item in os.listdir(lib_dir): + shutil.move( + os.path.join(lib_dir, item), + os.path.join(options.target_dir, item), + ) + shutil.rmtree(temp_target_dir) + return requirement_set diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/list.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/list.py new file mode 100644 index 0000000..3a0330a --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/list.py @@ -0,0 +1,183 @@ +from pip.basecommand import Command +from pip.exceptions import DistributionNotFound, BestVersionAlreadyInstalled +from pip.index import PackageFinder +from pip.log import logger +from pip.req import InstallRequirement +from pip.util import get_installed_distributions, dist_is_editable +from pip.cmdoptions import make_option_group, index_group + + +class ListCommand(Command): + """ + List installed packages, including editables. + + Packages are listed in a case-insensitive sorted order. + """ + name = 'list' + usage = """ + %prog [options]""" + summary = 'List installed packages.' + + def __init__(self, *args, **kw): + super(ListCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-o', '--outdated', + action='store_true', + default=False, + help='List outdated packages (excluding editables)') + cmd_opts.add_option( + '-u', '--uptodate', + action='store_true', + default=False, + help='List uptodate packages (excluding editables)') + cmd_opts.add_option( + '-e', '--editable', + action='store_true', + default=False, + help='List editable projects.') + cmd_opts.add_option( + '-l', '--local', + action='store_true', + default=False, + help=('If in a virtualenv that has global access, do not list ' + 'globally-installed packages.'), + ) + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + index_opts = make_option_group(index_group, self.parser) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def _build_package_finder(self, options, index_urls, session): + """ + Create a package finder appropriate to this list command. + """ + return PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + allow_external=options.allow_external, + allow_unverified=options.allow_unverified, + allow_all_external=options.allow_all_external, + allow_all_prereleases=options.pre, + session=session, + ) + + def run(self, options, args): + if options.outdated: + self.run_outdated(options) + elif options.uptodate: + self.run_uptodate(options) + elif options.editable: + self.run_editables(options) + else: + self.run_listing(options) + + def run_outdated(self, options): + for dist, remote_version_raw, remote_version_parsed in \ + self.find_packages_latests_versions(options): + if remote_version_parsed > dist.parsed_version: + logger.notify( + '%s (Current: %s Latest: %s)' % + (dist.project_name, dist.version, remote_version_raw) + ) + + def find_packages_latests_versions(self, options): + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.notify('Ignoring indexes: %s' % ','.join(index_urls)) + index_urls = [] + + if options.use_mirrors: + logger.deprecated( + "1.7", + "--use-mirrors has been deprecated and will be removed" + " in the future. Explicit uses of --index-url and/or " + "--extra-index-url is suggested." + ) + + if options.mirrors: + logger.deprecated( + "1.7", + "--mirrors has been deprecated and will be removed in " + " the future. Explicit uses of --index-url and/or " + "--extra-index-url is suggested." + ) + index_urls += options.mirrors + + session = self._build_session(options) + + finder = self._build_package_finder(options, index_urls, session) + + installed_packages = get_installed_distributions( + local_only=options.local, + include_editables=False, + ) + for dist in installed_packages: + req = InstallRequirement.from_line(dist.key, None) + try: + link = finder.find_requirement(req, True) + + # If link is None, means installed version is most up-to-date + if link is None: + continue + except DistributionNotFound: + continue + except BestVersionAlreadyInstalled: + remote_version = req.installed_version + else: + # It might be a good idea that link or finder had a public + # method that returned version + remote_version = finder._link_package_versions( + link, req.name + )[0] + remote_version_raw = remote_version[2] + remote_version_parsed = remote_version[0] + yield dist, remote_version_raw, remote_version_parsed + + def run_listing(self, options): + installed_packages = get_installed_distributions( + local_only=options.local, + ) + self.output_package_listing(installed_packages) + + def run_editables(self, options): + installed_packages = get_installed_distributions( + local_only=options.local, + editables_only=True, + ) + self.output_package_listing(installed_packages) + + def output_package_listing(self, installed_packages): + installed_packages = sorted( + installed_packages, + key=lambda dist: dist.project_name.lower(), + ) + for dist in installed_packages: + if dist_is_editable(dist): + line = '%s (%s, %s)' % ( + dist.project_name, + dist.version, + dist.location, + ) + else: + line = '%s (%s)' % (dist.project_name, dist.version) + logger.notify(line) + + def run_uptodate(self, options): + uptodate = [] + for dist, remote_version_raw, remote_version_parsed in \ + self.find_packages_latests_versions(options): + if dist.parsed_version == remote_version_parsed: + uptodate.append(dist) + self.output_package_listing(uptodate) diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/search.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/search.py new file mode 100644 index 0000000..a26f8b4 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/search.py @@ -0,0 +1,146 @@ +import sys +import textwrap + +from pip.basecommand import Command, SUCCESS +from pip.util import get_terminal_size +from pip.log import logger +from pip.backwardcompat import xmlrpclib, reduce, cmp +from pip.exceptions import CommandError +from pip.status_codes import NO_MATCHES_FOUND +from pip._vendor import pkg_resources +from distutils.version import StrictVersion, LooseVersion + + +class SearchCommand(Command): + """Search for PyPI packages whose name or summary contains .""" + name = 'search' + usage = """ + %prog [options] """ + summary = 'Search PyPI for packages.' + + def __init__(self, *args, **kw): + super(SearchCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '--index', + dest='index', + metavar='URL', + default='https://pypi.python.org/pypi', + help='Base URL of Python Package Index (default %default)') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + raise CommandError('Missing required argument (search query).') + query = args + index_url = options.index + + pypi_hits = self.search(query, index_url) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + if pypi_hits: + return SUCCESS + return NO_MATCHES_FOUND + + def search(self, query, index_url): + pypi = xmlrpclib.ServerProxy(index_url) + hits = pypi.search({'name': query, 'summary': query}, 'or') + return hits + + +def transform_hits(hits): + """ + The list from pypi is really a list of versions. We want a list of + packages with the list of versions stored inline. This converts the + list from pypi into one we can use. + """ + packages = {} + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + score = hit['_pypi_ordering'] + if score is None: + score = 0 + + if name not in packages.keys(): + packages[name] = { + 'name': name, + 'summary': summary, + 'versions': [version], + 'score': score, + } + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + packages[name]['score'] = score + + # each record has a unique name now, so we will convert the dict into a + # list sorted by score + package_list = sorted( + packages.values(), + key=lambda x: x['score'], + reverse=True, + ) + return package_list + + +def print_results(hits, name_column_width=25, terminal_width=None): + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + if terminal_width is not None: + # wrap and indent summary to fit terminal + summary = textwrap.wrap( + summary, + terminal_width - name_column_width - 5, + ) + summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) + line = '%s - %s' % (name.ljust(name_column_width), summary) + try: + logger.notify(line) + if name in installed_packages: + dist = pkg_resources.get_distribution(name) + logger.indent += 2 + try: + latest = highest_version(hit['versions']) + if dist.version == latest: + logger.notify('INSTALLED: %s (latest)' % dist.version) + else: + logger.notify('INSTALLED: %s' % dist.version) + logger.notify('LATEST: %s' % latest) + finally: + logger.indent -= 2 + except UnicodeEncodeError: + pass + + +def compare_versions(version1, version2): + try: + return cmp(StrictVersion(version1), StrictVersion(version2)) + # in case of abnormal version number, fall back to LooseVersion + except ValueError: + pass + try: + return cmp(LooseVersion(version1), LooseVersion(version2)) + except TypeError: + # certain LooseVersion comparions raise due to unorderable types, + # fallback to string comparison + return cmp([str(v) for v in LooseVersion(version1).version], + [str(v) for v in LooseVersion(version2).version]) + + +def highest_version(versions): + return reduce( + (lambda v1, v2: compare_versions(v1, v2) == 1 and v1 or v2), + versions, + ) diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/show.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/show.py new file mode 100644 index 0000000..e0d2bc7 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/show.py @@ -0,0 +1,87 @@ +import os + +from pip.basecommand import Command +from pip.log import logger +from pip._vendor import pkg_resources + + +class ShowCommand(Command): + """Show information about one or more installed packages.""" + name = 'show' + usage = """ + %prog [options] ...""" + summary = 'Show information about installed packages.' + + def __init__(self, *args, **kw): + super(ShowCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-f', '--files', + dest='files', + action='store_true', + default=False, + help='Show the full list of installed files for each package.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + logger.warn('ERROR: Please provide a package name or names.') + return + query = args + + results = search_packages_info(query) + print_results(results, options.files) + + +def search_packages_info(query): + """ + Gather details from installed distributions. Print distribution name, + version, location, and installed files. Installed files requires a + pip generated 'installed-files.txt' in the distributions '.egg-info' + directory. + """ + installed = dict( + [(p.project_name.lower(), p) for p in pkg_resources.working_set]) + query_names = [name.lower() for name in query] + for dist in [installed[pkg] for pkg in query_names if pkg in installed]: + package = { + 'name': dist.project_name, + 'version': dist.version, + 'location': dist.location, + 'requires': [dep.project_name for dep in dist.requires()], + } + file_list = None + if isinstance(dist, pkg_resources.DistInfoDistribution): + # RECORDs should be part of .dist-info metadatas + if dist.has_metadata('RECORD'): + lines = dist.get_metadata_lines('RECORD') + paths = [l.split(',')[0] for l in lines] + paths = [os.path.join(dist.location, p) for p in paths] + file_list = [os.path.relpath(p, dist.egg_info) + for p in paths] + else: + # Otherwise use pip's log for .egg-info's + if dist.has_metadata('installed-files.txt'): + file_list = dist.get_metadata_lines('installed-files.txt') + # use and short-circuit to check for None + package['files'] = file_list and sorted(file_list) + yield package + + +def print_results(distributions, list_all_files): + """ + Print the informations from installed distributions found. + """ + for dist in distributions: + logger.notify("---") + logger.notify("Name: %s" % dist['name']) + logger.notify("Version: %s" % dist['version']) + logger.notify("Location: %s" % dist['location']) + logger.notify("Requires: %s" % ', '.join(dist['requires'])) + if list_all_files: + logger.notify("Files:") + if dist['files'] is not None: + for line in dist['files']: + logger.notify(" %s" % line.strip()) + else: + logger.notify("Cannot locate installed-files.txt") diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/uninstall.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/uninstall.py new file mode 100644 index 0000000..3d81a30 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/uninstall.py @@ -0,0 +1,64 @@ +from pip.req import InstallRequirement, RequirementSet, parse_requirements +from pip.basecommand import Command +from pip.exceptions import InstallationError + + +class UninstallCommand(Command): + """ + Uninstall packages. + + pip is able to uninstall most installed packages. Known exceptions are: + + - Pure distutils packages installed with ``python setup.py install``, which + leave behind no metadata to determine what files were installed. + - Script wrappers installed by ``python setup.py develop``. + """ + name = 'uninstall' + usage = """ + %prog [options] ... + %prog [options] -r ...""" + summary = 'Uninstall packages.' + + def __init__(self, *args, **kw): + super(UninstallCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Uninstall all the packages listed in the given requirements ' + 'file. This option can be used multiple times.', + ) + self.cmd_opts.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + session = self._build_session(options) + + requirement_set = RequirementSet( + build_dir=None, + src_dir=None, + download_dir=None, + session=session, + ) + for name in args: + requirement_set.add_requirement( + InstallRequirement.from_line(name)) + for filename in options.requirements: + for req in parse_requirements( + filename, + options=options, + session=session): + requirement_set.add_requirement(req) + if not requirement_set.has_requirements: + raise InstallationError( + 'You must give at least one requirement to %(name)s (see "pip ' + 'help %(name)s")' % dict(name=self.name) + ) + requirement_set.uninstall(auto_confirm=options.yes) diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/unzip.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/unzip.py new file mode 100644 index 0000000..ed66ab9 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/unzip.py @@ -0,0 +1,7 @@ +from pip.commands.zip import ZipCommand + + +class UnzipCommand(ZipCommand): + """Unzip individual packages.""" + name = 'unzip' + summary = 'DEPRECATED. Unzip individual packages.' diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/wheel.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/wheel.py new file mode 100644 index 0000000..5536816 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/wheel.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import os + +from pip.basecommand import Command +from pip.index import PackageFinder +from pip.log import logger +from pip.exceptions import CommandError, PreviousBuildDirError +from pip.req import InstallRequirement, RequirementSet, parse_requirements +from pip.util import normalize_path +from pip.wheel import WheelBuilder +from pip import cmdoptions + +DEFAULT_WHEEL_DIR = os.path.join(normalize_path(os.curdir), 'wheelhouse') + + +class WheelCommand(Command): + """ + Build Wheel archives for your requirements and dependencies. + + Wheel is a built-package format, and offers the advantage of not + recompiling your software during every install. For more details, see the + wheel docs: http://wheel.readthedocs.org/en/latest. + + Requirements: setuptools>=0.8, and wheel. + + 'pip wheel' uses the bdist_wheel setuptools extension from the wheel + package to build individual wheels. + + """ + + name = 'wheel' + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] ... + %prog [options] ... + %prog [options] ...""" + + summary = 'Build wheels from your requirements.' + + def __init__(self, *args, **kw): + super(WheelCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-w', '--wheel-dir', + dest='wheel_dir', + metavar='dir', + default=DEFAULT_WHEEL_DIR, + help=("Build wheels into , where the default is " + "'/wheelhouse'."), + ) + cmd_opts.add_option(cmdoptions.use_wheel.make()) + cmd_opts.add_option(cmdoptions.no_use_wheel.make()) + cmd_opts.add_option( + '--build-option', + dest='build_options', + metavar='options', + action='append', + help="Extra arguments to be supplied to 'setup.py bdist_wheel'.") + cmd_opts.add_option(cmdoptions.requirements.make()) + cmd_opts.add_option(cmdoptions.download_cache.make()) + cmd_opts.add_option(cmdoptions.no_deps.make()) + cmd_opts.add_option(cmdoptions.build_dir.make()) + + cmd_opts.add_option( + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the 'bdist_wheel' command.") + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option(cmdoptions.no_clean.make()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + + # confirm requirements + try: + import wheel.bdist_wheel + # Hack to make flake8 not complain about an unused import + wheel.bdist_wheel + except ImportError: + raise CommandError( + "'pip wheel' requires the 'wheel' package. To fix this, run: " + "pip install wheel" + ) + + try: + import pkg_resources + except ImportError: + raise CommandError( + "'pip wheel' requires setuptools >= 0.8 for dist-info support." + " To fix this, run: pip install --upgrade setuptools" + ) + else: + if not hasattr(pkg_resources, 'DistInfoDistribution'): + raise CommandError( + "'pip wheel' requires setuptools >= 0.8 for dist-info " + "support. To fix this, run: pip install --upgrade " + "setuptools" + ) + + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.notify('Ignoring indexes: %s' % ','.join(index_urls)) + index_urls = [] + + if options.use_mirrors: + logger.deprecated( + "1.7", + "--use-mirrors has been deprecated and will be removed" + " in the future. Explicit uses of --index-url and/or " + "--extra-index-url is suggested." + ) + + if options.mirrors: + logger.deprecated( + "1.7", + "--mirrors has been deprecated and will be removed in " + " the future. Explicit uses of --index-url and/or " + "--extra-index-url is suggested." + ) + index_urls += options.mirrors + + session = self._build_session(options) + + finder = PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + use_wheel=options.use_wheel, + allow_external=options.allow_external, + allow_unverified=options.allow_unverified, + allow_all_external=options.allow_all_external, + allow_all_prereleases=options.pre, + session=session, + ) + + options.build_dir = os.path.abspath(options.build_dir) + requirement_set = RequirementSet( + build_dir=options.build_dir, + src_dir=None, + download_dir=None, + download_cache=options.download_cache, + ignore_dependencies=options.ignore_dependencies, + ignore_installed=True, + session=session, + wheel_download_dir=options.wheel_dir + ) + + # make the wheelhouse + if not os.path.exists(options.wheel_dir): + os.makedirs(options.wheel_dir) + + # parse args and/or requirements files + for name in args: + requirement_set.add_requirement( + InstallRequirement.from_line(name, None)) + + for filename in options.requirements: + for req in parse_requirements( + filename, + finder=finder, + options=options, + session=session): + if req.editable: + logger.notify("ignoring %s" % req.url) + continue + requirement_set.add_requirement(req) + + # fail if no requirements + if not requirement_set.has_requirements: + opts = {'name': self.name} + msg = ('You must give at least one requirement ' + 'to %(name)s (see "pip help %(name)s")' % opts) + logger.error(msg) + return + + try: + # build wheels + wb = WheelBuilder( + requirement_set, + finder, + options.wheel_dir, + build_options=options.build_options or [], + global_options=options.global_options or [], + ) + wb.build() + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + if not options.no_clean: + requirement_set.cleanup_files() diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/zip.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/zip.py new file mode 100644 index 0000000..6b17762 --- /dev/null +++ b/jython-tosca-parser/src/main/resources/Lib/site-packages/pip/commands/zip.py @@ -0,0 +1,404 @@ +import sys +import re +import fnmatch +import os +import shutil +import zipfile +from pip.util import display_path, backup_dir, rmtree +from pip.log import logger +from pip.exceptions import InstallationError +from pip.basecommand import Command + + +class ZipCommand(Command): + """Zip individual packages.""" + name = 'zip' + usage = """ + %prog [options] ...""" + summary = 'DEPRECATED. Zip individual packages.' + + def __init__(self, *args, **kw): + super(ZipCommand, self).__init__(*args, **kw) + if self.name == 'zip': + self.cmd_opts.add_option( + '--unzip', + action='store_true', + dest='unzip', + help='Unzip (rather than zip) a package.') + else: + self.cmd_opts.add_option( + '--zip', + action='store_false', + dest='unzip', + default=True, + help='Zip (rather than unzip) a package.') + self.cmd_opts.add_option( + '--no-pyc', + action='store_true', + dest='no_pyc', + help=( + 'Do not include .pyc files in zip files (useful on Google App ' + 'Engine).'), + ) + self.cmd_opts.add_option( + '-l', '--list', + action='store_true', + dest='list', + help='List the packages available, and their zip status.') + self.cmd_opts.add_option( + '--sort-files', + action='store_true', + dest='sort_files', + help=('With --list, sort packages according to how many files they' + ' contain.'), + ) + self.cmd_opts.add_option( + '--path', + action='append', + dest='paths', + help=('Restrict operations to the given paths (may include ' + 'wildcards).'), + ) + self.cmd_opts.add_option( + '-n', '--simulate', + action='store_true', + help='Do not actually perform the zip/unzip operation.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def paths(self): + """All the entries of sys.path, possibly restricted by --path""" + if not self.select_paths: + return sys.path + result = [] + match_any = set() + for path in sys.path: + path = os.path.normcase(os.path.abspath(path)) + for match in self.select_paths: + match = os.path.normcase(os.path.abspath(match)) + if '*' in match: + if re.search(fnmatch.translate(match + '*'), path): + result.append(path) + match_any.add(match) + break + else: + if path.startswith(match): + result.append(path) + match_any.add(match) + break + else: + logger.debug("Skipping path %s because it doesn't match %s" + % (path, ', '.join(self.select_paths))) + for match in self.select_paths: + if match not in match_any and '*' not in match: + result.append(match) + logger.debug("Adding path %s because it doesn't match " + "anything already on sys.path" % match) + return result + + def run(self, options, args): + + logger.deprecated( + '1.7', + "DEPRECATION: 'pip zip' and 'pip unzip` are deprecated, and will " + "be removed in a future release." + ) + + self.select_paths = options.paths + self.simulate = options.simulate + if options.list: + return self.list(options, args) + if not args: + raise InstallationError( + 'You must give at least one package to zip or unzip') + packages = [] + for arg in args: + module_name, filename = self.find_package(arg) + if options.unzip and os.path.isdir(filename): + raise InstallationError( + 'The module %s (in %s) is not a zip file; cannot be ' + 'unzipped' % (module_name, filename) + ) + elif not options.unzip and not os.path.isdir(filename): + raise InstallationError( + 'The module %s (in %s) is not a directory; cannot be ' + 'zipped' % (module_name, filename) + ) + packages.append((module_name, filename)) + last_status = None + for module_name, filename in packages: + if options.unzip: + last_status = self.unzip_package(module_name, filename) + else: + last_status = self.zip_package( + module_name, filename, options.no_pyc + ) + return last_status + + def unzip_package(self, module_name, filename): + zip_filename = os.path.dirname(filename) + if (not os.path.isfile(zip_filename) + and zipfile.is_zipfile(zip_filename)): + raise InstallationError( + 'Module %s (in %s) isn\'t located in a zip file in %s' + % (module_name, filename, zip_filename)) + package_path = os.path.dirname(zip_filename) + if package_path not in self.paths(): + logger.warn( + 'Unpacking %s into %s, but %s is not on sys.path' + % (display_path(zip_filename), display_path(package_path), + display_path(package_path))) + logger.notify( + 'Unzipping %s (in %s)' % (module_name, display_path(zip_filename)) + ) + if self.simulate: + logger.notify( + 'Skipping remaining operations because of --simulate' + ) + return + logger.indent += 2 + try: + # FIXME: this should be undoable: + zip = zipfile.ZipFile(zip_filename) + to_save = [] + for info in zip.infolist(): + name = info.filename + if name.startswith(module_name + os.path.sep): + content = zip.read(name) + dest = os.path.join(package_path, name) + if not os.path.exists(os.path.dirname(dest)): + os.makedirs(os.path.dirname(dest)) + if not content and dest.endswith(os.path.sep): + if not os.path.exists(dest): + os.makedirs(dest) + else: + f = open(dest, 'wb') + f.write(content) + f.close() + else: + to_save.append((name, zip.read(name))) + zip.close() + if not to_save: + logger.info( + 'Removing now-empty zip file %s' % + display_path(zip_filename) + ) + os.unlink(zip_filename) + self.remove_filename_from_pth(zip_filename) + else: + logger.info( + 'Removing entries in %s/ from zip file %s' % + (module_name, display_path(zip_filename)) + ) + zip = zipfile.ZipFile(zip_filename, 'w') + for name, content in to_save: + zip.writestr(name, content) + zip.close() + finally: + logger.indent -= 2 + + def zip_package(self, module_name, filename, no_pyc): + orig_filename = filename + logger.notify('Zip %s (in %s)' % (module_name, display_path(filename))) + logger.indent += 2 + if filename.endswith('.egg'): + dest_filename = filename + else: + dest_filename = filename + '.zip' + try: + # FIXME: I think this needs to be undoable: + if filename == dest_filename: + filename = backup_dir(orig_filename) + logger.notify( + 'Moving %s aside to %s' % (orig_filename, filename) + ) + if not self.simulate: + shutil.move(orig_filename, filename) + try: + logger.info( + 'Creating zip file in %s' % display_path(dest_filename) + ) + if not self.simulate: + zip = zipfile.ZipFile(dest_filename, 'w') + zip.writestr(module_name + '/', '') + for dirpath, dirnames, filenames in os.walk(filename): + if no_pyc: + filenames = [f for f in filenames + if not f.lower().endswith('.pyc')] + for fns, is_dir in [ + (dirnames, True), (filenames, False)]: + for fn in fns: + full = os.path.join(dirpath, fn) + dest = os.path.join( + module_name, + dirpath[len(filename):].lstrip( + os.path.sep + ), + fn, + ) + if is_dir: + zip.writestr(dest + '/', '') + else: + zip.write(full, dest) + zip.close() + logger.info( + 'Removing old directory %s' % display_path(filename) + ) + if not self.simulate: + rmtree(filename) + except: + # FIXME: need to do an undo here + raise + # FIXME: should also be undone: + self.add_filename_to_pth(dest_filename) + finally: + logger.indent -= 2 + + def remove_filename_from_pth(self, filename): + for pth in self.pth_files(): + f = open(pth, 'r') + lines = f.readlines() + f.close() + new_lines = [ + l for l in lines if l.strip() != filename] + if lines != new_lines: + logger.info('Removing reference to %s from .pth file %s' + % (display_path(filename), display_path(pth))) + if not [line for line in new_lines if line]: + logger.info( + '%s file would be empty: deleting' % display_path(pth) + ) + if not self.simulate: + os.unlink(pth) + else: + if not self.simulate: + f = open(pth, 'wb') + f.writelines(new_lines) + f.close() + return + logger.warn( + 'Cannot find a reference to %s in any .pth file' % + display_path(filename) + ) + + def add_filename_to_pth(self, filename): + path = os.path.dirname(filename) + dest = filename + '.pth' + if path not in self.paths(): + logger.warn( + 'Adding .pth file %s, but it is not on sys.path' % + display_path(dest) + ) + if not self.simulate: + if os.path.exists(dest): + f = open(dest) + lines = f.readlines() + f.close() + if lines and not lines[-1].endswith('\n'): + lines[-1] += '\n' + lines.append(filename + '\n') + else: + lines = [filename + '\n'] + f = open(dest, 'wb') + f.writelines(lines) + f.close() + + def pth_files(self): + for path in self.paths(): + if not os.path.exists(path) or not os.path.isdir(path): + continue + for filename in os.listdir(path): + if filename.endswith('.pth'): + yield os.path.join(path, filename) + + def find_package(self, package): + for path in self.paths(): + full = os.path.join(path, package) + if os.path.exists(full): + return package, full + if not os.path.isdir(path) and zipfile.is_zipfile(path): + zip = zipfile.ZipFile(path, 'r') + try: + zip.read(os.path.join(package, '__init__.py')) + except KeyError: + pass + else: + zip.close() + return package, full + zip.close() + # FIXME: need special error for package.py case: + raise InstallationError( + 'No package with the name %s found' % package) + + def list(self, options, args): + if args: + raise InstallationError( + 'You cannot give an argument with --list') + for path in sorted(self.paths()): + if not os.path.exists(path): + continue + basename = os.path.basename(path.rstrip(os.path.sep)) + if os.path.isfile(path) and zipfile.is_zipfile(path): + if os.path.dirname(path) not in self.paths(): + logger.notify('Zipped egg: %s' % display_path(path)) + continue + if (basename != 'site-packages' + and basename != 'dist-packages' + and not path.replace('\\', '/').endswith('lib/python')): + continue + logger.notify('In %s:' % display_path(path)) + logger.indent += 2 + zipped = [] + unzipped = [] + try: + for filename in sorted(os.listdir(path)): + ext = os.path.splitext(filename)[1].lower() + if ext in ('.pth', '.egg-info', '.egg-link'): + continue + if ext == '.py': + logger.info( + 'Not displaying %s: not a package' % + display_path(filename) + ) + continue + full = os.path.join(path, filename) + if os.path.isdir(full): + unzipped.append((filename, self.count_package(full))) + elif zipfile.is_zipfile(full): + zipped.append(filename) + else: + logger.info( + 'Unknown file: %s' % display_path(filename) + ) + if zipped: + logger.notify('Zipped packages:') + logger.indent += 2 + try: + for filename in zipped: + logger.notify(filename) + finally: + logger.indent -= 2 + else: + logger.notify('No zipped packages.') + if unzipped: + if options.sort_files: + unzipped.sort(key=lambda x: -x[1]) + logger.notify('Unzipped packages:') + logger.indent += 2 + try: + for filename, count in unzipped: + logger.notify('%s (%i files)' % (filename, count)) + finally: + logger.indent -= 2 + else: + logger.notify('No unzipped packages.') + finally: + logger.indent -= 2 + + def count_package(self, path): + total = 0 + for dirpath, dirnames, filenames in os.walk(path): + filenames = [f for f in filenames + if not f.lower().endswith('.pyc')] + total += len(filenames) + return total -- cgit 1.2.3-korg