summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn L. Villalovos <john.l.villalovos@intel.com>2015-03-16 20:49:10 -0700
committerJohn L. Villalovos <john.l.villalovos@intel.com>2015-03-26 11:43:55 -0700
commit9c76f67f13c033b67b23206798701548207dd880 (patch)
treee089031b26a7fb97ee099bb6f7bdb21deaebafc0
parent52b99aa91d0fbb5ea363b5febb367d602dbc56db (diff)
downloadgit-repo-9c76f67f13c033b67b23206798701548207dd880.tar.gz
Always capture output for GitCommand
Switch the GitCommand program to always capture the output for stdout and stderr. And by default print the output while running. The options capture_stdout and capture_stderr have effectively become options to supress the printing of stdout and stderr. Update the 'git fetch' to use '--progress' so that the progress messages will be displayed. git checks if the output location isatty() and if it is not a TTY it will by default not print the progress messages. Change-Id: Ifdae138e008f80a59195f9f43c911a1a5210ec60
-rw-r--r--git_command.py64
-rw-r--r--project.py7
2 files changed, 54 insertions, 17 deletions
diff --git a/git_command.py b/git_command.py
index 53b3e75c..259fb02c 100644
--- a/git_command.py
+++ b/git_command.py
@@ -14,7 +14,9 @@
14# limitations under the License. 14# limitations under the License.
15 15
16from __future__ import print_function 16from __future__ import print_function
17import fcntl
17import os 18import os
19import select
18import sys 20import sys
19import subprocess 21import subprocess
20import tempfile 22import tempfile
@@ -76,6 +78,16 @@ def terminate_ssh_clients():
76 78
77_git_version = None 79_git_version = None
78 80
81class _sfd(object):
82 """select file descriptor class"""
83 def __init__(self, fd, dest, std_name):
84 assert std_name in ('stdout', 'stderr')
85 self.fd = fd
86 self.dest = dest
87 self.std_name = std_name
88 def fileno(self):
89 return self.fd.fileno()
90
79class _GitCall(object): 91class _GitCall(object):
80 def version(self): 92 def version(self):
81 p = GitCommand(None, ['--version'], capture_stdout=True) 93 p = GitCommand(None, ['--version'], capture_stdout=True)
@@ -139,6 +151,9 @@ class GitCommand(object):
139 if key in env: 151 if key in env:
140 del env[key] 152 del env[key]
141 153
154 # If we are not capturing std* then need to print it.
155 self.tee = {'stdout': not capture_stdout, 'stderr': not capture_stderr}
156
142 if disable_editor: 157 if disable_editor:
143 _setenv(env, 'GIT_EDITOR', ':') 158 _setenv(env, 'GIT_EDITOR', ':')
144 if ssh_proxy: 159 if ssh_proxy:
@@ -162,22 +177,21 @@ class GitCommand(object):
162 if gitdir: 177 if gitdir:
163 _setenv(env, GIT_DIR, gitdir) 178 _setenv(env, GIT_DIR, gitdir)
164 cwd = None 179 cwd = None
165 command.extend(cmdv) 180 command.append(cmdv[0])
181 # Need to use the --progress flag for fetch/clone so output will be
182 # displayed as by default git only does progress output if stderr is a TTY.
183 if sys.stderr.isatty() and cmdv[0] in ('fetch', 'clone'):
184 if '--progress' not in cmdv and '--quiet' not in cmdv:
185 command.append('--progress')
186 command.extend(cmdv[1:])
166 187
167 if provide_stdin: 188 if provide_stdin:
168 stdin = subprocess.PIPE 189 stdin = subprocess.PIPE
169 else: 190 else:
170 stdin = None 191 stdin = None
171 192
172 if capture_stdout: 193 stdout = subprocess.PIPE
173 stdout = subprocess.PIPE 194 stderr = subprocess.PIPE
174 else:
175 stdout = None
176
177 if capture_stderr:
178 stderr = subprocess.PIPE
179 else:
180 stderr = None
181 195
182 if IsTrace(): 196 if IsTrace():
183 global LAST_CWD 197 global LAST_CWD
@@ -226,8 +240,34 @@ class GitCommand(object):
226 def Wait(self): 240 def Wait(self):
227 try: 241 try:
228 p = self.process 242 p = self.process
229 (self.stdout, self.stderr) = p.communicate() 243 rc = self._CaptureOutput()
230 rc = p.returncode
231 finally: 244 finally:
232 _remove_ssh_client(p) 245 _remove_ssh_client(p)
233 return rc 246 return rc
247
248 def _CaptureOutput(self):
249 p = self.process
250 s_in = [_sfd(p.stdout, sys.stdout, 'stdout'),
251 _sfd(p.stderr, sys.stderr, 'stderr')]
252 self.stdout = ''
253 self.stderr = ''
254
255 for s in s_in:
256 flags = fcntl.fcntl(s.fd, fcntl.F_GETFL)
257 fcntl.fcntl(s.fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
258
259 while s_in:
260 in_ready, _, _ = select.select(s_in, [], [])
261 for s in in_ready:
262 buf = s.fd.read(4096)
263 if not buf:
264 s_in.remove(s)
265 continue
266 if s.std_name == 'stdout':
267 self.stdout += buf
268 else:
269 self.stderr += buf
270 if self.tee[s.std_name]:
271 s.dest.write(buf)
272 s.dest.flush()
273 return p.wait()
diff --git a/project.py b/project.py
index 028deb5f..1245fa2a 100644
--- a/project.py
+++ b/project.py
@@ -1874,10 +1874,8 @@ class Project(object):
1874 1874
1875 ok = False 1875 ok = False
1876 for _i in range(2): 1876 for _i in range(2):
1877 gitcmd = GitCommand(self, cmd, bare=True, capture_stderr=True, 1877 gitcmd = GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy)
1878 ssh_proxy=ssh_proxy)
1879 ret = gitcmd.Wait() 1878 ret = gitcmd.Wait()
1880 print(gitcmd.stderr, file=sys.stderr, end='')
1881 if ret == 0: 1879 if ret == 0:
1882 ok = True 1880 ok = True
1883 break 1881 break
@@ -1886,9 +1884,8 @@ class Project(object):
1886 "error:" in gitcmd.stderr and 1884 "error:" in gitcmd.stderr and
1887 "git remote prune" in gitcmd.stderr): 1885 "git remote prune" in gitcmd.stderr):
1888 prunecmd = GitCommand(self, ['remote', 'prune', name], bare=True, 1886 prunecmd = GitCommand(self, ['remote', 'prune', name], bare=True,
1889 capture_stderr=True, ssh_proxy=ssh_proxy) 1887 ssh_proxy=ssh_proxy)
1890 ret = prunecmd.Wait() 1888 ret = prunecmd.Wait()
1891 print(prunecmd.stderr, file=sys.stderr, end='')
1892 if ret: 1889 if ret:
1893 break 1890 break
1894 continue 1891 continue