Mercurial > repos > bcclaywell > argo_navis
comparison venv/lib/python2.7/site-packages/pip/vcs/git.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
| author | bcclaywell |
|---|---|
| date | Mon, 12 Oct 2015 17:43:33 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d67268158946 |
|---|---|
| 1 from __future__ import absolute_import | |
| 2 | |
| 3 import logging | |
| 4 import tempfile | |
| 5 import os.path | |
| 6 | |
| 7 from pip._vendor.six.moves.urllib import parse as urllib_parse | |
| 8 from pip._vendor.six.moves.urllib import request as urllib_request | |
| 9 | |
| 10 from pip.utils import display_path, rmtree | |
| 11 from pip.vcs import vcs, VersionControl | |
| 12 | |
| 13 | |
| 14 urlsplit = urllib_parse.urlsplit | |
| 15 urlunsplit = urllib_parse.urlunsplit | |
| 16 | |
| 17 | |
| 18 logger = logging.getLogger(__name__) | |
| 19 | |
| 20 | |
| 21 class Git(VersionControl): | |
| 22 name = 'git' | |
| 23 dirname = '.git' | |
| 24 repo_name = 'clone' | |
| 25 schemes = ( | |
| 26 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', | |
| 27 ) | |
| 28 | |
| 29 def __init__(self, url=None, *args, **kwargs): | |
| 30 | |
| 31 # Works around an apparent Git bug | |
| 32 # (see http://article.gmane.org/gmane.comp.version-control.git/146500) | |
| 33 if url: | |
| 34 scheme, netloc, path, query, fragment = urlsplit(url) | |
| 35 if scheme.endswith('file'): | |
| 36 initial_slashes = path[:-len(path.lstrip('/'))] | |
| 37 newpath = ( | |
| 38 initial_slashes + | |
| 39 urllib_request.url2pathname(path) | |
| 40 .replace('\\', '/').lstrip('/') | |
| 41 ) | |
| 42 url = urlunsplit((scheme, netloc, newpath, query, fragment)) | |
| 43 after_plus = scheme.find('+') + 1 | |
| 44 url = scheme[:after_plus] + urlunsplit( | |
| 45 (scheme[after_plus:], netloc, newpath, query, fragment), | |
| 46 ) | |
| 47 | |
| 48 super(Git, self).__init__(url, *args, **kwargs) | |
| 49 | |
| 50 def export(self, location): | |
| 51 """Export the Git repository at the url to the destination location""" | |
| 52 temp_dir = tempfile.mkdtemp('-export', 'pip-') | |
| 53 self.unpack(temp_dir) | |
| 54 try: | |
| 55 if not location.endswith('/'): | |
| 56 location = location + '/' | |
| 57 self.run_command( | |
| 58 ['checkout-index', '-a', '-f', '--prefix', location], | |
| 59 filter_stdout=self._filter, show_stdout=False, cwd=temp_dir) | |
| 60 finally: | |
| 61 rmtree(temp_dir) | |
| 62 | |
| 63 def check_rev_options(self, rev, dest, rev_options): | |
| 64 """Check the revision options before checkout to compensate that tags | |
| 65 and branches may need origin/ as a prefix. | |
| 66 Returns the SHA1 of the branch or tag if found. | |
| 67 """ | |
| 68 revisions = self.get_refs(dest) | |
| 69 | |
| 70 origin_rev = 'origin/%s' % rev | |
| 71 if origin_rev in revisions: | |
| 72 # remote branch | |
| 73 return [revisions[origin_rev]] | |
| 74 elif rev in revisions: | |
| 75 # a local tag or branch name | |
| 76 return [revisions[rev]] | |
| 77 else: | |
| 78 logger.warning( | |
| 79 "Could not find a tag or branch '%s', assuming commit.", rev, | |
| 80 ) | |
| 81 return rev_options | |
| 82 | |
| 83 def switch(self, dest, url, rev_options): | |
| 84 self.run_command(['config', 'remote.origin.url', url], cwd=dest) | |
| 85 self.run_command(['checkout', '-q'] + rev_options, cwd=dest) | |
| 86 | |
| 87 self.update_submodules(dest) | |
| 88 | |
| 89 def update(self, dest, rev_options): | |
| 90 # First fetch changes from the default remote | |
| 91 self.run_command(['fetch', '-q'], cwd=dest) | |
| 92 # Then reset to wanted revision (maby even origin/master) | |
| 93 if rev_options: | |
| 94 rev_options = self.check_rev_options( | |
| 95 rev_options[0], dest, rev_options, | |
| 96 ) | |
| 97 self.run_command(['reset', '--hard', '-q'] + rev_options, cwd=dest) | |
| 98 #: update submodules | |
| 99 self.update_submodules(dest) | |
| 100 | |
| 101 def obtain(self, dest): | |
| 102 url, rev = self.get_url_rev() | |
| 103 if rev: | |
| 104 rev_options = [rev] | |
| 105 rev_display = ' (to %s)' % rev | |
| 106 else: | |
| 107 rev_options = ['origin/master'] | |
| 108 rev_display = '' | |
| 109 if self.check_destination(dest, url, rev_options, rev_display): | |
| 110 logger.info( | |
| 111 'Cloning %s%s to %s', url, rev_display, display_path(dest), | |
| 112 ) | |
| 113 self.run_command(['clone', '-q', url, dest]) | |
| 114 | |
| 115 if rev: | |
| 116 rev_options = self.check_rev_options(rev, dest, rev_options) | |
| 117 # Only do a checkout if rev_options differs from HEAD | |
| 118 if not self.get_revision(dest).startswith(rev_options[0]): | |
| 119 self.run_command( | |
| 120 ['checkout', '-q'] + rev_options, | |
| 121 cwd=dest, | |
| 122 ) | |
| 123 #: repo may contain submodules | |
| 124 self.update_submodules(dest) | |
| 125 | |
| 126 def get_url(self, location): | |
| 127 url = self.run_command( | |
| 128 ['config', 'remote.origin.url'], | |
| 129 show_stdout=False, cwd=location) | |
| 130 return url.strip() | |
| 131 | |
| 132 def get_revision(self, location): | |
| 133 current_rev = self.run_command( | |
| 134 ['rev-parse', 'HEAD'], show_stdout=False, cwd=location) | |
| 135 return current_rev.strip() | |
| 136 | |
| 137 def get_refs(self, location): | |
| 138 """Return map of named refs (branches or tags) to commit hashes.""" | |
| 139 output = self.run_command(['show-ref'], | |
| 140 show_stdout=False, cwd=location) | |
| 141 rv = {} | |
| 142 for line in output.strip().splitlines(): | |
| 143 commit, ref = line.split(' ', 1) | |
| 144 ref = ref.strip() | |
| 145 ref_name = None | |
| 146 if ref.startswith('refs/remotes/'): | |
| 147 ref_name = ref[len('refs/remotes/'):] | |
| 148 elif ref.startswith('refs/heads/'): | |
| 149 ref_name = ref[len('refs/heads/'):] | |
| 150 elif ref.startswith('refs/tags/'): | |
| 151 ref_name = ref[len('refs/tags/'):] | |
| 152 if ref_name is not None: | |
| 153 rv[ref_name] = commit.strip() | |
| 154 return rv | |
| 155 | |
| 156 def get_src_requirement(self, dist, location, find_tags): | |
| 157 repo = self.get_url(location) | |
| 158 if not repo.lower().startswith('git:'): | |
| 159 repo = 'git+' + repo | |
| 160 egg_project_name = dist.egg_name().split('-', 1)[0] | |
| 161 if not repo: | |
| 162 return None | |
| 163 current_rev = self.get_revision(location) | |
| 164 refs = self.get_refs(location) | |
| 165 # refs maps names to commit hashes; we need the inverse | |
| 166 # if multiple names map to a single commit, we pick the first one | |
| 167 # alphabetically | |
| 168 names_by_commit = {} | |
| 169 for ref, commit in sorted(refs.items()): | |
| 170 if commit not in names_by_commit: | |
| 171 names_by_commit[commit] = ref | |
| 172 | |
| 173 if current_rev in names_by_commit: | |
| 174 # It's a tag or branch. | |
| 175 name = names_by_commit[current_rev] | |
| 176 full_egg_name = ( | |
| 177 '%s-%s' % (egg_project_name, self.translate_egg_surname(name)) | |
| 178 ) | |
| 179 else: | |
| 180 full_egg_name = '%s-dev' % egg_project_name | |
| 181 | |
| 182 return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name) | |
| 183 | |
| 184 def get_url_rev(self): | |
| 185 """ | |
| 186 Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. | |
| 187 That's required because although they use SSH they sometimes doesn't | |
| 188 work with a ssh:// scheme (e.g. Github). But we need a scheme for | |
| 189 parsing. Hence we remove it again afterwards and return it as a stub. | |
| 190 """ | |
| 191 if '://' not in self.url: | |
| 192 assert 'file:' not in self.url | |
| 193 self.url = self.url.replace('git+', 'git+ssh://') | |
| 194 url, rev = super(Git, self).get_url_rev() | |
| 195 url = url.replace('ssh://', '') | |
| 196 else: | |
| 197 url, rev = super(Git, self).get_url_rev() | |
| 198 | |
| 199 return url, rev | |
| 200 | |
| 201 def update_submodules(self, location): | |
| 202 if not os.path.exists(os.path.join(location, '.gitmodules')): | |
| 203 return | |
| 204 self.run_command( | |
| 205 ['submodule', 'update', '--init', '--recursive', '-q'], | |
| 206 cwd=location, | |
| 207 ) | |
| 208 | |
| 209 vcs.register(Git) |
