def _WindowsPager(repo): (name, cmd, gopts, _gargs, copts, cargs, argv) = repo.config if _UsePager(name, cmd, gopts, copts): python = sys.executable thisScript = os.path.abspath(__file__) args = sys.argv[1:] argsSplit = args.index('--') args1 = args[:argsSplit] args2 = args[argsSplit + 1:] pager = _SelectPager(cmd.manifest.globalConfig) shellCommand = [python, thisScript] + args1 + [ '--', '--piped-into-pager', '--no-pager' ] + args2 + ['|', pager] if IsTrace(): Trace(' '.join(shellCommand)) subprocess.call(shellCommand, shell=True) return True else: # set global variable if output is piped into pager; means that pager is simulated, this # leads to correct coloring in windows import pager pager.active = gopts.pipedIntoPager return False
def _NeedUpdate(self): Trace(': scan refs %s', self._gitdir) for name, mtime in list(self._mtime.items()): try: if mtime != os.path.getmtime(os.path.join(self._gitdir, name)): return True except OSError: return True return False
def os_link(src, dst): if isUnix(): # requires src in relation to dst src = os.path.relpath(src, os.path.dirname(dst)) os.symlink(src, dst) else: isDir = True if os.path.isdir(src) else False src = os.path.relpath(src, os.path.dirname(dst)) src = toWindowsPath(src) dst = toWindowsPath(dst) # ln in MinGW does not create hard links? - it copies # call windows cmd tool 'mklink' from git bash (mingw) if isDir: cmd = 'cmd /c mklink /D "%s" "%s"' % (dst, src) if IsTrace(): Trace(cmd) subprocess.Popen(cmd, stdout=subprocess.PIPE).wait() else: cmd = 'cmd /c mklink "%s" "%s"' % (dst, src) if IsTrace(): Trace(cmd) subprocess.Popen(cmd, stdout=subprocess.PIPE).wait()
def _ReadJson(self): try: if os.path.getmtime(self._json) <= os.path.getmtime(self.file): platform_utils.remove(self._json) return None except OSError: return None try: Trace(': parsing %s', self.file) with open(self._json) as fd: return json.load(fd) except (IOError, ValueError): platform_utils.remove(self._json) return None
def _ReadJson(self): try: if os.path.getmtime(self._json) \ <= os.path.getmtime(self.file): platform_utils.remove(self._json) return None except OSError: return None try: Trace(': parsing %s', self.file) fd = open(self._json) try: return json.load(fd) finally: fd.close() except (IOError, ValueError): platform_utils.remove(self._json) return None
def _LoadAll(self): Trace(': load refs %s', self._gitdir) self._phyref = {} self._symref = {} self._mtime = {} self._ReadPackedRefs() self._ReadLoose('refs/') self._ReadLoose1(os.path.join(self._gitdir, HEAD), HEAD) scan = self._symref attempts = 0 while scan and attempts < 5: scan_next = {} for name, dest in list(scan.items()): if dest in self._phyref: self._phyref[name] = self._phyref[dest] else: scan_next[name] = dest scan = scan_next attempts += 1
def _ReadPickle(self): try: if os.path.getmtime(self._pickle) \ <= os.path.getmtime(self.file): os.remove(self._pickle) return None except OSError: return None try: Trace(': unpickle %s', self.file) fd = open(self._pickle, 'rb') try: return pickle.load(fd) finally: fd.close() except EOFError: os.remove(self._pickle) return None except IOError: os.remove(self._pickle) return None except pickle.PickleError: os.remove(self._pickle) return None
def __init__(self, project, cmdv, bare=False, provide_stdin=False, capture_stdout=False, capture_stderr=False, disable_editor=False, ssh_proxy=False, cwd=None, gitdir=None): env = os.environ.copy() for key in [ REPO_TRACE, GIT_DIR, 'GIT_ALTERNATE_OBJECT_DIRECTORIES', 'GIT_OBJECT_DIRECTORY', 'GIT_WORK_TREE', 'GIT_GRAFT_FILE', 'GIT_INDEX_FILE' ]: if key in env: del env[key] # If we are not capturing std* then need to print it. self.tee = {'stdout': not capture_stdout, 'stderr': not capture_stderr} if disable_editor: _setenv(env, 'GIT_EDITOR', ':') if ssh_proxy: _setenv(env, 'REPO_SSH_SOCK', ssh_sock()) _setenv(env, 'GIT_SSH', _ssh_proxy()) _setenv(env, 'GIT_SSH_VARIANT', 'ssh') if 'http_proxy' in env and 'darwin' == sys.platform: s = "'http.proxy=%s'" % (env['http_proxy'], ) p = env.get('GIT_CONFIG_PARAMETERS') if p is not None: s = p + ' ' + s _setenv(env, 'GIT_CONFIG_PARAMETERS', s) if 'GIT_ALLOW_PROTOCOL' not in env: _setenv( env, 'GIT_ALLOW_PROTOCOL', 'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc' ) if project: if not cwd: cwd = project.worktree if not gitdir: gitdir = project.gitdir command = [GIT] if bare: if gitdir: _setenv(env, GIT_DIR, gitdir) cwd = None command.append(cmdv[0]) # Need to use the --progress flag for fetch/clone so output will be # displayed as by default git only does progress output if stderr is a TTY. if sys.stderr.isatty() and cmdv[0] in ('fetch', 'clone'): if '--progress' not in cmdv and '--quiet' not in cmdv: command.append('--progress') command.extend(cmdv[1:]) if provide_stdin: stdin = subprocess.PIPE else: stdin = None stdout = subprocess.PIPE stderr = subprocess.PIPE if IsTrace(): global LAST_CWD global LAST_GITDIR dbg = '' if cwd and LAST_CWD != cwd: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': cd %s\n' % cwd LAST_CWD = cwd if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR] LAST_GITDIR = env[GIT_DIR] dbg += ': ' dbg += ' '.join(command) if stdin == subprocess.PIPE: dbg += ' 0<|' if stdout == subprocess.PIPE: dbg += ' 1>|' if stderr == subprocess.PIPE: dbg += ' 2>|' Trace('%s', dbg) try: p = subprocess.Popen(command, cwd=cwd, env=env, stdin=stdin, stdout=stdout, stderr=stderr) except Exception as e: raise GitError('%s: %s' % (command[1], e)) if ssh_proxy: _add_ssh_client(p) self.process = p self.stdin = p.stdin
def __init__(self, project, cmdv, bare=False, provide_stdin=False, capture_stdout=False, capture_stderr=False, disable_editor=False, ssh_proxy=False, cwd=None, gitdir=None): env = os.environ.copy() for key in [ REPO_TRACE, GIT_DIR, 'GIT_ALTERNATE_OBJECT_DIRECTORIES', 'GIT_OBJECT_DIRECTORY', 'GIT_WORK_TREE', 'GIT_GRAFT_FILE', 'GIT_INDEX_FILE' ]: if key in env: del env[key] if disable_editor: _setenv(env, 'GIT_EDITOR', ':') if ssh_proxy: _setenv(env, 'REPO_SSH_SOCK', ssh_sock()) _setenv(env, 'GIT_SSH', _ssh_proxy()) if 'http_proxy' in env and 'darwin' == sys.platform: s = "'http.proxy=%s'" % (env['http_proxy'], ) p = env.get('GIT_CONFIG_PARAMETERS') if p is not None: s = p + ' ' + s _setenv(env, 'GIT_CONFIG_PARAMETERS', s) if project: if not cwd: cwd = project.worktree if not gitdir: gitdir = project.gitdir command = [GIT] if bare: if gitdir: env[GIT_DIR] = gitdir cwd = None command.extend(cmdv) if provide_stdin: stdin = subprocess.PIPE else: stdin = None if capture_stdout: stdout = subprocess.PIPE else: stdout = None if capture_stderr: stderr = subprocess.PIPE else: stderr = None if IsTrace(): global LAST_CWD global LAST_GITDIR dbg = '' if cwd and LAST_CWD != cwd: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': cd %s\n' % cwd LAST_CWD = cwd if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR] LAST_GITDIR = env[GIT_DIR] dbg += ': ' dbg += ' '.join(command) if stdin == subprocess.PIPE: dbg += ' 0<|' if stdout == subprocess.PIPE: dbg += ' 1>|' if stderr == subprocess.PIPE: dbg += ' 2>|' Trace('%s', dbg) try: p = subprocess.Popen(command, cwd=cwd, env=env, stdin=stdin, stdout=stdout, stderr=stderr) except Exception as e: raise GitError('%s: %s' % (command[1], e)) if ssh_proxy: _add_ssh_client(p) portable.SUBPROCESSES.append(p) self.process = p self.stdin = p.stdin
def __init__(self, project, cmdv, bare=False, input=None, capture_stdout=False, capture_stderr=False, merge_output=False, disable_editor=False, ssh_proxy=None, cwd=None, gitdir=None): env = self._GetBasicEnv() if disable_editor: env['GIT_EDITOR'] = ':' if ssh_proxy: env['REPO_SSH_SOCK'] = ssh_proxy.sock() env['GIT_SSH'] = ssh_proxy.proxy env['GIT_SSH_VARIANT'] = 'ssh' if 'http_proxy' in env and 'darwin' == sys.platform: s = "'http.proxy=%s'" % (env['http_proxy'], ) p = env.get('GIT_CONFIG_PARAMETERS') if p is not None: s = p + ' ' + s env['GIT_CONFIG_PARAMETERS'] = s if 'GIT_ALLOW_PROTOCOL' not in env: env['GIT_ALLOW_PROTOCOL'] = ( 'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc' ) env['GIT_HTTP_USER_AGENT'] = user_agent.git if project: if not cwd: cwd = project.worktree if not gitdir: gitdir = project.gitdir command = [GIT] if bare: if gitdir: # Git on Windows wants its paths only using / for reliability. if platform_utils.isWindows(): gitdir = gitdir.replace('\\', '/') env[GIT_DIR] = gitdir cwd = None command.append(cmdv[0]) # Need to use the --progress flag for fetch/clone so output will be # displayed as by default git only does progress output if stderr is a TTY. if sys.stderr.isatty() and cmdv[0] in ('fetch', 'clone'): if '--progress' not in cmdv and '--quiet' not in cmdv: command.append('--progress') command.extend(cmdv[1:]) stdin = subprocess.PIPE if input else None stdout = subprocess.PIPE if capture_stdout else None stderr = (subprocess.STDOUT if merge_output else (subprocess.PIPE if capture_stderr else None)) if IsTrace(): global LAST_CWD global LAST_GITDIR dbg = '' if cwd and LAST_CWD != cwd: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': cd %s\n' % cwd LAST_CWD = cwd if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR] LAST_GITDIR = env[GIT_DIR] dbg += ': ' dbg += ' '.join(command) if stdin == subprocess.PIPE: dbg += ' 0<|' if stdout == subprocess.PIPE: dbg += ' 1>|' if stderr == subprocess.PIPE: dbg += ' 2>|' elif stderr == subprocess.STDOUT: dbg += ' 2>&1' Trace('%s', dbg) try: p = subprocess.Popen(command, cwd=cwd, env=env, encoding='utf-8', errors='backslashreplace', stdin=stdin, stdout=stdout, stderr=stderr) except Exception as e: raise GitError('%s: %s' % (command[1], e)) if ssh_proxy: ssh_proxy.add_client(p) self.process = p if input: if isinstance(input, str): input = input.encode('utf-8') p.stdin.write(input) p.stdin.close() try: self.stdout, self.stderr = p.communicate() finally: if ssh_proxy: ssh_proxy.remove_client(p) self.rc = p.wait()
def _open_ssh(host, port=None): global _ssh_master # Acquire the lock. This is needed to prevent opening multiple masters for # the same host when we're running "repo sync -jN" (for N > 1) _and_ the # manifest <remote fetch="ssh://xyz"> specifies a different host from the # one that was passed to repo init. _master_keys_lock.acquire() try: # Check to see whether we already think that the master is running; if we # think it's already running, return right away. if port is not None: key = '%s:%s' % (host, port) else: key = host if key in _master_keys: return True if (not _ssh_master or 'GIT_SSH' in os.environ or sys.platform in ('win32', 'cygwin')): # failed earlier, or cygwin ssh can't do this # return False # We will make two calls to ssh; this is the common part of both calls. command_base = ['ssh', '-o', 'ControlPath %s' % ssh_sock(), host] if port is not None: command_base[1:1] = ['-p', str(port)] # Since the key wasn't in _master_keys, we think that master isn't running. # ...but before actually starting a master, we'll double-check. This can # be important because we can't tell that that '*****@*****.**' is the same # as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file. check_command = command_base + ['-O', 'check'] try: Trace(': %s', ' '.join(check_command)) check_process = subprocess.Popen(check_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_process.communicate() # read output, but ignore it... isnt_running = check_process.wait() if not isnt_running: # Our double-check found that the master _was_ infact running. Add to # the list of keys. _master_keys.add(key) return True except Exception: # Ignore excpetions. We we will fall back to the normal command and print # to the log there. pass command = command_base[:1] + ['-M', '-N'] + command_base[1:] try: Trace(': %s', ' '.join(command)) p = subprocess.Popen(command) except Exception as e: _ssh_master = False print('\nwarn: cannot enable ssh control master for %s:%s\n%s' % (host, port, str(e)), file=sys.stderr) return False time.sleep(1) ssh_died = (p.poll() is not None) if ssh_died: return False _master_processes.append(p) _master_keys.add(key) return True finally: _master_keys_lock.release()
def _open_unlocked(self, host, port=None): """Make sure a ssh master session exists for |host| & |port|. If one doesn't exist already, we'll create it. We won't grab any locks, so the caller has to do that. This helps keep the business logic of actually creating the master separate from grabbing locks. """ # Check to see whether we already think that the master is running; if we # think it's already running, return right away. if port is not None: key = '%s:%s' % (host, port) else: key = host if key in self._master_keys: return True if self._master_broken.value or 'GIT_SSH' in os.environ: # Failed earlier, so don't retry. return False # We will make two calls to ssh; this is the common part of both calls. command_base = ['ssh', '-o', 'ControlPath %s' % self.sock(), host] if port is not None: command_base[1:1] = ['-p', str(port)] # Since the key wasn't in _master_keys, we think that master isn't running. # ...but before actually starting a master, we'll double-check. This can # be important because we can't tell that that '*****@*****.**' is the same # as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file. check_command = command_base + ['-O', 'check'] try: Trace(': %s', ' '.join(check_command)) check_process = subprocess.Popen(check_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_process.communicate() # read output, but ignore it... isnt_running = check_process.wait() if not isnt_running: # Our double-check found that the master _was_ infact running. Add to # the list of keys. self._master_keys[key] = True return True except Exception: # Ignore excpetions. We we will fall back to the normal command and print # to the log there. pass command = command_base[:1] + ['-M', '-N'] + command_base[1:] try: Trace(': %s', ' '.join(command)) p = subprocess.Popen(command) except Exception as e: self._master_broken.value = True print('\nwarn: cannot enable ssh control master for %s:%s\n%s' % (host, port, str(e)), file=sys.stderr) return False time.sleep(1) ssh_died = (p.poll() is not None) if ssh_died: return False self.add_master(p) self._master_keys[key] = True return True
def __init__( self, project, cmdv, bare=False, provide_stdin=False, capture_stdout=False, capture_stderr=False, merge_output=False, disable_editor=False, ssh_proxy=False, cwd=None, gitdir=None, ): env = self._GetBasicEnv() # If we are not capturing std* then need to print it. self.tee = {"stdout": not capture_stdout, "stderr": not capture_stderr} if disable_editor: env["GIT_EDITOR"] = ":" if ssh_proxy: env["REPO_SSH_SOCK"] = ssh_sock() env["GIT_SSH"] = _ssh_proxy() env["GIT_SSH_VARIANT"] = "ssh" if "http_proxy" in env and "darwin" == sys.platform: s = "'http.proxy=%s'" % (env["http_proxy"], ) p = env.get("GIT_CONFIG_PARAMETERS") if p is not None: s = p + " " + s env["GIT_CONFIG_PARAMETERS"] = s if "GIT_ALLOW_PROTOCOL" not in env: env["GIT_ALLOW_PROTOCOL"] = "file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc" env["GIT_HTTP_USER_AGENT"] = user_agent.git if project: if not cwd: cwd = project.worktree if not gitdir: gitdir = project.gitdir command = [GIT] if bare: if gitdir: env[GIT_DIR] = gitdir cwd = None command.append(cmdv[0]) # Need to use the --progress flag for fetch/clone so output will be # displayed as by default git only does progress output if stderr is a TTY. if sys.stderr.isatty() and cmdv[0] in ("fetch", "clone"): if "--progress" not in cmdv and "--quiet" not in cmdv: command.append("--progress") command.extend(cmdv[1:]) if provide_stdin: stdin = subprocess.PIPE else: stdin = None stdout = subprocess.PIPE stderr = subprocess.STDOUT if merge_output else subprocess.PIPE if IsTrace(): global LAST_CWD global LAST_GITDIR dbg = "" if cwd and LAST_CWD != cwd: if LAST_GITDIR or LAST_CWD: dbg += "\n" dbg += ": cd %s\n" % cwd LAST_CWD = cwd if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]: if LAST_GITDIR or LAST_CWD: dbg += "\n" dbg += ": export GIT_DIR=%s\n" % env[GIT_DIR] LAST_GITDIR = env[GIT_DIR] dbg += ": " dbg += " ".join(command) if stdin == subprocess.PIPE: dbg += " 0<|" if stdout == subprocess.PIPE: dbg += " 1>|" if stderr == subprocess.PIPE: dbg += " 2>|" elif stderr == subprocess.STDOUT: dbg += " 2>&1" Trace("%s", dbg) try: p = subprocess.Popen(command, cwd=cwd, env=env, stdin=stdin, stdout=stdout, stderr=stderr) except Exception as e: raise GitError("%s: %s" % (command[1], e)) if ssh_proxy: _add_ssh_client(p) self.process = p self.stdin = p.stdin
def Execute(self, opt, args): if not opt.command: self.Usage() cmd = [opt.command[0]] shell = True if re.compile(r'^[a-z0-9A-Z_/\.-]+$').match(cmd[0]): shell = False if shell and portable.isPosix(): cmd.append(cmd[0]) cmd.extend(opt.command[1:]) if opt.project_header \ and not shell \ and cmd[0] == 'git': # If this is a direct git command that can enable colorized # output and the user prefers coloring, add --color into the # command line because we are going to wrap the command into # a pipe and git won't know coloring should activate. # for cn in cmd[1:]: if not cn.startswith('-'): break else: cn = None # pylint: disable=W0631 if cn and cn in _CAN_COLOR: class ColorCmd(Coloring): def __init__(self, config, cmd): Coloring.__init__(self, config, cmd) if ColorCmd(self.manifest.manifestProject.config, cn).is_on: cmd.insert(cmd.index(cn) + 1, '--color') # pylint: enable=W0631 mirror = self.manifest.IsMirror out = ForallColoring(self.manifest.manifestProject.config) out.redirect(sys.stdout) rc = 0 first = True for project in self.GetProjects(args): env = os.environ.copy() def setenv(name, val): if val is None: val = '' env[name] = val setenv('REPO_PROJECT', project.name) setenv('REPO_PATH', project.relpath) setenv('REPO_REMOTE', project.remote.name) setenv('REPO_LREV', project.GetRevisionId()) setenv('REPO_RREV', project.revisionExpr) for a in project.annotations: setenv("REPO__%s" % (a.name), a.value) if mirror: setenv('GIT_DIR', project.gitdir) cwd = project.gitdir else: cwd = project.worktree if not os.path.exists(cwd): if (opt.project_header and opt.verbose) \ or not opt.project_header: print('skipping %s/' % project.relpath, file=sys.stderr) continue if opt.project_header: stdin = subprocess.PIPE stdout = subprocess.PIPE stderr = subprocess.PIPE else: stdin = None stdout = None stderr = None if not portable.isUnix(): if type(cmd) is list: cmd = " ".join(cmd) if IsTrace(): Trace("execute command: %s" % str(cmd).replace("%", "%%")) Trace("environment is: %s" % str(env)) p = subprocess.Popen(cmd, cwd=cwd, shell=shell, env=env, stdin=stdin, stdout=stdout, stderr=stderr) if opt.project_header: class sfd(object): def __init__(self, fd, dest): self.fd = fd self.dest = dest def fileno(self): return self.fd.fileno() # empty = True # errbuf = '' # # p.stdin.close() # s_in = [sfd(p.stdout, sys.stdout), # sfd(p.stderr, sys.stderr)] # # for s in s_in: # flags = fcntl.fcntl(s.fd, fcntl.F_GETFL) # fcntl.fcntl(s.fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) # # while s_in: # in_ready, _out_ready, _err_ready = select.select(s_in, [], []) # for s in in_ready: # buf = s.fd.read(4096) # if not buf: # s.fd.close() # s_in.remove(s) # continue # # if not opt.verbose: # if s.fd != p.stdout: # errbuf += buf # continue # # if empty: # if first: # first = False # else: # out.nl() # out.project('project %s/', project.relpath) # out.nl() # out.flush() # if errbuf: # sys.stderr.write(errbuf) # sys.stderr.flush() # errbuf = '' # empty = False # # s.dest.write(buf) # s.dest.flush() r = p.wait() if r != 0: if r != rc: rc = r if opt.abort_on_errors: print("error: %s: Aborting due to previous error" % project.relpath, file=sys.stderr) sys.exit(r) if rc != 0: sys.exit(rc)
def __init__(self, project, cmdv, bare=False, provide_stdin=False, capture_stdout=False, capture_stderr=False, merge_output=False, disable_editor=False, ssh_proxy=False, cwd=None, gitdir=None): env = self._GetBasicEnv() # If we are not capturing std* then need to print it. self.tee = {'stdout': not capture_stdout, 'stderr': not capture_stderr} if disable_editor: env['GIT_EDITOR'] = ':' if ssh_proxy: env['REPO_SSH_SOCK'] = ssh_sock() env['GIT_SSH'] = _ssh_proxy() env['GIT_SSH_VARIANT'] = 'ssh' if 'http_proxy' in env and 'darwin' == sys.platform: s = "'http.proxy=%s'" % (env['http_proxy'],) p = env.get('GIT_CONFIG_PARAMETERS') if p is not None: s = p + ' ' + s env['GIT_CONFIG_PARAMETERS'] = s if 'GIT_ALLOW_PROTOCOL' not in env: env['GIT_ALLOW_PROTOCOL'] = ( 'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc') env['GIT_HTTP_USER_AGENT'] = user_agent.git if project: if not cwd: cwd = project.worktree if not gitdir: gitdir = project.gitdir command = [GIT] if bare: if gitdir: env[GIT_DIR] = gitdir cwd = None command.append(cmdv[0]) # Need to use the --progress flag for fetch/clone so output will be # displayed as by default git only does progress output if stderr is a TTY. if sys.stderr.isatty() and cmdv[0] in ('fetch', 'clone'): if '--progress' not in cmdv and '--quiet' not in cmdv: command.append('--progress') command.extend(cmdv[1:]) if provide_stdin: stdin = subprocess.PIPE else: stdin = None stdout = subprocess.PIPE stderr = subprocess.STDOUT if merge_output else subprocess.PIPE if IsTrace(): global LAST_CWD global LAST_GITDIR dbg = '' if cwd and LAST_CWD != cwd: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': cd %s\n' % cwd LAST_CWD = cwd if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]: if LAST_GITDIR or LAST_CWD: dbg += '\n' dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR] LAST_GITDIR = env[GIT_DIR] dbg += ': ' dbg += ' '.join(command) if stdin == subprocess.PIPE: dbg += ' 0<|' if stdout == subprocess.PIPE: dbg += ' 1>|' if stderr == subprocess.PIPE: dbg += ' 2>|' elif stderr == subprocess.STDOUT: dbg += ' 2>&1' Trace('%s', dbg) try: p = subprocess.Popen(command, cwd=cwd, env=env, stdin=stdin, stdout=stdout, stderr=stderr) except Exception as e: raise GitError('%s: %s' % (command[1], e)) if ssh_proxy: _add_ssh_client(p) self.process = p self.stdin = p.stdin
def ReviewUrl(self, userEmail): if self._review_url is None: if self.review is None: return None u = self.review if u.endswith('/Gerrit'): u = u[:len(u) - len('/Gerrit')] if u.endswith('/ssh_info'): u = u[:len(u) - len('/ssh_info')] if not u.endswith('/'): u += '/' if u in REVIEW_CACHE: self._review_url = REVIEW_CACHE[u] elif 'REPO_HOST_PORT_INFO' in os.environ: host, port = os.environ['REPO_HOST_PORT_INFO'].split() self._review_url = self._SshReviewUrl(userEmail, host, port) REVIEW_CACHE[u] = self._review_url else: try: # NOTE: contrary to original repo: do not switch automatically to ssh, since this is contra-intuitive # try to fetch ssh infos from http gerrit server if protocol not specified protocolSeperator = "://" protocolSepIndex = u.find(protocolSeperator) if protocolSepIndex == -1: protocols = ["http", "https"] for prefix in protocols: http_url = '%s://%s' % (prefix, u) info_url = http_url + 'ssh_info' info = None try: info = portable.stream2str( urllib.request.urlopen(info_url).read()) if '<' in info: # Assume the server gave us some sort of HTML # response back, like maybe a login page. # raise UploadError( '%s: Cannot parse response' % info_url) if info != 'NOT_AVAILABLE': host, port = info.split() self._review_url = self._SshReviewUrl( userEmail, host, port) except Exception as e: Trace( "could not get ssh infos of %s from %s (received %s), error %s", u, info_url, info, e) info = 'NOT_AVAILABLE' if not self._review_url: # Assume HTTP if SSH is not enabled. self._review_url = http_url + 'p/' Trace( "warning: proceed upload with http url %s since no protocol given and no infos could be retrieved from %s", self._review_url, info_url) print("detected %s as review url" % self._review_url) else: self._review_url = u except urllib.error.HTTPError as e: raise UploadError('%s: %s' % (self.review, str(e))) except urllib.error.URLError as e: raise UploadError('%s: %s' % (self.review, str(e))) REVIEW_CACHE[u] = self._review_url return self._review_url + self.projectname