Files
gitea-cli/CLAUDE.md
timmy f28f20ba56 feat(config): support multiple Gitea profiles via GITEA_PROFILE env var
未設時讀 config.env(行為不變);設了讀 config.<profile>.env。
.gitignore 新增 config.*.env 但保留 config.example.env。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 16:18:16 +08:00

110 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 裡沒有測試buildlint開發流程就是`scripts/*.sh``bash -n` 語法檢查 → 在另一個 tmp 目錄實際跑一次看看。所有腳本共用 `scripts/lib/common.sh`
實際使用腳本時(在任何專案目錄下):
```bash
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 絕不落地
**修改任何腳本時都要守住**
1. `origin` remote 永遠是**乾淨 URL**,不含 token
2. Token 只能出現在 `config.env`、呼叫過程的環境變數、以及 `scripts/lib/common.sh` 裡的 `gitea_api` / `git_*_with_token` 函式內
3. Token 絕不進入 `.git/config`、remote URL、任何 logstdout/stderr
4. `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_FILE`
- `git_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/repo`
- `confirm_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 URL
- `list.sh` → repo 清單
- `clone.sh` → clone 到的絕對路徑
- `release.sh` → release URL + 每個 asset URL
- `tag.sh` → tag 名
- `delete.sh` → 空
使用者可以 `URL=$(publish.sh)` 拿結果。
### 新腳本骨架(照抄)
寫新腳本時以這個為起點:
```bash
#!/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`),不要硬編碼個人資訊