Пример #1
0
	def _get_fetch_info_from_stderr(self, proc, progress):
		# skip first line as it is some remote info we are not interested in
		output = IterableList('name')
		
		
		# lines which are no progress are fetch info lines
		# this also waits for the command to finish
		# Skip some progress lines that don't provide relevant information
		fetch_info_lines = list()
		for line in digest_process_messages(proc.stderr, progress):
			if line.startswith('From') or line.startswith('remote: Total'):
				continue
			elif line.startswith('warning:'):
				print >> sys.stderr, line
				continue
			elif line.startswith('fatal:'):
				raise GitCommandError(("Error when fetching: %s" % line,), 2)
			# END handle special messages
			fetch_info_lines.append(line)
		# END for each line
		
		# read head information 
		fp = open(join(self.repo.git_dir, 'FETCH_HEAD'),'r')
		fetch_head_info = fp.readlines()
		fp.close()
		
		assert len(fetch_info_lines) == len(fetch_head_info), "len(%s) != len(%s)" % (fetch_head_info, fetch_info_lines)
		
		output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) 
						for err_line,fetch_line in zip(fetch_info_lines, fetch_head_info))
		
		finalize_process(proc)
		return output
Пример #2
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
Пример #3
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        # skip first line as it is some remote info we are not interested in
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = list()
        for line in digest_process_messages(proc.stderr, progress):
            if line.startswith('From') or line.startswith('remote: Total') or line.startswith('POST') \
                    or line.startswith(' ='):
                continue
            elif line.startswith('warning:'):
                print >> sys.stderr, line
                continue
            elif line.startswith('fatal:'):
                raise GitCommandError(("Error when fetching: %s" % line, ), 2)
            # END handle special messages
            fetch_info_lines.append(line)
        # END for each line

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'r')
        fetch_head_info = fp.readlines()
        fp.close()

        # NOTE: HACK Just disabling this line will make github repositories work much better.
        # I simply couldn't stand it anymore, so here is the quick and dirty fix ... .
        # This project needs a lot of work !
        # assert len(fetch_info_lines) == len(fetch_head_info), "len(%s) != len(%s)" % (fetch_head_info, fetch_info_lines)

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))

        finalize_process(proc)
        return output
Пример #4
0
    def execute(self,
                command,
                istream=None,
                with_keep_cwd=False,
                with_extended_output=False,
                with_exceptions=True,
                as_process=False,
                output_stream=None,
                output_strip=True,
                **subprocess_kwargs):
        """Handles executing the command on the shell and consumes and returns
        the returned information (stdout)

        :param 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.

        :param istream:
            Standard input filehandle passed to subprocess.Popen.

        :param 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.

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

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

        :param 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.
            
        :param 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.
            
        :param output_strip:
            Strip the last line of the output if it is empty (default). Stripping should
            be disabled whenever it is important that the output is not modified in any
            way. For example when retrieving patch files using git-diff.
            
        :param subprocess_kwargs:
            Keyword arguments to be passed to subprocess.Popen. Please note that 
            some of the valid kwargs are already set by this method, the ones you 
            specify may not be the same ones.
            
        :return:
            * str(output) if extended_output = False (Default)
            * tuple(int(status), str(stdout), str(stderr)) if extended_output = True
             
            if ouput_stream is True, the stdout value will be your output stream:
            * output_stream if extended_output = False
            * tuple(int(status), output_stream, str(stderr)) if 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 self.GIT_PYTHON_TRACE and not self.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
        env = os.environ.copy()
        env['LANG'] = 'C'
        proc = Popen(
            command,
            cwd=cwd,
            stdin=istream,
            stderr=PIPE,
            stdout=PIPE,
            close_fds=(os.name == 'posix'),  # unsupported on linux
            env=env,
            **subprocess_kwargs)
        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, stderr_value = proc.communicate()
                # strip trailing "\n"
                if stdout_value.endswith("\n") and output_strip:
                    stdout_value = stdout_value[:-1]
                if stderr_value.endswith("\n"):
                    stderr_value = stderr_value[:-1]
                status = proc.returncode
            else:
                stream_copy(proc.stdout, output_stream, self.max_chunk_size)
                stdout_value = output_stream
                stderr_value = proc.stderr.read()
                # strip trailing "\n"
                if stderr_value.endswith("\n"):
                    stderr_value = stderr_value[:-1]
                status = proc.wait()
            # END stdout handling
        finally:
            proc.stdout.close()
            proc.stderr.close()

        if self.GIT_PYTHON_TRACE == 'full':
            cmdstr = " ".join(command)
            if stderr_value:
                print "%s -> %d; stdout: '%s'; stderr: '%s'" % (
                    cmdstr, status, stdout_value, stderr_value)
            elif stdout_value:
                print "%s -> %d; stdout: '%s'" % (cmdstr, status, stdout_value)
            else:
                print "%s -> %d" % (cmdstr, status)
        # END handle debug printing

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

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