File size: 2,103 Bytes
e2c4c72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import os
import subprocess
from collections import Counter

CONFIG_FILE_EXTENSIONS = (".json", ".yml", ".yaml", ".ini", ".conf", ".toml")


def is_text_file(filepath):
    # Check for binary file by scanning for null bytes.
    try:
        with open(filepath, "rb") as f:
            chunk = f.read(4096)
        if b"\0" in chunk:
            return False
        return True
    except Exception:
        return False


def should_skip_file(path):
    base = os.path.basename(path)
    # Skip dotfiles and dotdirs
    if base.startswith("."):
        return True
    # Skip config files by extension
    if base.lower().endswith(CONFIG_FILE_EXTENSIONS):
        return True
    return False


def get_tracked_files():
    try:
        output = subprocess.check_output(["git", "ls-files"], text=True)
        files = output.strip().split("\n")
        files = [f for f in files if f and os.path.isfile(f)]
        return files
    except subprocess.CalledProcessError:
        print("Error: Are you in a git repository?")
        return []


def main():
    files = get_tracked_files()
    email_counter = Counter()
    total_lines = 0

    for file in files:
        if should_skip_file(file):
            continue
        if not is_text_file(file):
            continue
        try:
            blame = subprocess.check_output(
                ["git", "blame", "-e", file], text=True, errors="replace"
            )
            for line in blame.splitlines():
                # The email always inside <>
                if "<" in line and ">" in line:
                    try:
                        email = line.split("<")[1].split(">")[0].strip()
                    except Exception:
                        continue
                    email_counter[email] += 1
                    total_lines += 1
        except subprocess.CalledProcessError:
            continue

    for email, lines in email_counter.most_common():
        percent = (lines / total_lines * 100) if total_lines else 0
        print(f"{email}: {lines}/{total_lines} {percent:.2f}%")


if __name__ == "__main__":
    main()