Example #1
0
def run_commit_hook(name, index):
    """Run the commit hook of the given name. Silently ignores hooks that do not exist.
    :param name: name of hook, like 'pre-commit'
    :param index: IndexFile instance
    :raises HookExecutionError: """
    hp = hook_path(name, index.repo.git_dir)
    if not os.access(hp, os.X_OK):
        return

    env = os.environ.copy()
    env['GIT_INDEX_FILE'] = index.path
    env['GIT_EDITOR'] = ':'
    cmd = subprocess.Popen(hp,
                           env=env,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           cwd=index.repo.working_dir,
                           close_fds=(os.name == 'posix'))
    stdout, stderr = cmd.communicate()
    cmd.stdout.close()
    cmd.stderr.close()

    if cmd.returncode != 0:
        stdout = force_text(stdout, defenc)
        stderr = force_text(stderr, defenc)
        raise HookExecutionError(hp, cmd.returncode, stdout, stderr)
Example #2
0
def run_commit_hook(name, index):
    """Run the commit hook of the given name. Silently ignores hooks that do not exist.
    :param name: name of hook, like 'pre-commit'
    :param index: IndexFile instance
    :raises HookExecutionError: """
    hp = hook_path(name, index.repo.git_dir)
    if not os.access(hp, os.X_OK):
        return

    env = os.environ.copy()
    env['GIT_INDEX_FILE'] = index.path
    env['GIT_EDITOR'] = ':'
    cmd = subprocess.Popen(hp,
                           env=env,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           cwd=index.repo.working_dir,
                           close_fds=(os.name == 'posix'))
    stdout, stderr = cmd.communicate()
    cmd.stdout.close()
    cmd.stderr.close()

    if cmd.returncode != 0:
        stdout = force_text(stdout, defenc)
        stderr = force_text(stderr, defenc)
        raise HookExecutionError(hp, cmd.returncode, stdout, stderr)
Example #3
0
def run_commit_hook(name, index):
    """Run the commit hook of the given name. Silently ignores hooks that do not exist.
    :param name: name of hook, like 'pre-commit'
    :param index: IndexFile instance
    :raises HookExecutionError: """
    hp = hook_path(name, index.repo.git_dir)
    if not os.access(hp, os.X_OK):
        return

    env = os.environ.copy()
    env['GIT_INDEX_FILE'] = safe_decode(index.path) if PY3 else safe_encode(index.path)
    env['GIT_EDITOR'] = ':'
    try:
        cmd = subprocess.Popen(hp,
                               env=env,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               cwd=index.repo.working_dir,
                               close_fds=is_posix,
                               creationflags=PROC_CREATIONFLAGS,)
    except Exception as ex:
        raise HookExecutionError(hp, ex)
    else:
        stdout = []
        stderr = []
        handle_process_output(cmd, stdout.append, stderr.append, finalize_process)
        stdout = ''.join(stdout)
        stderr = ''.join(stderr)
        if cmd.returncode != 0:
            stdout = force_text(stdout, defenc)
            stderr = force_text(stderr, defenc)
            raise HookExecutionError(hp, cmd.returncode, stdout, stderr)
Example #4
0
def run_commit_hook(name, index, *args):
    """Run the commit hook of the given name. Silently ignores hooks that do not exist.
    :param name: name of hook, like 'pre-commit'
    :param index: IndexFile instance
    :param args: arguments passed to hook file
    :raises HookExecutionError: """
    hp = hook_path(name, index.repo.git_dir)
    if not os.access(hp, os.X_OK):
        return

    env = os.environ.copy()
    env['GIT_INDEX_FILE'] = safe_decode(index.path) if PY3 else safe_encode(index.path)
    env['GIT_EDITOR'] = ':'
    try:
        cmd = subprocess.Popen([hp] + list(args),
                               env=env,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               cwd=index.repo.working_dir,
                               close_fds=is_posix,
                               creationflags=PROC_CREATIONFLAGS,)
    except Exception as ex:
        raise HookExecutionError(hp, ex)
    else:
        stdout = []
        stderr = []
        handle_process_output(cmd, stdout.append, stderr.append, finalize_process)
        stdout = ''.join(stdout)
        stderr = ''.join(stderr)
        if cmd.returncode != 0:
            stdout = force_text(stdout, defenc)
            stderr = force_text(stderr, defenc)
            raise HookExecutionError(hp, cmd.returncode, stderr, stdout)
