You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

115 lines
3.9 KiB

  1. from __future__ import absolute_import
  2. import logging
  3. import re
  4. import pip
  5. from pip.compat import stdlib_pkgs
  6. from pip.req import InstallRequirement
  7. from pip.utils import get_installed_distributions
  8. from pip._vendor import pkg_resources
  9. logger = logging.getLogger(__name__)
  10. # packages to exclude from freeze output
  11. freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute']
  12. def freeze(
  13. requirement=None,
  14. find_links=None, local_only=None, user_only=None, skip_regex=None,
  15. find_tags=False,
  16. default_vcs=None,
  17. isolated=False,
  18. wheel_cache=None):
  19. find_links = find_links or []
  20. skip_match = None
  21. if skip_regex:
  22. skip_match = re.compile(skip_regex)
  23. dependency_links = []
  24. for dist in pkg_resources.working_set:
  25. if dist.has_metadata('dependency_links.txt'):
  26. dependency_links.extend(
  27. dist.get_metadata_lines('dependency_links.txt')
  28. )
  29. for link in find_links:
  30. if '#egg=' in link:
  31. dependency_links.append(link)
  32. for link in find_links:
  33. yield '-f %s' % link
  34. installations = {}
  35. for dist in get_installed_distributions(local_only=local_only,
  36. skip=freeze_excludes,
  37. user_only=user_only):
  38. req = pip.FrozenRequirement.from_dist(
  39. dist,
  40. dependency_links,
  41. find_tags=find_tags,
  42. )
  43. installations[req.name] = req
  44. if requirement:
  45. with open(requirement) as req_file:
  46. for line in req_file:
  47. if (not line.strip() or
  48. line.strip().startswith('#') or
  49. (skip_match and skip_match.search(line)) or
  50. line.startswith((
  51. '-r', '--requirement',
  52. '-Z', '--always-unzip',
  53. '-f', '--find-links',
  54. '-i', '--index-url',
  55. '--extra-index-url'))):
  56. yield line.rstrip()
  57. continue
  58. if line.startswith('-e') or line.startswith('--editable'):
  59. if line.startswith('-e'):
  60. line = line[2:].strip()
  61. else:
  62. line = line[len('--editable'):].strip().lstrip('=')
  63. line_req = InstallRequirement.from_editable(
  64. line,
  65. default_vcs=default_vcs,
  66. isolated=isolated,
  67. wheel_cache=wheel_cache,
  68. )
  69. else:
  70. line_req = InstallRequirement.from_line(
  71. line,
  72. isolated=isolated,
  73. wheel_cache=wheel_cache,
  74. )
  75. if not line_req.name:
  76. logger.info(
  77. "Skipping line because it's not clear what it "
  78. "would install: %s",
  79. line.strip(),
  80. )
  81. logger.info(
  82. " (add #egg=PackageName to the URL to avoid"
  83. " this warning)"
  84. )
  85. elif line_req.name not in installations:
  86. logger.warning(
  87. "Requirement file contains %s, but that package is"
  88. " not installed",
  89. line.strip(),
  90. )
  91. else:
  92. yield str(installations[line_req.name]).rstrip()
  93. del installations[line_req.name]
  94. yield(
  95. '## The following requirements were added by '
  96. 'pip freeze:'
  97. )
  98. for installation in sorted(
  99. installations.values(), key=lambda x: x.name.lower()):
  100. yield str(installation).rstrip()