diff env/lib/python3.9/site-packages/pip/_internal/commands/cache.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/pip/_internal/commands/cache.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,232 @@
+import logging
+import os
+import textwrap
+
+import pip._internal.utils.filesystem as filesystem
+from pip._internal.cli.base_command import Command
+from pip._internal.cli.status_codes import ERROR, SUCCESS
+from pip._internal.exceptions import CommandError, PipError
+from pip._internal.utils.typing import MYPY_CHECK_RUNNING
+
+if MYPY_CHECK_RUNNING:
+    from optparse import Values
+    from typing import Any, List
+
+
+logger = logging.getLogger(__name__)
+
+
+class CacheCommand(Command):
+    """
+    Inspect and manage pip's wheel cache.
+
+    Subcommands:
+
+    - dir: Show the cache directory.
+    - info: Show information about the cache.
+    - list: List filenames of packages stored in the cache.
+    - remove: Remove one or more package from the cache.
+    - purge: Remove all items from the cache.
+
+    ``<pattern>`` can be a glob expression or a package name.
+    """
+
+    ignore_require_venv = True
+    usage = """
+        %prog dir
+        %prog info
+        %prog list [<pattern>] [--format=[human, abspath]]
+        %prog remove <pattern>
+        %prog purge
+    """
+
+    def add_options(self):
+        # type: () -> None
+
+        self.cmd_opts.add_option(
+            '--format',
+            action='store',
+            dest='list_format',
+            default="human",
+            choices=('human', 'abspath'),
+            help="Select the output format among: human (default) or abspath"
+        )
+
+        self.parser.insert_option_group(0, self.cmd_opts)
+
+    def run(self, options, args):
+        # type: (Values, List[Any]) -> int
+        handlers = {
+            "dir": self.get_cache_dir,
+            "info": self.get_cache_info,
+            "list": self.list_cache_items,
+            "remove": self.remove_cache_items,
+            "purge": self.purge_cache,
+        }
+
+        if not options.cache_dir:
+            logger.error("pip cache commands can not "
+                         "function since cache is disabled.")
+            return ERROR
+
+        # Determine action
+        if not args or args[0] not in handlers:
+            logger.error(
+                "Need an action (%s) to perform.",
+                ", ".join(sorted(handlers)),
+            )
+            return ERROR
+
+        action = args[0]
+
+        # Error handling happens here, not in the action-handlers.
+        try:
+            handlers[action](options, args[1:])
+        except PipError as e:
+            logger.error(e.args[0])
+            return ERROR
+
+        return SUCCESS
+
+    def get_cache_dir(self, options, args):
+        # type: (Values, List[Any]) -> None
+        if args:
+            raise CommandError('Too many arguments')
+
+        logger.info(options.cache_dir)
+
+    def get_cache_info(self, options, args):
+        # type: (Values, List[Any]) -> None
+        if args:
+            raise CommandError('Too many arguments')
+
+        num_http_files = len(self._find_http_files(options))
+        num_packages = len(self._find_wheels(options, '*'))
+
+        http_cache_location = self._cache_dir(options, 'http')
+        wheels_cache_location = self._cache_dir(options, 'wheels')
+        http_cache_size = filesystem.format_directory_size(http_cache_location)
+        wheels_cache_size = filesystem.format_directory_size(
+            wheels_cache_location
+        )
+
+        message = textwrap.dedent("""
+            Package index page cache location: {http_cache_location}
+            Package index page cache size: {http_cache_size}
+            Number of HTTP files: {num_http_files}
+            Wheels location: {wheels_cache_location}
+            Wheels size: {wheels_cache_size}
+            Number of wheels: {package_count}
+        """).format(
+            http_cache_location=http_cache_location,
+            http_cache_size=http_cache_size,
+            num_http_files=num_http_files,
+            wheels_cache_location=wheels_cache_location,
+            package_count=num_packages,
+            wheels_cache_size=wheels_cache_size,
+        ).strip()
+
+        logger.info(message)
+
+    def list_cache_items(self, options, args):
+        # type: (Values, List[Any]) -> None
+        if len(args) > 1:
+            raise CommandError('Too many arguments')
+
+        if args:
+            pattern = args[0]
+        else:
+            pattern = '*'
+
+        files = self._find_wheels(options, pattern)
+        if options.list_format == 'human':
+            self.format_for_human(files)
+        else:
+            self.format_for_abspath(files)
+
+    def format_for_human(self, files):
+        # type: (List[str]) -> None
+        if not files:
+            logger.info('Nothing cached.')
+            return
+
+        results = []
+        for filename in files:
+            wheel = os.path.basename(filename)
+            size = filesystem.format_file_size(filename)
+            results.append(f' - {wheel} ({size})')
+        logger.info('Cache contents:\n')
+        logger.info('\n'.join(sorted(results)))
+
+    def format_for_abspath(self, files):
+        # type: (List[str]) -> None
+        if not files:
+            return
+
+        results = []
+        for filename in files:
+            results.append(filename)
+
+        logger.info('\n'.join(sorted(results)))
+
+    def remove_cache_items(self, options, args):
+        # type: (Values, List[Any]) -> None
+        if len(args) > 1:
+            raise CommandError('Too many arguments')
+
+        if not args:
+            raise CommandError('Please provide a pattern')
+
+        files = self._find_wheels(options, args[0])
+
+        # Only fetch http files if no specific pattern given
+        if args[0] == '*':
+            files += self._find_http_files(options)
+
+        if not files:
+            raise CommandError('No matching packages')
+
+        for filename in files:
+            os.unlink(filename)
+            logger.debug('Removed %s', filename)
+        logger.info('Files removed: %s', len(files))
+
+    def purge_cache(self, options, args):
+        # type: (Values, List[Any]) -> None
+        if args:
+            raise CommandError('Too many arguments')
+
+        return self.remove_cache_items(options, ['*'])
+
+    def _cache_dir(self, options, subdir):
+        # type: (Values, str) -> str
+        return os.path.join(options.cache_dir, subdir)
+
+    def _find_http_files(self, options):
+        # type: (Values) -> List[str]
+        http_dir = self._cache_dir(options, 'http')
+        return filesystem.find_files(http_dir, '*')
+
+    def _find_wheels(self, options, pattern):
+        # type: (Values, str) -> List[str]
+        wheel_dir = self._cache_dir(options, 'wheels')
+
+        # The wheel filename format, as specified in PEP 427, is:
+        #     {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl
+        #
+        # Additionally, non-alphanumeric values in the distribution are
+        # normalized to underscores (_), meaning hyphens can never occur
+        # before `-{version}`.
+        #
+        # Given that information:
+        # - If the pattern we're given contains a hyphen (-), the user is
+        #   providing at least the version. Thus, we can just append `*.whl`
+        #   to match the rest of it.
+        # - If the pattern we're given doesn't contain a hyphen (-), the
+        #   user is only providing the name. Thus, we append `-*.whl` to
+        #   match the hyphen before the version, followed by anything else.
+        #
+        # PEP 427: https://www.python.org/dev/peps/pep-0427/
+        pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl")
+
+        return filesystem.find_files(wheel_dir, pattern)