summaryrefslogtreecommitdiffstats
path: root/git_command.py
diff options
context:
space:
mode:
Diffstat (limited to 'git_command.py')
-rw-r--r--git_command.py128
1 files changed, 79 insertions, 49 deletions
diff --git a/git_command.py b/git_command.py
index 32dcde09..a4081f45 100644
--- a/git_command.py
+++ b/git_command.py
@@ -22,6 +22,7 @@ import tempfile
22from signal import SIGTERM 22from signal import SIGTERM
23 23
24from error import GitError 24from error import GitError
25from git_refs import HEAD
25import platform_utils 26import platform_utils
26from repo_trace import REPO_TRACE, IsTrace, Trace 27from repo_trace import REPO_TRACE, IsTrace, Trace
27from wrapper import Wrapper 28from wrapper import Wrapper
@@ -99,50 +100,72 @@ class _GitCall(object):
99git = _GitCall() 100git = _GitCall()
100 101
101 102
102_user_agent = None 103def RepoSourceVersion():
104 """Return the version of the repo.git tree."""
105 ver = getattr(RepoSourceVersion, 'version', None)
103 106
104def RepoUserAgent(): 107 # We avoid GitCommand so we don't run into circular deps -- GitCommand needs
105 """Return a User-Agent string suitable for HTTP-like services. 108 # to initialize version info we provide.
109 if ver is None:
110 env = GitCommand._GetBasicEnv()
106 111
107 We follow the style as documented here: 112 proj = os.path.dirname(os.path.abspath(__file__))
108 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent 113 env[GIT_DIR] = os.path.join(proj, '.git')
109 """ 114
110 global _user_agent 115 p = subprocess.Popen([GIT, 'describe', HEAD], stdout=subprocess.PIPE,
111 116 env=env)
112 if _user_agent is None: 117 if p.wait() == 0:
113 py_version = sys.version_info 118 ver = p.stdout.read().strip().decode('utf-8')
114 119 if ver.startswith('v'):
115 os_name = sys.platform 120 ver = ver[1:]
116 if os_name == 'linux2':
117 os_name = 'Linux'
118 elif os_name == 'win32':
119 os_name = 'Win32'
120 elif os_name == 'cygwin':
121 os_name = 'Cygwin'
122 elif os_name == 'darwin':
123 os_name = 'Darwin'
124
125 p = GitCommand(
126 None, ['describe', 'HEAD'],
127 cwd=os.path.dirname(__file__),
128 capture_stdout=True)
129 if p.Wait() == 0:
130 repo_version = p.stdout
131 if repo_version and repo_version[-1] == '\n':
132 repo_version = repo_version[0:-1]
133 if repo_version and repo_version[0] == 'v':
134 repo_version = repo_version[1:]
135 else: 121 else:
136 repo_version = 'unknown' 122 ver = 'unknown'
123 setattr(RepoSourceVersion, 'version', ver)
137 124
138 _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % ( 125 return ver
139 repo_version,
140 os_name,
141 git.version_tuple().full,
142 py_version.major, py_version.minor, py_version.micro)
143 126
144 return _user_agent
145 127
128class UserAgent(object):
129 """Mange User-Agent settings when talking to external services
130
131 We follow the style as documented here:
132 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
133 """
134
135 _os = None
136 _repo_ua = None
137
138 @property
139 def os(self):
140 """The operating system name."""
141 if self._os is None:
142 os_name = sys.platform
143 if os_name.lower().startswith('linux'):
144 os_name = 'Linux'
145 elif os_name == 'win32':
146 os_name = 'Win32'
147 elif os_name == 'cygwin':
148 os_name = 'Cygwin'
149 elif os_name == 'darwin':
150 os_name = 'Darwin'
151 self._os = os_name
152
153 return self._os
154
155 @property
156 def repo(self):
157 """The UA when connecting directly from repo."""
158 if self._repo_ua is None:
159 py_version = sys.version_info
160 self._repo_ua = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
161 RepoSourceVersion(),
162 self.os,
163 git.version_tuple().full,
164 py_version.major, py_version.minor, py_version.micro)
165
166 return self._repo_ua
167
168user_agent = UserAgent()
146 169
147def git_require(min_version, fail=False, msg=''): 170def git_require(min_version, fail=False, msg=''):
148 git_version = git.version_tuple() 171 git_version = git.version_tuple()
@@ -171,17 +194,7 @@ class GitCommand(object):
171 ssh_proxy = False, 194 ssh_proxy = False,
172 cwd = None, 195 cwd = None,
173 gitdir = None): 196 gitdir = None):
174 env = os.environ.copy() 197 env = self._GetBasicEnv()
175
176 for key in [REPO_TRACE,
177 GIT_DIR,
178 'GIT_ALTERNATE_OBJECT_DIRECTORIES',
179 'GIT_OBJECT_DIRECTORY',
180 'GIT_WORK_TREE',
181 'GIT_GRAFT_FILE',
182 'GIT_INDEX_FILE']:
183 if key in env:
184 del env[key]
185 198
186 # If we are not capturing std* then need to print it. 199 # If we are not capturing std* then need to print it.
187 self.tee = {'stdout': not capture_stdout, 'stderr': not capture_stderr} 200 self.tee = {'stdout': not capture_stdout, 'stderr': not capture_stderr}
@@ -273,6 +286,23 @@ class GitCommand(object):
273 self.process = p 286 self.process = p
274 self.stdin = p.stdin 287 self.stdin = p.stdin
275 288
289 @staticmethod
290 def _GetBasicEnv():
291 """Return a basic env for running git under.
292
293 This is guaranteed to be side-effect free.
294 """
295 env = os.environ.copy()
296 for key in (REPO_TRACE,
297 GIT_DIR,
298 'GIT_ALTERNATE_OBJECT_DIRECTORIES',
299 'GIT_OBJECT_DIRECTORY',
300 'GIT_WORK_TREE',
301 'GIT_GRAFT_FILE',
302 'GIT_INDEX_FILE'):
303 env.pop(key, None)
304 return env
305
276 def Wait(self): 306 def Wait(self):
277 try: 307 try:
278 p = self.process 308 p = self.process