mercurial.py 5.0 KB

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