#!/usr/bin/env python3
"""
Generate team.md from .all-contributorsrc for TinyTorch site.
This script reads the .all-contributorsrc file and generates the team.md page
with all contributors automatically. Run this before building the site.
Usage:
python3 scripts/generate_team.py
"""
import json
from pathlib import Path
# Contribution type to emoji mapping (matches all-contributors spec)
CONTRIBUTION_EMOJIS = {
"bug": "๐ชฒ",
"code": "๐งโ๐ป",
"doc": "โ๏ธ",
"design": "๐จ",
"ideas": "๐ง ",
"review": "๐",
"test": "๐งช",
"tool": "๐ ๏ธ",
"content": "โ๏ธ",
"maintenance": "๐ ๏ธ",
}
# Special roles for staff members (not auto-generated)
STAFF_MEMBERS = {
"profvjreddi": {
"role": "๐ค Nerdy Professor ยท Harvard University",
"bio": "Gordon McKay Professor of Electrical Engineering at Harvard. Passionate about creating the next generation of AI engineers.",
"is_lead": True,
},
"AndreaMattiaGaravagno": {
"role": "๐งญ Tech Lead",
"is_staff": True,
},
"kai4avaya": {
"role": "๐ Web Wizard",
"is_staff": True,
},
}
# Non-GitHub staff (manually added)
MANUAL_STAFF = [
{
"name": "Kari Janapareddi",
"role": "๐ Chief of Staff",
"avatar_url": "https://ui-avatars.com/api/?name=Kari+Janapareddi&background=f97316&color=fff&size=120",
"profile": "#",
},
]
def load_contributors(rc_path: Path) -> list[dict]:
"""Load contributors from .all-contributorsrc file."""
if not rc_path.exists():
print(f"Warning: {rc_path} not found")
return []
with open(rc_path) as f:
data = json.load(f)
return data.get("contributors", [])
def get_contribution_emojis(contributions: list[str]) -> str:
"""Convert contribution types to emoji string."""
emojis = []
for contrib in contributions:
if contrib in CONTRIBUTION_EMOJIS:
emojis.append(CONTRIBUTION_EMOJIS[contrib])
return " ".join(emojis)
def generate_team_md(contributors: list[dict]) -> str:
"""Generate the team.md content from contributors list."""
# Separate lead, staff, and regular contributors
lead = None
staff = []
regular = []
for c in contributors:
login = c.get("login", "")
if login in STAFF_MEMBERS:
info = STAFF_MEMBERS[login]
c["_role"] = info.get("role", "")
c["_bio"] = info.get("bio", "")
if info.get("is_lead"):
lead = c
elif info.get("is_staff"):
staff.append(c)
else:
regular.append(c)
else:
regular.append(c)
# Sort regular contributors by number of contributions (descending)
regular.sort(key=lambda x: len(x.get("contributions", [])), reverse=True)
# Build the markdown
lines = []
# Header
lines.append("# Team")
lines.append("")
lines.append("**Meet the people building TinyTorch.**")
lines.append("")
lines.append("TinyTorch is built by a passionate community dedicated to making ML systems education accessible to everyone.")
lines.append("")
# CSS styles
lines.append("```{raw} html")
lines.append(CSS_STYLES)
lines.append("")
# Role legend
lines.append('
')
lines.append(' ๐ชฒ Bug Hunter')
lines.append(' ๐งโ๐ป Code Warrior')
lines.append(' โ๏ธ Documentation')
lines.append(' ๐จ Design')
lines.append(' ๐ง Ideas')
lines.append(' ๐ Reviewer')
lines.append(' ๐งช Testing')
lines.append(' ๐ ๏ธ Tooling')
lines.append('
')
lines.append("")
# Team grid
lines.append('')
# Lead
if lead:
avatar = lead.get("avatar_url", "")
if "?" not in avatar:
avatar += "?v=4&s=200"
name = lead.get("name", lead.get("login", ""))
profile = lead.get("profile", f"https://github.com/{lead.get('login', '')}")
emojis = get_contribution_emojis(lead.get("contributions", []))
lines.append('
')
lines.append(f'
')
lines.append(f'
')
lines.append(' ')
lines.append('
')
lines.append(f'
{name}
')
lines.append(f'
{lead.get("_role", "")}
')
lines.append(f'
{lead.get("_bio", "")}
')
lines.append(f'
{emojis}
')
lines.append('
')
lines.append('
')
lines.append("")
# Staff section
if staff or MANUAL_STAFF:
lines.append('
Community Staff
')
lines.append("")
lines.append('
')
lines.append("")
# Contributors section
if regular:
lines.append('
Contributors
')
for c in regular:
avatar = c.get("avatar_url", "")
if "?" not in avatar:
avatar += "?v=4&s=160"
name = c.get("name", c.get("login", ""))
profile = c.get("profile", f"https://github.com/{c.get('login', '')}")
emojis = get_contribution_emojis(c.get("contributions", []))
lines.append(f'
')
lines.append(f'
')
lines.append(f' {name}')
lines.append(f' {emojis}')
lines.append(' ')
lines.append('
')
lines.append('```')
lines.append("")
# Footer
lines.append("## Join the Team")
lines.append("")
lines.append("TinyTorch is open source and we welcome contributors of all experience levels!")
lines.append("")
lines.append("**Ways to get involved:**")
lines.append("")
lines.append("- ๐ชฒ **Found a bug?** [Report it on GitHub](https://github.com/harvard-edge/cs249r_book/issues)")
lines.append("- ๐ก **Have an idea?** [Start a discussion](https://github.com/harvard-edge/cs249r_book/discussions)")
lines.append("- ๐งโ๐ป **Want to contribute code?** [See our contributing guide](https://github.com/harvard-edge/cs249r_book/blob/main/CONTRIBUTING.md)")
lines.append("- โ๏ธ **Improve documentation?** Submit a pull request")
lines.append("")
lines.append('**Get recognized:** Comment on any issue or PR with `@all-contributors please add @username for bug, code, doc, or ideas`')
lines.append("")
lines.append("")
lines.append("## Contact")
lines.append("")
lines.append("- **GitHub Issues**: [Report bugs or request features](https://github.com/harvard-edge/cs249r_book/issues)")
lines.append("- **GitHub Discussions**: [Ask questions or share ideas](https://github.com/harvard-edge/cs249r_book/discussions)")
lines.append("- **Project Lead**: [Prof. Vijay Janapa Reddi](https://scholar.harvard.edu/vijay-janapa-reddi) ยท Harvard University")
lines.append("")
return "\n".join(lines)
# CSS styles (kept separate for readability)
CSS_STYLES = """"""
def main():
# Find the .all-contributorsrc file
script_dir = Path(__file__).parent
site_dir = script_dir.parent
tinytorch_dir = site_dir.parent
rc_path = tinytorch_dir / ".all-contributorsrc"
# Load contributors
contributors = load_contributors(rc_path)
if not contributors:
print("No contributors found!")
return 1
print(f"Found {len(contributors)} contributors")
# Generate team.md
content = generate_team_md(contributors)
# Write to team.md
team_path = site_dir / "team.md"
with open(team_path, "w") as f:
f.write(content)
print(f"Generated {team_path}")
return 0
if __name__ == "__main__":
exit(main())