def header(self): result = "%s:" % runez.purple(runez.short(self.path)) if not self.projects: return "%s %s" % (result, runez.orange("no git folders")) if self.predominant: result += runez.bold(" %s %s" % (len(self.projects[self.predominant]), self.predominant)) else: result += runez.orange(" no predominant project") if self.additional: result += " (%s)" % runez.purple(", ".join("+%s %s" % (len(self.projects[project]), project) for project in self.additional)) return result
def represented(cls, value, size=runez.UNSET, stringify=runez.stringified, dt=str): if isinstance(value, NotImplementedError): if size is None: return {"_error": "not implemented"} return runez.orange("not implemented") if isinstance(value, Exception): if size is None: return {"_error": runez.short(value, size=256)} return runez.red(runez.short(value, size=size)) return runez.represented_json(value, stringify=stringify, dt=dt, keep_none=True, none_key="-null-")
def freshness(self): """Short freshness overview""" result = [] if self.report._problem: result.append(runez.red(" ".join(self.report._problem))) if self.modified: result.append(runez.red(runez.plural(self.modified, "diff"))) if self.untracked: result.append(runez.orange("%s untracked" % len(self.untracked))) if self.report._note: result.append(runez.purple(" ".join(self.report._note))) if not self.report._problem and not self.report._note and self._parent.age is not None: message = "up to date" if self._parent.age > FRESHNESS_THRESHOLD: message += "*" result.append(runez.teal(message)) return ", ".join(result)
def test_colors(): dim = runez.color.style.dim assert runez.color.cast_style(dim) is dim assert runez.color.cast_style(runez.dim) is runez.dim assert runez.color.cast_style("dim") is dim assert runez.color.cast_color(dim) is dim assert runez.color.cast_color("dim") is dim assert runez.color.cast_color("blue") is runez.color.fg.blue msg1 = dim("hi") msg2 = runez.colored("hi", "dim") assert msg1 == msg2 with pytest.raises(ValueError): runez.color.cast_style("foo") assert not runez.color.is_coloring() with runez.ActivateColors(terminal.Ansi16Backend): # Check that backend can be passed as class (flavor auto-determined in that case) assert runez.color.is_coloring() assert "ansi16" in runez.color.backend.name msg1 = runez.dim("hi") msg2 = runez.colored("hi", "dim") assert msg1 == msg2 assert not runez.color.is_coloring() with runez.ActivateColors(terminal.Ansi16Backend(flavor="neutral")): assert runez.color.is_coloring() assert runez.red(None) == "\x1b[31mNone\x1b[39m" assert runez.blue("") == "" assert runez.plain("hello") == "hello" assert runez.yellow("hello") == "\x1b[33mhello\x1b[39m" assert runez.yellow("hello", size=4) == "\x1b[33mh...\x1b[39m" assert runez.bold(1) == "\x1b[1m1\x1b[22m" assert runez.color.bg.get(None) is None assert runez.color.bg.get("blue") is runez.color.bg.blue assert runez.dim("") == "" assert runez.dim("hello", size=4) == "\x1b[2mh...\x1b[22m" # Verify unicode char 'μ' from represented_duration() works assert "foo: %s" % runez.dim(runez.represented_duration(0.010049)) == "foo: \x1b[2m10 ms 49 μs\x1b[22m" assert "foo: %s" % runez.blue(runez.represented_duration(0.010049)) == "foo: \x1b[34m10 ms 49 μs\x1b[39m" assert not runez.color.is_coloring() assert runez.black("") == "" assert runez.blue("") == "" assert runez.brown("") == "" assert runez.gray("") == "" assert runez.green("") == "" assert runez.orange("") == "" assert runez.plain("hello") == "hello" assert runez.purple("") == "" assert runez.red(None) == "None" assert runez.teal("") == "" assert runez.white("") == "" assert runez.yellow("hello") == "hello" assert runez.blink("hello") == "hello" assert runez.bold(1) == "1" assert runez.dim("") == "" assert runez.invert("") == "" assert runez.italic("") == "" assert runez.strikethrough("") == "" assert runez.underline("") == "" assert str(runez.color.fg.black) == "black"
def handle_single_clean(target, what): """ :param GitCheckout target: Single checkout to clean :param str what: Operation """ report = target.git.fetch() if report.has_problems: if what != "reset": what = "clean" print( target.header( GitRunReport(report).add(problem="<can't %s" % what))) runez.abort("") if what == "reset": return clean_reset(target) if what == "show": return clean_show(target) total_cleaned = 0 print(target.header()) if what in "remote all": if not target.git.remote_cleanable_branches: print(" No remote branches can be cleaned") else: total = len(target.git.remote_cleanable_branches) cleaned = 0 for branch in target.git.remote_cleanable_branches: remote, _, name = branch.partition("/") if not remote and name: raise Exception("Unknown branch spec '%s'" % branch) if run_git(target, False, "branch", "--delete", "--remotes", branch): cleaned += run_git(target, False, "push", "--delete", remote, name) total_cleaned += cleaned if cleaned == total: print("%s cleaned" % runez.plural(cleaned, "remote branch")) else: print("%s/%s remote branches cleaned" % (cleaned, total)) target.git.reset_cached_properties() if what == "all": # Fetch to update remote branches (and correctly detect new dangling local) target.git.fetch() if what in "local all": if not target.git.local_cleanable_branches: print(" No local branches can be cleaned") else: total = len(target.git.local_cleanable_branches) cleaned = 0 for branch in target.git.local_cleanable_branches: if branch == target.git.branches.current: fallback = target.git.fallback_branch() if not fallback: print( "Skipping branch '%s', can't determine fallback branch" % target.git.branches.current) continue run_git(target, True, "checkout", fallback) run_git(target, True, "pull") cleaned += run_git(target, False, "branch", "--delete", branch) total_cleaned += cleaned if cleaned == total: print( runez.bold("%s cleaned" % runez.plural(cleaned, "local branch"))) else: print( runez.orange("%s/%s local branches cleaned" % (cleaned, total))) target.git.reset_cached_properties() if total_cleaned: print(target.header())
def cmd_import_speed(): """Show average import time of top-level python packages installed in this venv""" parser = runez.cli.parser() parser.add_argument("--all", action="store_true", help="Show all.") parser.add_argument("--border", choices=NAMED_BORDERS, default="reddit", help="Use custom border.") parser.add_argument("--iterations", "-i", type=int, default=3, help="Number of measurements to average.") parser.add_argument("name", nargs="*", help="Names of modules to show (by default: all).") args = parser.parse_args() names = runez.flattened(args.name, split=",") if args.all: names.extend(_all_deps()) if not names: sys.exit("Please specify module names, or use --all") names = sorted(set(names)) times = [] fastest = None slowest = None for name in names: t = ImportTime(name, iterations=args.iterations) times.append(t) if t.cumulative is None: continue if fastest is None or (t.cumulative < fastest.cumulative): fastest = t if slowest is None or t.cumulative > slowest.cumulative: slowest = t table = PrettyTable("Module,-X cumulative,Elapsed,Vs fastest,Note", border=args.border) table.header[3].align = "center" mid = _get_mid(times) or 0 for t in sorted(times): if t.cumulative is None: c = e = f = None else: factor = t.elapsed / fastest.elapsed c = runez.represented_duration(t.cumulative / 1000000, span=-2) e = runez.represented_duration(t.elapsed, span=-2) f = "x%.2f" % factor if t is fastest: f = "" elif t is slowest: f = runez.red(f) elif t.elapsed and t.elapsed > mid: f = runez.orange(f) table.add_row(t.module_name, c, e, f, t.problem or "") print(table)