def test_step_reporter(power_env, pw_cycle_test, color_scheme, pytest_extra_param): from colors import strip_color env = os.environ.copy() if color_scheme: env["LG_COLOR_SCHEME"] = color_scheme # step reporter is called when -vv is given # -s is necessary for manual power driver confirmation with pexpect.spawn('pytest -vvs {param} --lg-env {env} {test}'.format( param=pytest_extra_param, env=power_env, test=pw_cycle_test), env=env) as spawn: # rough match spawn.expect("cycle.*?state.*?=.*?start.*?\r\n") step_line = strip_color(spawn.after.decode("utf-8")).rstrip() # exact match assert step_line.endswith("cycle state='start'") spawn.expect("main: CYCLE the target None and press enter") spawn.sendline() # rough match spawn.expect("cycle.*?state.*?=.*?stop.*?\r\n") step_line = strip_color(spawn.after.decode("utf-8")).rstrip() # exact match assert step_line.endswith("cycle state='stop'") spawn.expect(pexpect.EOF) spawn.close() assert spawn.exitstatus == 0
def box_print(lines, icon, width=None): if width is None: width = 0 for line in lines: width = max(width, len(strip_color(line))) print(f'Рћї{"Рћђ" * (width - 3)} {icon} РћђРћљ') for line in lines: padding = width - len(strip_color(line)) print(f'Рћѓ {line}{" " * padding} Рћѓ') print(f'Рћћ{"Рћђ" * (width + 2)}Рћў')
def box_print(lines, icon, width=None): if width is None: width = 0 for line in lines: width = max(width, len(strip_color(line))) print(f'┌{"─" * (width - 3)} {icon} ─┐') for line in lines: padding = width - len(strip_color(line)) print(f'│ {line}{" " * padding} │') print(f'└{"─" * (width + 2)}┘')
def do_commands(lines): for line in lines: sys.stdout.write(colors.blue(prompt)) type_it_out(line) time.sleep(0.5) print os.system(colors.strip_color(line))
def _run(self, store, work_data, interrupt_data, args): work = work_data + interrupt_data log = defaultdict(lambda: {'delta': timedelta()}) current = store.get_recent_item() sum = 0 time_required = 0 if args["period"] is not None: days_prior = timedelta(days=args["period"]) else: days_prior = None counted_days = [] for item in work: if days_prior is None or (item.get_end().date() >= (datetime.today() - days_prior).date()): log[item.get_name()]["delta"] += item.get_delta() sum += item.get_delta().total_seconds() if item.get_start().date() not in counted_days\ and self.work_per_day is not None\ and str(item.get_end().date().weekday()) in self.workdays: time_required += self.work_per_day # This doesn't work if a log crosses dates. (e.g. starts on the first january and ends on the second counted_days.append(item.get_end().date()) name_col_len = 0 for name, item in log.items(): name_col_len = max(name_col_len, len(colors.strip_color(name))) secs = item['delta'].total_seconds() tmsg = [] if secs > 3600: hours = int(secs // 3600) secs -= hours * 3600 tmsg.append(str(hours) + ' hour' + ('s' if hours > 1 else '')) if secs > 60: mins = int(secs // 60) secs -= mins * 60 tmsg.append(str(mins) + ' minute' + ('s' if mins > 1 else '')) log[name]['tmsg'] = ', '.join(tmsg)[::-1].replace(',', '& ', 1)[::-1] for name, item in sorted(log.items(), key=(lambda x: x[1]), reverse=True): end = ' ← working' if current.get_name( ) == name and current.is_running() else '' print(colors.ljust_with_color(name, name_col_len), ' ∙∙ ', item['tmsg'], end) left_work = time_required - sum print("You worked in total: ", format_duration(sum)) if self.work_per_day is not None: print(("You still need to work: " if left_work > 0 else "You worked more than necessary: ") + format_duration(abs(left_work)))
def get_lines(parts, indent, prefix=None): lines = [] line = [] if prefix is not None: line_len = len(prefix) - 1 else: line_len = len(indent) - 1 for part in parts: if line_len + 1 + len(strip_color(part)) > text_width and line: lines.append(indent + ' '.join(line)) line = [] line_len = len(indent) - 1 line.append(part) line_len += len(strip_color(part)) + 1 if line: lines.append(indent + ' '.join(line)) if prefix is not None: lines[0] = lines[0][len(indent):] return lines
def writeText(self, text): if len(text) == 1 and ord(text) == 7: return #TO-DO deal with text colour text = strip_color(text) # if special key pressed, dealing with it, otherwise write to output if not self.dealingWithSpecialKey(text): self.outputCtrl.WriteText(text) self.lastPosition = self.outputCtrl.GetLastPosition() self.lastFreezePosition = self.lastPosition # scroll to the end of output #self.outputCtrl.SetScrollPos( wx.VERTICAL,self.outputCtrl.GetScrollRange(wx.VERTICAL)) self.outputCtrl.ShowPosition(self.outputCtrl.GetLastPosition())
def _finalize_subm(submission, result): final_stat = result.final_stat # guard against infinite loop if final_stat.verdict == 0: final_stat.verdict = common_pb2.SERR submission.submission_len = result.code_length submission.submission_score = final_stat.score submission.submission_status = final_stat.verdict if result.log['COMPILE_STDERR']: log = result.log['COMPILE_STDERR'] else: log = result.log['COMPILE_STDOUT'] if log.truncated: log += '[[[TRUNCATED]]]' submission.submission_error = strip_color(log.content) return submission
def extract(self, compile_output): def safe_get_named_group(match, name): try: return match.group(name) except IndexError: return None def get_matched_error(match): source = safe_get_named_group(match, 'filename') lineno = safe_get_named_group(match, 'lineno') classname = safe_get_named_group(match, 'classname') if not classname: classnameonly = safe_get_named_group(match, 'classnameonly') packagename = safe_get_named_group(match, 'packagename') if classnameonly and packagename: classname = '.'.join([packagename, classnameonly]) if classname: classname = normalize_classname(classname) return ClassNotFoundError(source, lineno, classname) errors = [] start = 0 compile_output = strip_color(compile_output) while start < len(compile_output): first_match = None for p in self._error_patterns: m = p.search(compile_output, start) if m: if not first_match or m.start() < first_match.start(): first_match = m if not first_match: break errors.append(get_matched_error(first_match)) start = first_match.end() + 1 return errors
def get_next_message(lines): if not lines: return (None, lines) line = lines[0] colorless_line = convert_smart_quotes_to_dumb_quotes( colors.strip_color(line)) m = re.match(r'^(\S.*?):(\d+):', colorless_line) if not m: return (None, lines) lines.pop(0) e = Message() e.file, e.line_number = m.groups() m = re.match(r'^\S.*?:\d+:(\d+):\s*(.*?):', colorless_line) if m: e.column, e.type = m.groups() e.text = [line] e.text_without_ansi_codes = [colorless_line] parsing_note = False while lines: next_line = lines[0] if not next_line: break colorless_next_line = colors.strip_color(lines[0]) m = re.match(r'^\S.*:\d+:', colorless_next_line) if m: if re.match(r'^\S.*?:\d+:\d+:\s*note:', colorless_next_line): parsing_note = True else: break lines.pop(0) if colorless_next_line.endswith(' generated.'): break if parsing_note: e.note.append(next_line) e.note_without_ansi_codes.append(colorless_next_line) continue if re.match(r"^[ ~]*\^[ ~]*$", colorless_next_line): previous_line = e.text_without_ansi_codes[-1] m = re.match(r"^(.*)\^~+", colorless_next_line) if m: e.highlighted_word = previous_line[len(m.group(1) ):len(m.group(0))] else: caret_index = colorless_next_line.index('^') m = re.match(r"^\w*", previous_line[caret_index:]) e.highlighted_word = m.group(0) e.underlined_word = '' m = re.match(r"^(.*?)~+", colorless_next_line) if m: e.underlined_word = previous_line[len(m.group(1) ):len(m.group(0))] e.text.append(next_line) e.text_without_ansi_codes.append(colorless_next_line) return (e, lines)
def normalize(self, s): """Removes escape sequences (e.g. colored output) and all whitespace from string s.""" return ''.join(strip_color(s).split())
lines = lines.split('\n') if False: print(dir(covdata.numbers)) print(dir(covdata)) print(covdata.statements) assert len(lines) == covdata.numbers.n_statements print(dir(covdata)) print(covdata.branch_lines()) cfg = dict( branch_bg = 52, ) #formatter=Terminal256Formatter(style='solarized-dark'))) import string for (i, line) in enumerate(lines): spaces = fill - len(colors.strip_color(line)) spaces = ' ' * spaces if (i + 1) not in covdata.missing: if False:#(i + 1) in covdata.statements: print((colors.color(unichr(0x258f), fg=46, bg=22) + colors.color(line + spaces, bg=22)).encode('utf8')) else: if (i + 1) in covdata.excluded: line = colors.strip_color(line) print((colors.color(unichr(0x258f), fg=46, bg=236) + colors.color(line + spaces, bg=236, fg=242)).encode('utf8')) elif (i + 1) in covdata.branch_lines(): line = colors.strip_color(line) print((colors.color(unichr(0x258a), bg=cfg['branch_bg'], fg=160) + colors.color(line + spaces, bg=cfg['branch_bg'])).encode('utf8')) else: print((colors.color(unichr(0x258f), fg=46) + line + spaces).encode('utf8')) else: #print((colors.color(unichr(0x258f), fg=160, bg=236) + colors.color(line + spaces, bg=236)).encode('utf8'))
def diff_color(input_file, cfg): """ colorizes a diff file """ cov = cfg.data term_width = click.get_terminal_size()[0] modified = [] measured = cov.data.measured_files() diff = PatchSet(input_file) for thing in diff: if thing.is_modified_file or thing.is_added_file: target = thing.target_file if target.startswith('b/') or target.startswith('a/'): target = target[2:] if abspath(target) in measured: covdata = cov._analyze(abspath(target)) modified.append((thing, covdata)) print(abspath(target)) else: msg = "skip: {}".format(thing.target_file) msg = msg + (' ' * (term_width - len(msg))) print(colors.color(msg, bg='yellow', fg='black')) # else: # print("THING", dir(thing)) for (patch, covdata) in modified: fname = str(patch.target_file) + (' ' * (term_width - len(patch.target_file))) print(colors.color(fname, bg='cyan', fg='black')) for hunk in patch: for line in hunk: kw = dict() if line.is_added: if line.target_line_no in covdata.missing: click.echo(colors.color(u'\u258f', fg='red', bg=52), nl=False, color=True) kw['bg'] = 52 else: click.echo(colors.color(u'\u258f', fg='green'), nl=False, color=True) else: print(' ', end='') out = str(line) if line.is_added: kw['fg'] = 'green' elif line.is_removed: kw['fg'] = 'red' print(colors.color(out, **kw)) return target_fname = abspath(target_fname) for fname in cov.data.measured_files(): if target_fname == abspath(fname): match.append(fname) if len(match) != 1: if len(match) == 0: # this file wasn't in the coverage data, so we just dump # it to stdout as-is. (FIXME: ideally, also # syntax-highlighted anyway) with open(target_fname, 'r') as f: for line in f.readlines(): sys.stdout.write(line) return else: raise RuntimeError("Multiple matches: %s" % ', '.join(match)) fname = match[0] covdata = cov._analyze(fname) percent = 1.0 # if no statements, it's all covered, right? if covdata.numbers.n_statements: percent = float(covdata.numbers.n_statements - covdata.numbers.n_missing) / covdata.numbers.n_statements total_statements = covdata.numbers.n_statements total_missing = covdata.numbers.n_missing fill = min(click.get_terminal_size()[0], 80) print_banner(fname, percent, fill) # it was tempting to write/override/wrap this Formatter and mess # with the background color based on our coverage data -- and # that's not a terrible idea, but the way TerminalFormatter is # written, it's not very nice. Basically, we'd have to wrap the # output stream, look for ANSI reset codes, and re-do the # background color after each reset (for "uncovered" lines)... # so I didn't do that. Instead we just hack it by clearing *all* # formatting from the "uncovered" lines and make them all "grey on # red" formatter = TerminalFormatter(style=style) lines = highlight( open(fname).read(), get_lexer_by_name('python'), formatter=formatter, ) lines = lines.split(u'\n') for (i, line) in enumerate(lines): # assert type(line) is unicode spaces = fill - len(colors.strip_color(line)) spaces = u' ' * spaces if (i + 1) not in covdata.missing: if (i + 1) in covdata.excluded: line = colors.strip_color(line) click.echo(colors.color(u'\u258f', fg=46, bg=236) + colors.color(line + spaces, bg=236, fg=242), color=True) elif cfg.branch and (i + 1) in covdata.branch_lines(): line = colors.strip_color(line) click.echo(colors.color(u'\u258f', bg=52, fg=160) + colors.color(line + spaces, bg=52), color=True) else: click.echo(u'{}{}{}'.format(colors.color(u'\u258f', fg=46), line, spaces), color=True) else: # HACK-O-MATIC, uhm. Yeah, so what we're doing here is # splitting the output from the formatter on the ANSI # "reset" code, and the re-assembling it with the "52" # (dark red) background color. I appoligize in advance; # PRs with improvements encouraged! reset_code = u"\x1b[39;49;00m" segments = (line + spaces).split(reset_code) reset_plus_bg = u"\x1b[39;49;00m\x1b[39;49;48;5;52m" out = u"\x1b[39;49;48;5;52m" + reset_plus_bg.join(segments) click.echo(colors.color(u'\u258f', bg=52, fg=160) + out, color=True)
def term_color(target_fname, cfg, style='monokai'): cov = cfg.data target_fname = realpath(target_fname) match = filter( lambda f: target_fname == realpath(f), cov.data.measured_files() ) if len(match) > 1: raise RuntimeError("Multiple matches: %s" % ', '.join(match)) if len(match) == 0: # this file wasn't in the coverage data, so we just dump # it to stdout as-is. (FIXME: ideally, also # syntax-highlighted anyway) with open(target_fname, 'r') as f: sys.stdout.write( f.read() ) return fname = match[0] covdata = cov._analyze(fname) percent = 1.0 # if no statements, it's all covered, right? if covdata.numbers.n_statements: percent = float(covdata.numbers.n_statements - covdata.numbers.n_missing) / covdata.numbers.n_statements total_statements = covdata.numbers.n_statements total_missing = covdata.numbers.n_missing fill = min(click.get_terminal_size()[0], 80) print_banner(fname, percent, fill) # it was tempting to write/override/wrap this Formatter and mess # with the background color based on our coverage data -- and # that's not a terrible idea, but the way TerminalFormatter is # written, it's not very nice. Basically, we'd have to wrap the # output stream, look for ANSI reset codes, and re-do the # background color after each reset (for "uncovered" lines)... # so I didn't do that. Instead we just hack it by clearing *all* # formatting from the "uncovered" lines and make them all "grey on # red" formatter = TerminalFormatter(style=style) lines = highlight( open(fname).read(), get_lexer_by_name('python'), formatter=formatter, ) lines = lines.split(u'\n') for (i, line) in enumerate(lines): # assert type(line) is unicode spaces = fill - len(colors.strip_color(line)) spaces = u' ' * spaces if (i + 1) not in covdata.missing: if (i + 1) in covdata.excluded: line = colors.strip_color(line) click.echo(colors.color(u'\u258f', fg=46, bg=236) + colors.color(line + spaces, bg=236, fg=242), color=True) elif cfg.branch and (i + 1) in covdata.branch_lines(): line = colors.strip_color(line) click.echo(colors.color(u'\u258f', bg=52, fg=160) + colors.color(line + spaces, bg=52), color=True) else: click.echo(u'{}{}{}'.format(colors.color(u'\u258f', fg=46), line, spaces), color=True) else: # HACK-O-MATIC, uhm. Yeah, so what we're doing here is # splitting the output from the formatter on the ANSI # "reset" code, and the re-assembling it with the "52" # (dark red) background color. I appoligize in advance; # PRs with improvements encouraged! reset_code = u"\x1b[39;49;00m" segments = (line + spaces).split(reset_code) reset_plus_bg = u"\x1b[39;49;00m\x1b[39;49;48;5;52m" out = u"\x1b[39;49;48;5;52m" + reset_plus_bg.join(segments) click.echo(colors.color(u'\u258c', bg=52, fg=160) + out, color=True)
def test_f(): assert strip_color(red("foo")) == "foo"
def _wrap_chunks(self, chunks): # noqa: C901 """_wrap_chunks(chunks : [string]) -> [string] Wrap a sequence of text chunks and return a list of lines of length 'self.width' or less. (If 'break_long_words' is false, some lines may be longer than this.) Chunks correspond roughly to words and the whitespace between them: each chunk is indivisible (modulo 'break_long_words'), but a line break can come between any two chunks. Chunks should not have internal whitespace; ie. a chunk is either all whitespace or a "word". Whitespace chunks will be removed from the beginning and end of lines, but apart from that whitespace is preserved. """ lines = [] if self.width <= 0: raise ValueError("invalid width %r (must be > 0)" % self.width) if six.PY3: # pragma: no branch if self.max_lines is not None: if self.max_lines > 1: indent = self.subsequent_indent else: indent = self.initial_indent if len(indent) + len(self.placeholder.lstrip()) > self.width: raise ValueError("placeholder too large for max width") # Arrange in reverse order so items can be efficiently popped # from a stack of chucks. chunks.reverse() while chunks: # Start the list of chunks that will make up the current line. # cur_len is just the length of all the chunks in cur_line. cur_line = [] cur_len = 0 # Figure out which static string will prefix this line. if lines: indent = self.subsequent_indent else: indent = self.initial_indent # Maximum width for this line. width = self.width - len(indent) # First chunk on line is whitespace -- drop it, unless this # is the very beginning of the text (ie. no lines started yet). if self.drop_whitespace and strip_color(chunks[-1]).strip() == '' and lines: del chunks[-1] while chunks: # modified upstream code, not going to refactor for ambiguous variable name. l = len(strip_color(chunks[-1])) # noqa: E741 # Can at least squeeze this chunk onto the current line. # modified upstream code, not going to refactor for ambiguous variable name. if cur_len + l <= width: # noqa: E741 cur_line.append(chunks.pop()) cur_len += l # Nope, this line is full. else: break # The current line is full, and the next chunk is too big to # fit on *any* line (not just this one). if chunks and len(strip_color(chunks[-1])) > width: self._handle_long_word(chunks, cur_line, cur_len, width) cur_len = sum(map(len, cur_line)) # If the last chunk on this line is all whitespace, drop it. if self.drop_whitespace and cur_line and strip_color(cur_line[-1]).strip() == '': cur_len -= len(strip_color(cur_line[-1])) del cur_line[-1] if cur_line: if six.PY2: lines.append(indent + ''.join(cur_line)) else: if (self.max_lines is None or len(lines) + 1 < self.max_lines or (not chunks or self.drop_whitespace and len(chunks) == 1 and not chunks[0].strip()) and cur_len <= width): # Convert current line back to a string and store it in # list of all lines (return value). lines.append(indent + ''.join(cur_line)) else: while cur_line: if strip_color(cur_line[-1]).strip() and cur_len + len(self.placeholder) <= width: cur_line.append(self.placeholder) lines.append(indent + ''.join(cur_line)) break cur_len -= len(strip_color(cur_line[-1])) del cur_line[-1] else: if lines: prev_line = lines[-1].rstrip() if len(strip_color(prev_line)) + len(self.placeholder) <= self.width: lines[-1] = prev_line + self.placeholder break lines.append(indent + self.placeholder.lstrip()) break return lines
def test_remove_color(self): """ We can get the original message without the colors """ self.assertEqual(strip_color(color("RED", "red")), "RED")
def diff_color(input_file, cfg): """ colorizes a diff file """ cov = cfg.data with paged_echo() as pager: term_width = click.get_terminal_size()[0] modified = [] measured = cov.get_data().measured_files() diff = PatchSet(input_file) for thing in diff: if thing.is_modified_file or thing.is_added_file: target = thing.target_file if target.startswith('b/') or target.startswith('a/'): target = target[2:] if abspath(target) in measured: covdata = cov._analyze(abspath(target)) modified.append((thing, covdata)) # pager.echo(abspath(target)) else: msg = "skip: {}".format(target) msg = msg + (' ' * (term_width - len(msg))) pager.echo(colors.color(msg, bg='yellow', fg='black')) total_added_lines = 0 total_covered_lines = 0 for (patch, covdata) in modified: fname = str(patch.target_file) + (' ' * (term_width - len(patch.target_file))) pager.echo(colors.color(fname, bg='cyan', fg='black')) for hunk in patch: for line in hunk: kw = dict() if line.is_added: total_added_lines += 1 if line.target_line_no in covdata.missing: pager.echo(colors.color(u'\u258c', fg='red', bg=52), nl=False, color=True) kw['bg'] = 52 else: total_covered_lines += 1 pager.echo(colors.color(u'\u258f', fg='green'), nl=False, color=True) else: pager.echo(' ', nl=False) out = u"{}".format(line).strip() if line.is_added: kw['fg'] = 'green' elif line.is_removed: kw['fg'] = 'red' pager.echo(colors.color(out, **kw)) if total_added_lines == 0: raise click.ClickException("No covered lines at all") percent_covered = (total_covered_lines / float(total_added_lines)) msg = u"{} covered of {} added lines".format(total_covered_lines, total_added_lines) print_banner(msg, percent_covered, pager=pager) return target_fname = abspath(target_fname) for fname in cov.get_data().measured_files(): if target_fname == abspath(fname): match.append(fname) if len(match) != 1: if len(match) == 0: # this file wasn't in the coverage data, so we just dump # it to stdout as-is. (FIXME: ideally, also # syntax-highlighted anyway) with open(target_fname, 'r') as f: for line in f.readlines(): sys.stdout.write(line) return else: raise RuntimeError("Multiple matches: %s" % ', '.join(match)) fname = match[0] covdata = cov._analyze(fname) percent = 1.0 # if no statements, it's all covered, right? if covdata.numbers.n_statements: percent = float(covdata.numbers.n_statements - covdata.numbers.n_missing) / covdata.numbers.n_statements total_statements = covdata.numbers.n_statements total_missing = covdata.numbers.n_missing fill = min(click.get_terminal_size()[0], 80) print_banner(fname, percent, fill) # it was tempting to write/override/wrap this Formatter and mess # with the background color based on our coverage data -- and # that's not a terrible idea, but the way TerminalFormatter is # written, it's not very nice. Basically, we'd have to wrap the # output stream, look for ANSI reset codes, and re-do the # background color after each reset (for "uncovered" lines)... so # I didn't do that. Instead we just hack it by splitting on the # reset codes (see below) formatter = TerminalFormatter(style=style) lines = highlight( open(fname).read(), get_lexer_by_name('python'), formatter=formatter, ) lines = lines.split(u'\n') for (i, line) in enumerate(lines): # assert type(line) is unicode spaces = fill - len(colors.strip_color(line)) spaces = u' ' * spaces if (i + 1) not in covdata.missing: if (i + 1) in covdata.excluded: line = colors.strip_color(line) pager.echo(colors.color(u'\u258f', fg=46, bg=236) + colors.color(line + spaces, bg=236, fg=242), color=True) elif cfg.branch and (i + 1) in covdata.branch_lines(): line = colors.strip_color(line) pager.echo(colors.color(u'\u258f', bg=52, fg=160) + colors.color(line + spaces, bg=52), color=True) else: pager.echo(u'{}{}{}'.format(colors.color(u'\u258f', fg=46), line, spaces), color=True) else: # HACK-O-MATIC, uhm. Yeah, so what we're doing here is # splitting the output from the formatter on the ANSI # "reset" code, and the re-assembling it with the "52" # (dark red) background color. I appoligize in advance; # PRs with improvements encouraged! reset_code = u"\x1b[39;49;00m" segments = (line + spaces).split(reset_code) reset_plus_bg = u"\x1b[39;49;00m\x1b[39;49;48;5;52m" out = u"\x1b[39;49;48;5;52m" + reset_plus_bg.join(segments) pager.echo(colors.color(u'\u258f', bg=52, fg=160) + out, color=True)
def term_color(target_fname, cfg, style='monokai'): cov = cfg.data target_fname = realpath(target_fname) match = [f for f in cov.get_data().measured_files() if target_fname == realpath(f)] if len(match) > 1: raise RuntimeError("Multiple matches: %s" % ', '.join(match)) if len(match) == 0: print("not in coverage") # this file wasn't in the coverage data, so we just dump # it to stdout as-is. (FIXME: ideally, also # syntax-highlighted anyway) with open(target_fname, 'r') as f: sys.stdout.write( f.read() ) return fname = match[0] covdata = cov._analyze(fname) percent = 1.0 # if no statements, it's all covered, right? if covdata.numbers.n_statements: percent = float(covdata.numbers.n_statements - covdata.numbers.n_missing) / covdata.numbers.n_statements total_statements = covdata.numbers.n_statements total_missing = covdata.numbers.n_missing fill = min(click.get_terminal_size()[0], 80) print_banner(fname, percent, fill) # it was tempting to write/override/wrap this Formatter and mess # with the background color based on our coverage data -- and # that's not a terrible idea, but the way TerminalFormatter is # written, it's not very nice. Basically, we'd have to wrap the # output stream, look for ANSI reset codes, and re-do the # background color after each reset (for "uncovered" lines)... # so I didn't do that. Instead we just hack it by clearing *all* # formatting from the "uncovered" lines and make them all "grey on # red" formatter = TerminalFormatter(style=style) raw_data = open(fname).read() lexer = get_lexer_by_name('python') lexer.stripall = False lexer.stripnl = False lines = highlight(raw_data, lexer, formatter=formatter) lines = lines.split(u'\n') # coverage thinks the first line is called "1", not "0" offset = 1 for (i, line) in enumerate(lines): # assert type(line) is unicode spaces = fill - len(colors.strip_color(line)) spaces = u' ' * spaces if (i + offset) not in covdata.missing: if (i + offset) in covdata.excluded: line = colors.strip_color(line) click.echo(colors.color(u'\u258f', fg=46, bg=236) + colors.color(line + spaces, bg=236, fg=242), color=True) elif cfg.branch and (i + offset) in covdata.branch_lines(): line = colors.strip_color(line) click.echo(colors.color(u'\u258f', bg=52, fg=160) + colors.color(line + spaces, bg=52), color=True) else: click.echo(u'{}{}{}'.format(colors.color(u'\u258f', fg=46), line, spaces), color=True) else: # HACK-O-MATIC, uhm. Yeah, so what we're doing here is # splitting the output from the formatter on the ANSI # "reset" code, and the re-assembling it with the "52" # (dark red) background color. I appoligize in advance; # PRs with improvements encouraged! reset_code = u"\x1b[39;49;00m" segments = (line + spaces).split(reset_code) reset_plus_bg = u"\x1b[39;49;00m\x1b[39;49;48;5;52m" out = u"\x1b[39;49;48;5;52m" + reset_plus_bg.join(segments) click.echo(colors.color(u'\u258c', bg=52, fg=160) + out, color=True)
def format(self, record): rec = super().format(record) return strip_color(rec)
def hint(argv): stack_base = "$sp" if (len(argv) > 0): stack_base = argv[0] vptype = gdb.lookup_type("void").pointer() isym = gdb.execute("info symbol $pc", False, True) m = re.search(".*(\+ [0-9]*) in section.*", isym) funcstart = None if (m is not None): # print("m = '%s'" % (m,) ) # print("m.group(0) = '%s'" % (m.group(0),) ) # print("m.group(1) = '%s'" % (m.group(1),) ) offset = m.group(1) funcstart = gdb.parse_and_eval(f"$pc-{offset}") print(f"Searching for call to {funcstart}") # print("offset = '%s'" % (offset,) ) callre = re.compile("call (0x[0-9a-f]*)") ccallre = re.compile("call \*%") # computed calls # $rsp-16 is kinda the default position # for other archs we might search differently? for i in range(-8, 64): pos = f"{stack_base}+({vptype.sizeof}*{i})" mem = vdb.memory.read(pos, vptype.sizeof) val = gdb.Value(mem, vptype) at = vdb.memory.mmap.get_atype(val) if (at == vdb.memory.access_type.ACCESS_EX): cmd = f"dis/{hint_context.value} {int(val)}" # print("cmd = '%s'" % (cmd,) ) dis = gdb.execute(cmd, False, True) dis = dis.splitlines() # rng = dis[0] dis = dis[1:] pose = gdb.parse_and_eval(pos) print(vdb.color.color(f"At {pose} ({pos}) in ", hint_start_color.value), end="") print(f"{val}:") if (funcstart is not None): for d in dis: pd = colors.strip_color(d) m = callre.search(pd) if (m is None): m = ccallre.search(pd) if (m is not None): print(vdb.color.color(hint_marker.value, hint_color.value), end="") print( " (computed call, check actual registers if possible)" ) else: # print("m = '%s'" % (m,) ) # print("m.group(0) = '%s'" % (m.group(0),) ) # print("m.group(1) = '%s'" % (m.group(1),) ) target = m.group(1) target = vdb.util.xint(target) # print("target = '%s'" % (target,) ) # print("funcstart = '%s'" % (funcstart,) ) if (target == int(funcstart)): print( vdb.color.color(hint_marker.value, hint_color.value)) for d in dis: if (len(d) > 0): print(d)
def format_color(f_str, values, bg): bw_str = f_str.format(*[strip_color(str(v)) for v in values]) col_str = bw_str for v in values: col_str = col_str.replace(strip_color(str(v)), str(v)) return colorize_bg(col_str, bg=bg)
def format(self, record: logging.LogRecord) -> str: """Format the message and remove ANSI color codes from it.""" text = super().format(record) return colors.strip_color(text)
def _repl(m): s = m.group(1) s = strip_color(s) if strip else s return f"{color_fun(s)}"
def _format_usage(self, usage, actions, groups, prefix): # noqa: C901 if prefix is None: prefix = _('usage: ') # if usage is specified, use that if usage is not None: usage = usage % dict(prog=self._prog) # if no optionals or positionals are available, usage is just prog elif usage is None and not actions: usage = '%(prog)s' % dict(prog=self._prog) # if optionals and positionals are available, calculate usage elif usage is None: prog = '%(prog)s' % dict(prog=self._prog) # split optionals from positionals optionals = [] positionals = [] for action in actions: if action.option_strings: optionals.append(action) else: positionals.append(action) # build full usage string format = self._format_actions_usage action_usage = format(optionals + positionals, groups) usage = ' '.join([s for s in [prog, action_usage] if s]) # wrap the usage parts if it's too long text_width = self._width - self._current_indent if len(prefix) + len(strip_color(usage)) > text_width: # break usage into wrappable parts part_regexp = r'\(.*?\)+|\[.*?\]+|\S+' opt_usage = format(optionals, groups) pos_usage = format(positionals, groups) opt_parts = _re.findall(part_regexp, opt_usage) pos_parts = _re.findall(part_regexp, pos_usage) assert ' '.join(opt_parts) == opt_usage assert ' '.join(pos_parts) == pos_usage # helper for wrapping lines def get_lines(parts, indent, prefix=None): lines = [] line = [] if prefix is not None: line_len = len(prefix) - 1 else: line_len = len(indent) - 1 for part in parts: if line_len + 1 + len(strip_color(part)) > text_width and line: lines.append(indent + ' '.join(line)) line = [] line_len = len(indent) - 1 line.append(part) line_len += len(strip_color(part)) + 1 if line: lines.append(indent + ' '.join(line)) if prefix is not None: lines[0] = lines[0][len(indent):] return lines # if prog is short, follow it with optionals or positionals len_prog = len(strip_color(prog)) if len(prefix) + len_prog <= 0.75 * text_width: indent = ' ' * (len(prefix) + len_prog + 1) if opt_parts: lines = get_lines([prog] + opt_parts, indent, prefix) lines.extend(get_lines(pos_parts, indent)) elif pos_parts: lines = get_lines([prog] + pos_parts, indent, prefix) else: lines = [prog] # if prog is long, put it on its own line else: indent = ' ' * len(prefix) parts = opt_parts + pos_parts lines = get_lines(parts, indent) if len(lines) > 1: lines = [] lines.extend(get_lines(opt_parts, indent)) lines.extend(get_lines(pos_parts, indent)) lines = [prog] + lines # join lines into usage usage = '\n'.join(lines) # prefix with 'usage:' return '%s%s\n\n' % (prefix, usage)
def ansi_remove(self, txt): if colors: return colors.strip_color(txt) else: return txt
def run_tests( tests ): parser = argparse.ArgumentParser(description='run vdb tests.') parser.add_argument("-s","--show", action="store_true", help = "Show the list of active tests (and a bit of info)") parser.add_argument("-f","--filter", type=str, action="store", help = "Regex to filter tests for") parser.add_argument("-d","--debug", action="store_true", help = "enables test debugging mode") args = parser.parse_args(sys.argv[1:]) if( args.filter ): cre = re.compile(args.filter) for test in tests: name = test.get("name",None) if( name is not None and cre.search(name) is not None ): pass else: test["enabled"] = False if( args.show ): otbl = [] otbl.append(["Name","Enabled","Commands","Expect","Hash","File"]) for test in tests: line=[] for kw in ["name","enabled","commands","expect","hash","file"]: var = test.get(kw,None) if( kw == "commands" ): var = len(var) if( kw == "enabled" ): if( var == True or var is None ): var = "Y" else: var = "N" line.append( var ) otbl.append(line) print(vdb.util.format_table(otbl)) return None failed = 0 passed = 0 skipped = 0 for test in tests: f = test.get("file",None) c = test.get("commands",None) cl = test.get("enabled_commands",None) cmset = None if( cl is not None ): fc = fake_config(cl) vdb.config.set_array_elements(fc,d1="-") # print("fc.elements = '%s'" % (fc.elements,) ) cmset = set(fc.elements) nc=[] for ci in range(0,len(c)): if( ci in cmset ): nc.append(c[ci]) c = nc n = test.get("name", "unnamed test" ) en = test.get("enabled",None) op = test.get("output",args.debug) print("Test '%s' :" % n) if( en is not None and en == False ): skip("Skipping, not enabled") skipped += 1 continue if( f is not None and c is not None ): b = compile(f) g,h = run_binary( b, c ) h0 = test.get("hash",None) if( h0 is not None ): if( h == h0 ): good("hash passed") passed += 1 else: fail("hash failed") print("Expected: %s, result %s" % (h0,h) ) failed += 1 else: g,h = run_binary( None, c ) e = test.get("expect",None) if( op ): print(g) if( args.debug ): continue if( e is not None ): tolines = open(e, 'r').readlines() g=colors.strip_color(g) r = diff(g.splitlines(keepends=True),tolines) if( len(r) > 0 ): fail("Failed:") print("".join(r)) ofn = os.path.splitext(e)[0] ofn += ".out" with open(ofn,"w") as o: o.write(g) failed += 1 else: good("expect passed") passed += 1 # print("r = '%s'" % (r,) ) fc = failcolor sk = skipcolor if( failed == 0 ): fc = goodcolor if( skipped == 0 ): sk = goodcolor print(vdb.color.color(f"Passed: {passed}",goodcolor),end="") print(vdb.color.color(f", Failed: {failed}",fc),end="") print(vdb.color.color(f", Skipped: {skipped}",sk))