Example #5
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(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 = []
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()
        handle_process_output(proc,
                              None,
                              progress_handler,
                              finalizer=None,
                              decode_streams=False)

        stderr_text = progress.error_lines and '\n'.join(
            progress.error_lines) or ''
        proc.wait(stderr=stderr_text)
        if stderr_text:
            log.warning("Error lines received while fetching: %s", stderr_text)

        for line in progress.other_lines:
            line = force_text(line)
            for cmd in cmds:
                if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                    fetch_info_lines.append(line)
                    continue

        # read head information
        with open(osp.join(self.repo.common_dir, 'FETCH_HEAD'), 'rb') as fp:
            fetch_head_info = [l.decode(defenc) for l in fp.readlines()]

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            log.debug("info lines: " + str(fetch_info_lines))
            log.debug("head info : " + str(fetch_head_info))
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #6
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(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()
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()

        stderr_text = None

        for line in proc.stderr:
            line = force_text(line)
            for pline in progress_handler(line):
                # END handle special messages
                for cmd in cmds:
                    if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                        fetch_info_lines.append(line)
                        continue
                    # end find command code
                # end for each comand code we know
            # end for each line progress didn't handle
        # end
        if progress.error_lines():
            stderr_text = '\n'.join(progress.error_lines())

        finalize_process(proc, stderr=stderr_text)

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb')
        fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
        fp.close()

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #7
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(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()
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()

        stderr_text = None

        for line in proc.stderr:
            line = force_text(line)
            for pline in progress_handler(line):
                # END handle special messages
                for cmd in cmds:
                    if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                        fetch_info_lines.append(line)
                        continue
                    # end find command code
                # end for each comand code we know
            # end for each line progress didn't handle
        # end
        if progress.error_lines():
            stderr_text = '\n'.join(progress.error_lines())
            
        finalize_process(proc, stderr=stderr_text)

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb')
        fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
        fp.close()

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization
        
        output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line)
                      for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #8
0
def run_commit_hook(name: str, index: 'IndexFile', *args: str) -> None:
    """Run the commit hook of the given name. Silently ignores hooks that do not exist.
    :param name: name of hook, like 'pre-commit'
    :param index: IndexFile instance
    :param args: arguments passed to hook file
    :raises HookExecutionError: """
    hp = hook_path(name, index.repo.git_dir)
    if not os.access(hp, os.X_OK):
        return None

    env = os.environ.copy()
    env['GIT_INDEX_FILE'] = safe_decode(str(index.path))
    env['GIT_EDITOR'] = ':'
    cmd = [hp]
    try:
        if is_win and not _has_file_extension(hp):
            # Windows only uses extensions to determine how to open files
            # (doesn't understand shebangs). Try using bash to run the hook.
            relative_hp = Path(hp).relative_to(
                index.repo.working_dir).as_posix()
            cmd = ["bash.exe", relative_hp]

        cmd = subprocess.Popen(
            cmd + list(args),
            env=env,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=index.repo.working_dir,
            close_fds=is_posix,
            creationflags=PROC_CREATIONFLAGS,
        )
    except Exception as ex:
        raise HookExecutionError(hp, ex) from ex
    else:
        stdout_list: List[str] = []
        stderr_list: List[str] = []
        handle_process_output(cmd, stdout_list.append, stderr_list.append,
                              finalize_process)
        stdout = ''.join(stdout_list)
        stderr = ''.join(stderr_list)
        if cmd.returncode != 0:
            stdout = force_text(stdout, defenc)
            stderr = force_text(stderr, defenc)
            raise HookExecutionError(hp, cmd.returncode, stderr, stdout)
Example #9
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(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 = []
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()
        handle_process_output(proc, None, progress_handler, finalizer=None, decode_streams=False)

        stderr_text = progress.error_lines and '\n'.join(progress.error_lines) or ''
        proc.wait(stderr=stderr_text)
        if stderr_text:
            log.warning("Error lines received while fetching: %s", stderr_text)

        for line in progress.other_lines:
            line = force_text(line)
            for cmd in cmds:
                if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                    fetch_info_lines.append(line)
                    continue

        # read head information
        with open(osp.join(self.repo.common_dir, 'FETCH_HEAD'), 'rb') as fp:
            fetch_head_info = [l.decode(defenc) for l in fp.readlines()]

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            log.debug("info lines: " + str(fetch_info_lines))
            log.debug("head info : " + str(fetch_head_info))
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line)
                      for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #10
0
def run_commit_hook(name: str, index: 'IndexFile', *args: str) -> None:
    """Run the commit hook of the given name. Silently ignores hooks that do not exist.
    :param name: name of hook, like 'pre-commit'
    :param index: IndexFile instance
    :param args: arguments passed to hook file
    :raises HookExecutionError: """
    hp = hook_path(name, index.repo.git_dir)
    if not os.access(hp, os.X_OK):
        return None

    env = os.environ.copy()
    env['GIT_INDEX_FILE'] = safe_decode(str(index.path))
    env['GIT_EDITOR'] = ':'
    try:
        cmd = subprocess.Popen(
            [hp] + list(args),
            env=env,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=index.repo.working_dir,
            close_fds=is_posix,
            creationflags=PROC_CREATIONFLAGS,
        )
    except Exception as ex:
        raise HookExecutionError(hp, ex) from ex
    else:
        stdout_list = []  # type:  List[str]
        stderr_list = []  # type:  List[str]
        handle_process_output(cmd, stdout_list.append, stderr_list.append,
                              finalize_process)
        stdout = ''.join(stdout_list)
        stderr = ''.join(stderr_list)
        if cmd.returncode != 0:
            stdout = force_text(stdout, defenc)
            stderr = force_text(stderr, defenc)
            raise HookExecutionError(hp, cmd.returncode, stderr, stdout)
Example #11
0
 def _value_to_string(self, value: Union[str, bytes, int, float,
                                         bool]) -> str:
     if isinstance(value, (int, float, bool)):
         return str(value)
     return force_text(value)
Example #12
0
 def _value_to_string(self, value):
     if isinstance(value, (int, float, bool)):
         return str(value)
     return force_text(value)
Example #13
0
 def _value_to_string(self, value):
     if isinstance(value, (int, float, bool)):
         return str(value)
     return force_text(value)
Example #14
0
    def _get_fetch_info_from_stderr(self, proc: 'Git.AutoInterrupt',
                                    progress: Union[Callable[..., Any], RemoteProgress, None],
                                    kill_after_timeout: Union[None, float] = None,
                                    ) -> IterableList['FetchInfo']:

        progress = to_progress_instance(progress)

        # skip first line as it is some remote info we are not interested in
        output: IterableList['FetchInfo'] = 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 = []
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()
        handle_process_output(proc, None, progress_handler, finalizer=None, decode_streams=False,
                              kill_after_timeout=kill_after_timeout)

        stderr_text = progress.error_lines and '\n'.join(progress.error_lines) or ''
        proc.wait(stderr=stderr_text)
        if stderr_text:
            log.warning("Error lines received while fetching: %s", stderr_text)

        for line in progress.other_lines:
            line = force_text(line)
            for cmd in cmds:
                if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                    fetch_info_lines.append(line)
                    continue

        # read head information
        fetch_head = SymbolicReference(self.repo, "FETCH_HEAD")
        with open(fetch_head.abspath, 'rb') as fp:
            fetch_head_info = [line.decode(defenc) for line in fp.readlines()]

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            log.debug(b"info lines: " + str(fetch_info_lines).encode("UTF-8"))
            log.debug(b"head info: " + str(fetch_head_info).encode("UTF-8"))
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info):
            try:
                output.append(FetchInfo._from_line(self.repo, err_line, fetch_line))
            except ValueError as exc:
                log.debug("Caught error while parsing line: %s", exc)
                log.warning("Git informed while fetching: %s", err_line.strip())
        return output