diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b04a2ca --- /dev/null +++ b/.editorconfig @@ -0,0 +1,27 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.py] +indent_size = 4 + +[*.md] +# Preserve Markdown hard line breaks, matching the trailing-whitespace hook. +trim_trailing_whitespace = false + +[LICENSE] +# Preserve the standard license's fixed-layout indentation. +indent_size = unset +indent_style = unset + +[Makefile] +indent_style = tab diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 766bb08..7688391 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,6 +46,13 @@ repos: description: trims trailing whitespace args: [--markdown-linebreak-ext=md] + - repo: https://github.com/editorconfig-checker/editorconfig-checker.python + rev: e8b4e28241a9ae8296ba6e4a491b5da4eda73283 # frozen: 3.11.1 + hooks: + - id: editorconfig-checker + name: run editorconfig checker + description: check that text files follow the .editorconfig rules + - repo: https://github.com/codespell-project/codespell rev: 57b21406f092110c18776e39b0bda50d37c945c8 # frozen: v2.4.3 hooks: diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py index ef54f57..7efc99e 100644 --- a/scripts/leaderboard.py +++ b/scripts/leaderboard.py @@ -89,33 +89,33 @@ # fetched. Each entry matches the levels.json schema. FALLBACK_LEVELS = [ {"level": 0, "name": "Newbie", "emoji": "🐣", "color": "#94a3b8", - "rarity": "common", "description": "Hello World."}, + "rarity": "common", "description": "Hello World."}, {"level": 1, "name": "Script Kid", "emoji": "πŸ›Ή", "color": "#10b981", - "rarity": "common", "description": "Copy-paste from Stack Overflow."}, + "rarity": "common", "description": "Copy-paste from Stack Overflow."}, {"level": 5, "name": "Data Miner", "emoji": "πŸ’Ž", "color": "#06b6d4", - "rarity": "uncommon", "description": "Sifting through JSON for gold."}, + "rarity": "uncommon", "description": "Sifting through JSON for gold."}, {"level": 10, "name": "Architect", "emoji": "πŸ‘‘", "color": "#ef4444", - "rarity": "epic", "description": "You dream in UML diagrams."}, + "rarity": "epic", "description": "You dream in UML diagrams."}, {"level": 25, "name": "Kingslayer", "emoji": "πŸ—‘οΈ", "color": "#facc15", - "rarity": "epic", "description": "There are no men like me."}, + "rarity": "epic", "description": "There are no men like me."}, {"level": 50, "name": "Ring-bearer", "emoji": "πŸ’", "color": "#fbbf24", - "rarity": "legendary", "description": "Carry it to the fire."}, + "rarity": "legendary", "description": "Carry it to the fire."}, {"level": 100, "name": "Eru IlΓΊvatar", "emoji": "✨", "color": "#fbbf24", - "rarity": "mythic", "description": "The Creator."}, + "rarity": "mythic", "description": "The Creator."}, {"level": 200, "name": "One With The Force", "emoji": "🌌", - "color": "#6366f1", "rarity": "mythic", - "description": "Luminous beings are we."}, + "color": "#6366f1", "rarity": "mythic", + "description": "Luminous beings are we."}, {"level": 250, "name": "The Source", "emoji": "πŸ”†", - "color": "#ffffff", "rarity": "mythic", - "description": "Where the path ends and the cycle restarts."}, + "color": "#ffffff", "rarity": "mythic", + "description": "Where the path ends and the cycle restarts."}, {"level": 500, "name": "The Creative Director", "emoji": "✨", - "color": "#ffffff", "rarity": "mythic", - "description": "The vision is complete. Roll credits."}, + "color": "#ffffff", "rarity": "mythic", + "description": "The vision is complete. Roll credits."}, {"level": 750, "name": "Meta-Reality Architect", "emoji": "πŸ›οΈ", - "color": "#fbbf24", "rarity": "mythic", - "description": "You designed the cage you live in. It's quite nice."}, + "color": "#fbbf24", "rarity": "mythic", + "description": "You designed the cage you live in. It's quite nice."}, {"level": 1000, "name": "Infinity", "emoji": "♾️", "color": "#000000", - "rarity": "absolute", "description": "Beyond all limits."}, + "rarity": "absolute", "description": "Beyond all limits."}, ] # --- Gamification: Achievement definitions --- @@ -133,53 +133,53 @@ def _peak_rarity_rank(contrib): ACHIEVEMENTS = [ ("🎯", "First Commit", "Make your first contribution", - lambda c: c["commits"] >= 1), + lambda c: c["commits"] >= 1), ("βœ‹", "High Five", "Reach 5 commits", - lambda c: c["commits"] >= 5), + lambda c: c["commits"] >= 5), ("🌟", "Rising Star", "Reach 25 commits", - lambda c: c["commits"] >= 25), + lambda c: c["commits"] >= 25), ("🌐", "Explorer", "Contribute to 2+ repositories", - lambda c: c["repos_count"] >= 2), + lambda c: c["repos_count"] >= 2), ("πŸ—οΈ", "Architect", "Contribute to 3+ repositories", - lambda c: c["repos_count"] >= 3), + lambda c: c["repos_count"] >= 3), ("πŸ’ͺ", "Dedicated", "Reach 50 commits", - lambda c: c["commits"] >= 50), + lambda c: c["commits"] >= 50), ("πŸš€", "Rockstar", "Reach 100 commits", - lambda c: c["commits"] >= 100), + lambda c: c["commits"] >= 100), ("πŸ›‘οΈ", "Quarter Master", "Reach 250 commits", - lambda c: c["commits"] >= 250), + lambda c: c["commits"] >= 250), ("⭐", "Superstar", "Reach 500 commits", - lambda c: c["commits"] >= 500), + lambda c: c["commits"] >= 500), ("πŸ‘‘", "Elite", "Reach 750 commits", - lambda c: c["commits"] >= 750), + lambda c: c["commits"] >= 750), ("πŸ†", "Thousand Club", "Reach 1000 commits", - lambda c: c["commits"] >= 1000), + lambda c: c["commits"] >= 1000), ("🌱", "Quick Streak", "Commit for 3+ consecutive days", - lambda c: c["longest_streak"] >= 3), + lambda c: c["longest_streak"] >= 3), ("πŸ“†", "Weekday Warrior", "Commit for 5+ consecutive days", - lambda c: c["longest_streak"] >= 5), + lambda c: c["longest_streak"] >= 5), ("πŸ“…", "Week Streak", "Commit for 7+ consecutive days", - lambda c: c["longest_streak"] >= 7), + lambda c: c["longest_streak"] >= 7), ("πŸ’«", "Fortnight Streak", "Commit for 14+ consecutive days", - lambda c: c["longest_streak"] >= 14), + lambda c: c["longest_streak"] >= 14), ("πŸ—“οΈ", "Three-Week Streak", "Commit for 21+ consecutive days", - lambda c: c["longest_streak"] >= 21), + lambda c: c["longest_streak"] >= 21), ("πŸ”₯", "Month Streak", "Commit for 30+ consecutive days", - lambda c: c["longest_streak"] >= 30), + lambda c: c["longest_streak"] >= 30), ("⬜", "Common Ground", "Reach a common-rarity level", - lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["common"]), + lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["common"]), ("🟩", "Uncommon Rising", "Reach an uncommon-rarity level", - lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["uncommon"]), + lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["uncommon"]), ("🟦", "Rare Find", "Reach a rare-rarity level", - lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["rare"]), + lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["rare"]), ("πŸŸͺ", "Epic Coder", "Reach an epic-rarity level", - lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["epic"]), + lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["epic"]), ("🟧", "Legendary Dev", "Reach a legendary-rarity level", - lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["legendary"]), + lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["legendary"]), ("πŸŸ₯", "Mythic Status", "Reach a mythic-rarity level", - lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["mythic"]), + lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["mythic"]), ("⬛", "Absolute Power", "Reach an absolute-rarity level", - lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["absolute"]), + lambda c: _peak_rarity_rank(c) >= _RARITY_RANK["absolute"]), ] @@ -262,8 +262,8 @@ def resolve_login_from_noreply(email): """Extract a GitHub login from a noreply email address. Handles both formats: - - username@users.noreply.github.com - - 12345678+username@users.noreply.github.com + - username@users.noreply.github.com + - 12345678+username@users.noreply.github.com """ if email.endswith("@users.noreply.github.com"): local = email.split("@")[0]