diff options
Diffstat (limited to 'git_command.py')
-rw-r--r-- | git_command.py | 128 |
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 | |||
22 | from signal import SIGTERM | 22 | from signal import SIGTERM |
23 | 23 | ||
24 | from error import GitError | 24 | from error import GitError |
25 | from git_refs import HEAD | ||
25 | import platform_utils | 26 | import platform_utils |
26 | from repo_trace import REPO_TRACE, IsTrace, Trace | 27 | from repo_trace import REPO_TRACE, IsTrace, Trace |
27 | from wrapper import Wrapper | 28 | from wrapper import Wrapper |
@@ -99,50 +100,72 @@ class _GitCall(object): | |||
99 | git = _GitCall() | 100 | git = _GitCall() |
100 | 101 | ||
101 | 102 | ||
102 | _user_agent = None | 103 | def RepoSourceVersion(): |
104 | """Return the version of the repo.git tree.""" | ||
105 | ver = getattr(RepoSourceVersion, 'version', None) | ||
103 | 106 | ||
104 | def 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 | ||
128 | class 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 | |||
168 | user_agent = UserAgent() | ||
146 | 169 | ||
147 | def git_require(min_version, fail=False, msg=''): | 170 | def 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 |