summaryrefslogtreecommitdiff
path: root/Devalloc/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'Devalloc/main.py')
-rwxr-xr-xDevalloc/main.py38
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)