From 0430c856390f4635c2346fd84d25323b7aa2b547 Mon Sep 17 00:00:00 2001 From: Vijay Janapa Reddi Date: Tue, 20 Jan 2026 13:48:55 -0500 Subject: [PATCH] Populate contributors from git history - Scanned git history for each project folder - Added historical contributors to .all-contributorsrc files - Generated README contributor tables with emoji badges - Added generate_readme_tables.py script for future updates Contributors added: - Book: profvjreddi, Mjrovai, GabrielAmazonas, hzeljko - Kits: profvjreddi - Labs: profvjreddi - TinyTorch: AmirAlasady, profvjreddi, kai4avaya, minhdang26403, didier-durand, karthikdani, jettythek --- .../contributors/generate_readme_tables.py | 165 ++++++++++++++++++ book/.all-contributorsrc | 56 +++++- book/README.md | 10 ++ kits/.all-contributorsrc | 23 ++- kits/README.md | 7 + labs/.all-contributorsrc | 20 ++- labs/README.md | 7 + tinytorch/.all-contributorsrc | 81 ++++++++- tinytorch/README.md | 8 +- 9 files changed, 364 insertions(+), 13 deletions(-) create mode 100755 .github/workflows/contributors/generate_readme_tables.py diff --git a/.github/workflows/contributors/generate_readme_tables.py b/.github/workflows/contributors/generate_readme_tables.py new file mode 100755 index 000000000..9a8d24d38 --- /dev/null +++ b/.github/workflows/contributors/generate_readme_tables.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +""" +Generate All Contributors tables for README files. + +This script reads .all-contributorsrc files and generates the HTML tables +that go in the README.md files. + +Usage: + python generate_readme_tables.py [--project PROJECT] [--update] +""" + +import json +import re +import argparse +from pathlib import Path + +PROJECTS = { + "book": "book/", + "kits": "kits/", + "labs": "labs/", + "tinytorch": "tinytorch/", +} + +# Emoji mapping for contribution types +EMOJI_KEY = { + "bug": "๐Ÿ›", + "code": "๐Ÿ’ป", + "doc": "๐Ÿ“–", + "design": "๐ŸŽจ", + "ideas": "๐Ÿ’ก", + "review": "๐Ÿ‘€", + "test": "๐Ÿงช", + "tool": "๐Ÿ”ง", + "translation": "๐ŸŒ", + "tutorial": "โœ…", + "video": "๐Ÿ“น", + "question": "๐Ÿ’ฌ", + "maintenance": "๐Ÿšง", + "infra": "๐Ÿš‡", + "platform": "๐Ÿ“ฆ", + "projectManagement": "๐Ÿ“†", + "research": "๐Ÿ”ฌ", +} + + +def generate_contributor_cell(contributor: dict, image_size: int = 80) -> str: + """Generate HTML for a single contributor cell.""" + login = contributor['login'] + name = contributor.get('name', login) + avatar_url = contributor.get('avatar_url', f"https://avatars.githubusercontent.com/{login}") + profile = contributor.get('profile', f"https://github.com/{login}") + contributions = contributor.get('contributions', []) + + # Generate emoji badges + badges = " ".join(EMOJI_KEY.get(c, c) for c in contributions) + + return f'''{name}
{name}

