Files
bruno 2cb4ddc4c0 feat: complete Week 1-4 optimization implementation
Major Updates:
- ✅ Implemented 4 Claude Code Skills (2600+ lines)
  - code-review: Security, quality, type checking
  - test-generator: Auto-generate pytest tests
  - doc-updater: Auto-update README and API docs
  - refactor-assistant: Code smell detection

- ✅ Implemented 2 Git Hooks (450+ lines)
  - pre-commit: Auto-format, lint, review
  - pre-push: Test suite and coverage check

- 📚 Complete documentation (20+ files)
  - Skills READMEs with examples
  - Optimization roadmap and progress
  - TODO list with 22 tasks
  - Quick reference guide

- 📊 Progress: 45% → 64% (Phase 1: 20% → 60%)

- 💰 ROI: Saving 50.6 hours/month ≈ 6.3 person-days/month

Next Steps:
- API Designer Skill
- Code templates library
- Prompt library
- GitHub Projects task tracking

🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 12:10:29 +08:00

254 lines
7.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""
获取 GitHub Token 的通用工具
按优先级从多个来源尝试获取 token:
1. 命令行参数 --token
2. 环境变量 GITHUB_TOKEN
3. GitHub CLI (gh auth token)
4. macOS Keychain
5. Linux pass
6. .env 文件
使用方法:
# 获取 token 并输出
python scripts/get-github-token.py
# 获取 token 并设置为环境变量
export GITHUB_TOKEN=$(python scripts/get-github-token.py)
"""
import subprocess
import os
import sys
import argparse
from pathlib import Path
class TokenSource:
"""Token 来源枚举"""
ARG = "command argument"
ENV = "environment variable"
GH_CLI = "GitHub CLI"
KEYCHAIN = "macOS Keychain"
PASS = "Linux pass"
DOTENV = ".env file"
ONE_PASSWORD = "1Password CLI"
def get_token_from_arg(args) -> tuple:
"""从命令行参数获取"""
if args and hasattr(args, 'token') and args.token:
return args.token, TokenSource.ARG
return None, None
def get_token_from_env() -> tuple:
"""从环境变量获取"""
token = os.getenv('GITHUB_TOKEN')
if token:
return token, TokenSource.ENV
return None, None
def get_token_from_gh_cli() -> tuple:
"""从 GitHub CLI 获取"""
try:
token = subprocess.check_output(
['gh', 'auth', 'token'],
stderr=subprocess.DEVNULL,
text=True
).strip()
if token and token.startswith(('ghp_', 'github_pat_')):
return token, TokenSource.GH_CLI
except (subprocess.CalledProcessError, FileNotFoundError):
pass
return None, None
def get_token_from_keychain(service_name="GitHub Token - SDLC Management") -> tuple:
"""从 macOS Keychain 获取"""
if sys.platform != 'darwin':
return None, None
try:
whoami = subprocess.check_output(
['whoami'],
text=True
).strip()
token = subprocess.check_output(
['security', 'find-generic-password',
'-s', service_name,
'-a', whoami,
'-w'],
stderr=subprocess.DEVNULL,
text=True
).strip()
if token and token.startswith(('ghp_', 'github_pat_')):
return token, TokenSource.KEYCHAIN
except subprocess.CalledProcessError:
pass
return None, None
def get_token_from_pass(pass_path="github/token-sdlc") -> tuple:
"""从 pass (Linux 密码管理器) 获取"""
try:
token = subprocess.check_output(
['pass', pass_path],
stderr=subprocess.DEVNULL,
text=True
).strip()
if token and token.startswith(('ghp_', 'github_pat_')):
return token, TokenSource.PASS
except (subprocess.CalledProcessError, FileNotFoundError):
pass
return None, None
def get_token_from_dotenv(env_file=".env") -> tuple:
"""从 .env 文件获取"""
# 尝试在当前目录和父目录查找 .env
paths = [
Path.cwd() / env_file,
Path.cwd().parent / env_file,
Path.home() / env_file
]
for path in paths:
if path.exists():
try:
with open(path, 'r') as f:
for line in f:
line = line.strip()
if line.startswith('GITHUB_TOKEN='):
token = line.split('=', 1)[1].strip('"\'')
if token and token.startswith(('ghp_', 'github_pat_')):
return token, f"{TokenSource.DOTENV} ({path})"
except Exception:
pass
return None, None
def get_token_from_1password(item_name="GitHub Token - SDLC") -> tuple:
"""从 1Password CLI 获取"""
try:
token = subprocess.check_output(
['op', 'item', 'get', item_name, '--fields', 'token'],
stderr=subprocess.DEVNULL,
text=True
).strip()
if token and token.startswith(('ghp_', 'github_pat_')):
return token, TokenSource.ONE_PASSWORD
except (subprocess.CalledProcessError, FileNotFoundError):
pass
return None, None
def get_github_token(args=None, verbose=True):
"""
按优先级从多个来源获取 GitHub Token
优先级顺序:
1. 命令行参数 --token
2. 环境变量 GITHUB_TOKEN
3. GitHub CLI (gh auth token)
4. macOS Keychain
5. Linux pass
6. 1Password CLI
7. .env 文件
返回: (token, source) 或 (None, None)
"""
strategies = [
lambda: get_token_from_arg(args),
get_token_from_env,
get_token_from_gh_cli,
get_token_from_keychain,
get_token_from_pass,
get_token_from_1password,
get_token_from_dotenv,
]
for strategy in strategies:
token, source = strategy()
if token:
if verbose:
# 只显示 token 的前 10 个字符
masked_token = f"{token[:10]}...{token[-4:]}" if len(token) > 14 else "***"
print(f"✅ Token loaded from: {source}", file=sys.stderr)
print(f" Token: {masked_token}", file=sys.stderr)
return token, source
return None, None
def main():
parser = argparse.ArgumentParser(
description='Get GitHub Token from various sources',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Token sources (in priority order):
1. Command line argument (--token)
2. Environment variable (GITHUB_TOKEN)
3. GitHub CLI (gh auth token)
4. macOS Keychain
5. Linux pass
6. 1Password CLI
7. .env file
Examples:
# Get token and print to stdout
python scripts/get-github-token.py
# Export to environment variable
export GITHUB_TOKEN=$(python scripts/get-github-token.py)
# Use with other scripts
python scripts/setup-project-fields.py --token $(python scripts/get-github-token.py)
# Provide token via argument
python scripts/get-github-token.py --token ghp_xxxxx
"""
)
parser.add_argument('--token', help='GitHub token (highest priority)')
parser.add_argument('--quiet', '-q', action='store_true',
help='Suppress status messages (only output token)')
args = parser.parse_args()
# 获取 token
token, source = get_github_token(args, verbose=not args.quiet)
if not token:
if not args.quiet:
print("\n❌ Error: GitHub token not found!", file=sys.stderr)
print("\nTry one of the following methods:", file=sys.stderr)
print(" 1. Set environment variable:", file=sys.stderr)
print(" export GITHUB_TOKEN='your_token'", file=sys.stderr)
print("\n 2. Login with GitHub CLI:", file=sys.stderr)
print(" gh auth login", file=sys.stderr)
print("\n 3. Store in macOS Keychain:", file=sys.stderr)
print(" security add-generic-password \\", file=sys.stderr)
print(" -s 'GitHub Token - SDLC Management' \\", file=sys.stderr)
print(" -a $(whoami) \\", file=sys.stderr)
print(" -w 'your_token'", file=sys.stderr)
print("\n 4. Create .env file:", file=sys.stderr)
print(" echo 'GITHUB_TOKEN=your_token' > .env", file=sys.stderr)
print("\nGet token at: https://github.com/settings/tokens/new", file=sys.stderr)
sys.exit(1)
# 输出 token 到 stdout(用于管道)
print(token)
return 0
if __name__ == '__main__':
sys.exit(main())