def _execute_build_cmd(self, build_command, name, run_id): path = build_command.location if not path or path == ".": path = os.getcwd() script = build_command.command self._scheduler.indicate_build(run_id) self._ui.debug_output_info("Start build\n", None, script, path) def _keep_alive(seconds): self._ui.warning( "Keep alive. current job runs since %dmin\n" % (seconds / 60), run_id, script, path) try: return_code, stdout_result, stderr_result = subprocess_timeout.run( '/bin/sh', path, False, True, stdin_input=str.encode(script), keep_alive_output=_keep_alive) except OSError as err: build_command.mark_failed() run_id.fail_immediately() run_id.report_run_failed( script, err.errno, "Build of " + name + " failed.") if err.errno == 2: msg = ("{ind}Build of %s failed.\n" + "{ind}{ind}It failed with: %s.\n" + "{ind}{ind}File name: %s\n") % (name, err.strerror, err.filename) else: msg = str(err) self._ui.error(msg, run_id, script, path) return stdout_result = coerce_string(stdout_result.decode('utf-8')) stderr_result = coerce_string(stderr_result.decode('utf-8')) if self._build_log: self.process_output(name, stdout_result, stderr_result) if return_code != 0: build_command.mark_failed() run_id.fail_immediately() run_id.report_run_failed( script, return_code, "Build of " + name + " failed.") self._ui.error("{ind}Build of " + name + " failed.\n", None, script, path) if stdout_result and stdout_result.strip(): lines = escape_braces(stdout_result).split('\n') self._ui.error("{ind}stdout:\n\n{ind}{ind}" + "\n{ind}{ind}".join(lines) + "\n") if stderr_result and stderr_result.strip(): lines = escape_braces(stderr_result).split('\n') self._ui.error("{ind}stderr:\n\n{ind}{ind}" + "\n{ind}{ind}".join(lines) + "\n") raise FailedBuilding(name, build_command) build_command.mark_succeeded()
def format(self, record): """ Apply level-specific styling to log records. :param record: A :class:`~logging.LogRecord` object. :returns: The result of :func:`logging.Formatter.format()`. This method injects ANSI escape sequences that are specific to the level of each log record (because such logic cannot be expressed in the syntax of a log format string). It works by making a copy of the log record, changing the `msg` field inside the copy and passing the copy into the :func:`~logging.Formatter.format()` method of the base class. """ style = self.nn.get(self.level_styles, record.levelname) if style: # Due to the way that Python's logging module is structured and # documented the only (IMHO) clean way to customize its behavior is # to change incoming LogRecord objects before they get to the base # formatter. However we don't want to break other formatters and # handlers, so we'll copy the log record. record = copy.copy(record) record.msg = ansi_wrap(coerce_string(record.msg), **style) # Delegate the remaining formatting to the base formatter. return logging.Formatter.format(self, record)
def _execute_build_cmd(self, build_command, name, run_id): path = build_command.location if not path or path == ".": path = os.getcwd() script = build_command.command self._ui.debug_output_info("Start build\n", None, script, path) def _keep_alive(seconds): self._ui.warning( "Keep alive. current job runs since %dmin" % (seconds / 60), run_id, script, path) return_code, stdout_result, stderr_result = subprocess_timeout.run( '/bin/sh', path, False, True, stdin_input=str.encode(script), keep_alive_output=_keep_alive) stdout_result = coerce_string(stdout_result.decode('utf-8')) stderr_result = coerce_string(stderr_result.decode('utf-8')) if self._build_log: self.process_output(name, stdout_result, stderr_result) if return_code != 0: build_command.mark_failed() run_id.fail_immediately() run_id.report_run_failed(script, return_code, "Build of " + name + " failed.") self._ui.error("{ind}Build of " + name + " failed.\n", None, script, path) if stdout_result and stdout_result.strip(): lines = stdout_result.split('\n') self._ui.error("{ind}stdout:\n\n{ind}{ind}" + "\n{ind}{ind}".join(lines) + "\n") if stderr_result and stderr_result.strip(): lines = stderr_result.split('\n') self._ui.error("{ind}stderr:\n\n{ind}{ind}" + "\n{ind}{ind}".join(lines) + "\n") raise FailedBuilding(name, build_command) else: build_command.mark_succeeded()
def _output(self, text, color, *args, **kw): self._erase_spinner() text = coerce_string(text) if terminal_supports_colors(sys.stdout): text = ansi_wrap(text, color=color) auto_encode(sys.stdout, text, ind=_DETAIL_INDENT, *args, **kw) sys.stdout.flush()
def normalize_columns(row, expandtabs=False): results = [] for value in row: text = coerce_string(value) if expandtabs: text = text.expandtabs() results.append(text) return results
def _output(self, text, color, *args, **kw): if self._need_to_erase_spinner: if self._progress_spinner and self._progress_spinner.interactive: sys.stdout.write(erase_line_code) self._need_to_erase_spinner = False text = coerce_string(text) if terminal_supports_colors(sys.stdout): text = ansi_wrap(text, color=color) auto_encode(sys.stdout, text, ind=_DETAIL_INDENT, *args, **kw)
def format(self, record): style = self.nn.get(self.level_styles, record.levelname) if style and coloredlogs.Empty is not None: copy = coloredlogs.Empty() copy.__class__ = record.__class__ copy.__dict__.update(record.__dict__) copy.levelname = ansi_wrap(coerce_string(record.levelname), **style) record = copy # Delegate the remaining formatting to the base formatter. return logging.Formatter.format(self, record)
def output(text, *args, **kw): """ Print a formatted message to the standard output stream. For details about argument handling please refer to :func:`~humanfriendly.text.format()`. Renders the message using :func:`~humanfriendly.text.format()` and writes the resulting string (followed by a newline) to :data:`sys.stdout` using :func:`auto_encode()`. """ auto_encode(sys.stdout, coerce_string(text) + '\n', *args, **kw)
def message(text, *args, **kw): """ Print a formatted message to the standard error stream. For details about argument handling please refer to :func:`~humanfriendly.text.format()`. Renders the message using :func:`~humanfriendly.text.format()` and writes the resulting string (followed by a newline) to :data:`sys.stderr` using :func:`auto_encode()`. """ auto_encode(sys.stderr, coerce_string(text) + '\n', *args, **kw)
def format(self, record): """ Apply level-specific styling to log records. :param record: A :class:`~logging.LogRecord` object. :returns: The result of :func:`logging.Formatter.format()`. This method injects ANSI escape sequences that are specific to the level of each log record (because such logic cannot be expressed in the syntax of a log format string). It works by making a copy of the log record, changing the `msg` field inside the copy and passing the copy into the :func:`~logging.Formatter.format()` method of the base class. """ style = self.nn.get(self.level_styles, record.levelname) # After the introduction of the `Empty' class it was reported in issue # 33 that format() can be called when `Empty' has already been garbage # collected. This explains the (otherwise rather out of place) `Empty # is not None' check in the following `if' statement. The reasoning # here is that it's much better to log a message without formatting # then to raise an exception ;-). # # For more details refer to issue 33 on GitHub: # https://github.com/xolox/python-coloredlogs/issues/33 if style and Empty is not None: # Due to the way that Python's logging module is structured and # documented the only (IMHO) clean way to customize its behavior is # to change incoming LogRecord objects before they get to the base # formatter. However we don't want to break other formatters and # handlers, so we copy the log record. # # In the past this used copy.copy() but as reported in issue 29 # (which is reproducible) this can cause deadlocks. The following # Python voodoo is intended to accomplish the same thing as # copy.copy() without all of the generalization and overhead that # we don't need for our -very limited- use case. # # For more details refer to issue 29 on GitHub: # https://github.com/xolox/python-coloredlogs/issues/29 copy = Empty() copy.__class__ = logging.LogRecord copy.__dict__.update(record.__dict__) copy.msg = ansi_wrap(coerce_string(record.msg), **style) record = copy # Delegate the remaining formatting to the base formatter. return logging.Formatter.format(self, record)
def warning(text, *args, **kw): """ Show a warning message on the terminal. For details about argument handling please refer to :func:`~humanfriendly.text.format()`. Renders the message using :func:`~humanfriendly.text.format()` and writes the resulting string (followed by a newline) to :data:`sys.stderr` using :func:`auto_encode()`. If :data:`sys.stderr` is connected to a terminal that supports colors, :func:`ansi_wrap()` is used to color the message in a red font (to make the warning stand out from surrounding text). """ text = coerce_string(text) if terminal_supports_colors(sys.stderr): text = ansi_wrap(text, color='red') auto_encode(sys.stderr, text + '\n', *args, **kw)
def _read(stream): data = stream.readline() decoded = data.decode('utf-8') return coerce_string(decoded)
def normalize_columns(row): return [coerce_string(c) for c in row]
def output(text, *args, **kw): auto_encode(sys.stdout, coerce_string(text) + '\n', *args, **kw)
def _execute_build_cmd(self, build_command, name, run_id): path = build_command.location if not path or path == ".": path = os.getcwd() script = build_command.command self._scheduler.indicate_build(run_id) self._ui.debug_output_info("Start build\n", None, script, path) def _keep_alive(seconds): self._ui.warning( "Keep alive. current job runs since %dmin\n" % (seconds / 60), run_id, script, path) try: return_code, stdout_result, stderr_result = subprocess_timeout.run( '/bin/sh', path, False, True, stdin_input=str.encode(script), keep_alive_output=_keep_alive) except OSError as err: build_command.mark_failed() run_id.fail_immediately() run_id.report_run_failed(script, err.errno, "Build of " + name + " failed.") if err.errno == 2: msg = ("{ind}Build of %s failed.\n" + "{ind}{ind}It failed with: %s.\n" + "{ind}{ind}File name: %s\n") % (name, err.strerror, err.filename) else: msg = str(err) self._ui.error(msg, run_id, script, path) return stdout_result = coerce_string(stdout_result.decode('utf-8')) stderr_result = coerce_string(stderr_result.decode('utf-8')) if self._build_log: self.process_output(name, stdout_result, stderr_result) if return_code != 0: build_command.mark_failed() run_id.fail_immediately() run_id.report_run_failed(script, return_code, "Build of " + name + " failed.") self._ui.error("{ind}Build of " + name + " failed.\n", None, script, path) if stdout_result and stdout_result.strip(): lines = escape_braces(stdout_result).split('\n') self._ui.error("{ind}stdout:\n\n{ind}{ind}" + "\n{ind}{ind}".join(lines) + "\n") if stderr_result and stderr_result.strip(): lines = escape_braces(stderr_result).split('\n') self._ui.error("{ind}stderr:\n\n{ind}{ind}" + "\n{ind}{ind}".join(lines) + "\n") raise FailedBuilding(name, build_command) build_command.mark_succeeded()
def escape_braces(string): string = coerce_string(string) return string.replace('{', '{{').replace('}', '}}')
def output(self, text, *args, **kw): self._erase_spinner() auto_encode(sys.stdout, coerce_string(text) + '\n', *args, **kw) sys.stdout.flush()