[READ-ONLY] Mirror of https://github.com/mrgnw/scripts.
0

Configure Feed

Select the types of activity you want to include in your feed.

scripts / gitl
4.0 kB 164 lines
1#!/usr/bin/env -S uv run --script 2# /// script 3# requires-python = ">=3.13" 4# dependencies = ["rich"] 5# /// 6import subprocess 7import sys 8from datetime import datetime 9from subprocess import check_output 10 11from rich.console import Console 12from rich.text import Text 13 14DEFAULT_LINES = 8 15 16COLORS = { 17 "hash": (90, 70, 140), 18 "date": (102, 91, 255), 19 "time": (79, 164, 255), 20 "dim": (60, 60, 80), 21 "at": (70, 70, 90), 22 "msg": (220, 218, 240), 23 "paren": (100, 100, 120), 24 "head": (255, 249, 86), 25 "main": (104, 244, 255), 26 "branch": (79, 255, 249), 27} 28 29 30def make_fader(day_idx): 31 fade = max(0.85**day_idx, 0.45) if day_idx > 0 else 1.0 32 33 def apply(name): 34 r, g, b = COLORS[name] 35 return f"rgb({int(r * fade)},{int(g * fade)},{int(b * fade)})" 36 37 return apply 38 39 40def parse_commit(line): 41 h, year, month, day, hour, minute, msg, branches = line.split(";", 7) 42 return { 43 "hash": h, 44 "date": (int(year), int(month), int(day)), 45 "time": (hour, minute), 46 "month_day": (month, day), 47 "msg": msg, 48 "branches": branches.strip().strip("()"), 49 } 50 51 52def format_branches(branches, fade): 53 text = Text() 54 if not branches: 55 return text 56 57 text.append(" (", style=fade("paren")) 58 59 for i, branch in enumerate(branches.split(",")): 60 branch = branch.strip() 61 if i > 0: 62 text.append(", ", style=fade("paren")) 63 64 if " -> " in branch: 65 _, branch = branch.split(" -> ") 66 text.append("HEAD", style=f"bold {fade('head')}") 67 text.append(" -> ", style=fade("paren")) 68 69 is_origin = branch.startswith("origin/") 70 name = branch[7:] if is_origin else branch 71 base_style = "bold underline" if is_origin else "bold" 72 73 color = "head" if name == "HEAD" else "main" if name in ("main", "master") else "branch" 74 text.append(name, style=f"{base_style} {fade(color)}") 75 76 text.append(")", style=fade("paren")) 77 return text 78 79 80def format_datetime(commit, now, fade): 81 text = Text() 82 year, month, day = commit["date"] 83 month_str, day_str = commit["month_day"] 84 hour, minute = commit["time"] 85 86 if year < now.year: 87 text.append(f"{year}-{month_str}{day_str}", style=fade("time")) 88 else: 89 same_month = month == now.month 90 same_day = same_month and day == now.day 91 92 if same_day: 93 text.append(f"{month_str}{day_str}", style=fade("dim")) 94 elif same_month: 95 text.append(month_str, style=fade("dim")) 96 text.append(day_str, style=fade("date")) 97 else: 98 text.append(f"{month_str}{day_str}", style=fade("date")) 99 100 text.append("@", style=fade("at")) 101 text.append(f"{hour}{minute}", style=fade("time")) 102 103 return text 104 105 106def get_commits(n, console): 107 try: 108 log = check_output( 109 ["git", "log", "-n", str(n), "--pretty=format:%h;%cd;%s;%d", "--date=format:%Y;%m;%d;%H;%M"], 110 stderr=subprocess.DEVNULL, 111 ).decode() 112 except Exception: 113 console.print("gitl: not a git repository (or no commits yet)", style="red") 114 return [] 115 return [parse_commit(line) for line in log.splitlines()] if log else [] 116 117 118def assign_day_indices(commits): 119 current_day = None 120 day_idx = -1 121 for commit in commits: 122 if commit["date"] != current_day: 123 current_day = commit["date"] 124 day_idx += 1 125 commit["day_idx"] = day_idx 126 127 128def main(): 129 console = Console() 130 now = datetime.now() 131 today = (now.year, now.month, now.day) 132 133 if len(sys.argv) > 1: 134 try: 135 commits = get_commits(int(sys.argv[1]), console) 136 except ValueError: 137 console.print("Usage: gitl [n_lines]", style="red") 138 sys.exit(1) 139 else: 140 commits = get_commits(100, console) 141 today_count = sum(1 for c in commits if c["date"] == today) 142 commits = commits[: max(DEFAULT_LINES, today_count)] 143 144 if not commits: 145 return 146 147 assign_day_indices(commits) 148 149 for commit in commits: 150 fade = make_fader(commit["day_idx"]) 151 text = Text() 152 153 text.append(commit["hash"], style=f"bold {fade('hash')}") 154 text.append(" ") 155 text.append_text(format_datetime(commit, now, fade)) 156 text.append(" ") 157 text.append(commit["msg"], style=fade("msg")) 158 text.append_text(format_branches(commit["branches"], fade)) 159 160 console.print(text) 161 162 163if __name__ == "__main__": 164 main()