Пример #1
0
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
Пример #2
0
    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
Пример #3
0
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()
Пример #4
0
 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
Пример #5
0
 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
Пример #6
0
    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
Пример #7
0
 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
Пример #8
0
    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
Пример #9
0
    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
Пример #10
0
    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()
Пример #11
0
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()
Пример #12
0
    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
Пример #13
0
    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
Пример #14
0
    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)
Пример #15
0
  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
Пример #16
0
    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