Beispiel #1
0
 def wait(self):
     """
     Wait for the process and return its status code. 
     
     Raise
         GitCommandError if the return status is not 0
     """
     status = self.proc.wait()
     if status != 0:
         raise GitCommandError(self.args, status, self.proc.stderr.read())
     # END status handling 
     return status
Beispiel #2
0
    def execute(
        self,
        command,
        istream=None,
        with_keep_cwd=False,
        with_extended_output=False,
        with_exceptions=True,
        with_raw_output=False,
    ):
        """
        Handles executing the command on the shell and consumes and returns
        the returned information (stdout)

        ``command``
            The command argument list to execute

        ``istream``
            Standard input filehandle passed to subprocess.Popen.

        ``with_keep_cwd``
            Whether to use the current working directory from os.getcwd().
            GitPython uses get_work_tree() as its working directory by
            default and get_git_dir() for bare repositories.

        ``with_extended_output``
            Whether to return a (status, stdout, stderr) tuple.

        ``with_exceptions``
            Whether to raise an exception when git returns a non-zero status.

        ``with_raw_output``
            Whether to avoid stripping off trailing whitespace.

        Returns
            str(output)                     # extended_output = False (Default)
            tuple(int(status), str(output)) # extended_output = True
        """

        if GIT_PYTHON_TRACE and not GIT_PYTHON_TRACE == 'full':
            print ' '.join(command)

        # Allow the user to have the command executed in their working dir.
        if with_keep_cwd or self.git_dir is None:
            cwd = os.getcwd()
        else:
            cwd = self.git_dir

        # Start the process
        proc = subprocess.Popen(command,
                                cwd=cwd,
                                stdin=istream,
                                stderr=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                **extra)

        # Wait for the process to return
        try:
            stdout_value = proc.stdout.read()
            stderr_value = proc.stderr.read()
            status = proc.wait()
        finally:
            proc.stdout.close()
            proc.stderr.close()

        # Strip off trailing whitespace by default
        if not with_raw_output:
            stdout_value = stdout_value.rstrip()
            stderr_value = stderr_value.rstrip()

        if with_exceptions and status != 0:
            raise GitCommandError(command, status, stderr_value)

        if GIT_PYTHON_TRACE == 'full':
            if stderr_value:
                print "%s -> %d: '%s' !! '%s'" % (command, status,
                                                  stdout_value, stderr_value)
            elif stdout_value:
                print "%s -> %d: '%s'" % (command, status, stdout_value)
            else:
                print "%s -> %d" % (command, status)

        # Allow access to the command's status code
        if with_extended_output:
            return (status, stdout_value, stderr_value)
        else:
            return stdout_value
Beispiel #3
0
    def execute(self, command,
                istream=None,
                with_keep_cwd=False,
                with_extended_output=False,
                with_exceptions=True,
                as_process=False, 
                output_stream=None
                ):
        """
        Handles executing the command on the shell and consumes and returns
        the returned information (stdout)

        ``command``
            The command argument list to execute.
            It should be a string, or a sequence of program arguments. The
            program to execute is the first item in the args sequence or string.

        ``istream``
            Standard input filehandle passed to subprocess.Popen.

        ``with_keep_cwd``
            Whether to use the current working directory from os.getcwd().
            The cmd otherwise uses its own working_dir that it has been initialized
            with if possible.

        ``with_extended_output``
            Whether to return a (status, stdout, stderr) tuple.

        ``with_exceptions``
            Whether to raise an exception when git returns a non-zero status.

        ``as_process``
            Whether to return the created process instance directly from which 
            streams can be read on demand. This will render with_extended_output and 
            with_exceptions ineffective - the caller will have 
            to deal with the details himself.
            It is important to note that the process will be placed into an AutoInterrupt
            wrapper that will interrupt the process once it goes out of scope. If you 
            use the command in iterators, you should pass the whole process instance 
            instead of a single stream.
            
        ``output_stream``
            If set to a file-like object, data produced by the git command will be 
            output to the given stream directly.
            This feature only has any effect if as_process is False. Processes will
            always be created with a pipe due to issues with subprocess.
            This merely is a workaround as data will be copied from the 
            output pipe to the given output stream directly.
            
        
        Returns::
        
         str(output)                                   # extended_output = False (Default)
         tuple(int(status), str(stdout), str(stderr)) # extended_output = True
         
         if ouput_stream is True, the stdout value will be your output stream:
         output_stream                                  # extended_output = False
         tuple(int(status), output_stream, str(stderr))# extended_output = True
        
        Raise
            GitCommandError
        
        NOTE
           If you add additional keyword arguments to the signature of this method, 
           you must update the execute_kwargs tuple housed in this module.
        """
        if GIT_PYTHON_TRACE and not GIT_PYTHON_TRACE == 'full':
            print ' '.join(command)

        # Allow the user to have the command executed in their working dir.
        if with_keep_cwd or self._working_dir is None:
          cwd = os.getcwd()
        else:
          cwd=self._working_dir
          
        # Start the process
        proc = subprocess.Popen(command,
                                cwd=cwd,
                                stdin=istream,
                                stderr=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                **extra
                                )
        if as_process:
            return self.AutoInterrupt(proc, command)
        
        # Wait for the process to return
        status = 0
        stdout_value = ''
        stderr_value = ''
        try:
            if output_stream is None:
                stdout_value = proc.stdout.read().rstrip()      # strip trailing "\n"
            else:
                max_chunk_size = 1024*64
                while True:
                    chunk = proc.stdout.read(max_chunk_size)
                    output_stream.write(chunk)
                    if len(chunk) < max_chunk_size:
                        break
                # END reading output stream
                stdout_value = output_stream
            # END stdout handling
            stderr_value = proc.stderr.read().rstrip()          # strip trailing "\n"
            
            # waiting here should do nothing as we have finished stream reading
            status = proc.wait()
        finally:
            proc.stdout.close()
            proc.stderr.close()

        if with_exceptions and status != 0:
            raise GitCommandError(command, status, stderr_value)

        if GIT_PYTHON_TRACE == 'full':
            if stderr_value:
              print "%s -> %d: '%s' !! '%s'" % (command, status, stdout_value, stderr_value)
            elif stdout_value:
              print "%s -> %d: '%s'" % (command, status, stdout_value)
            else:
              print "%s -> %d" % (command, status)

        # Allow access to the command's status code
        if with_extended_output:
            return (status, stdout_value, stderr_value)
        else:
            return stdout_value