#!/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' {name}') 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('
') for s in staff: avatar = s.get("avatar_url", "") if "?" not in avatar: avatar += "?v=4&s=120" name = s.get("name", s.get("login", "")) profile = s.get("profile", f"https://github.com/{s.get('login', '')}") role = s.get("_role", "") lines.append(f' ') lines.append(f' {name}') lines.append(f'
{name}
') lines.append(f'
{role}
') lines.append('
') lines.append("") # Add manual staff for s in MANUAL_STAFF: lines.append(f' ') lines.append(f' {s[') lines.append(f'
{s["name"]}
') lines.append(f'
{s["role"]}
') lines.append('
') 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' {name}') 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())