{badges}''' + + +def generate_table(contributors: list[dict], per_line: int = 7, image_size: int = 80) -> str: + """Generate the full HTML table for contributors.""" + if not contributors: + return "" + + lines = ["", " "] + + for i in range(0, len(contributors), per_line): + row = contributors[i:i + per_line] + lines.append(" ") + for contributor in row: + lines.append(" " + generate_contributor_cell(contributor, image_size)) + lines.append(" ") + + lines.append(" ") + lines.append("
") + + return "\n".join(lines) + + +def update_readme(project_path: str, table_html: str) -> bool: + """Update the README.md with the new contributors table.""" + readme_path = Path(project_path) / "README.md" + + if not readme_path.exists(): + print(f"Warning: {readme_path} does not exist") + return False + + with open(readme_path, 'r') as f: + content = f.read() + + # Pattern to match the ALL-CONTRIBUTORS-LIST section + pattern = r'().*?()' + + if not re.search(pattern, content, re.DOTALL): + print(f"Warning: No ALL-CONTRIBUTORS-LIST markers found in {readme_path}") + return False + + # Build replacement content + replacement = f'''\\1 + + +{table_html} + + + + +\\2''' + + new_content = re.sub(pattern, replacement, content, flags=re.DOTALL) + + with open(readme_path, 'w') as f: + f.write(new_content) + + return True + + +def process_project(project_name: str, project_path: str, update: bool = False) -> None: + """Process a single project.""" + rc_path = Path(project_path) / ".all-contributorsrc" + + if not rc_path.exists(): + print(f"Skipping {project_name}: no .all-contributorsrc found") + return + + with open(rc_path, 'r') as f: + rc_data = json.load(f) + + contributors = rc_data.get('contributors', []) + per_line = rc_data.get('contributorsPerLine', 7) + image_size = rc_data.get('imageSize', 80) + + if not contributors: + print(f"{project_name}: No contributors to display") + return + + table_html = generate_table(contributors, per_line, image_size) + + print(f"\n=== {project_name} ({len(contributors)} contributors) ===") + + if update: + if update_readme(project_path, table_html): + print(f"Updated {project_path}README.md") + else: + print(f"Failed to update {project_path}README.md") + else: + print(table_html) + + +def main(): + parser = argparse.ArgumentParser(description="Generate All Contributors tables") + parser.add_argument("--project", choices=list(PROJECTS.keys()), help="Process specific project") + parser.add_argument("--update", action="store_true", help="Update README files") + args = parser.parse_args() + + if args.project: + projects = {args.project: PROJECTS[args.project]} + else: + projects = PROJECTS + + for name, path in projects.items(): + process_project(name, path, args.update) + + +if __name__ == "__main__": + main() diff --git a/book/.all-contributorsrc b/book/.all-contributorsrc index 45f638b2d..b16008584 100644 --- a/book/.all-contributorsrc +++ b/book/.all-contributorsrc @@ -3,12 +3,62 @@ "projectOwner": "harvard-edge", "repoType": "github", "repoHost": "https://github.com", - "files": ["README.md"], + "files": [ + "README.md" + ], "imageSize": 80, "commit": false, "commitConvention": "angular", "contributorsPerLine": 7, "linkToUsage": false, "skipCi": true, - "contributors": [] -} + "contributors": [ + { + "login": "profvjreddi", + "name": "Vijay Janapa Reddi", + "avatar_url": "https://avatars.githubusercontent.com/profvjreddi", + "profile": "https://github.com/profvjreddi", + "contributions": [ + "bug", + "code", + "design", + "doc", + "ideas", + "review", + "test", + "tool" + ] + }, + { + "login": "Mjrovai", + "name": "Marcelo Rovai", + "avatar_url": "https://avatars.githubusercontent.com/Mjrovai", + "profile": "https://github.com/Mjrovai", + "contributions": [ + "code", + "design", + "test" + ] + }, + { + "login": "GabrielAmazonas", + "name": "Gabriel Amazonas", + "avatar_url": "https://avatars.githubusercontent.com/GabrielAmazonas", + "profile": "https://github.com/GabrielAmazonas", + "contributions": [ + "bug", + "doc", + "ideas" + ] + }, + { + "login": "hzeljko", + "name": "Zeljko Hrcek", + "avatar_url": "https://avatars.githubusercontent.com/hzeljko", + "profile": "https://github.com/hzeljko", + "contributions": [ + "code" + ] + } + ] +} \ No newline at end of file diff --git a/book/README.md b/book/README.md index 8d4d3c3bc..27d7cb2ae 100644 --- a/book/README.md +++ b/book/README.md @@ -163,6 +163,16 @@ Thanks to these wonderful people who helped improve the book ([emoji key](https: + + + + + + + + + +
Vijay Janapa Reddi
Vijay Janapa Reddi

๐Ÿ› ๐Ÿ’ป ๐ŸŽจ ๐Ÿ“– ๐Ÿ’ก ๐Ÿ‘€ ๐Ÿงช ๐Ÿ”ง
Marcelo Rovai
Marcelo Rovai

๐Ÿ’ป ๐ŸŽจ ๐Ÿงช
Gabriel Amazonas
Gabriel Amazonas

๐Ÿ› ๐Ÿ“– ๐Ÿ’ก
Zeljko Hrcek
Zeljko Hrcek

๐Ÿ’ป
diff --git a/kits/.all-contributorsrc b/kits/.all-contributorsrc index 4d47483db..452b383cc 100644 --- a/kits/.all-contributorsrc +++ b/kits/.all-contributorsrc @@ -3,12 +3,29 @@ "projectOwner": "harvard-edge", "repoType": "github", "repoHost": "https://github.com", - "files": ["README.md"], + "files": [ + "README.md" + ], "imageSize": 80, "commit": false, "commitConvention": "angular", "contributorsPerLine": 7, "linkToUsage": false, "skipCi": true, - "contributors": [] -} + "contributors": [ + { + "login": "profvjreddi", + "name": "Vijay Janapa Reddi", + "avatar_url": "https://avatars.githubusercontent.com/profvjreddi", + "profile": "https://github.com/profvjreddi", + "contributions": [ + "bug", + "code", + "design", + "doc", + "test", + "tool" + ] + } + ] +} \ No newline at end of file diff --git a/kits/README.md b/kits/README.md index e013939a7..8cb9c3499 100644 --- a/kits/README.md +++ b/kits/README.md @@ -139,6 +139,13 @@ Thanks to these wonderful people who helped improve the hardware kits ([emoji ke + + + + + + +
Vijay Janapa Reddi
Vijay Janapa Reddi

๐Ÿ› ๐Ÿ’ป ๐ŸŽจ ๐Ÿ“– ๐Ÿงช ๐Ÿ”ง
diff --git a/labs/.all-contributorsrc b/labs/.all-contributorsrc index f96500ff7..85424273f 100644 --- a/labs/.all-contributorsrc +++ b/labs/.all-contributorsrc @@ -3,12 +3,26 @@ "projectOwner": "harvard-edge", "repoType": "github", "repoHost": "https://github.com", - "files": ["README.md"], + "files": [ + "README.md" + ], "imageSize": 80, "commit": false, "commitConvention": "angular", "contributorsPerLine": 7, "linkToUsage": false, "skipCi": true, - "contributors": [] -} + "contributors": [ + { + "login": "profvjreddi", + "name": "Vijay Janapa Reddi", + "avatar_url": "https://avatars.githubusercontent.com/profvjreddi", + "profile": "https://github.com/profvjreddi", + "contributions": [ + "code", + "design", + "doc" + ] + } + ] +} \ No newline at end of file diff --git a/labs/README.md b/labs/README.md index e1cef90f9..68d74ae24 100644 --- a/labs/README.md +++ b/labs/README.md @@ -74,6 +74,13 @@ Thanks to these wonderful people who helped build the labs ([emoji key](https:// + + + + + + +
Vijay Janapa Reddi
Vijay Janapa Reddi

๐Ÿ’ป ๐ŸŽจ ๐Ÿ“–
diff --git a/tinytorch/.all-contributorsrc b/tinytorch/.all-contributorsrc index 55d0852c0..693edbfd0 100644 --- a/tinytorch/.all-contributorsrc +++ b/tinytorch/.all-contributorsrc @@ -3,7 +3,9 @@ "projectOwner": "harvard-edge", "repoType": "github", "repoHost": "https://github.com", - "files": ["README.md"], + "files": [ + "README.md" + ], "imageSize": 80, "commit": false, "commitConvention": "angular", @@ -16,7 +18,80 @@ "name": "Amir Alasady", "avatar_url": "https://avatars.githubusercontent.com/AmirAlasady", "profile": "https://github.com/AmirAlasady", - "contributions": ["bug"] + "contributions": [ + "bug" + ] + }, + { + "login": "profvjreddi", + "name": "Vijay Janapa Reddi", + "avatar_url": "https://avatars.githubusercontent.com/profvjreddi", + "profile": "https://github.com/profvjreddi", + "contributions": [ + "bug", + "code", + "design", + "doc", + "ideas", + "review", + "test", + "tool" + ] + }, + { + "login": "kai4avaya", + "name": "kai", + "avatar_url": "https://avatars.githubusercontent.com/kai4avaya", + "profile": "https://github.com/kai4avaya", + "contributions": [ + "bug", + "code", + "design", + "doc", + "test" + ] + }, + { + "login": "minhdang26403", + "name": "Dang Truong", + "avatar_url": "https://avatars.githubusercontent.com/minhdang26403", + "profile": "https://github.com/minhdang26403", + "contributions": [ + "bug", + "code", + "doc", + "test" + ] + }, + { + "login": "didier-durand", + "name": "Didier Durand", + "avatar_url": "https://avatars.githubusercontent.com/didier-durand", + "profile": "https://github.com/didier-durand", + "contributions": [ + "bug", + "code", + "doc" + ] + }, + { + "login": "karthikdani", + "name": "Karthik Dani", + "avatar_url": "https://avatars.githubusercontent.com/karthikdani", + "profile": "https://github.com/karthikdani", + "contributions": [ + "bug", + "code" + ] + }, + { + "login": "jettythek", + "name": "jettythek", + "avatar_url": "https://avatars.githubusercontent.com/jettythek", + "profile": "https://github.com/jettythek", + "contributions": [ + "code" + ] } ] -} +} \ No newline at end of file diff --git a/tinytorch/README.md b/tinytorch/README.md index eac2cc755..5cac62bd9 100644 --- a/tinytorch/README.md +++ b/tinytorch/README.md @@ -265,7 +265,13 @@ Thanks to these wonderful people who helped improve TinyTorch ([emoji key](https - + + + + + + +
Amir Alasady
Amir Alasady

๐Ÿ›
Amir Alasady
Amir Alasady

๐Ÿ›
Vijay Janapa Reddi
Vijay Janapa Reddi

๐Ÿ› ๐Ÿ’ป ๐ŸŽจ ๐Ÿ“– ๐Ÿ’ก ๐Ÿ‘€ ๐Ÿงช ๐Ÿ”ง
kai
kai

๐Ÿ› ๐Ÿ’ป ๐ŸŽจ ๐Ÿ“– ๐Ÿงช
Dang Truong
Dang Truong

๐Ÿ› ๐Ÿ’ป ๐Ÿ“– ๐Ÿงช
Didier Durand
Didier Durand

๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
Karthik Dani
Karthik Dani

๐Ÿ› ๐Ÿ’ป
jettythek
jettythek

๐Ÿ’ป