diff options
| author | Shawn O. Pearce <sop@google.com> | 2011-09-19 08:05:31 -0700 |
|---|---|---|
| committer | Shawn O. Pearce <sop@google.com> | 2011-09-19 14:51:47 -0700 |
| commit | 334851e4b6390f4c78e463b977003f1d967c88ed (patch) | |
| tree | 7c8c5004c7cbb3079b460aee97095955013147ff | |
| parent | 014d0609899dba70a1af0b32de377ca08c54aded (diff) | |
| download | git-repo-334851e4b6390f4c78e463b977003f1d967c88ed.tar.gz | |
Enhance HTTP support
Setting REPO_CURL_VERBOSE=1 in the environment will register a debug
level HTTPHandler on the urllib2 library, showing HTTP requests and
responses on the stderr channel of repo.
During any HTTP or HTTPS request created inside of the repo process,
a custom User-Agent header is now defined:
User-Agent: git-repo/1.7.5 (Linux) git/1.7.7 Python/2.6.5
Change-Id: Ia5026fb1e1500659bd2af27416d85e205048bf26
Signed-off-by: Shawn O. Pearce <sop@google.com>
| -rw-r--r-- | git_command.py | 35 | ||||
| -rwxr-xr-x | main.py | 60 |
2 files changed, 77 insertions, 18 deletions
diff --git a/git_command.py b/git_command.py index 513b9ebf..d1e0c971 100644 --- a/git_command.py +++ b/git_command.py | |||
| @@ -72,6 +72,8 @@ def terminate_ssh_clients(): | |||
| 72 | pass | 72 | pass |
| 73 | _ssh_clients = [] | 73 | _ssh_clients = [] |
| 74 | 74 | ||
| 75 | _git_version = None | ||
| 76 | |||
| 75 | class _GitCall(object): | 77 | class _GitCall(object): |
| 76 | def version(self): | 78 | def version(self): |
| 77 | p = GitCommand(None, ['--version'], capture_stdout=True) | 79 | p = GitCommand(None, ['--version'], capture_stdout=True) |
| @@ -79,6 +81,21 @@ class _GitCall(object): | |||
| 79 | return p.stdout | 81 | return p.stdout |
| 80 | return None | 82 | return None |
| 81 | 83 | ||
| 84 | def version_tuple(self): | ||
| 85 | global _git_version | ||
| 86 | |||
| 87 | if _git_version is None: | ||
| 88 | ver_str = git.version() | ||
| 89 | if ver_str.startswith('git version '): | ||
| 90 | _git_version = tuple( | ||
| 91 | map(lambda x: int(x), | ||
| 92 | ver_str[len('git version '):].strip().split('.')[0:3] | ||
| 93 | )) | ||
| 94 | else: | ||
| 95 | print >>sys.stderr, 'fatal: "%s" unsupported' % ver_str | ||
| 96 | sys.exit(1) | ||
| 97 | return _git_version | ||
| 98 | |||
| 82 | def __getattr__(self, name): | 99 | def __getattr__(self, name): |
| 83 | name = name.replace('_','-') | 100 | name = name.replace('_','-') |
| 84 | def fun(*cmdv): | 101 | def fun(*cmdv): |
| @@ -88,23 +105,9 @@ class _GitCall(object): | |||
| 88 | return fun | 105 | return fun |
| 89 | git = _GitCall() | 106 | git = _GitCall() |
| 90 | 107 | ||
| 91 | _git_version = None | ||
| 92 | |||
| 93 | def git_require(min_version, fail=False): | 108 | def git_require(min_version, fail=False): |
| 94 | global _git_version | 109 | git_version = git.version_tuple() |
| 95 | 110 | if min_version <= git_version: | |
| 96 | if _git_version is None: | ||
| 97 | ver_str = git.version() | ||
| 98 | if ver_str.startswith('git version '): | ||
| 99 | _git_version = tuple( | ||
| 100 | map(lambda x: int(x), | ||
| 101 | ver_str[len('git version '):].strip().split('.')[0:3] | ||
| 102 | )) | ||
| 103 | else: | ||
| 104 | print >>sys.stderr, 'fatal: "%s" unsupported' % ver_str | ||
| 105 | sys.exit(1) | ||
| 106 | |||
| 107 | if min_version <= _git_version: | ||
| 108 | return True | 111 | return True |
| 109 | if fail: | 112 | if fail: |
| 110 | need = '.'.join(map(lambda x: str(x), min_version)) | 113 | need = '.'.join(map(lambda x: str(x), min_version)) |
| @@ -29,6 +29,7 @@ import sys | |||
| 29 | import urllib2 | 29 | import urllib2 |
| 30 | 30 | ||
| 31 | from trace import SetTrace | 31 | from trace import SetTrace |
| 32 | from git_command import git, GitCommand | ||
| 32 | from git_config import init_ssh, close_ssh | 33 | from git_config import init_ssh, close_ssh |
| 33 | from command import InteractiveCommand | 34 | from command import InteractiveCommand |
| 34 | from command import MirrorSafeCommand | 35 | from command import MirrorSafeCommand |
| @@ -134,6 +135,9 @@ class _Repo(object): | |||
| 134 | print >>sys.stderr, 'error: no project in current directory' | 135 | print >>sys.stderr, 'error: no project in current directory' |
| 135 | sys.exit(1) | 136 | sys.exit(1) |
| 136 | 137 | ||
| 138 | def _MyRepoPath(): | ||
| 139 | return os.path.dirname(__file__) | ||
| 140 | |||
| 137 | def _MyWrapperPath(): | 141 | def _MyWrapperPath(): |
| 138 | return os.path.join(os.path.dirname(__file__), 'repo') | 142 | return os.path.join(os.path.dirname(__file__), 'repo') |
| 139 | 143 | ||
| @@ -200,11 +204,63 @@ def _PruneOptions(argv, opt): | |||
| 200 | continue | 204 | continue |
| 201 | i += 1 | 205 | i += 1 |
| 202 | 206 | ||
| 207 | _user_agent = None | ||
| 208 | |||
| 209 | def _UserAgent(): | ||
| 210 | global _user_agent | ||
| 211 | |||
| 212 | if _user_agent is None: | ||
| 213 | py_version = sys.version_info | ||
| 214 | |||
| 215 | os_name = sys.platform | ||
| 216 | if os_name == 'linux2': | ||
| 217 | os_name = 'Linux' | ||
| 218 | elif os_name == 'win32': | ||
| 219 | os_name = 'Win32' | ||
| 220 | elif os_name == 'cygwin': | ||
| 221 | os_name = 'Cygwin' | ||
| 222 | elif os_name == 'darwin': | ||
| 223 | os_name = 'Darwin' | ||
| 224 | |||
| 225 | p = GitCommand( | ||
| 226 | None, ['describe', 'HEAD'], | ||
| 227 | cwd = _MyRepoPath(), | ||
| 228 | capture_stdout = True) | ||
| 229 | if p.Wait() == 0: | ||
| 230 | repo_version = p.stdout | ||
| 231 | if len(repo_version) > 0 and repo_version[-1] == '\n': | ||
| 232 | repo_version = repo_version[0:-1] | ||
| 233 | if len(repo_version) > 0 and repo_version[0] == 'v': | ||
| 234 | repo_version = repo_version[1:] | ||
| 235 | else: | ||
| 236 | repo_version = 'unknown' | ||
| 237 | |||
| 238 | _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % ( | ||
| 239 | repo_version, | ||
| 240 | os_name, | ||
| 241 | '.'.join(map(lambda d: str(d), git.version_tuple())), | ||
| 242 | py_version[0], py_version[1], py_version[2]) | ||
| 243 | return _user_agent | ||
| 244 | |||
| 245 | class _UserAgentHandler(urllib2.BaseHandler): | ||
| 246 | def http_request(self, req): | ||
| 247 | req.add_header('User-Agent', _UserAgent()) | ||
| 248 | return req | ||
| 249 | |||
| 250 | def https_request(self, req): | ||
| 251 | req.add_header('User-Agent', _UserAgent()) | ||
| 252 | return req | ||
| 253 | |||
| 203 | def init_http(): | 254 | def init_http(): |
| 255 | handlers = [_UserAgentHandler()] | ||
| 256 | |||
| 204 | if 'http_proxy' in os.environ: | 257 | if 'http_proxy' in os.environ: |
| 205 | url = os.environ['http_proxy'] | 258 | url = os.environ['http_proxy'] |
| 206 | proxy_support = urllib2.ProxyHandler({'http': url, 'https': url}) | 259 | handlers.append(urllib2.ProxyHandler({'http': url, 'https': url})) |
| 207 | urllib2.install_opener(urllib2.build_opener(proxy_support)) | 260 | if 'REPO_CURL_VERBOSE' in os.environ: |
| 261 | handlers.append(urllib2.HTTPHandler(debuglevel=1)) | ||
| 262 | handlers.append(urllib2.HTTPSHandler(debuglevel=1)) | ||
| 263 | urllib2.install_opener(urllib2.build_opener(*handlers)) | ||
| 208 | 264 | ||
| 209 | def _Main(argv): | 265 | def _Main(argv): |
| 210 | opt = optparse.OptionParser(usage="repo wrapperinfo -- ...") | 266 | opt = optparse.OptionParser(usage="repo wrapperinfo -- ...") |
