text: """
  Create a wheel (.whl) distribution.
  
  A wheel is a built archive format.
  """
  
  import os
  import shutil
  import sys
  import re
  from email.generator import Generator
  from distutils.core import Command
  from distutils.sysconfig import get_python_version
  from distutils import log as logger
  from glob import iglob
  from shutil import rmtree
  from warnings import warn
  
  import pkg_resources
  
  from .pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag, get_platform
  from .pkginfo import write_pkg_info
  from .metadata import pkginfo_to_metadata
  from .wheelfile import WheelFile
  from . import pep425tags
  from . import __version__ as wheel_version
  
  
  safe_name = pkg_resources.safe_name
  safe_version = pkg_resources.safe_version
  
  PY_LIMITED_API_PATTERN = r'cp3\d'
  
  
  def safer_name(name):
      return safe_name(name).replace('-', '_')
  
  
  def safer_version(version):
      return safe_version(version).replace('-', '_')
  
  
  class bdist_wheel(Command):
  
      description = 'create a wheel distribution'
  
      user_options = [('bdist-dir=', 'b',
                       "temporary directory for creating the distribution"),
                      ('plat-name=', 'p',
                       "platform name to embed in generated filenames "
                       "(default: %s)" % get_platform()),
                      ('keep-temp', 'k',
                       "keep the pseudo-installation tree around after " +
                       "creating the distribution archive"),
                      ('dist-dir=', 'd',
                       "directory to put final built distributions in"),
                      ('skip-build', None,
                       "skip rebuilding everything (for testing/debugging)"),
                      ('relative', None,
                       "build the archive using relative paths"
                       "(default: false)"),
                      ('owner=', 'u',
                       "Owner name used when creating a tar file"
                       " [default: current user]"),
                      ('group=', 'g',
                       "Group name used when creating a tar file"
                       " [default: current group]"),
                      ('universal', None,
                       "make a universal wheel"
                       " (default: false)"),
                      ('python-tag=', None,
                       "Python implementation compatibility tag"
                       " (default: py%s)" % get_impl_ver()[0]),
                      ('build-number=', None,
                       "Build number for this particular version. "
                       "As specified in PEP-0427, this must start with a digit. "
                       "[default: None]"),
                      ('py-limited-api=', None,
                       "Python tag (cp32|cp33|cpNN) for abi3 wheel tag"
                       " (default: false)"),
                      ]
  
      boolean_options = ['keep-temp', 'skip-build', 'relative', 'universal']
  
      def initialize_options(self):
          self.bdist_dir = None
          self.data_dir = None
          self.plat_name = None
          self.plat_tag = None
          self.format = 'zip'
          self.keep_temp = False
          self.dist_dir = None
          self.egginfo_dir = None
          self.root_is_pure = None
          self.skip_build = None
          self.relative = False
          self.owner = None
          self.group = None
          self.universal = False
          self.python_tag = 'py' + get_impl_ver()[0]
          self.build_number = None
          self.py_limited_api = False
          self.plat_name_supplied = False
  
      def finalize_options(self):
          if self.bdist_dir is None:
              bdist_base = self.get_finalized_command('bdist').bdist_base
              self.bdist_dir = os.path.join(bdist_base, 'wheel')
  
          self.data_dir = self.wheel_dist_name + '.data'
          self.plat_name_supplied = self.plat_name is not None
  
          need_options = ('dist_dir', 'plat_name', 'skip_build')
  
          self.set_undefined_options('bdist',
                                     *zip(need_options, need_options))
  
          self.root_is_pure = not (self.distribution.has_ext_modules()
                                   or self.distribution.has_c_libraries())
  
          if self.py_limited_api and not re.match(PY_LIMITED_API_PATTERN, self.py_limited_api):
              raise ValueError("py-limited-api must match '%s'" % PY_LIMITED_API_PATTERN)
  
          # Support legacy [wheel] section for setting universal
          wheel = self.distribution.get_option_dict('wheel')
          if 'universal' in wheel:
              # please don't define this in your global configs
              logger.warn('The [wheel] section is deprecated. Use [bdist_wheel] instead.')
              val = wheel['universal'][1].strip()
              if val.lower() in ('1', 'true', 'yes'):
                  self.universal = True
  
          if self.build_number is not None and not self.build_number[:1].isdigit():
              raise ValueError("Build tag (build-number) must start with a digit.")
  
      @property
      def wheel_dist_name(self):
          """Return distribution full name with - replaced with _"""
          components = (safer_name(self.distribution.get_name()),
                        safer_version(self.distribution.get_version()))
          if self.build_number:
              components += (self.build_number,)
          return '-'.join(components)
  
      def get_tag(self):
          # bdist sets self.plat_name if unset, we should only use it for purepy
          # wheels if the user supplied it.
          if self.plat_name_supplied:
              plat_name = self.plat_name
          elif self.root_is_pure:
              plat_name = 'any'
          else:
              plat_name = self.plat_name or get_platform()
              if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize == 2147483647:
                  plat_name = 'linux_i686'
          plat_name = plat_name.replace('-', '_').replace('.', '_')
  
          if self.root_is_pure:
              if self.universal:
                  impl = 'py2.py3'
              else:
                  impl = self.python_tag
              tag = (impl, 'none', plat_name)
          else:
              impl_name = get_abbr_impl()
              impl_ver = get_impl_ver()
              impl = impl_name + impl_ver
              # We don't work on CPython 3.1, 3.0.
              if self.py_limited_api and (impl_name + impl_ver).startswith('cp3'):
                  impl = self.py_limited_api
                  abi_tag = 'abi3'
              else:
                  abi_tag = str(get_abi_tag()).lower()
              tag = (impl, abi_tag, plat_name)
              supported_tags = pep425tags.get_supported(
                  supplied_platform=plat_name if self.plat_name_supplied else None)
              # XXX switch to this alternate implementation for non-pure:
              if not self.py_limited_api:
                  assert tag == supported_tags[0], "%s != %s" % (tag, supported_tags[0])
              assert tag in supported_tags, "would build wheel with unsupported tag {}".format(tag)
          return tag
  
      def run(self):
          build_scripts = self.reinitialize_command('build_scripts')
          build_scripts.executable = 'python'
  
          if not self.skip_build:
              self.run_command('build')
  
          install = self.reinitialize_command('install',
                                              reinit_subcommands=True)
          install.root = self.bdist_dir
          install.compile = False
          install.skip_build = self.skip_build
          install.warn_dir = False
  
          # A wheel without setuptools scripts is more cross-platform.
          # Use the (undocumented) `no_ep` option to setuptools'
          # install_scripts command to avoid creating entry point scripts.
          install_scripts = self.reinitialize_command('install_scripts')
          install_scripts.no_ep = True
  
          # Use a custom scheme for the archive, because we have to decide
          # at installation time which scheme to use.
          for key in ('headers', 'scripts', 'data', 'purelib', 'platlib'):
              setattr(install,
                      'install_' + key,
                      os.path.join(self.data_dir, key))
  
          basedir_observed = ''
  
          if os.name == 'nt':
              # win32 barfs if any of these are ''; could be '.'?
              # (distutils.command.install:change_roots bug)
              basedir_observed = os.path.normpath(os.path.join(self.data_dir, '..'))
              self.install_libbase = self.install_lib = basedir_observed
  
          setattr(install,
                  'install_purelib' if self.root_is_pure else 'install_platlib',
                  basedir_observed)
  
          logger.info("installing to %s", self.bdist_dir)
  
          self.run_command('install')
  
          impl_tag, abi_tag, plat_tag = self.get_tag()
          archive_basename = "{}-{}-{}-{}".format(self.wheel_dist_name, impl_tag, abi_tag, plat_tag)
          if not self.relative:
              archive_root = self.bdist_dir
          else:
              archive_root = os.path.join(
                  self.bdist_dir,
                  self._ensure_relative(install.install_base))
  
          self.set_undefined_options('install_egg_info', ('target', 'egginfo_dir'))
          distinfo_dirname = '{}-{}.dist-info'.format(
              safer_name(self.distribution.get_name()),
              safer_version(self.distribution.get_version()))
          distinfo_dir = os.path.join(self.bdist_dir, distinfo_dirname)
          self.egg2dist(self.egginfo_dir, distinfo_dir)
  
          self.write_wheelfile(distinfo_dir)
  
          # Make the archive
          if not os.path.exists(self.dist_dir):
              os.makedirs(self.dist_dir)
  
          wheel_path = os.path.join(self.dist_dir, archive_basename + '.whl')
          with WheelFile(wheel_path, 'w') as wf:
              wf.write_files(archive_root)
  
          # Add to 'Distribution.dist_files' so that the "upload" command works
          getattr(self.distribution, 'dist_files', []).append(
              ('bdist_wheel', get_python_version(), wheel_path))
  
          if not self.keep_temp:
              logger.info('removing %s', self.bdist_dir)
              if not self.dry_run:
                  rmtree(self.bdist_dir)
  
      def write_wheelfile(self, wheelfile_base, generator='bdist_wheel (' + wheel_version + ')'):
          from email.message import Message
          msg = Message()
          msg['Wheel-Version'] = '1.0'  # of the spec
          msg['Generator'] = generator
          msg['Root-Is-Purelib'] = str(self.root_is_pure).lower()
          if self.build_number is not None:
              msg['Build'] = self.build_number
  
          # Doesn't work for bdist_wininst
          impl_tag, abi_tag, plat_tag = self.get_tag()
          for impl in impl_tag.split('.'):
              for abi in abi_tag.split('.'):
                  for plat in plat_tag.split('.'):
                      msg['Tag'] = '-'.join((impl, abi, plat))
  
          wheelfile_path = os.path.join(wheelfile_base, 'WHEEL')
          logger.info('creating %s', wheelfile_path)
          with open(wheelfile_path, 'w') as f:
              Generator(f, maxheaderlen=0).flatten(msg)
  
      def _ensure_relative(self, path):
          # copied from dir_util, deleted
          drive, path = os.path.splitdrive(path)
          if path[0:1] == os.sep:
              path = drive + path[1:]
          return path
  
      @property
      def license_paths(self):
          metadata = self.distribution.get_option_dict('metadata')
          files = set()
          patterns = sorted({
              option for option in metadata.get('license_files', ('', ''))[1].split()
          })
  
          if 'license_file' in metadata:
              warn('The "license_file" option is deprecated. Use "license_files" instead.',
                   DeprecationWarning)
              files.add(metadata['license_file'][1])
  
          if 'license_file' not in metadata and 'license_files' not in metadata:
              patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')
  
          for pattern in patterns:
              for path in iglob(pattern):
                  if path not in files and os.path.isfile(path):
                      logger.info('adding license file "%s" (matched pattern "%s")', path, pattern)
                      files.add(path)
  
          return files
  
      def egg2dist(self, egginfo_path, distinfo_path):
          """Convert an .egg-info directory into a .dist-info directory"""
          def adios(p):
              """Appropriately delete directory, file or link."""
              if os.path.exists(p) and not os.path.islink(p) and os.path.isdir(p):
                  shutil.rmtree(p)
              elif os.path.exists(p):
                  os.unlink(p)
  
          adios(distinfo_path)
  
          if not os.path.exists(egginfo_path):
              # There is no egg-info. This is probably because the egg-info
              # file/directory is not named matching the distribution name used
              # to name the archive file. Check for this case and report
              # accordingly.
              import glob
              pat = os.path.join(os.path.dirname(egginfo_path), '*.egg-info')
              possible = glob.glob(pat)
              err = "Egg metadata expected at %s but not found" % (egginfo_path,)
              if possible:
                  alt = os.path.basename(possible[0])
                  err += " (%s found - possible misnamed archive file?)" % (alt,)
  
              raise ValueError(err)
  
          if os.path.isfile(egginfo_path):
              # .egg-info is a single file
              pkginfo_path = egginfo_path
              pkg_info = pkginfo_to_metadata(egginfo_path, egginfo_path)
              os.mkdir(distinfo_path)
          else:
              # .egg-info is a directory
              pkginfo_path = os.path.join(egginfo_path, 'PKG-INFO')
              pkg_info = pkginfo_to_metadata(egginfo_path, pkginfo_path)
  
              # ignore common egg metadata that is useless to wheel
              shutil.copytree(egginfo_path, distinfo_path,
                              ignore=lambda x, y: {'PKG-INFO', 'requires.txt', 'SOURCES.txt',
                                                   'not-zip-safe'}
                              )
  
              # delete dependency_links if it is only whitespace
              dependency_links_path = os.path.join(distinfo_path, 'dependency_links.txt')
              with open(dependency_links_path, 'r') as dependency_links_file:
                  dependency_links = dependency_links_file.read().strip()
              if not dependency_links:
                  adios(dependency_links_path)
  
          write_pkg_info(os.path.join(distinfo_path, 'METADATA'), pkg_info)
  
          for license_path in self.license_paths:
              filename = os.path.basename(license_path)
              shutil.copy(license_path, os.path.join(distinfo_path, filename))
  
          adios(egginfo_path)
  