diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d2524114..fc79bfc4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,4 +15,11 @@ repos: entry: uv run python scripts/validate_notebooks.py language: system files: '\.ipynb$' - pass_filenames: true \ No newline at end of file + pass_filenames: true + + - id: validate-authors-sorted + name: Validate and sort authors.yaml + entry: uv run python scripts/validate_authors_sorted.py --fix + language: system + files: 'authors\.yaml$' + pass_filenames: false \ No newline at end of file diff --git a/Makefile b/Makefile index c204b89e..ab9fb3b1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help format lint check fix test clean install +.PHONY: help format lint check fix test clean install sort-authors # Default target help: @@ -10,6 +10,7 @@ help: @echo " make test - Run tests" @echo " make install - Install dependencies" @echo " make clean - Remove cache files" + @echo " make sort-authors - Sort authors.yaml alphabetically" # Format code with ruff format: @@ -54,3 +55,8 @@ clean: find . -type d -name ".ruff_cache" -exec rm -rf {} + 2>/dev/null || true find . -type f -name "*.pyc" -delete 2>/dev/null || true @echo "Cache cleaned!" + +# Sort authors.yaml alphabetically +sort-authors: + @echo "Sorting authors.yaml..." + uv run python scripts/validate_authors_sorted.py --fix diff --git a/authors.yaml b/authors.yaml index c5f8c05d..4e411140 100644 --- a/authors.yaml +++ b/authors.yaml @@ -3,6 +3,13 @@ # This file maps author GitHub usernames (used in registry.yaml) to their full details # for display on the website. +Adriaan-ANT: + name: Adriaan Engelbrecht + avatar: https://avatars.githubusercontent.com/u/222316629?v=4 +alexalbertt: + name: Alex Albert + website: https://github.com/alexalbertt + avatar: https://avatars.githubusercontent.com/u/34638987?v=4 Anthropic: name: Anthropic website: https://www.anthropic.com @@ -11,26 +18,25 @@ Briiick: name: Alexander Bricken website: https://bricken.co avatar: https://avatars.githubusercontent.com/u/44481408?v=4 -GarvanD: - name: Garvan Doyle - website: https://garvandoyle.com - avatar: https://avatars.githubusercontent.com/u/22383376?v=4 -JiriDeJonghe: - name: Jiri De Jonghe - website: https://github.com/JiriDeJonghe - avatar: https://avatars.githubusercontent.com/u/33628402?v=4 -alexalbertt: - name: Alex Albert - website: https://github.com/alexalbertt - avatar: https://avatars.githubusercontent.com/u/34638987?v=4 davidhershey: name: David Hershey website: https://github.com/davidhershey avatar: https://avatars.githubusercontent.com/u/11651858?v=4 +GarvanD: + name: Garvan Doyle + website: https://garvandoyle.com + avatar: https://avatars.githubusercontent.com/u/22383376?v=4 +henrykeetay: + name: Henry Keetay + avatar: https://avatars.githubusercontent.com/u/227475578?v=4 james-briggs: name: james-briggs website: https://github.com/James-Briggs avatar: https://avatars.githubusercontent.com/u/64431405?v=4 +JiriDeJonghe: + name: Jiri De Jonghe + website: https://github.com/JiriDeJonghe + avatar: https://avatars.githubusercontent.com/u/33628402?v=4 jpvajda: name: john-vajda website: https://github.com/jpvajda @@ -39,6 +45,13 @@ maheshmurag: name: Mahesh Murag website: https://github.com/maheshmurag avatar: https://avatars.githubusercontent.com/u/5667029?v=4 +nadine-anthropic: + name: Nadine Yasser + avatar: https://avatars.githubusercontent.com/u/238355370?v=4 +PedramNavid: + name: Pedram Navid + website: http://x.com/pdrmnvd + avatar: https://avatars.githubusercontent.com/u/1045990 ravi03071991: name: Ravi Theja website: https://sites.google.com/view/ravi-theja @@ -51,16 +64,7 @@ RichmondAlake: name: Richmond Alake website: https://github.com/RichmondAlake avatar: https://github.com/RichmondAlake.png -PedramNavid: - name: Pedram Navid - website: http://x.com/pdrmnvd - avatar: https://avatars.githubusercontent.com/u/1045990 -nadine-anthropic: - name: Nadine Yasser - avatar: https://avatars.githubusercontent.com/u/238355370?v=4 -henrykeetay: - name: Henry Keetay - avatar: https://avatars.githubusercontent.com/u/227475578?v=4 -Adriaan-ANT: - name: Adriaan Engelbrecht - avatar: https://avatars.githubusercontent.com/u/222316629?v=4 \ No newline at end of file +zealoushacker: + name: Alex Notov + website: https://github.com/zealoushacker + avatar: https://avatars.githubusercontent.com/u/346275?v=4 diff --git a/pyproject.toml b/pyproject.toml index 4cd138f4..308e2981 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,8 @@ dev = [ "pytest>=8.3.3", "nbval>=0.11.0", "pre-commit>=3.8.0", - "nbconvert>=7.16.0", + "nbconvert>=7.16.0", + "pyyaml>=6.0.3", ] [tool.hatch.build.targets.wheel] diff --git a/registry.yaml b/registry.yaml index ddc481a7..1b387363 100644 --- a/registry.yaml +++ b/registry.yaml @@ -355,7 +355,7 @@ PowerPoint, PDF skills. path: skills/notebooks/01_skills_introduction.ipynb authors: - - Anthropic + - zealoushacker date: '2025-10-14' categories: - Skills @@ -364,7 +364,7 @@ PowerPoint, PDF skills. path: skills/notebooks/02_skills_financial_applications.ipynb authors: - - Anthropic + - zealoushacker date: '2025-10-15' categories: - Skills @@ -373,7 +373,7 @@ organizational workflows. path: skills/notebooks/03_skills_custom_development.ipynb authors: - - Anthropic + - zealoushacker date: '2025-10-15' categories: - Skills @@ -528,7 +528,7 @@ context editing. path: tool_use/memory_cookbook.ipynb authors: - - Anthropic + - zealoushacker date: '2025-05-22' categories: - Tools diff --git a/scripts/validate_authors_sorted.py b/scripts/validate_authors_sorted.py new file mode 100644 index 00000000..0dfdf53a --- /dev/null +++ b/scripts/validate_authors_sorted.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +"""Validate and optionally fix authors.yaml sorting (case-insensitive alphabetical).""" + +import argparse +import sys +from pathlib import Path +from typing import Any + +import yaml + +# Ensure UTF-8 output on Windows +if sys.platform == "win32": + sys.stdout.reconfigure(encoding="utf-8") + sys.stderr.reconfigure(encoding="utf-8") + +AUTHORS_FILE = Path(__file__).parent.parent / "authors.yaml" + +HEADER = """\ +# yaml-language-server: $schema=./.github/authors_schema.json +# Authors mapping: GitHub username -> Author details +# This file maps author GitHub usernames (used in registry.yaml) to their full details +# for display on the website. + +""" + + +def load_authors() -> dict[str, Any] | None: + """Load authors.yaml and return the data.""" + with open(AUTHORS_FILE, encoding="utf-8") as f: + return yaml.safe_load(f) + + +def is_sorted(data: dict) -> bool: + """Check if the keys are sorted alphabetically (case-insensitive).""" + keys = list(data.keys()) + return keys == sorted(keys, key=str.lower) + + +def sort_authors(data: dict, check_only: bool = False) -> bool: + """Sort and write authors.yaml. Returns True if file was/would be changed.""" + sorted_data = dict(sorted(data.items(), key=lambda x: x[0].lower())) + + if check_only: + return list(data.keys()) != list(sorted_data.keys()) + + with open(AUTHORS_FILE, "w", encoding="utf-8") as f: + f.write(HEADER) + yaml.dump(sorted_data, f, default_flow_style=False, allow_unicode=True, sort_keys=False) + + return True + + +def show_diff(keys: list, sorted_keys: list) -> None: + """Show the difference between current and expected order.""" + print("authors.yaml is not sorted alphabetically (case-insensitive).") + print("\nCurrent order:") + for k in keys: + print(f" {k}") + + print("\nExpected order:") + for k in sorted_keys: + print(f" {k}") + + print("\nOut of place entries:") + for i, (current, expected) in enumerate(zip(keys, sorted_keys, strict=False)): + if current != expected: + print(f" Position {i}: got '{current}', expected '{expected}'") + + +def main(): + parser = argparse.ArgumentParser(description="Validate or fix authors.yaml sorting") + parser.add_argument( + "--fix", action="store_true", help="Sort the file instead of just validating" + ) + args = parser.parse_args() + + data = load_authors() + + if not data: + print("authors.yaml is empty") + sys.exit(0) + + already_sorted = is_sorted(data) + + if args.fix: + if already_sorted: + print("1 file left unchanged") + else: + sort_authors(data) + print("1 file reformatted") + sys.exit(0) + + # Validation mode + if already_sorted: + print("1 file left unchanged") + sys.exit(0) + + keys = list(data.keys()) + sorted_keys = sorted(keys, key=str.lower) + show_diff(keys, sorted_keys) + print("\nRun with --fix to sort automatically") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/uv.lock b/uv.lock index db658d5a..a0ea15c5 100644 --- a/uv.lock +++ b/uv.lock @@ -138,6 +138,7 @@ dev = [ { name = "nbval" }, { name = "pre-commit" }, { name = "pytest" }, + { name = "pyyaml" }, { name = "ruff" }, ] @@ -160,6 +161,7 @@ dev = [ { name = "nbval", specifier = ">=0.11.0" }, { name = "pre-commit", specifier = ">=3.8.0" }, { name = "pytest", specifier = ">=8.3.3" }, + { name = "pyyaml", specifier = ">=6.0.3" }, { name = "ruff", specifier = ">=0.14.2" }, ]