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.
 
 
 
 

140 lines
4.9 KiB

  1. from __future__ import absolute_import
  2. import logging
  3. import os
  4. import tempfile
  5. import re
  6. from pip.utils import display_path, rmtree
  7. from pip.vcs import vcs, VersionControl
  8. from pip.download import path_to_url
  9. from pip._vendor.six.moves import configparser
  10. logger = logging.getLogger(__name__)
  11. class Mercurial(VersionControl):
  12. name = 'hg'
  13. dirname = '.hg'
  14. repo_name = 'clone'
  15. schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http')
  16. def export(self, location):
  17. """Export the Hg repository at the url to the destination location"""
  18. temp_dir = tempfile.mkdtemp('-export', 'pip-')
  19. self.unpack(temp_dir)
  20. try:
  21. self.run_command(
  22. ['archive', location], show_stdout=False, cwd=temp_dir)
  23. finally:
  24. rmtree(temp_dir)
  25. def switch(self, dest, url, rev_options):
  26. repo_config = os.path.join(dest, self.dirname, 'hgrc')
  27. config = configparser.SafeConfigParser()
  28. try:
  29. config.read(repo_config)
  30. config.set('paths', 'default', url)
  31. with open(repo_config, 'w') as config_file:
  32. config.write(config_file)
  33. except (OSError, configparser.NoSectionError) as exc:
  34. logger.warning(
  35. 'Could not switch Mercurial repository to %s: %s', url, exc,
  36. )
  37. else:
  38. self.run_command(['update', '-q'] + rev_options, cwd=dest)
  39. def update(self, dest, rev_options):
  40. self.run_command(['pull', '-q'], cwd=dest)
  41. self.run_command(['update', '-q'] + rev_options, cwd=dest)
  42. def obtain(self, dest):
  43. url, rev = self.get_url_rev()
  44. if rev:
  45. rev_options = [rev]
  46. rev_display = ' (to revision %s)' % rev
  47. else:
  48. rev_options = []
  49. rev_display = ''
  50. if self.check_destination(dest, url, rev_options, rev_display):
  51. logger.info(
  52. 'Cloning hg %s%s to %s',
  53. url,
  54. rev_display,
  55. display_path(dest),
  56. )
  57. self.run_command(['clone', '--noupdate', '-q', url, dest])
  58. self.run_command(['update', '-q'] + rev_options, cwd=dest)
  59. def get_url(self, location):
  60. url = self.run_command(
  61. ['showconfig', 'paths.default'],
  62. show_stdout=False, cwd=location).strip()
  63. if self._is_local_repository(url):
  64. url = path_to_url(url)
  65. return url.strip()
  66. def get_tag_revs(self, location):
  67. tags = self.run_command(['tags'], show_stdout=False, cwd=location)
  68. tag_revs = []
  69. for line in tags.splitlines():
  70. tags_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line)
  71. if tags_match:
  72. tag = tags_match.group(1)
  73. rev = tags_match.group(2)
  74. if "tip" != tag:
  75. tag_revs.append((rev.strip(), tag.strip()))
  76. return dict(tag_revs)
  77. def get_branch_revs(self, location):
  78. branches = self.run_command(
  79. ['branches'], show_stdout=False, cwd=location)
  80. branch_revs = []
  81. for line in branches.splitlines():
  82. branches_match = re.search(r'([\w\d\.-]+)\s*([\d]+):.*$', line)
  83. if branches_match:
  84. branch = branches_match.group(1)
  85. rev = branches_match.group(2)
  86. if "default" != branch:
  87. branch_revs.append((rev.strip(), branch.strip()))
  88. return dict(branch_revs)
  89. def get_revision(self, location):
  90. current_revision = self.run_command(
  91. ['parents', '--template={rev}'],
  92. show_stdout=False, cwd=location).strip()
  93. return current_revision
  94. def get_revision_hash(self, location):
  95. current_rev_hash = self.run_command(
  96. ['parents', '--template={node}'],
  97. show_stdout=False, cwd=location).strip()
  98. return current_rev_hash
  99. def get_src_requirement(self, dist, location, find_tags):
  100. repo = self.get_url(location)
  101. if not repo.lower().startswith('hg:'):
  102. repo = 'hg+' + repo
  103. egg_project_name = dist.egg_name().split('-', 1)[0]
  104. if not repo:
  105. return None
  106. current_rev = self.get_revision(location)
  107. current_rev_hash = self.get_revision_hash(location)
  108. tag_revs = self.get_tag_revs(location)
  109. branch_revs = self.get_branch_revs(location)
  110. if current_rev in tag_revs:
  111. # It's a tag
  112. full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev])
  113. elif current_rev in branch_revs:
  114. # It's the tip of a branch
  115. full_egg_name = '%s-%s' % (
  116. egg_project_name,
  117. branch_revs[current_rev],
  118. )
  119. else:
  120. full_egg_name = '%s-dev' % egg_project_name
  121. return '%s@%s#egg=%s' % (repo, current_rev_hash, full_egg_name)
  122. vcs.register(Mercurial)