未設時讀 config.env(行為不變);設了讀 config.<profile>.env。 .gitignore 新增 config.*.env 但保留 config.example.env。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.2 KiB
4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
專案性質
這是一個 Claude Code skill(根目錄的 SKILL.md 就是 skill 定義檔)。本身不是一般應用程式,產物是一組 bash 腳本(scripts/*.sh),針對自架 Gitea 做常見操作。publish.sh 是最早的腳本,其他腳本是逐步擴充而來。
常用指令
在本 repo 裡沒有測試/build/lint;開發流程就是:改 scripts/*.sh → bash -n 語法檢查 → 在另一個 tmp 目錄實際跑一次看看。所有腳本共用 scripts/lib/common.sh。
實際使用腳本時(在任何專案目錄下):
bash /path/to/gitea-cli/scripts/publish.sh [repo] [public|private] [-m "msg"]
bash /path/to/gitea-cli/scripts/list.sh [--private|--public] [--format table|tsv|name]
# ... 其他腳本見 SKILL.md / README.md
首次使用前要 cp config.example.env config.env 並填入 GITEA_URL / GITEA_USER / GITEA_TOKEN。
架構與關鍵不變量
安全模型:token 絕不落地
修改任何腳本時都要守住:
originremote 永遠是乾淨 URL,不含 token- Token 只能出現在
config.env、呼叫過程的環境變數、以及scripts/lib/common.sh裡的gitea_api/git_*_with_token函式內 - Token 絕不進入
.git/config、remote URL、任何 log(stdout/stderr) config.env被.gitignore排除
共用 lib scripts/lib/common.sh
所有 API / push / clone 都走 lib,腳本本身不寫 curl 也不直接操作 credential helper。lib 提供:
load_config:讀config.env(或GITEA_PROFILE指定時讀config.<profile>.env),檢查三個變數都非空非預設gitea_api <METHOD> <path> [json-body]:單一 API 呼叫入口;回傳後讀$HTTP_CODE與$GITEA_API_RESP_FILEgit_push_with_token <branch>/git_push_tag_with_token <tag>/git_clone_with_token <clean-url> <target>:一次性帶 token 的 git 操作infer_repo_from_cwd:從git remote get-url origin推斷owner/repoconfirm_destructive <prompt>/confirm_exact_match <expected>:破壞性操作互動;GITEA_YES=1或腳本處理的-y可略過log_info/log_ok/log_warn/log_err/log_done:統一前綴、全部寫 stderr
什麼不放進 lib(刻意留在各腳本):
- 各腳本自己的 arg 解析(每支不同)
- JSON body 組字串(放在呼叫處最直觀;複雜的用 jq 在呼叫端組)
publish.sh的三種 git 狀態分支(publish 獨有)
stdout / stderr 分流
- stderr:
log_*進度訊息、錯誤 - stdout:最終結構化輸出
publish.sh/rename.sh/visibility.sh/archive.sh/meta.sh→ repo web URLlist.sh→ repo 清單clone.sh→ clone 到的絕對路徑release.sh→ release URL + 每個 asset URLtag.sh→ tag 名delete.sh→ 空
使用者可以 URL=$(publish.sh) 拿結果。
新腳本骨架(照抄)
寫新腳本時以這個為起點:
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/common.sh
source "${SCRIPT_DIR}/lib/common.sh"
load_config
# require_cmd jq # 若會用到
usage() {
cat >&2 <<'EOF'
Usage: <script>.sh ...
EOF
exit 1
}
# arg parsing
# ...
log_info "..."
gitea_api METHOD "/path" "$BODY"
case "$HTTP_CODE" in
2??) log_ok "..." ;;
404) log_err "..."; exit 1 ;;
*) log_err "... (HTTP ${HTTP_CODE})"; { cat "$GITEA_API_RESP_FILE"; echo ""; } >&2; exit 1 ;;
esac
log_done "完成"
echo "<結構化結果>" # stdout
相容性限制
使用 Gitea API v1,Forgejo 相容;GitHub / GitLab 不相容。要擴充到其他平台要重寫 API 呼叫處。
寫入偏好
- 腳本訊息與使用者文件皆為繁體中文(台灣用語)
- 沿用既有風格:▶ 進行中、✓ 成功、⚠ 警告、❌ 失敗、✅ 完成
SKILL.md是給 Claude 讀的 skill metadata + 簡短說明;README.md是給人看的完整文件。修改功能時兩份都要同步- 範例路徑用通用形式(
/path/to/gitea-cli),不要硬編碼個人資訊