-
-
Save iamkubi/42445857323a58bcd56fe8bc2d6c5aa1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import subprocess | |
| from collections import defaultdict | |
| def get_git_files(): | |
| """Get a list of all files tracked by git in the current working directory, excluding specific directories.""" | |
| files_raw = subprocess.check_output(['git', 'ls-tree', '-r', 'HEAD', '--name-only'], text=True) | |
| files = files_raw.strip().split('\n') | |
| # Directories to ignore | |
| ignore_dirs = {'vendor', 'node_modules'} | |
| # Filter out files that are in the ignored directories | |
| filtered_files = [file for file in files if not any(dir_name + '/' in file for dir_name in ignore_dirs)] | |
| return filtered_files | |
| def get_blame_stats(file_path): | |
| """Get blame stats for a given file, focusing on email addresses, with error handling for binary files.""" | |
| try: | |
| blame_output = subprocess.check_output(['git', 'blame', '--line-porcelain', file_path], text=True, errors='ignore') | |
| except subprocess.CalledProcessError as e: | |
| print(f"Error processing file {file_path}: {e}") | |
| return {} | |
| email_lines = defaultdict(int) | |
| for line in blame_output.split('\n'): | |
| if line.startswith('author-mail '): | |
| email = line[len('author-mail <'):-1] # Extract email, removing <> | |
| email_lines[email] += 1 | |
| return email_lines | |
| def calculate_majority_ownership(files, ignored_emails=None, ignore_no_majority=True, min_ownership_percentage=90): | |
| """Calculate the majority ownership of each file, applying filters and ignoring specified emails.""" | |
| if ignored_emails is None: | |
| ignored_emails = [] | |
| results = [] | |
| file_count = len(files) | |
| for i, file_path in enumerate(files, 1): | |
| email_lines = get_blame_stats(file_path) | |
| if not email_lines: | |
| if not ignore_no_majority: | |
| results.append((file_path, 'No majority owner found', 0)) | |
| continue | |
| total_lines = sum(email_lines.values()) | |
| if total_lines == 0: | |
| if not ignore_no_majority: | |
| results.append((file_path, 'File is empty or no lines attributed', 0)) | |
| continue | |
| majority_owner_email, lines_owned = max(email_lines.items(), key=lambda item: item[1]) | |
| ownership_percentage = (lines_owned / total_lines) * 100 | |
| if ownership_percentage >= min_ownership_percentage: | |
| results.append((file_path, majority_owner_email, ownership_percentage)) | |
| # Sort and print results | |
| sorted_results = sorted(results, key=lambda x: x[2], reverse=True) | |
| return sorted_results | |
| def main(): | |
| """Main function.""" | |
| files = get_git_files() | |
| ignored_emails = [ | |
| # Have Permission | |
| "git@lance.sh", | |
| "sir3lit@gmail.com", | |
| "admin@softwarenoob.com", | |
| "dane@daneeveritt.com", "DaneEveritt@users.noreply.github.com", | |
| "stepan.fedotov@gmail.com", "TrixterTheTux@users.noreply.github.com", | |
| "parkervcp@gmail.com", | |
| "git@anand.io", "arcdigital@users.noreply.github.com", | |
| ] | |
| results = calculate_majority_ownership(files, ignored_emails) | |
| for file_path, email, percentage in results: | |
| if email not in ignored_emails: | |
| print(f"{file_path}: {email} ({percentage:.2f}%)") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
dope