コード例 #1
0
    def git(self, cmd, extra_args=(), capture_stdout=False,
            capture_stderr=False, check=True, cwd=None):
        '''Helper for running a git command using metadata from a Project
        instance.

        :param cmd: git command as a string (or list of strings); all strings
                    are formatted using self.format() before use.
        :param extra_args: sequence of additional arguments to pass to the git
                           command (useful mostly if cmd is a string).
        :param capture_stdout: True if stdout should be captured into the
                               returned object instead of being printed.
        :param capture_stderr: Like capture_stdout, but for stderr. Use with
                               caution as it prevents error messages from being
                               shown to the user.
        :param check: True if a subprocess.CalledProcessError should be raised
                      if the git command finishes with a non-zero return code.
        :param cwd: directory to run command in (default: self.abspath)

        Returns a CompletedProcess (which is back-ported for Python 3.4).'''
        _warn_once_if_no_git()

        if isinstance(cmd, str):
            cmd_list = shlex.split(cmd)
        else:
            cmd_list = list(cmd)

        extra_args = list(extra_args)

        if cwd is None:
            cwd = self.abspath

        args = ['git'] + [self.format(arg) for arg in cmd_list] + extra_args
        cmd_str = util.quote_sh_list(args)

        log.dbg("running '{}'".format(cmd_str), 'in', cwd,
                level=log.VERBOSE_VERY)
        popen = subprocess.Popen(
            args, cwd=cwd,
            stdout=subprocess.PIPE if capture_stdout else None,
            stderr=subprocess.PIPE if capture_stderr else None)

        stdout, stderr = popen.communicate()

        dbg_msg = "'{}' in {} finished with exit status {}".format(
            cmd_str, cwd, popen.returncode)
        if capture_stdout:
            dbg_msg += " and wrote {} to stdout".format(stdout)
        if capture_stderr:
            dbg_msg += " and wrote {} to stderr".format(stderr)
        log.dbg(dbg_msg, level=log.VERBOSE_VERY)

        if check and popen.returncode:
            raise subprocess.CalledProcessError(popen.returncode, cmd_list,
                                                output=stdout, stderr=stderr)
        else:
            return CompletedProcess(popen.args, popen.returncode,
                                    stdout, stderr)