diff options
author | Ben Sima <ben@bsima.me> | 2020-09-29 11:42:46 -0400 |
---|---|---|
committer | Ben Sima <ben@bsima.me> | 2020-09-29 11:42:46 -0400 |
commit | babb2fdc69bb0d777e72072d3509eeed4c1b651d (patch) | |
tree | 93d0d628552a4c2081bb7cb83802450d3fbd087f /Devalloc/main.py | |
parent | 810cd2a3aad87c53c8b90889576f5833a3e9557c (diff) |
devalloc: calculate and print stale files
Diffstat (limited to 'Devalloc/main.py')
-rwxr-xr-x | Devalloc/main.py | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/Devalloc/main.py b/Devalloc/main.py index 1010966..d807aae 100755 --- a/Devalloc/main.py +++ b/Devalloc/main.py @@ -4,6 +4,7 @@ Analyze developer allocation across a codebase. """ import argparse +import datetime import logging import os import re @@ -70,6 +71,12 @@ def get_args(): help="print the liabilities (files with < 3 active contributors)", ) cli.add_argument( + "-s", + "--stale", + action="store_true", + help="print stale files (haven't been touched in 6 months)", + ) + cli.add_argument( "-i", "--ignored", nargs="+", default=[], help="patterns to ignore in paths", ) cli.add_argument( @@ -97,13 +104,27 @@ def guard_git(repo): sys.exit(f"error: not a git repository: {repo}") +def staleness(path, now): + timestamp = datetime.datetime.strptime( + subprocess.check_output(["git", "log", "-n1", "--pretty=%aI", path]) + .decode("utf-8") + .strip(), + "%Y-%m-%dT%H:%M:%S%z", + ) + delta = now - timestamp + if delta.days > 180: + return delta.days + else: + return None + + class Repo: "Represents a repo and stats for the repo." def __init__(self, ignored_paths, active_users): self.paths = [ p - for p in subprocess.check_output(["git", "ls-files"]) + for p in subprocess.check_output(["git", "ls-files", "--no-deleted"]) .decode("utf-8") .split() if not any(i in p for i in ignored_paths) @@ -118,6 +139,12 @@ class Repo: for path, authors in self.stats.items() if 1 < len(authors) < 3 } + now = datetime.datetime.utcnow().astimezone() + self.stale = {} + for path, _ in self.stats.items(): + _staleness = staleness(path, now) + if _staleness: + self.stale[path] = _staleness def print_blackholes(self, full): "Print number of blackholes, or list of all blackholes." @@ -149,6 +176,14 @@ class Repo: ) ) + def print_stale(self, full): + "Print stale files" + n_stale = len(self.stale) + print(f"Stale files: {n_stale}") + if full: + for path, days in self.stale.items(): + print(f" {path} ({days} days)") + if __name__ == "__main__": ARGS = get_args() @@ -166,3 +201,4 @@ if __name__ == "__main__": REPO.print_score() REPO.print_blackholes(ARGS.blackholes) REPO.print_liabilities(ARGS.liabilities) + REPO.print_stale(ARGS.stale) |