Files
gitea/tools/gitea-link.sh
jiantw83andClaude Opus 5 f8123e829b feat(gitea): 新增 wiki 轉議題技能
What:新增 wiki-to-issue 技能,把一頁 wiki 轉成同一個存取庫的議題;配套新增 tools/gitea-link.sh 解析連結、tools/issue.sh 讀寫議題。

Why:wiki 頁要變成可追蹤的工作時,原本得自己拼 API:組 JSON、查標籤 id、挑回應欄位,跳脫一錯就把對外的議題內容寫壞。

How:連結是唯一入口,gitea-link.sh 解不出 wiki 頁就中止,不猜存取庫也不猜頁名;標籤只從既有的挑;站台沒有專案看板 API 時據實回報請使用者手動拖,不假裝關聯成功。

Who:使用 jsc 技能組、需要把 wiki 內容交辦出去的人。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 09:19:08 +08:00

78 lines
2.9 KiB
Bash
Executable File
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.
#!/usr/bin/env sh
# gitea-link.sh — 解析 Gitea 的 wiki 頁或議題連結(供 jsc-gitea:wiki-to-issue、html-export 使用)。
#
# 為什麼要有這支腳本:兩支技能都以「一條連結」為唯一入口,沒有連結就中斷。連結長什麼樣、
# 哪一段是存取庫、哪一段是頁名,是固定的字串規則,交給模型每次自己拆,拆錯就寫到別的存取庫去。
#
# 用法:
# gitea-link.sh parse <url> 解析連結,印出可直接 eval 的欄位
#
# parse 輸出(每行一個 key=value,值已加單引號):
# kind='wiki' repo='owner/repo' page='PAGE_NAME' host='https://gitea.example'
# kind='issue' repo='owner/repo' index='12' host='https://gitea.example'
#
# 認得的形式:
# https://host/{owner}/{repo}/wiki/{page} (page 可含 %XX 編碼,會還原)
# https://host/{owner}/{repo}/wiki/{page}/_edit (尾巴的 _edit、_new 會去掉)
# https://host/{owner}/{repo}/issues/{index}
# https://host/{owner}/{repo}/issues/{index}#issuecomment-123
#
# 結束碼: 0=解析成功 2=用法錯誤 3=不是認得的 wiki 或議題連結
#
# 陷阱:
# - 結束碼 3 由呼叫端當成「沒有連結」處理,直接中斷流程,不要退回去猜存取庫或頁名。
# - 只解析連結本身,不打網路,也不檢查頁面存不存在;那是 wiki-get 與 issue.sh 的事。
set -eu
usage() {
echo 'usage: gitea-link.sh parse <url>' >&2
exit 2
}
[ "$#" -eq 2 ] || usage
[ "$1" = parse ] || usage
url="$2"
[ -n "$url" ] || usage
python3 - "$url" <<'PY'
import re, sys
from urllib.parse import urlsplit, unquote
url = sys.argv[1].strip()
if not re.match(r'^https?://', url):
print('[jsc][連結解析][ERR]:連結要以 http:// 或 https:// 開頭。', file=sys.stderr)
sys.exit(3)
u = urlsplit(url)
host = f'{u.scheme}://{u.netloc}'
parts = [p for p in u.path.split('/') if p]
if len(parts) < 4:
print('[jsc][連結解析][ERR]:認不出存取庫與頁面,需要 /{owner}/{repo}/wiki/{page} 或 /{owner}/{repo}/issues/{index}。', file=sys.stderr)
sys.exit(3)
owner, repo, kind = parts[0], parts[1], parts[2]
rest = parts[3:]
def out(**kv):
for k, v in kv.items():
print(f"{k}='{str(v)}'")
if kind == 'wiki':
while rest and rest[-1] in ('_edit', '_new', '_pages'):
rest.pop()
if not rest:
print('[jsc][連結解析][ERR]:wiki 連結少了頁名。', file=sys.stderr)
sys.exit(3)
page = unquote('/'.join(rest))
out(kind='wiki', repo=f'{owner}/{repo}', page=page, host=host)
elif kind == 'issues':
idx = rest[0].split('#')[0]
if not idx.isdigit():
print('[jsc][連結解析][ERR]:議題編號不是數字。', file=sys.stderr)
sys.exit(3)
out(kind='issue', repo=f'{owner}/{repo}', index=idx, host=host)
else:
print(f'[jsc][連結解析][ERR]:只認得 wiki 與 issues 連結,收到「{kind}」。', file=sys.stderr)
sys.exit(3)
PY